[Ns-developers] ns-3 node draft proposal

Gustavo Carneiro gjcarneiro at gmail.com
Mon Nov 13 07:27:03 PST 2006


On 11/13/06, Mathieu Lacage <Mathieu.Lacage at sophia.inria.fr> wrote:
>
> On Mon, 2006-11-13 at 12:00 +0000, Gustavo Carneiro wrote:
> >  Hi Mathieu,
> >
> >   For now I only have a couple of comments, then we'll see... :)
> >
> > On 11/13/06, Mathieu Lacage <Mathieu.Lacage at sophia.inria.fr> wrote:
> > >
> > > hi all,
> > >
> > > Based on the 'ns-3 design' document, I have put together a draft
> > > proposal with sample scenarios, a small rationale document and some
> > > sample headers. If you think that some really important use-cases or
> > > constraints have not been taken into account, I think that it would be
> > > nice to comment on this now.
> > >
> > > Any kind of feedback, positive or negative, is welcome.
> >
> >
> > ** Comment #1:
> >
> > I just had a glance at the simple-router.cc example and saw this:
> >
> > class EthernetTopologyFactory
> > {
> > [...]
> >   template <typename T>
> >   uint32_t AddInterface (T *node, EthernetCable *cable);
> > [...]
> >
> >   Can we please refrain from using templates so much?  Why is T a
> templated
> > typename, why can't it be simply NodeBase?
>
> Because AddInterface accesses the m_ipv4 field of the node object and
> the m_ipv4 field is not part of the Node base class but of the node
> subclass.
>
> Arguably, I don't care much about making the T type a LeafIpv4Node type.
> It just means that the helper methods/class will not be as widely
> re-useable as possible.


  But the template type does not change anything.  Right now you can't
attempt pass nodes that do not have an IP stack to
EthernetTopologyFactory::AddInterface, which makes the template type about
as useful as a pointer to such type, but more complex.

I do not think that this would be such a big
> deal.


  Well, speaking for myself, and probably other potential users, I find the
prospect of having to deal with templates midly discouraging.  I mean, I
don't mind using existing templates, but if your example is a sign of things
to come than it seems we will have to define our own templated methods,
which is not nice. :-(

  I'm sure there are other ways to accomplish the same effect with some
refactoring.  Example:

template <typename T>
uint32_t
EthernetTopologyFactory::AddInterface (T *node, EthernetCable *cable)
{
  ethernet = new Ethernet (node,
               m_macCurrent,
               m_ethernetType);
  m_macCurrent++;
  ethernet->Connect (cable);

    //  interfaceIndex = node->m_ipv4->AddInterface (new ArpIpv4Interface
(node, ethernet));
    // node->m_ipv4->Configure (interfaceIndex,
    //          m_ipv4Current,
    //          m_ipv4MaskCurrent);
    // m_ipv4Current++;

    // Replace with:

  Interface *iface = node->AddInterface ();

  EthernetInterface *etherIface = iface->QueryInterface("EthernetInterface")
  if (etherIface)
     etherIface->SetUp(ethernet);

  IPv4Interface *ipv4Iface = iface->QueryInterface("IPv4Interface")
  if (ipv4Iface)
     etherIface->SetUp(m_ipv4Current, m_ipv4MaskCurrent);

  return interface->index;
}

  Oh, gosh, so I've come full circle and ended up with my idea of using
AddInterface/QueryInterface again... sorry about that :P

  Anyway, here's the rest of it, and a comment in the end:


class Object {

  vector<void *> interfaces;
  public:
    void AddInterface(string name, void *iface);
    void * QueryInterface(string name);
}

class Interface : public Object  {
  Node *node;
  int index;
}


class Node {
vector<Interface *> interfaces;

   public:

     virtual Interface *AddInterface() {
        Interface *iface = new Interface();
        this->interfaces.append(iface);
        return iface;
    }
}


class EthernetInterface : Interface  {
   Ethernet ether;
   public:

   void SetUp(Ethernet &ether) {
      this->ether = ether;
   }
}


class EthernetNode : Node {

  public:
     virtual Interface *AddInterface() {
        Interface *iface = Node::AddInterface();
        EthernetIface *ethIface = new EthernetInterface();
        // attaches ethernet state to the abstract interface
        iface->AddInterface("EthernetInterface", ethIface);
        return iface;
   }
}

class IPv4Interface : Interface {
   int m_ipv4Current,
   int m_ipv4MaskCurrent;
  public:
     void SetUp(int ipv4Current, int ipv4MaskCurrent) {
          m_ipv4Current = ipv4Current;
          m_ipv4CurrentMask = ipv4CurrentMask;
     }
}

class LeafIPv4Node : EthernetNode {

  public:
     virtual Interface *AddInterface() {
        Interface *iface = EthernetNode::AddInterface();
        IPv4Iface *ipv4Iface = new IPv4Interface();
        iface->AddInterface("IPv4Interface", ipv4Iface);
        return iface;
   }
}

  What I've learned from this small and incomplete coding exercise is that
network interfaces have properties specific to all layers that use them.
For the physical layer, interfaces have a 'cable' object, for MAC layer they
have MAC address, for IP layer they have IP address.  If you want to allow
"mix and match" of layers in a node as if it were lego pieces then you need
to let interfaces dynamically aggregate different pieces of information
relevant to each layer.


> ** Comment #2:
> >
> > About the sockets API:
> >
> >   " This class has not been designed yet but I expect that the Tcp
> socket
> >     API is split in two classes, TcpServerSocket and TcpClientSocket, in
> >     a way similar to the design of the java socket API where sockets
> >     listening for incoming connections are called ServerSocket: they can
> >     then create any number of ClientSockets from the incoming
> connections
> >     once they have been accepted."
> >
> > Unless I'm confusing something, doesn't the design document talk about
> > implementing a POSIX sockets API?   I thought the idea was to implement
> > POSIX sockets in order to facilitate writing protocols that can be
> easily
> > ported to/from regular POSIX operating systems, such as Linux and *BSD.
>
> Regular C/posix style socket APIs can be built on top of a Java-like
> socket. Java-like sockets simply happen to be a much better designed
> object-oriented API which is why I would like to re-use them to allow
> users of the in-simulator sockets to save themselves pain.


  Well, I could argue that users save some pain in the long run, but  on the
other hand they are forced to learn a new API (arguably the Java sockets API
is not as well known as the POSIX by a long shot), which increases the pain
in the short run.

  I could also argue that the argument that a POSIX API could be built on
top is not very strong, since having two different socket APIs woud be just
confusing for people looking to extend existing protocols implemented in
NS-3, some using POSIX sockets, some using Java sockets.


> ** Comment #3 (well, so I lied, it's 3 comments :D)
> >
> > "For brevity and clarity, all examples in this document omit to use the
> > ns3::ptr template smart pointer class but I assume that it is used
> > everywhere so, memory-management issues are somewhat simplified."
> >
> >
> >   This ns3::ptr smart pointer sounds interesting.  I was going to
> suggest
> > something along those lines myself.  However, I can't find it
> anywhere.  But
> > I would expect a smart pointer would perform reference counting
> > transparently in the background, and so I would expect a standard Object
> > base class for everything that can have a refence count (and so would
> have a
> > refcount member)...  Could shed some light on your plans for this?
>
> boost::shared_ptr uses an external reference count. This is not really
> optimal so, I would like to make the ns3::ptr template smarter and use a
> boost::shared_ptr if the underlying class has no public refcount field
> or use the public refcount field directly if it can. i.e., if you notice
> that you are using too much memory or cpu with the external refcount,
> all you have to do is add a public refcount field to your class (or a
> pair of ref/unref methods) and everything will work as usual, except
> faster. This is, however, more of an implementation detail than anything
> else.


OK; that sounds fine.

-- 
Gustavo J. A. M. Carneiro
"The universe is always one step beyond logic."


More information about the Ns-developers mailing list