[Ns-developers] [ns3] socket API

Tom Henderson tomh at tomh.org
Tue Apr 15 13:15:31 PDT 2008


Mathieu,

here are a few comments on other aspects of your thread.  

>
>1) need to implement a "pull" API in ns3::Socket. The assumption is that
>the subclass of the ns3::Socket class we want to use will implement
>internally a tx and an rx buffer: the synchronous wrapper on top of it
>needs to access that buffer to implement the normal recv calls.

I agree that we need a pull API for receiving data.

>
>Proposal:
>
>/**
> * return a _single_ packet by removing it from the internal rx 
> * buffer if it is smaller than maxSize. If the size of
> * the next packet to return is bigger than maxSize, return 0 and
> * set ENOMEM.
> * If you want to get the "from" address, it is stored as a tag
> * in the packet returned.
> * _Must_ be possible to call this method from the Recv callback.
> */
>Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);

why not return a packet with the amount of data specified?  i.e., why does it fail if the application guesses wrongly about the packet boundaries?

>
>/**
> * Return number of bytes which can be returned from one or 
> * multiple calls to Recv.
> * Must be possible to call this method from the Recv callback.
> */
>uint32_t GetRxAvailable (void) const;
>
>The above two methods should be enough to implement a synchronous recv
>function. If we implement them, we should remove the packet and address
>arguments from the RecvCallback which would then be of type
>Callback<void>.
>
>2) the current Socket::Send method is quite painful to use and
>implement. Proposal:
>
>/**
> * 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).

agree

> * 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);

why not require Connect () before Send() is used?

>
>/**
> * returns the number of bytes which can be sent in a single call
> * to Send. 
> */
>uint32_t GetTxAvailable (void) const;
>
>If we implement this, we should remove the SendTo method. 

I do not really see the need to remove SendTo() since it is a legacy API call.

> Problem: if we
>do this, we cannot specify the "to" address for
>int Socket::SendTo (uint8_t *buffer, uint32_t size);
>because there is no Ptr<Packet> to attach the "to" address to.
>
>Solution: get rid of the Socket::Send* methods which take raw buffers
>and implement them exclusively at the "synchronous" layer.
>
>3) How should socket options and ioctls be supported ?
>Proposal: 
>
>in src/node:
>
>class Ipv4SocketOptions
>{
>  /* Implement the linux IP_PKTINFO socket option. */
>  virtual void EnablePktInfo (void) = 0;
>  virtual void DisablePktInfo (void) = 0;
>  virtual bool IsPktInfoEnabled (void) = 0;
>
>  /* Implement the linux IP_OPTIONS socket option. */
>  virtual void SetOptions (const uint8_t [40] buffer, uint32_t size);
>  // return size of options data.
>  virtual uint32_t GetOptions (uint8_t [40] buffer);
>
>  /* implement IP_RECVTTL */
>  virtual void EnableRecvTtl (void) = 0;
>  virtual void DisableRecvTtl (void) = 0;
>  virtual uint32_t IsRecvTtlEnabled (void) = 0;
>
>  // all others...
>};
>
>class UdpSocketOptions : public Ipv4SocketOptions
>{
>public:
>  // udp-specific options.
>};
>
>class TcpSocketOptions : public Ipv4SocketOptions {...};
>
>All the above would be implemented in src/internet-node/ as aggregated
>classes to each Socket. i.e., user code:
>
>Ptr<Socket> sock = ...;
>Ptr<Ipv4SocketOptions> ipv4 = sock->GetObject<Ipv4SocketOptions> ();
>NS_ASSERT (ipv4 != 0);
>ipv4->EnableRecvTtl ();
>
>Another option here would be to just add all of the above methods to the
>existing src/node/udp.h and src/node/tcp.h classes with an extra
>Ptr<Socket> argument:
>
>class Udp  ...
>{
>public:
>  /* Implement the linux IP_PKTINFO socket option. */
>  virtual void EnablePktInfo (Ptr<Socket> socket) = 0;
>  virtual void DisablePktInfo (Ptr<Socket> socket) = 0;
>  virtual bool IsPktInfoEnabled (Ptr<Socket> socket) = 0;
>};
>
>The former approach feels slightly more "right".

I agree.

>
>4) How is ancillary information supported ? It is attached as a tag to
>each packet whether it is sent or received.

OK by me.

>
>5) posix sockets are extended with:
>
>int simu_recv (int fd, Ptr<Packet> packet, int flags);
>int simu_send (int fd, Ptr<Packet> packet, int flags);
>ssize_t simu_write (int fd, Ptr<Packet> packet);
>ssize_t simu_read (int fd, Ptr<Packet> packet);

also for sendmsg, sendto?

Tom




More information about the Ns-developers mailing list