Add GetTxBuffer; add some socket options; make limited UDP receive buffer functional
--- 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