[Ns-developers] NS3 Skeleton code posted for review
L.Wood at surrey.ac.uk
Sat Nov 25 09:23:16 PST 2006
I have trouble following why you'd want to promote features over
time in a single hierarchy. The net result is that people will add
new features as high in the hierarchy as they can, and over time
everything will just end up promoted to the base class anyway as
others need it, as that's the only way to ensure that a feature is
universally available. So you're simply slowing base bloat, which
is inevitable, but increasing code maintenance and the potential to
introduce errors meanwhile, and you'll wind up with a huge base class
all over again. (This also applies to packet classes. ns2's packet.h
I'd like to avoid the nxn sparsely-populated feature matrix of ns2,
where features A and B can't be used together in a packet or node at
the same time. Promoting everything to the base node eventually is one
way to avoid this, but undesirable.
Alternatively, multiple virtual inheritance (which C++ supports)
could be used, so you only inherit e.g. from the EnergyNode if you
need it. That would be multiple inheritance from childs of the base
node (EnergyNode, InternetNode, and others); as everything is virtual,
the "diamond problem" is avoided in C++.
(And the same multiple-inheritance thinking can be applied to packet
classes and packet features, avoiding the packet.h bloat.)
I don't think "but our favourite flavour of object Tcl doesn't support
multiple inheritance!" is a valid objection here. Dump that flavour.
<http://www.ee.surrey.ac.uk/Personal/L.Wood/><L.Wood at surrey.ac.uk>
From: ns-developers-bounces at ISI.EDU on behalf of Tom Henderson
Sent: Fri 2006-11-24 23:34
To: George Riley
Subject: Re: [Ns-developers] NS3 Skeleton code posted for review
George Riley wrote:
> Hi All,
> I have posted several .h and .cc files that reflect, I think, current
> on an appropriate design for nodes, a node factory, and a protocol stack.
> The code is not intended to compile, as there are many missing pieces.
> ALso, I've not yet entered all of the Doxygen comments needed to extract
> documentation; that will happen soon.
> If anyone wants to look it over, I suggest node.h, node.cc, capability.h,
> node-factory.h and node-factory.cc as a starting point. The protocols,
> are also partially there, perhaps enough to see data flow through a stack.
I have a few questions/comments on this design, just focusing for the
moment on the files you mentioned above:
- I would summarize this design by describing it as the combination of
i) C++ interface classes for providing a common base class public
interface for polymorphic objects (this is what you have called a
"Capability"), and ii) use of base class Node as a collection of
pointers to the various interface classes. Would you agree with this
- as you know, one concern I have with this design is that it will cause
base class Node to grow very large over time. What I am concerned about
is that everyone who adds a new object to the simulator will feel
compelled to make it accessible via a new capability, and that nodes of
different types (sensors, IP, GENI, etc.) will see a lot of "noise" in
the base class Node. Also, there are a lot of capabilities already
defined in your proposed node.h but hardly any of them are actually used
yet in your sample code.
Would you agree to try to make the design use these capabilities more
judiciously? Here are my thoughts on how to do this:
i) capabilities can be added at any level of the node hierarchy, not
just base class node
ii) if/when containers of pointers to nodes are needed, scenario writers
either use a collection of pointers to the appropriate subclass that
contains the capabilities of interest (e.g., InternetNode or
SensorNode), or perform a safe downcast (dynamic_cast) where an existing
base class node pointer already exists.
iii) if it becomes clear that the above two criteria are not sufficient
for the capability of interest, it can be "promoted" to a higher level
of the hierarchy, including up to base class node. For instance, if
InternetNode is using "EnergyModel" and it becomes clear that it would
be useful for other classes deriving from base Node, it could be
promoted at that point.
iv) do not add a capability to a node until there is a strong use case
for needing to access it through a base or subclass node pointer
I believe that the above would make the code more modular in the long
run at the cost of requiring users to think a little bit more about the
class of Node pointer that they are using, so to me it is a reasonable
tradeoff and one that can be undone in the future if needed (because
adding or "promoting" capabilities should be backward compatible)
So what this would mean in the near term is that we would remove the
capabilities from class Node and put a few into class InternetNode, and
have your scenarios use containers of InternetNode pointers instead of
base node, and we add these as needs arise during development.
- we discussed off-list at some point the avoidance of a single
"common-defs.h" file and making such typedefs as local as possible, from
modularity standpoint; do you agree? I understand the use of typedefs
for improving readability of complicated types, and for portability, but
I don't think many of these qualify from that standpoint (such as
Count_t and Byte_t, for instance), and might detract from readability by
adding unnecessary indirection.
- we also discussed off-list that it might be better to wrap many of
these capabilities into a "Kernel" or "Stack" capability. I didn't see
this in node.h, but I saw this in the simple*.cc files, except that they
were of the form:
i.e. the existing capabilities just nested one layer deeper. What I
had in mind instead was that GetL3Demux would not be publicly visible,
and instead that was just wrapped as part of the Kernel capability, so
that it made it easier to define node stacks (such as Network Simulation
Cradle) that did not have an explicit L3Demux object; do you agree?
> See simple?.cc as several examples of current thinking on creating
> simple simulation scenarios.
> Finally, see application.h / application.cc for a first stab at a
> design for mimicking the BSD sockets API.
I agree with Gustavo's comment that I had thought of Sockets being part
of the stack or kernel instead of part of the application; applications
could obtain a pointer to class socket or else an integer handle like a
file descriptor and call socket functions, to interact with the rest of
I might as well add a final comment on NetHook; I haven't carefully
examined all of the files yet (including ipv4.h, l3demux, l3proto):
- For NetHook, I support defining this special callback type in general
but would prefer to make the list of hooks be a superset of the
Netfilter hooks; e.g., we have at least 5 hooks that map directly to the
5 standard Linux hooks.
More information about the Ns-developers