Add GetTxBuffer; add some socket options; make limited UDP receive buffer functional
authorTom Henderson <tomh@tomh.org>
Sat, 03 May 2008 11:11:24 -0700
changeset 3105 682950a37ea6
parent 3104 24d9d9aa0977
child 3106 79d23124124b
child 3108 f284bfbc9e46
Add GetTxBuffer; add some socket options; make limited UDP receive buffer functional
src/internet-node/tcp-socket.cc
src/internet-node/tcp-socket.h
src/internet-node/udp-socket.cc
src/internet-node/udp-socket.h
src/node/packet-socket.cc
src/node/packet-socket.h
src/node/socket.h
src/node/udp.cc
src/node/udp.h
--- a/src/internet-node/tcp-socket.cc	Fri May 02 10:55:07 2008 -0700
+++ b/src/internet-node/tcp-socket.cc	Sat May 03 11:11:24 2008 -0700
@@ -435,6 +435,14 @@
     }
 }
 
+// XXX Raj to make this functional
+uint32_t
+TcpSocket::GetTxAvailable (void) const
+{
+  // No finite send buffer is modelled
+  return 0xffffffff;
+}
+
 int
 TcpSocket::Listen (uint32_t q)
 {
@@ -472,6 +480,33 @@
   return m_rxAvailable;
 }
 
+// XXX Raj to finish
+void
+TcpSocket::SetSndBuf (uint32_t size)
+{
+
+}
+
+// XXX Raj to finish
+uint32_t
+TcpSocket::GetSndBuf (void) 
+{
+  return 0;
+}
+
+// XXX Raj to finish
+void
+TcpSocket::SetRcvBuf (uint32_t size)
+{
+}
+
+// XXX Raj to finish
+uint32_t
+TcpSocket::GetRcvBuf (void) 
+{
+  return 0;
+}
+
 void
 TcpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
 {
--- a/src/internet-node/tcp-socket.h	Fri May 02 10:55:07 2008 -0700
+++ b/src/internet-node/tcp-socket.h	Sat May 03 11:11:24 2008 -0700
@@ -68,11 +68,17 @@
   virtual int Send (Ptr<Packet> p);
   virtual int Send (const uint8_t* buf, uint32_t size);
   virtual int SendTo(const Address &address, Ptr<Packet> p);
+  virtual uint32_t GetTxAvailable (void) const;
   virtual int Listen(uint32_t queueLimit);
 
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
   virtual uint32_t GetRxAvailable (void) const;
 
+  virtual void SetSndBuf (uint32_t size);
+  virtual uint32_t GetSndBuf (void);
+  virtual void SetRcvBuf (uint32_t size);
+  virtual uint32_t GetRcvBuf (void);
+
 private:
   friend class Tcp;
   // invoked by Tcp class
--- a/src/internet-node/udp-socket.cc	Fri May 02 10:55:07 2008 -0700
+++ b/src/internet-node/udp-socket.cc	Sat May 03 11:11:24 2008 -0700
@@ -28,11 +28,25 @@
 #include "ipv4-end-point.h"
 #include "ipv4-l4-demux.h"
 #include "ns3/ipv4.h"
+#include "ns3/udp.h"
+#include "ns3/trace-source-accessor.h"
 
 NS_LOG_COMPONENT_DEFINE ("UdpSocket");
 
 namespace ns3 {
 
+TypeId
+UdpSocket::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::UdpSocket")
+    .SetParent<Socket> ()
+    .AddConstructor<UdpSocket> ()
+    .AddTraceSource ("Drop", "Drop UDP packet due to receive buffer overflow",
+                     MakeTraceSourceAccessor (&UdpSocket::m_dropTrace))
+    ;
+  return tid;
+}
+
 UdpSocket::UdpSocket ()
   : m_endPoint (0),
     m_node (0),
@@ -41,7 +55,8 @@
     m_shutdownSend (false),
     m_shutdownRecv (false),
     m_connected (false),
-    m_rxAvailable (0)
+    m_rxAvailable (0),
+    m_udp_rmem (0)
 {
   NS_LOG_FUNCTION_NOARGS ();
 }
@@ -73,6 +88,9 @@
 UdpSocket::SetNode (Ptr<Node> node)
 {
   m_node = node;
+  Ptr<Udp> u = node->GetObject<Udp> ();
+  m_udp_rmem =u->GetDefaultRxBuffer ();
+
 }
 void 
 UdpSocket::SetUdp (Ptr<UdpL4Protocol> udp)
@@ -316,8 +334,15 @@
   return 0;
 }
 
+uint32_t
+UdpSocket::GetTxAvailable (void) const
+{
+  // No finite send buffer is modelled
+  return 0xffffffff;
+}
+
 int 
-UdpSocket::SendTo(const Address &address, Ptr<Packet> p)
+UdpSocket::SendTo (const Address &address, Ptr<Packet> p)
 {
   NS_LOG_FUNCTION (this << address << p);
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
@@ -363,15 +388,59 @@
     {
       return;
     }
-  Address address = InetSocketAddress (ipv4, port);
-  SocketRxAddressTag tag;
-  tag.SetAddress (address);
-  packet->AddTag (tag);
-  m_deliveryQueue.push (packet);
-  m_rxAvailable += packet->GetSize ();
-  NotifyDataRecv ();
+  if ((m_rxAvailable + packet->GetSize ()) <= m_udp_rmem) 
+    {
+      Address address = InetSocketAddress (ipv4, port);
+      SocketRxAddressTag tag;
+      tag.SetAddress (address);
+      packet->AddTag (tag);
+      m_deliveryQueue.push (packet);
+      m_rxAvailable += packet->GetSize ();
+      NotifyDataRecv ();
+    }
+  else
+    {
+      // In general, this case should not occur unless the
+      // receiving application reads data from this socket slowly
+      // in comparison to the arrival rate
+      //
+      // drop and trace packet
+      NS_LOG_WARN ("No receive buffer space available.  Drop.");
+      m_dropTrace (packet);
+    }
 }
 
+void 
+UdpSocket::SetSndBuf (uint32_t size)
+{
+  // return EINVAL since we are not modelling a finite send buffer
+  // Enforcing buffer size should be added if we ever start to model
+  // non-zero processing delay in the UDP/IP stack
+  m_errno = ERROR_INVAL;
+}
+
+uint32_t 
+UdpSocket::GetSndBuf (void)
+{
+  m_errno = ERROR_NOTERROR;
+  return 0xffffffff;
+}
+
+void 
+UdpSocket::SetRcvBuf (uint32_t size)
+{
+  m_errno = ERROR_NOTERROR;
+  m_udp_rmem = size;
+}
+
+uint32_t 
+UdpSocket::GetRcvBuf (void)
+{
+  m_errno = ERROR_NOTERROR;
+  return m_udp_rmem;
+}
+
+
 } //namespace ns3
 
 
--- a/src/internet-node/udp-socket.h	Fri May 02 10:55:07 2008 -0700
+++ b/src/internet-node/udp-socket.h	Sat May 03 11:11:24 2008 -0700
@@ -23,6 +23,7 @@
 #include <stdint.h>
 #include <queue>
 #include "ns3/callback.h"
+#include "ns3/traced-callback.h"
 #include "ns3/socket.h"
 #include "ns3/ptr.h"
 #include "ns3/ipv4-address.h"
@@ -37,6 +38,7 @@
 class UdpSocket : public Socket
 {
 public:
+  static TypeId GetTypeId (void);
   /**
    * Create an unbound udp socket.
    */
@@ -56,10 +58,16 @@
   virtual int Connect(const Address &address);
   virtual int Send (Ptr<Packet> p);
   virtual int SendTo(const Address &address,Ptr<Packet> p);
+  virtual uint32_t GetTxAvailable (void) const;
 
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
   virtual uint32_t GetRxAvailable (void) const;
 
+  virtual void SetSndBuf (uint32_t size);
+  virtual uint32_t GetSndBuf (void);
+  virtual void SetRcvBuf (uint32_t size);
+  virtual uint32_t GetRcvBuf (void);
+
 private:
   friend class Udp;
   // invoked by Udp class
@@ -77,6 +85,8 @@
   uint16_t m_defaultPort;
   Callback<void,Ptr<Socket>,uint32_t,const Address &> m_dummyRxCallback;
   Callback<void,Ptr<Socket>,uint8_t const*,uint32_t,const Address &> m_rxCallback;
+  TracedCallback<Ptr<const Packet> > m_dropTrace;
+
   enum SocketErrno m_errno;
   bool m_shutdownSend;
   bool m_shutdownRecv;
@@ -84,6 +94,8 @@
 
   std::queue<Ptr<Packet> > m_deliveryQueue;
   uint32_t m_rxAvailable;
+  
+  uint32_t m_udp_rmem;
 };
 
 }//namespace ns3
--- a/src/node/packet-socket.cc	Fri May 02 10:55:07 2008 -0700
+++ b/src/node/packet-socket.cc	Sat May 03 11:11:24 2008 -0700
@@ -214,6 +214,13 @@
   return SendTo (m_destAddr, p);
 }
 
+uint32_t 
+PacketSocket::GetTxAvailable (void) const
+{
+  // No finite send buffer is modelled
+  return 0xffffffff;
+}
+
 int
 PacketSocket::SendTo(const Address &address, Ptr<Packet> p)
 {
@@ -338,4 +345,23 @@
   return m_rxAvailable;
 }
 
+void 
+PacketSocket::SetSndBuf (uint32_t size)
+{
+}
+uint32_t 
+PacketSocket::GetSndBuf (void)
+{
+return 0;
+}
+void 
+PacketSocket::SetRcvBuf (uint32_t size)
+{
+}
+uint32_t 
+PacketSocket::GetRcvBuf (void)
+{
+return 0;
+}
+
 }//namespace ns3
--- a/src/node/packet-socket.h	Fri May 02 10:55:07 2008 -0700
+++ b/src/node/packet-socket.h	Sat May 03 11:11:24 2008 -0700
@@ -86,11 +86,17 @@
   virtual int ShutdownRecv (void);
   virtual int Connect(const Address &address);
   virtual int Send (Ptr<Packet> p);
+  virtual uint32_t GetTxAvailable (void) const;
+
   virtual int SendTo(const Address &address,Ptr<Packet> p);
 
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
   virtual uint32_t GetRxAvailable (void) const;
 
+  virtual void SetSndBuf (uint32_t size);
+  virtual uint32_t GetSndBuf (void);
+  virtual void SetRcvBuf (uint32_t size);
+  virtual uint32_t GetRcvBuf (void);
 
 private:
   void ForwardUp (Ptr<NetDevice> device, Ptr<Packet> packet, 
--- a/src/node/socket.h	Fri May 02 10:55:07 2008 -0700
+++ b/src/node/socket.h	Sat May 03 11:11:24 2008 -0700
@@ -221,6 +221,12 @@
   virtual int Send (Ptr<Packet> p) = 0;
   
   /**
+   * returns the number of bytes which can be sent in a single call
+   * to Send. 
+   */
+  virtual uint32_t GetTxAvailable (void) const = 0;
+
+  /**
    * \brief Send data (or dummy data) to the remote host
    * \param buf A pointer to a raw byte buffer of some data to send.  If this 
    * is 0, we send dummy data whose size is specified by the second parameter
@@ -280,6 +286,35 @@
    */
   virtual uint32_t GetRxAvailable (void) const = 0;
  
+  /**
+   * \brief ns-3 version of setsockopt (SO_SNDBUF)
+   * 
+   * The error code value can be checked by calling GetErrno () 
+   */
+  virtual void SetSndBuf (uint32_t size) = 0;
+  /**
+   * \brief ns-3 version of getsockopt (SO_SNDBUF)
+   * 
+   * The error code value can be checked by calling GetErrno () 
+   *
+   * \returns The size in bytes of the send buffer
+   */
+  virtual uint32_t GetSndBuf (void) = 0;
+  /**
+   * \brief ns-3 version of setsockopt (SO_RCVBUF)
+   * 
+   * The error code value can be checked by calling GetErrno () 
+   */
+  virtual void SetRcvBuf (uint32_t size) = 0;
+  /**
+   * \brief ns-3 version of getsockopt (SO_RCVBUF)
+   * 
+   * The error code value can be checked by calling GetErrno () 
+   *
+   * \returns The size in bytes of the receive buffer
+   */
+  virtual uint32_t GetRcvBuf (void) = 0;
+
 protected:
   void NotifyCloseCompleted (void);
   void NotifyConnectionSucceeded (void);
--- a/src/node/udp.cc	Fri May 02 10:55:07 2008 -0700
+++ b/src/node/udp.cc	Sat May 03 11:11:24 2008 -0700
@@ -18,6 +18,7 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 #include "udp.h"
+#include "ns3/uinteger.h"
 
 namespace ns3 {
 
@@ -26,11 +27,23 @@
 TypeId Udp::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::Udp")
-    .SetParent<SocketFactory> ();
+    .SetParent<SocketFactory> ()
+    .AddAttribute ("DefaultRxBufferSize",
+                   "Default UDP maximum receive buffer size (bytes)",
+                   UintegerValue (0xffffffffl),
+                   MakeUintegerAccessor (&Udp::m_defaultRxBuffer),
+                   MakeUintegerChecker<uint32_t> ())
+    ;
   return tid;
 }
 
 Udp::Udp ()
 {}
 
+uint32_t
+Udp::GetDefaultRxBuffer (void) const
+{
+  return m_defaultRxBuffer;
+}
+
 } // namespace ns3
--- a/src/node/udp.h	Fri May 02 10:55:07 2008 -0700
+++ b/src/node/udp.h	Sat May 03 11:11:24 2008 -0700
@@ -53,6 +53,10 @@
    * implementations..
    */
   virtual Ptr<Socket> CreateSocket (void) = 0;
+
+  uint32_t GetDefaultRxBuffer (void) const;
+private:
+  uint32_t  m_defaultRxBuffer;
 };
 
 } // namespace ns3