[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