ns-3 meeting summary, November 2007 The ns-3 development team met at the University of Washington from November 26-30, 2007, to review the ns-3 codebase and discuss next development steps and roadmap. Attendees: ========== Matt Adams (for wifi discussions) Raj Bhattacharjea Craig Dowell Tom Henderson Joe Kopena Mathieu Lacage Ilango Purushothaman (for wifi) George Riley Sumit Roy (for wifi) Fei Ye (for wifi) Main topics covered: ============== - Packet object design -- whether they support interface aggregation -- whether they should subclass Object - Socket API issues -- Threading and blocking socket calls -- char pointer-based Send() calls - Whether to rename, reorganize code to better distingish between Components, Objects, and Interfaces, or otherwise how to better explain the system - ns-3-wifi, ns-2 802.11 work, and wireless in general - Layout and topology code, and linking to topology generators - The TCP repository and Internet Node internal architecture - API stabilization is an important goal to work toward for the sake of early adopters, and affects task ordering and plans. - Roadmap items Action items and agreements: ============================ - No need to put Packet into QI framework for now; we can add later if need arises, without changing the API (which is Ptr). - Design a RefCountObject base class and have class Packet subclass from it. This avoids ref counted objects that don't support QI from having to reimplement Ref and Unref. Public methods would be Ref(), Unref(), and Dispose(). This is independent of class Object. (George) - Document packet metadata and interaction with ascii tracing better. (Mathieu) - Add Send and SendTo methods to the socket API to accept char pointers; document that the callee immediately makes a copy of it. These are non-virtual and simply immediately create a Packet and pass it on to the corresponding Send(Packet) methods. (Raj) - Document how to use Packet Header and Footer classes to conveniently add data to a packet. (Mathieu) - Investigate threading and blocking APIs needed to support NRL Protolib and the protocols built on it. (Joe) - After long discussion, decided on no change to class names (IObject, CObject), file names, and source code directory organization to better distinguish between Interface and Components. Instead, we will try to resolve possible ambiguity in these concepts within the tutorial and documentation. We will not require use of a component manager to create objects. (all) - Identified a number of objects that require iids, cids, and agreed to be more consistent about adding InterfaceId and ClassId where appropriate. (Craig to work on some guidelines for documenting this) - Two conventions regarding default values will be adopted: -- Default values used to set values on an object should, in general, also have getters and setters to access the value through the object's interface. -- Default values may be used for initialization only, and can either be global, static values or global but changeable per node. - For higher-level code such as topology code, it should be documented what are the interfaces in use in the code, what classids are supported, and what default values are used beneath the API. - We spent a day discussing topology code (building larger simulations) and concluded the following: -- We want some notion of a container to group nodes and net devices. We ought to be able to add objects to existing containers, and to merge containers into a new container. Some of these layout operations will then operate on containers of objects instead of the objects themselves. -- We will probably want to create some Layout classes that apply a particular mobility/position model to a container of nodes -- The current MobilityModel framework is probably not aligned with this approach. -- We need some kind of IP address generator (Craig had started one of these in the tutorial branch) -- Some more work needs to be done on HierarchicalMobilityModel. There needs to be multiple mobility models defined: A reference mobility model that lays out the center point of each cluster, followed by a mobility model that computes position relative to the center point, (and so on if it recurses). - Despite initial consideration to rename a lot of objects in Internet Node (relating to socket factories), will keep most of the naming the same. We had a lot of discussion/confirmation of current design points. - Agreed to try to refactor Internet Node so that it is not a subclass but instead is a special object that aggregates all of the consitutent interfaces (i.e., Internet Node no longer derives from Node but is an object with cid and iid that basically implements what is in Construct() presently). Rename it to "InternetStack." - Developers prefer ns-3 manual to be written in Doxygen instead of texinfo. We think that it can be fixed up to do this (support images). Keep tutorial as texinfo or whatever format is preferred. Also, avoid use of docs repository; keep everything in main tree. (Tom) - Python bindings will not be immediately prioritized, but work will continue on developing these. (Gustavo, in absentia, and Craig) - Create new src/contrib directory for allowing users/developers to place contributed code that we as a group have not yet planned to maintain as part of the API (perhaps because we are gauging interest in adopting them in the core). Headers from contrib directory could be included from any module. Two candidates for the initial contrib/ code are Gustavo's EventGarbageCollector (now only in the OLSR branch) and Mathieu's Gnuplot class from ns-3-wifi. Roadmap: ======= - We intend to continue monthly releases (Dec. 15, Jan 15, ...) for the time being. - The group agreed that, while neither module is completely done, there is value in merging ns-3-wifi and ns-3-tcp so that early users have main tree support for a wifi model and a reliable stream service is functional, even if it is not yet RFC compliant. - The push will be to get the wifi and tcp merge done before Dec. 15, and get things to usable, debugged state by Jan or Feb. - Mathieu intends to work the following on ns-3-wifi: -- Phy layer cleanup, bug fixing -- Split to accommodate multiple phys -- Documentation, scalability -- 802.11e (EDCA almost there, HDCA more work needed -> scheduler) --- End of January, usable 802.11e EDCA - Raj intends to continue work on TCP ported from GTNetS: -- Coarse retransmission timer (Tahoe behavior) -- Delayed ack timer and delayed acks -- Fork on accept -- Fix newreno behavior -- Expose DefaultValues through class Tcp's public inteface -- Connection close -- Then work on other GTNetS variants - The next major chunk to tackle is topology/layout code. -- Mathieu and Craig are both working on this, with Mathieu working on some initial prototyping and mobility model refactoring, and Craig working on requirements and possibly some prototyping also -- Probably nothing for merging until February timeframe, but this is a last critical piece of our core APIs that we have to settle soon -- Refactoring class Internet Node is left for the topology exercise - A stable release with TCP, WiFi, and topology/layout helpers is seen as a major milestone accomplishment for the project and likely starting point for wider adoption. -- Should work toward having code and support (documentation) stable in mid-summer 2008 to start publicizing in research and educational settings that fall. -- Major changes such be rolled in ASAP with the goal of stabilizing the API for early adopters. - Other items on the near-term roadmap: -- Protolib integration (Joe, Tom) -- Calendar scheduler (Raj) -- Real-time scheduler (Craig, Tom) -- Network simulation cradle support (Tom, Sam Jansen) =========================================================================== == Detailed ns-3 meeting nodes, November 26-30, 2007 == Compiled by Tom Henderson and Joe Kopena =========================================================================== =========================================================================== == Monday 11/26/07 =========================================================================== [ Introductions ] Tom Henderson Mathieu Lacage Joe Kopena Craig Dowell George Riley Raj Bhattacharjea Sumit Roy [ Plan ] Monday & Tuesday, go over architecture & APIs while George is here Wednesday morning, wireless issues [ Adoption ] Tom looking at moving some emulation work over to ns-3 next year. Very interested in emulation, testing actual wireless applications IMUNES and/or UML over NS3 [ Funding ] NSF CISE directorate Community Research Infrastructure grant CRI: Buying and developing tools that will be used in other research [ Tom's introductory slides ] Researchers are increasingly interested in code integration, moving more easily between simulations and experiments Rutgers/NSF ORBIT project; PlanetLab/OneLab Sumit has initiated collaborations to tie in ns-3 to these projects Tom: Interested in moving quagga MANET code over, NRL protolib Started to correspond with Michael Demmer (sp?) concerning moving DTN reference code into ns-3 in order to do richer link simulation DTN already includes its own rudimentary simulation code Tom: Think it's worthwhile to support one user community well rather than trying to please everyone Mathieu: Doesn't necessarily want to spend 100% of time on wifi model Prioritize getting WiFi and TCP working George: NSF is interested in having ns-3 host workshops in different areas Should develop project poster, standard slidedeck for talks August, SIGCOMM in Seattle; ns3 workshop or tutorial? Sumit: NSF very interested in having CRI projects work together Target the handful of hardware emulation projects, develop simulation/emulation co-framework Re. INRIA, other organizations, NSF OIS (office of international research) could be leveraged Tracy Camp at Colorado School of Mines interested in developing INSPECT tool as a primary animator for NS3 IP Assignment Tool Divying out addresses on a hierarchical basis Topics people are interested in: George Objects & how they should be used Internet nodes, packet metadata Craig How to explain & use components; how to show someone how to extend the system More models Joe Topics largely covered on slides Some addressed partially: tracing probably better now, wireless more mature? Validation something lab could contribute easily Worth having simple models as wifi, etc mature, education, early research Sumit: Worthwhile, especially for education. Many more detailed features only matter if you're focusing in on details, more abstract versions, i.e. of MAC, are just fine for lots of work Raj TCP ------------------------------------------------------------------- Topic 1: Packets Issue: why not have packets support interface aggregation? George: Can't possibly predict now how NS3 will be used in future Example: No one in NS2 would have ever imagined people would want to send packets to nodes that don't exist; but people doing worm and virus research definitely do that currently Mathieu: Copying components is problematic George: Need to be able to subclass Packet Mathieu: Can already support that Joe: Seems like this subclassing packet issue is mostly related to tracking packets through the simulator, i.e. to color them in an animator The main issue that is problematic with making Packet an Object is the copying of dynamically aggregated interfaces, as Gustavo pointed out. In general, interfaces can't copy themselves and packets don't know what interfaces have been aggregated to them. Opens up can of worms to support this. Mathieu: Gustavo put the problem very well. There is a clear need for a uniform solution for data attributes for packets. The hard part is how to specify this. This is independent of whether you use tags or polymorphism. Consider, for instance, supporting a colored packet. How do you specify the color? Suppose you support a ColoredPacket subclass. What if now you want your ColoredPacket to also support some kind of 802.11e QoS attribute? Now you get into multiple inheritance issue-- how do they interact? This issue seemed to conclude with the consensus that we can subclass packets if needed but that the hard issue is still open-- how to specify these data attributes. An old issue: Are there any negative interactions with packet metadata system? Gustavo had pointed out that tracing interfered with his header definition. Mathieu: Packet metadata useful for pretty printing packets, tracking Packet metadata header: must be able to create a header object without providing any arguments to constructor, and then immediately call RemoveHeader Deserialization cannot depend on anything in the constructor Mathieu: Gustavo's problem was inadvertently a bad suggestion on my part, to have him deserialize in two stages, where second header deserialization depended on the result of the first one. Now fixed. George: I dislike having a big switch on the type field in the packet, yet this is often done in real implementations. Metadata, only used in ASCII tracing Should be more clearly differentiated that this is not the frame/IP/UDP headers, etc For example: Want to output OLSR information in the print tracing So add a metadata header to look at the packet contents and pretty print appropriately PocketSocket API George & Raj: Need to add a method to the socket API to send chars or uint8_t*s Mathieu: Need to document well that we are immediately doing a copy of it, and that caller maintains ownership of the data Already in Raj's code; need to add something to take care of NULL data In Socket class, need to add Send() and SendTo() comands which take raw data pointers - Those are non-virtual, and simply immediately create a packet and pass it on to the Send(Packet) and corresponding SendTo() virtual methods. Handling dummy data will be done in the Packet constructor Joe: Would like convenience functions to access the packet data Mathieu: Should be using packet headers and footers to do that; this preserves the tracing/printing metadata structure, etc Joe: Most people will view those as being about packet headers, and will assume they should be manipulating the buffer/data George/Joe: Maybe rename to ProtocolDataUnits like in GTNets Mathieu: Maybe change api to AddPDUAtStart(), AddPDUAtEnd() Consensus: Focus on documentation rather than class name changes, examples highlighting how to add data to payloads. Threading & blocking APIs---needed for legacy applications, etc Interested in porting ProtoLib & getting access to those protocols & tools Joe: Set up to be easy to port other thread libraries, etc; should look at what's easier: creating a thread/blocking scheme to work w/ protolib, or writing substructures of protolib Mathieu: Could take yans code fairly easily George: need to be concerned about stack size and stack overflow On overall ns-3 performance: George: globosim is a difficult target to beat performance wise Tom: Hard to compare things apples to apples; in very early profiling we did of QualNet many years ago, the models were less sophisticated than those of OPNET. ns-3 may be in a similar state. However, would be useful to do some rough benchmarking to get a rough idea on orders of magnitude comparisons Mathieu: Gustavo routinely running 5000 node simulations on his own wireless model Joe: Ditto George: 5000 nodes not a whole lot for a simple wireless model ---------------------------------------------- New topic: Components and Craig's ns-3-comp repository What is the rule of thumb on using the component system? Mathieu proposal: whereever you want to have something easily swapped out Feature: How to modify or extend the system, without having to modify the codebase Example: Mathieu's wifi, chose not to make rate algorithm components George: But that's exactly the thing that people may want to change Making net-devices and channels components makes it easier to write things like topology helpers which populate the simulation, taking the class id for the device/channel as a parameter It's also very clear that internal elements such as the TCP implementation are natural candidates for being components George: Should the event scheduler be a component? How do you draw the line on what's a component and what's not? Mathieu: How do developers determine easily what's an interface and what's a component, what supports query interface, etc? Long component discussion that morphed into why components/interfaces are not clonable, and then into the use case that George worked on regarding forking TCP accept. Led to a long discussion about reworking/ renaming the socket factory/TCP/Socket code. Socket class hierarchy: isocket -> tcp -> reno isocket -> tcp -> tahoe isocket -> udp tcp includes common functionality reno, tahoe, etc subclass that and present their own interfaces for specialty functionality when accept() is called, the tcp specialization creates a new instance---which it knows how to do since it is the specialization---and then copies over its state, such as its settings like congestion window size on the creation side, the node requests a socket factory from its interfaces. that factory offers functionality to take a class id and create a new socket. it probably also needs to keep a list of sockets created so that the socket is not destroyed if the application kills off all of its references George and Raj are going to work on such a refactoring. (Note: on Friday later in this meeting, some of these refactoring decisions were overcome by other discussions) What happens if you create a socket and lose all the references? When application deletes last Ptr, the socket can't go away since it must close cleanly and maybe be in time wait state. Seems like there will need to be some other process that garbage collects sockets that are otherwise dereferenced and have timed out. Back to implementing components: Craig: We have blurry distinction between objects, interfaces, and components. How as a user do I know that class Node is an interface while class Packet is not? Tom: By looking at the source code-- do you have an iid and/or a cid? Craig: Prefer other more explicit means rather than forcing users to read source code to find these facts out. Long discussion about how the whole iid/cid system works... Interfaces must create the IID objects, then in constructor call SetInterfaceID to bind to the class ClassID must just create the IID object; the binding happens in MakeClassId Usually the base/common functionality class will bind to the interface & I only need to bind another interface if I am exporting an extended, subclass specific interface Note that if I implement multiple interfaces, then I may acquire multiple interface IDs Looked at two instances of trying to implement this in ns-3: - mobility model - error model MobilityModel includes both the pure virtual interface and the common functionality; ErrorModel does the same Craig thinks these should be kept separate, maintain a naming convention for classes and interfaces Mathieu's suggested criteria for using components: In normal course of things, object is exposed to user, rather than hidden in core (in the public API) Want to allow user to provide a new implementation without hacking NS3 There is code in the core which might instead use user's implementation Tom: For user developers, basic policy decision on creating objects directly using create versus using component manager If I don't think they'll ever want to change it easily, or I don't want them to, then I should just create it directly Joe: Would find it Craig: Need somewhere to go and look for interfaces that may be swapped out If you have an iid, then you have a separate .h file---have to cleanly split out the interface and the implementation George: Need to split out QI and memory management from Object Alternative: copy and pasting code from Object class---poor George is on top of this Name: RefCountObject This is a base class of IObject that provides just reference counting and dispose functionality Object class gets renamed to IObject File has to move to i-object.h Any file with an i-* filename is an interface that has an iid and calls SetInterfaceId in the constructor Note that these header files will also need .cc files to actually declare the interface id (MakeInterfaceId()) Mathieu: Actually it's fairly complex to cut the ref counting out of IObject because of the way interfaces handle it Proposal: Introduce RefCountObject as a standalone, without dependency either way between RefCountObject and IObject Craig also proposed source directory reorganization into public-interfaces, base components, components: Joe: Two non-intuitive things about this: source tree structure not imitated in build directory (raj agrees; mathieu: very few libraries out there do that, most lump into one big directory); some items placed non-intuitively. for example: ascii-trace in internet-node and ipv4address in node. Mathieu rationale: node is really all the code/interfaces you would need to implement an ipv4 node if, for example, you wanted to write a dtn node, you wouldn't actually have any real dependencies on the ipv4 stuff on the other end, only core dependency on ipv4 right now is that NetDevice has to define a function to map ipv4 to multicast addresses, but it doesn't actually have to really do anything ascii trace is in internet-node because it was originally based on that and include some elements for tracing internet stack functions could be split out though, use a generic interface that any node will have to implement for tracing purposes, whether it's ipv4/internet based or not original goal of splitting internet-node and node: envision multiple implementations of internet-node, for example based on different kernel stacks could also support things like other network stacks entirely, sensor nodes, etc Logical conclusion of Craig's proposal would result in lots of small files. Where we had, in the past, two files, error-model.cc and error-model.h we would now have: i-error-model.h (declares IErrorModel, iid) i-error-model.cc (implements IErrorModel, iid) i-list-error-model.h (declares IListErrorModel, iid) i-list-error-model.cc (implements IListErrorModel, iid) c-list-error-model.h (declares CListErrorModel, cid) c-list-error-model.cc (implements CListErrorModel, cid) ... i.e., for each iid or cid in the system, you get one separate .h and one separate .cc file if these are all separated like this. And the i- and c- prefix breaks alphabetical grouping of like files. Also still outstanding is whether any files/directories moved around. Need to sleep on these proposals... =========================================================================== == Tuesday 11/27/07 =========================================================================== The primary focus of the day's discussions was Craig Dowell's proposal for ns-3 components, and resolving blurry distinctions between Object, Interface, Component, and reference counted object (one that uses reference counting API but is not an Object and doesn't support QI: class Packet is an example of this). The motivation for Craig's proposal was his observation, when writing the tutorial, that it was difficult to concisely and uniformly describe what was an ns-3 component or interface, or how a user might figure out what was a component or interface vs. some other type of object in the system (among other related questions), and how users should approach thinking about the system and how to extend it. To address this lack of clarity, Craig proposed an ns-3-comp repository with the following features: - distinguish fully between Interface and Component (do not allow an Object to have both a cid and an iid) - identify interfaces and components in the class name by prefixing the class name with an "I" or a "C" such as IErrorModel, to allow the user to clearly know by the type name whether an object is an Interface or component - place an "i-" or "c-" prefix on the file names of interface or component source files, respectively. - place one class per source file. - reorganize the component-related source code directories as follows: public-interfaces/ base-components/ components/ Craig sketched out how to do this with the PointToPoint objects as an example. There seemed to be universal agreement that Craig's approach would provide a more rigorous, consistent architecture for new users to understand the ns-3 component system, because it would be consistently applied to all interfaces and components. Several opinions were expressed that such a change might be painful on a number of levels: - dislike of "hungarian"-like notation conventions - "i-" and "c-" prefixes break the alphabetical grouping of .h/.cc files for similarly related objects - deployed to its fullest, it might force users to pretty much abandon the use of Create<> for object creation; all components would be created through the component manager, client code would handle interfaces and not the underlying components themselves, and the APIs would change (e.g., passing Ptr instead of Ptr) - would lead to an increase in the number of source files and #include lists in files, since each object with either an iid or cid would get its own .cc and .h file. For example, each new component would require at least two source files (if it did not provide any new interface), and four source files if it provided a new interface. - many of these source files might be small (the ratio of lines of code to lines of GPL might be low), and source files that are either too large or too small impede the readability of the code. On the other hand, it was observed that for some systems (e.g., Java) it was quite natural to think of every class existing in a separate source file. Mathieu expressed the opinion that a lot of these issues boiled down to style issues and impressions of how hard things would be for new users to grasp, given various style conventions. For instance, generating a list of all possible interfaces in the system could probably be performed as part of Doxygen by introspection, but more importantly, was probably not a feature that a user would particularly care about; he or she would want to know whether the particular model under consideration for extension was a component, but not what the entire list of ns-3 components was. So some discussion revolved around whether the various changes did directly address the ease of approaching this system for new users. It was observed that some users would probably like a more rigid or rigorous system than what we have (with clearer rules) while some would probably hate the change because of what it trades off in terms of code readability and directory navigability. Mathieu later observed that the implication of what Craig was suggesting was a more complete embrace of a component-based approach to objects at our public APIs (software components, in the sense of COM or Java Beans), rather than an inconsistent application of the design pattern. Presently, ns-3 is much more an object-oriented system, where use of component manager by user code is an option, but this type of change, if applied to its logical conclusion, would lead to much more of a component-based system flavor, such as deprecating the ability to create an object directly without indirecting through the component manager. We had some discussion of trying to take pieces of Craig's system and apply it (such as prefixing the class name, suffixing it instead of prefixing (such as ErrorModelI or ErrorModelInterface), or using an "Impl" suffix to denote components, etc.) but each one of these alternatives seemed to rub against some other style rule in our system. In the end, it seemed like the main options on the table were to keep the status quo or more fully embrace software componentry. That is, the implications of adopting a naming pattern like Craig suggested, and subsequently trying to drive out exceptions to how objects are treated and thought about in the system seemed to be leading us more towards a fully component-based system at the public APIs. After much discussion, since there seemed no universal agreement on a preferred way forward, Tom proposed that we stay with the status quo for the following (somewhat subjective) reasons: - belief that the current system without major change already satisfies the key requirements: -- InterfaceIds allow for QueryInterface to allow interface aggregation and solve the "weak base class" and downcast problem found in ns-2 -- ClassIds allow for virtual constructors based on class ids that can be tied into the default value system for easy run-time substitution of "components" (classes) that share the same interface: e.g. how one can easily replace classes such as Agent/TCP with Agent/TCP/SackTCP in ns-2's OTcl - a move away from object paradigm might be more unfamiliar to ns-2 user base, whereas our use of component manager now maps adequately into the ns-2 object creation system, so while making the system easier in some ways it may make it harder in other ways for legacy ns-2 users to learn/understand - belief that the hurdles that Craig identified on explaining the system to newcomers can be handled adequately with documentation and tutorial - not enough of an incentive to make such a major API change at this point in development Still, it seems we have some work to do to define and write policy rules for iids, cids, component mgr, and guidance as to how to learn our system. So, some questions about our design might be answered as follows: What is an ns-3 component? How does a user know what is a component? - derives from Object - has one or more ClassIds that can be used by the Component Manager to instantiate - supports at least one Interface What is an ns-3 interface? How does a user know what is an interface? - derives from Object - has an InterfaceId; (therefore, answers to the question "how does one know about whether an object is a component/interface can be answered by inspecting whether it has a cid or iid, respectively"-- but it is not immediately known by looking at either the class name, source code file name, or directory location) Can an object be both an interface and a component? - Yes; it contains a cid and an iid Why would one do that? - If it is thought that there is not much point in separating the interface from the implementation if there is not much chance of reuse of the interface with a different implementation. What happens if one has a blended interface/component and a new implementation (component) arrives? - split out the cid into a new class Will the names of the classes be prefixed with I or C? - No Will the header file names or directory organization be changed? - No Will each module (class and subclasses) be declared/implemented in one source file respectively, or one per class? - Depends on the author or particular model. How does a developer pick a convention? - what seems to make sense to that author. Either keep all of the interfaces declared in one file, or split them out to many files, but try to be consistent one way or the other - one guideline is that if splitting each class into separate files leads still to relatively large header files, one can split them to improve readability, but if each class declaration has only a few lines of code, then a single file might make sense. This can be changed later as needed on a case-by-case basis. How does a user know which interfaces are used? - The problem is how to know which interfaces a piece of ns-3 code will used. There is no way, for instance, to know whether some piece of code, beneath the public API (say, a topology object), accesses a "TCP" or "Transport" interface, and consequently whether substituting SCTP for TCP will break the code. This must be documented as part of the API How does a user know which components are substitutable? - similar problem Which objects should get iids/cids? - we came up with this (probably incomplete) list TCP/UDP Queues Error Models Scheduler Application Channel Ipv4 Ipv4RoutingTable Socket Mobility When do you create a component? some suggested criteria: 1) must be exported and visible to the user 2) multiple implementations exist or are planned with the same or similar interfaces 3) if this object will be created in generic core code (such as topology code) where users might be expected to want to swap out implementation while keeping the same interface When do you use ComponentManager (rather than Create) to create objects? 1) only if it is a component (has a cid) 2) then, only if you want the caller of your code to be able to swap out the component Related to this, we had discussion of default values. What members are default values? - things that you want to allow user to control via command line arguments or scripting defaults - good example of these types of parameters: "sysctl -a" or tcl/lib/ns-default.tcl in ns-2 - model author's discretion as to how many of these are hooked into the default value system Should a parameter initialized by a default value have also a getter/setter in the interface? - generally, yes, unless it doesnt' make semantic sense How do you use them? - global and static values - global but changeable per node - initialization only Aren't default values a back door interface to components? How to ensure that if a class typically uses default values to initialize data members (e.g., TCP m_ssthresh is initialized to DefaultValue::tcp.ssthresh), that replaceable component TCP also uses the same default value and doesn't instead hard code ssthresh? - Answer: we should treat default values used in the object as part of that object's interface-- they can be supported in the interface class, and documented as being in use in the implementation. More generally on this latter point, for higher-level code like topology code, it should be documented what are the interfaces in use in the code, what classids are supported, and what default values are used beneath the API. Other items -------- I think we did agree to define a RefCountObject as a base class for Packet, that provides the memory management piece of Object only. We agreed that the conceputal model of subclassing Node as a means to construct InternetNode was perhaps not the best way, and instead some means of conveying that _aggregation_ and not _subclassing_ was the means to build different types of nodes. We also had some discussion of how one might write "BuildInternetNode()" function, perhaps along the lines of frameworks that Craig introduced earlier. Need to work this further... =========================================================================== == Wednesday 11/28/07 =========================================================================== Mathieu: - wants to be a user of the 802.11 model (not an active developer/extender) - group is interested in rate control algorithms - do not work on ad hoc networks per se, but on cross-layer optimizations - interested in testbed integration ns-3-wifi roadmap - phy layer cleanup, bug fixing - split to accommodate multiple phys - documentation, scalability - 802.11e (EDCA almost there, HDCA more work needed-> scheduler) -- end of January, usable 802.11e EDCA Sumit: - interested in large simulation, support analysis, extract parameters, and feed into testbed Ilango: reviewed his ns-2 extensions: - scanning - beacons - auth/association - handoffs (no RSS monitoring) Unmet needs: - multi-channel - multi-interface - AP queue for buffering packets - power saving mode - fading (slow fade) model - voice traffic Fei: - discussion of requirements for integrating vehicular traffic simulators - problems with continuous time aspects (fluid models) of traffic meshing with discrete network simulators - it was not clear that Prof. Dailey's work on traffic flow simulators would provide an appropriate simulator Joe: these also point to the use cases for simple wireless models, statistics, and database support Mathieu: regarding supporting functionality that Ilango desires: - EDCA will take 1-2 weeks - multi-channel is easy, unless you want cross-channel interference - slow fading, prop loss model-- not going there (Sumit said UW would take that) - scanning-- Mac not doing any kind of scanning presently Mathieu commented that a transition for ilango to either the dei80211mr (has multi-interface) or ns-3 models would cause Ilango to have to reimplement a lot of his work. Seemed that rather Ilango should try to get a paper with what he has. Fei talked about his requirements and what he liked about DC-REDNA code: - model per-packet SNR, capture effect - mobility hooks - fading models (DC code do not support either multi-channel or EDCA. But both of them are needed for future research.) Discussion of performance problem for ad hoc wireless - do we want to support grid-based propagation model? - Tom: consider Cornell SNS - Joe-- will benchmark performance after the holidays Action items ---------- - Mathieu to arrange for discussion between Walid's OneLab team and Sumit regarding ORBIT plans - UW team to try to elaborate an initial ns-3/ORBIT integration plan - Sumit-- start to look at support for software defined radio (USRP) =========================================================================== == Thursday 11/29/07 =========================================================================== Today's discussion centered on APIs and techniques to create larger-scale simulation layouts and topologies. Basically, how do you ease the simulation user's job when he or she must create large numbers of similarly (not necessarily identically configured) objects and connect them together. Joe Kopena suggested that the name Layout might be more appropriate for these classes, since "Topology" has some geographic connotation. We agreed to prefer this terminology, although there is a history with the term topology (e.g., ns-2 topology and Internet topology tools). There are multiple levels of abstraction that we could shoot for; for instance, a function such as "CreateAdHocNetworkTopology(int numNodes)" which created and plumbed lots of things all in one shot. We decided that for now, we would avoid trying to do too much in one function and instead would focus on methods to apply a common configuration step on a group of N like objects. Goals: - Identify common low-level topology primitives that are hopefully common across wired/wireless and associated layouts - Enumerate common layouts/topologies and try to find common constructs - Define methods to apply a common configuration step on a group N of like objects. - Write pseudocode for some of these scenarios and see where the holes are in our current code Non-goal: One-liner "super topology" constructors that encapsulate a bunch of configuration steps into one or two lines of code. Wireless layouts =================== Joe elaborated some layouts of interest to him: Layout 1: N nodes with a single wifi device each, arranged according to some topology (position layout and mobility model) Layout 2: Same as layout 1 but with ability to define some special nodes with two NetDevices that can form a link on a different channel, and possible to identify subsets of nodes within a geographic region (a bounding box) that run a specific application. Layout 3: Hierarchical clusters. Clusters interconnected by higher-level backbones. Some "distinguished nodes" have more than one net device. Hierarchy can recurse. We concluded the following: - we want some notion of a container to group nodes and net devices. We ought to be able to add objects to existing containers, and to merge containers into a new container. Some of these layout operations will then operate on containers of objects instead of the objects themselves. - we will probably want to create some Layout classes that apply a particular mobility/position model to a container of nodes - the current MobilityModel framework is probably not aligned with this approach. - we need some kind of IP address generator (Craig had started one of these in the tutorial branch) - some more work needs to be done on HierarchicalMobilityModel. There needs to be multiple mobility models defined: a reference mobility model that lays out the center point of each cluster, followed by a mobility model that computes position relative to the center point, (and so on if it recurses). Some pseudocode generated: class Layout :public Object { // Find all nodes in nc which fall within b static NodeContainer FindSubset(NodeContainer nc, BoundingBox b); .. } class NodeContainer : public Object { DeviceContainer BuildDevices(Ptr, ClassId); } class DeviceContainer : public Object { } // Create grid of single net-device nodes, with two multihomed nodes // having two net-devices Ptr nodeGroup1 = Create (); nodeGroup1->CreateNodes (18); Ptr nodeGroup2 = Create (); nodeGroup2->CreateNodes (2); Ptr nodeGroup3 = Create (nodeGroup1, nodeGroup2); // Layout-- this needs work nodeGroup3->AddMobilityModel(cid); Ptr layout = GridLayout (...); nodeGroup3->ApplyLayout(layout) Ptr cA = Create; Ptr cB = Create; //set wifi parameters Ptr devGroupA = nodeGroup3->BuildDevices(cA, wifi::cid); Ptr addressGen = Create (Ipv4Address start, Ipv4Mask mask); nodeGroup3->Ipv4Assign (addressGen, devGroupA); //set gsm parameters DeviceContainer devGroupB = nodeGroup2->BuildDevices(cB, gsm::cid); nodeGroup2->Ipv4Assign(addressGen, devGroupB); // Add application to subset of nodes NodeContainer cAppGroup = Layout::FindSubset(nodeGroup1, BoundingBox x); cAppGroup->AddApplication(cid or template argument); ================================================================================ Layout 3: Create hierarchical clustering, with each cluster containing a node connnected to some other wireless backbone Ptr refMM = Create (BoundingBox); int clusterSize = 10; int numClusters = 10; Ptr nodeGroup1 = Create (); nodeGroup1->CreateNodes (clusterSize - 1); Ptr nodeGroup2 = Create (); nodeGroup2->CreateNodes (1); Ptr nodeGroup3 = Create (nodeGroup1, nodeGroup2); // Layout for (i=1..numClusters) { Ptr cluster = Create (); cluster->CreateNodes (clusterSize -1); } // Layout nodeGroup3->AddHierarchicalMobilityModel(refMM, cid); Ptr layout = Layout (BoundingBox...); nodeGroup3->ApplyLayout(layout) (incomplete) ... Wired layouts ============== We had some discussion of wired layouts, including what ns-2 does for large scale topologies, and what GTNetS does for small-scale ones. We concluded that two low-level primitives were PointToPoint and Bus (shared media) links, and that larger topologies (Star, Tree, etc.) could all be built with these. - Dumbbell (Bus + point-to-point + Bus) - Star (point-to-point to a central node) - Clique (Mesh of point-to-point) - Tree (point-to-point with levels, fanout) One interesting issue is that of mesh of point to point links. By not assigning IP addresses upon topology construction, it requires O(n^2) operations to assign them later. We could provide overloaded functions that optionally could pass an Ipv4AddressGenerator in as an argument. Note that Craig Dowell provided a basic Ipv4AddressGenerator tool in his tutorial directory. A cursory review of the Internet topology generator tools suggested that there are hierarchical structures; first at the AS level, then at the router level, and perhaps another level below. The average degree of each node and the probability of forming links between given nodes can be specified; not sure how the tools guarantee connectivity. This resembles what we desire to achieve in wireless (hierarchical clusters, with "backbone" radios interconnecting the clusters). We had some discussion about the similarities and differences between the hierarchical wired and wireless layouts, and see whether a unified approach might apply. (some differences: not sure how to guarantee connectivity in wired partial mesh case; not sure how to handle optional position object in wired). Link to ns-2 topology generator: http://www.isi.edu/nsnam/ns/ns-topogen.html It seems like we will want to do similar things to what ns-2 did, in terms of writing scripts to take output of topology generators and convert them to ns-2 links. The hard part, again, seems to be how to handle IP addressing (which is not an issue in ns-2). Mathieu's clarifications: - we use value semantics for Containers: this is so much easier than having to create a bunch of pointers and manage them ! - we overload a lot of methods to provide really simple versions. like, the ip assignment: you don't have to create a separate ipv4 address generator. - NodeContainer::SetPositionReference takes as input another Ptr which is expected to have a position model whose position becomes the reference for layout and for the mobility model. - for the layout, rather than parameterize with a generic Layout class and switch on the cid and a bunch of DefaultValues, I add a bunch of methods to NodeContainer. i.e., LayoutRandom2dRectangle. We could do it the other way around. I think that this is easier to use (although harder to extend) but, then, the goal to me is to be easy to use first - in which module should he NodeContainer live in ? It is probably going to depend on everything since it is going to tie together all our existing modules. // Create wireless backbone NodeContainer c; c.CreateNodes (7); c.AddMobilityModel (RandomWaypointMobilityModel::cid); c.LayoutRandom2dRectangle (UniformVariable (0.0, 100.0), UniformVariable (0.0, 100.0)); c.BuildDevices (WifiNetDevice::cid, Create ()); c.AssignIp (Ipv4Address ("192.168.0.10"), Ipv4Mask ("255.255.255.0")); // create the wireless clusters around each backbone node. Ptr childrenChannel = Create (); for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++) { NodeContainer child = NodeContainer (); child.SetPositionReference (*i); child.CreateNodes (30); child.AddNode (*i); child.AddMobilityModel (RandomWaypointMobilityModel::cid); child.LayoutRandom2dRectangle (UniformVariable (0.0, 10.0), UniformVariable (0.0, 10.0)); DeviceContainer devices = child.BuildDevices (WifiNetDevice::cid, childrenChannel); child.AssignIp (devices, ipGenerator); } // setup the geographical applications. c = NodeContainer (); c.AddByBoundingBox (NodeList::Begin (), NodeList::End (), BoundingBox (0.0, 0.0, 100.0, 100.0)); c.AddApplication (OnOffApplication::cid); // create p2p backbone NodeContainer c; c.CreateNodes (2); c.BuildDevices (P2pNetDevice::cid, Create ()); c.AssignIp (); // create the left side of the dumbbell NodeContainer left; left.AddNode (c.GetNode (0)); left.CreateNodes (40); left.BuildDevices (CsmaNetDevice::cid, Create ()); left.AssignIp (); // create the right side of the dumbbell NodeContainer right; right.AddNode (c.GetNode (0)); right.CreateNodes (40); right.BuildDevices (CsmaNetDevice::cid, Create ()); right.AssignIp (); Proposed actions =============== We agreed that solving some of the topology issues should be dealt with in the near term (next month or two) both to stabilize the API and also to provide wireless users with something to work with. Some of the mobility models will have to be reworked to support the above. - Craig will build on the above notes to provide a ns-developers post of what are the assumed requirements/goals and framework of the proposed approach. Prior to ns-developers post, we will socialize it with the meeting attendees for initial comments. - Mathieu to look at refactoring the mobility models (particularly hierarchical) to better support these layouts. - Raj will socialize/vet the design at some point with Ellen Zegura at Ga. Tech, to make sure we are not repeating past mistakes of other simulators. =========================================================================== == Friday 11/30/07 =========================================================================== Attending: Tom, Raj, Mathieu, Joe Raj talking about TCP structure Current: SocketFactory -> Tcp -> TcpImpl CreateSocket Socket -> TCP Socket Ipv4L4Protocol -> TcpL4Protocol Ipv4L4Demux Fast retransmit: After triple ack is received, send segment which is presumed to plug the hole, then continue sending from the top of the window. If that doesn't fill hole or there is another hole then you will eventually get a timeout and go into full recovery. What is actual GTNets behavior? Raj current status: Syn setup happens, fast retransmit needs to be fixed to jump up to the top of the window, need to work on timeout timers Structure concept: Client QIs for the SocketFactory, of which there is one class That SocketFactory looks at a variable or takes a parameter to CreateSocket() to determine what specific socket class (TCP variant) to instantiate based on a provided class id If nothing is set it goes with some default known to be in the distribution The Socket implements the state and logic, possibly drawing from a base class providing much of the functionality This concept differs from the discussion earlier in the week, in which each variant provides a different factory, however it still meets George's goal of being able to run sockets implementing different variants on the same machine Concerned about simulation phase effects and synchronization Most of the sockets for a sim will start about the same time, get into step Have one timer per host which all sockets are using That timer should jitter its start to avoid simulation wide syncing This timer should be usable across many variants; if any really care about doing timing differently then they can work out their own structure. One complicating factory there will be coordinating multiple sockets of the same variant while not being in the controller Note that this timing controller could be the socket factory SocketFactory is base socket factory interface, which you need because the application shouldn't really care whether it's getting LinuxTCPSocketFactory, GTNetsTCPSocketFactory, or even UDPSocketFactory; should change the socket factory class names to reflect the type. More broadly: Every different L4 protocol coming in will provide a different socket factory which uses default values and class ids to instantiate different implementations if it has any. Talk about parameterization/configuration interfaces/objects Need a TCPSocket interface to allow user to set different parameters for different implementations Things that you would normally go and set in proc are managed by some other object For example, could QI for a TCP stack object which includes that, host timer code, etc Mathieu does not care about saving even a couple hundred lines of code by keeping the socket creation and parameterization generic enough to be used in multiple stacks. Joe is appalled. Integration problem with Cradle: Cradle is generating packets w/ IP headers, which are being passed into the NS3 IP layer. Need to remove those, work around them, or something like that. Related issues with outstanding bugs with IP selection, which should be moved up into socket layer. Tom will look into using packet tags for this. Splitting out routing information from IP object Very similar discussion to splitting up TCP interface functionality Argument for not splitting. Discussion about routing; how to plug in protocols, etc Implement Ipv4RoutingProtocol; currently: static routing, OLSR Protocol calls AddRoutingProtocol(protocol obj, priority) In order of priority the router will send packets to that particular routing protocol. Want an InternetStack class to aggregate interfaces to a Node, rather than a class InternetNode that derives from Node Discussion and run through of Joe's scripts, simulations, netdevs, and apps Statistics: How to track frame transmissions? Problem: Want to track the number of frames generated by different classes of traffic Very easy for applications to track number of packets on their own But they can't track frame because they have to control over multihop Partial solution: Doing the tracking in packet metadata tags How does that get incremented? Discussion on ARP bug (#107), posted to NS3 bugzilla Future work discusssion: Topology helpers TCP variants WiFi Schedulers---current one may not scale well Visualization Protolib General short term plan: Merge WiFi and TCP, start getting comments Aim on finishing them up in January and build toward a big release Once TCP, WiFi, and topology helpers are in, should be much easier to attract users Big draw for many people will be when they start seeing papers produced using NS3 Long discussion about packet tagging and mangling. The issue of how to create colored packets was revisited. It seems that reusing the tracing framework (creating a Packet tagging trace source) might provide a solution. (End of meeting)