[Ns-developers] [ns3] socket API

Mathieu Lacage mathieu.lacage at sophia.inria.fr
Mon Apr 14 20:04:22 PDT 2008


hi george,

On Mon, 2008-04-14 at 21:07 -0400, George Riley wrote:
> > 
> >  /**
> > * return -1 if packet does not fit in tx buffer (current behavior
> > is 
> > * to send the part of the packet which fits in the tx buffer).
> > * If the packet does not fit, the caller can split the packet to
> > send
> > * (based on output by GetTxAvailable) and re-attempt to send the
> > * packet.
> > * If you want to provide a per-packet "to" address, store it as a
> > * special tag in the outgoing packet.
> > */
> > int Send (Ptr<Packet> p, uint32_t flags);
> I still contend, as I have from the beginning, that we need the
> send calls that take buffer pointers and length values as arguments,
> and still believe that.  The sockets API does not send packets, it
> sends bytes, and we need this to stay.  I don't really understand
> the pain you refer to.

There is no question that we are sending bytes, but, there are two
things to consider:

  - a lot of real applications do not want to generate real bytes: they
just want to generate random payload of a specific size and the only way
to do this (efficiently) is to avoid generating bytes in the first place
and to instanciate a Ptr<Packet> and pass it down directly to the
low-level socket code

  - a lot of applications want to generate real bytes but they actually
want to use our fancy Ptr<Packet> to generate these real bytes because
it is convenient and because it is efficient. Gustavo has been doing
that very successfully in the olsr code to generate his olsr messages
over sockets and that seems like a very valid use-case.

In both cases, you need to be able to pass back and forth Ptr<Packet>
objects to represent the bytes you want to send across the socket API.
So, yes, you are sending bytes: you just don't want to send them using a
raw byte buffer in these cases. The socket code itself might take your
"fancy" byte buffers and resize, split, and re-arrange them. It might
decide to return to you 100 packets of size one rather than the one
packet of size 100 you gave to it if you are using tcp, but, that is an
implementation detail of the socket, and it has little to do with the
means we use to generate and receive bytes at the socket API boundary.

Now, once you have started sending these fancy byte buffers back and
forth, it is trivial to efficiently pass a real raw byte buffer also
because you can convert to raw byte buffers with Packet::PeekData and
from raw byte buffers with Packet::Packet. You cannot do it efficiently
the other way around so, you really want to use as a primitive tool
Ptr<Packet> to pass the buffer around. What we do now is exactly that:
the functions which take a raw buffer are one-liners which perform that
conversion.

So, what I am suggesting is not to remove functionality but to move the
trivial one-liner methods I alluded to in the paragraph above from the
Socket code to user applications because:
  - it is totally painless for applications
  - it makes it easier to implement more advanced socket features such
as ancillary data through a tag attached to a Ptr<Packet> because you
don't have to re-invent the C-style ancillary data API (which is truly
horrid)
  - it decreases the size of the Socket API in node/socket.h without any
loss of functionality and no increased application-level complexity.

I hope that the above explains better the rationale for my proposal.

regards,
Mathieu



More information about the Ns-developers mailing list