RecvFrom() expansion, add flags parameter to some Send calls
authorTom Henderson <tomh@tomh.org>
Mon, 09 Jun 2008 06:40:21 -0700
changeset 3269 448134601b03
parent 3257 ba198dad54a2
child 3270 e01d2843b3a0
RecvFrom() expansion, add flags parameter to some Send calls
examples/tcp-large-transfer.cc
src/applications/packet-sink/packet-sink.cc
src/applications/udp-echo/udp-echo-client.cc
src/applications/udp-echo/udp-echo-server.cc
src/internet-node/tcp-socket-impl.cc
src/internet-node/tcp-socket-impl.h
src/internet-node/udp-socket-impl.cc
src/internet-node/udp-socket-impl.h
src/node/packet-socket.cc
src/node/packet-socket.h
src/node/socket.cc
src/node/socket.h
src/node/tcp-socket.h
src/node/udp-socket.h
src/routing/olsr/olsr-agent-impl.cc
--- a/examples/tcp-large-transfer.cc	Sat Jun 07 10:38:39 2008 -0700
+++ b/examples/tcp-large-transfer.cc	Mon Jun 09 06:40:21 2008 -0700
@@ -204,7 +204,7 @@
       char m = toascii (97 + i % 26);
       data[i] = m;
     }
-    uint32_t amountSent = localSocket->Send (data, curSize);
+    uint32_t amountSent = localSocket->Send (data, curSize, 0);
     if(amountSent < curSize)
       {
         std::cout << "Socket blocking, returning" << std::endl;
--- a/src/applications/packet-sink/packet-sink.cc	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/applications/packet-sink/packet-sink.cc	Mon Jun 09 06:40:21 2008 -0700
@@ -105,7 +105,7 @@
   Ptr<Packet> packet;
   while (packet = socket->Recv ())
     {
-      SocketRxAddressTag tag;
+      SocketAddressTag tag;
       bool found;
       found = packet->FindFirstMatchingTag (tag);
       NS_ASSERT (found);
--- a/src/applications/udp-echo/udp-echo-client.cc	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-client.cc	Mon Jun 09 06:40:21 2008 -0700
@@ -156,7 +156,7 @@
   Ptr<Packet> packet;
   while (packet = socket->Recv ())
     {
-      SocketRxAddressTag tag;
+      SocketAddressTag tag;
       bool found;
       found  = packet->FindFirstMatchingTag (tag);
       NS_ASSERT (found);
--- a/src/applications/udp-echo/udp-echo-server.cc	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-server.cc	Mon Jun 09 06:40:21 2008 -0700
@@ -97,7 +97,7 @@
   Ptr<Packet> packet;
   while (packet = socket->Recv ())
     {
-      SocketRxAddressTag tag;
+      SocketAddressTag tag;
       bool found;
       found = packet->FindFirstMatchingTag (tag); 
       NS_ASSERT (found);
@@ -110,7 +110,7 @@
             address.GetIpv4());
 
           NS_LOG_LOGIC ("Echoing packet");
-          socket->SendTo (packet, from);
+          socket->SendTo (packet, 0, from);
         }
     }
 }
--- a/src/internet-node/tcp-socket-impl.cc	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/internet-node/tcp-socket-impl.cc	Mon Jun 09 06:40:21 2008 -0700
@@ -346,8 +346,10 @@
     }
   return -1;
 }
+
+//p here is just data, no headers
 int 
-TcpSocketImpl::Send (const Ptr<Packet> p) //p here is just data, no headers
+TcpSocketImpl::Send (Ptr<Packet> p, uint32_t flags) 
 {
   NS_LOG_FUNCTION (this << p);
   if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
@@ -382,11 +384,6 @@
   }
 }
 
-int TcpSocketImpl::Send (const uint8_t* buf, uint32_t size)
-{
-  return Send (Create<Packet> (buf, size));
-}
-
 int TcpSocketImpl::DoSendTo (Ptr<Packet> p, const Address &address)
 {
   NS_LOG_FUNCTION (this << p << address);
@@ -420,7 +417,7 @@
 }
 
 int 
-TcpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
+TcpSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
 {
   NS_LOG_FUNCTION (this << address << p);
   if (!m_connected)
@@ -430,7 +427,7 @@
     }
   else
     {
-      return Send (p); //drop the address according to BSD manpages
+      return Send (p, flags); //drop the address according to BSD manpages
     }
 }
 
@@ -532,6 +529,23 @@
   return m_rxAvailable;
 }
 
+Ptr<Packet>
+TcpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
+  Address &fromAddress)
+{
+  NS_LOG_FUNCTION (this << maxSize << flags);
+  Ptr<Packet> packet = Recv (maxSize, flags);
+  if (packet != 0)
+    {
+      SocketAddressTag tag;
+      bool found;
+      found = packet->FindFirstMatchingTag (tag);
+      NS_ASSERT (found);
+      fromAddress = tag.GetAddress ();
+    }
+  return packet;
+}
+
 void
 TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
 {
@@ -1048,7 +1062,7 @@
       m_nextRxSequence += s;           // Advance next expected sequence
       //bytesReceived += s;       // Statistics
       NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence );
-      SocketRxAddressTag tag;
+      SocketAddressTag tag;
       tag.SetAddress (fromAddress);
       p->AddTag (tag);
       //buffer this, it'll be read by call to Recv
@@ -1106,7 +1120,7 @@
           i->second = 0; // relase reference to already buffered
         }
       // Save for later delivery
-      SocketRxAddressTag tag;
+      SocketAddressTag tag;
       tag.SetAddress (fromAddress);
       p->AddTag (tag);
       m_bufferedData[tcpHeader.GetSequenceNumber () ] = p;  
--- a/src/internet-node/tcp-socket-impl.h	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/internet-node/tcp-socket-impl.h	Mon Jun 09 06:40:21 2008 -0700
@@ -65,14 +65,14 @@
   virtual int ShutdownSend (void);
   virtual int ShutdownRecv (void);
   virtual int Connect(const Address &address);
-  virtual int Send (Ptr<Packet> p);
-  virtual int Send (const uint8_t* buf, uint32_t size);
-  virtual int SendTo(Ptr<Packet> p, const Address &address);
+  virtual int Listen(uint32_t queueLimit);
   virtual uint32_t GetTxAvailable (void) const;
-  virtual int Listen(uint32_t queueLimit);
-
+  virtual int Send (Ptr<Packet> p, uint32_t flags);
+  virtual int SendTo(Ptr<Packet> p, uint32_t flags, const Address &toAddress);
+  virtual uint32_t GetRxAvailable (void) const;
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
-  virtual uint32_t GetRxAvailable (void) const;
+  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
+    Address &fromAddress);
 
 private:
   friend class Tcp;
--- a/src/internet-node/udp-socket-impl.cc	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/internet-node/udp-socket-impl.cc	Mon Jun 09 06:40:21 2008 -0700
@@ -224,9 +224,9 @@
 }
 
 int 
-UdpSocketImpl::Send (Ptr<Packet> p)
+UdpSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
 {
-  NS_LOG_FUNCTION (this << p);
+  NS_LOG_FUNCTION (this << p << flags);
 
   if (!m_connected)
     {
@@ -239,7 +239,7 @@
 int 
 UdpSocketImpl::DoSend (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this << p);
   if (m_endPoint == 0)
     {
       if (Bind () == -1)
@@ -380,19 +380,28 @@
 }
 
 int 
-UdpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
+UdpSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
 {
-  NS_LOG_FUNCTION (this << address << p);
+  NS_LOG_FUNCTION (this << p << flags << address);
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   Ipv4Address ipv4 = transport.GetIpv4 ();
   uint16_t port = transport.GetPort ();
   return DoSendTo (p, ipv4, port);
 }
 
+uint32_t
+UdpSocketImpl::GetRxAvailable (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  // We separately maintain this state to avoid walking the queue 
+  // every time this might be called
+  return m_rxAvailable;
+}
+
 Ptr<Packet>
 UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this << maxSize << flags);
   if (m_deliveryQueue.empty() )
     {
       return 0;
@@ -410,13 +419,21 @@
   return p;
 }
 
-uint32_t
-UdpSocketImpl::GetRxAvailable (void) const
+Ptr<Packet>
+UdpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags, 
+  Address &fromAddress)
 {
-  NS_LOG_FUNCTION_NOARGS ();
-  // We separately maintain this state to avoid walking the queue 
-  // every time this might be called
-  return m_rxAvailable;
+  NS_LOG_FUNCTION (this << maxSize << flags);
+  Ptr<Packet> packet = Recv (maxSize, flags);
+  if (packet != 0)
+    {
+      SocketAddressTag tag;
+      bool found;
+      found = packet->FindFirstMatchingTag (tag);
+      NS_ASSERT (found);
+      fromAddress = tag.GetAddress ();
+    }
+  return packet;
 }
 
 void 
@@ -431,7 +448,7 @@
   if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
     {
       Address address = InetSocketAddress (ipv4, port);
-      SocketRxAddressTag tag;
+      SocketAddressTag tag;
       tag.SetAddress (address);
       packet->AddTag (tag);
       m_deliveryQueue.push (packet);
@@ -638,7 +655,7 @@
   // Unicast test
   m_receivedPacket = Create<Packet> ();
   m_receivedPacket2 = Create<Packet> ();
-  NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123), 
+  NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123), 0, 
     InetSocketAddress (Ipv4Address("10.0.0.1"), 1234)), 123);
   Simulator::Run ();
   NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
@@ -651,7 +668,7 @@
 
   m_receivedPacket = Create<Packet> ();
   m_receivedPacket2 = Create<Packet> ();
-  NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123), 
+  NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123), 0, 
     InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123);
   Simulator::Run ();
   NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
@@ -673,7 +690,7 @@
 
   m_receivedPacket = Create<Packet> ();
   m_receivedPacket2 = Create<Packet> ();
-  NS_TEST_ASSERT_EQUAL (txSocket->SendTo (Create<Packet> (123),
+  NS_TEST_ASSERT_EQUAL (txSocket->SendTo (Create<Packet> (123), 0,
 InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123);
   Simulator::Run ();
   NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
--- a/src/internet-node/udp-socket-impl.h	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/internet-node/udp-socket-impl.h	Mon Jun 09 06:40:21 2008 -0700
@@ -58,12 +58,13 @@
   virtual int ShutdownRecv (void);
   virtual int Connect(const Address &address);
   virtual int Listen (uint32_t queueLimit);
-  virtual int Send (Ptr<Packet> p);
-  virtual int SendTo (Ptr<Packet> p, const Address &address);
   virtual uint32_t GetTxAvailable (void) const;
-
+  virtual int Send (Ptr<Packet> p, uint32_t flags);
+  virtual int SendTo (Ptr<Packet> p, uint32_t flags, const Address &address);
+  virtual uint32_t GetRxAvailable (void) const;
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
-  virtual uint32_t GetRxAvailable (void) const;
+  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
+    Address &fromAddress);
 
 private:
   // Attributes set through UdpSocket base class 
--- a/src/node/packet-socket.cc	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/node/packet-socket.cc	Mon Jun 09 06:40:21 2008 -0700
@@ -230,7 +230,7 @@
 }
 
 int
-PacketSocket::Send (Ptr<Packet> p)
+PacketSocket::Send (Ptr<Packet> p, uint32_t flags)
 {
   NS_LOG_FUNCTION_NOARGS ();
   if (m_state == STATE_OPEN ||
@@ -239,7 +239,7 @@
       m_errno = ERROR_NOTCONN;
       return -1;
     }
-  return SendTo (p, m_destAddr);
+  return SendTo (p, flags, m_destAddr);
 }
 
 uint32_t
@@ -275,7 +275,7 @@
 }
 
 int
-PacketSocket::SendTo(Ptr<Packet> p, const Address &address)
+PacketSocket::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
 {
   NS_LOG_FUNCTION_NOARGS ();
   PacketSocketAddress ad;
@@ -361,7 +361,7 @@
 
   if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
     {
-      SocketRxAddressTag tag;
+      SocketAddressTag tag;
       tag.SetAddress (address);
       packet->AddTag (tag);
       m_deliveryQueue.push (packet);
@@ -381,6 +381,15 @@
     }
 }
 
+uint32_t
+PacketSocket::GetRxAvailable (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  // We separately maintain this state to avoid walking the queue 
+  // every time this might be called
+  return m_rxAvailable;
+}
+
 Ptr<Packet> 
 PacketSocket::Recv (uint32_t maxSize, uint32_t flags)
 {
@@ -402,13 +411,20 @@
   return p;
 }
 
-uint32_t
-PacketSocket::GetRxAvailable (void) const
+Ptr<Packet>
+PacketSocket::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  // We separately maintain this state to avoid walking the queue 
-  // every time this might be called
-  return m_rxAvailable;
+  Ptr<Packet> packet = Recv (maxSize, flags);
+  if (packet != 0)
+    {
+      SocketAddressTag tag;
+      bool found;
+      found = packet->FindFirstMatchingTag (tag);
+      NS_ASSERT (found);
+      fromAddress = tag.GetAddress ();
+    }
+  return packet;
 }
 
 }//namespace ns3
--- a/src/node/packet-socket.h	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/node/packet-socket.h	Mon Jun 09 06:40:21 2008 -0700
@@ -93,13 +93,13 @@
   virtual int ShutdownRecv (void);
   virtual int Connect(const Address &address);
   virtual int Listen(uint32_t queueLimit);
-  virtual int Send (Ptr<Packet> p);
   virtual uint32_t GetTxAvailable (void) const;
-
-  virtual int SendTo(Ptr<Packet> p, const Address &address);
-
+  virtual int Send (Ptr<Packet> p, uint32_t flags);
+  virtual int SendTo(Ptr<Packet> p, uint32_t flags, const Address &toAddress);
+  virtual uint32_t GetRxAvailable (void) const;
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
-  virtual uint32_t GetRxAvailable (void) const;
+  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
+    Address &fromAddress);
 
 private:
   void ForwardUp (Ptr<NetDevice> device, Ptr<Packet> packet, 
--- a/src/node/socket.cc	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/node/socket.cc	Mon Jun 09 06:40:21 2008 -0700
@@ -40,13 +40,6 @@
   NS_LOG_FUNCTION_NOARGS ();
 }
 
-void
-Socket::SetCloseUnblocksCallback (Callback<void,Ptr<Socket> > closeUnblocks)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_closeUnblocks = closeUnblocks;
-}
-
 Ptr<Socket> 
 Socket::CreateSocket (Ptr<Node> node, TypeId tid)
 {
@@ -110,6 +103,13 @@
   m_receivedData = receivedData;
 }
 
+int 
+Socket::Send (Ptr<Packet> p)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return Send (p, 0);
+}
+
 void
 Socket::NotifyCloseUnblocks (void)
 {
@@ -125,7 +125,8 @@
   return 0; //XXX the base class version does nothing
 }
 
-int Socket::Send (const uint8_t* buf, uint32_t size)
+int 
+Socket::Send (const uint8_t* buf, uint32_t size, uint32_t flags)
 {
   NS_LOG_FUNCTION_NOARGS ();
   Ptr<Packet> p;
@@ -137,24 +138,12 @@
     {
       p = Create<Packet> (size);
     }
-  return Send (p);
-}
-
-Ptr<Packet>
-Socket::Recv (void)
-{
-  return Recv (std::numeric_limits<uint32_t>::max(), 0);
+  return Send (p, flags);
 }
 
 int 
-Socket::Recv (uint8_t* buf, uint32_t size, uint32_t flags)
-{
-  Ptr<Packet> p = Recv (size, flags); // read up to "size" bytes
-  memcpy (buf, p->PeekData (), p->GetSize());
-  return p->GetSize ();
-}
-
-int Socket::SendTo (const uint8_t* buf, uint32_t size, const Address &address)
+Socket::SendTo (const uint8_t* buf, uint32_t size, uint32_t flags,
+                const Address &toAddress)
 {
   NS_LOG_FUNCTION_NOARGS ();
   Ptr<Packet> p;
@@ -166,7 +155,48 @@
     {
       p = Create<Packet> (size);
     }
-  return SendTo (p, address);
+  return SendTo (p, flags, toAddress);
+}
+
+Ptr<Packet>
+Socket::Recv (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return Recv (std::numeric_limits<uint32_t>::max(), 0);
+}
+
+int 
+Socket::Recv (uint8_t* buf, uint32_t size, uint32_t flags)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ptr<Packet> p = Recv (size, flags); // read up to "size" bytes
+  if (p == 0)
+    {
+      return 0;
+    }
+  memcpy (buf, p->PeekData (), p->GetSize());
+  return p->GetSize ();
+}
+
+Ptr<Packet>
+Socket::RecvFrom (Address &fromAddress)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return RecvFrom (std::numeric_limits<uint32_t>::max(), 0, fromAddress);
+}
+
+int 
+Socket::RecvFrom (uint8_t* buf, uint32_t size, uint32_t flags,
+                  Address &fromAddress)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ptr<Packet> p = RecvFrom (size, flags, fromAddress); 
+  if (p == 0)
+    {
+      return 0;
+    }
+  memcpy (buf, p->PeekData (), p->GetSize());
+  return p->GetSize ();
 }
 
 void 
@@ -281,54 +311,54 @@
  *           Socket Tags
  ***************************************************************/
 
-SocketRxAddressTag::SocketRxAddressTag ()  
+SocketAddressTag::SocketAddressTag ()  
 {
 }
 
 void 
-SocketRxAddressTag::SetAddress (Address addr)
+SocketAddressTag::SetAddress (Address addr)
 {
   m_address = addr;
 }
 
 Address 
-SocketRxAddressTag::GetAddress (void) const
+SocketAddressTag::GetAddress (void) const
 {
   return m_address;
 }
 
 
 TypeId
-SocketRxAddressTag::GetTypeId (void)
+SocketAddressTag::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("ns3::SocketRxAddressTag")
+  static TypeId tid = TypeId ("ns3::SocketAddressTag")
     .SetParent<Tag> ()
-    .AddConstructor<SocketRxAddressTag> ()
+    .AddConstructor<SocketAddressTag> ()
     ;
   return tid;
 }
 TypeId
-SocketRxAddressTag::GetInstanceTypeId (void) const
+SocketAddressTag::GetInstanceTypeId (void) const
 {
   return GetTypeId ();
 }
 uint32_t
-SocketRxAddressTag::GetSerializedSize (void) const
+SocketAddressTag::GetSerializedSize (void) const
 {
   return m_address.GetSerializedSize ();
 }
 void
-SocketRxAddressTag::Serialize (TagBuffer i) const
+SocketAddressTag::Serialize (TagBuffer i) const
 {
   m_address.Serialize (i);
 }
 void
-SocketRxAddressTag::Deserialize (TagBuffer i)
+SocketAddressTag::Deserialize (TagBuffer i)
 {
   m_address.Deserialize (i);
 }
 void
-SocketRxAddressTag::Print (std::ostream &os) const
+SocketAddressTag::Print (std::ostream &os) const
 {
   os << "address=" << m_address;
 }
@@ -386,4 +416,5 @@
   os << "Ttl=" << (uint32_t) m_ttl;
 }
 
+
 }//namespace ns3
--- a/src/node/socket.h	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/node/socket.h	Mon Jun 09 06:40:21 2008 -0700
@@ -92,27 +92,22 @@
    * \param tid The TypeId of the socket to create
    */
   static Ptr<Socket> CreateSocket (Ptr<Node> node, TypeId tid);
-
   /**
    * \return the errno associated to the last call which failed in this
    *         socket. Each socket's errno is initialized to zero
    *         when the socket is created.
    */
   virtual enum Socket::SocketErrno GetErrno (void) const = 0;
-
   /**
    * \returns the node this socket is associated with.
    */
   virtual Ptr<Node> GetNode (void) const = 0;
 
-  void SetCloseUnblocksCallback (Callback<void, Ptr<Socket> > closeUnblocks);
-
   /**
    * \param closeCompleted Callback invoked when the close operation is
    *        completed.
    */
   void SetCloseCallback (Callback<void, Ptr<Socket> > closeCompleted);
-
   /**
    * \param connectionSucceeded this callback is invoked when the 
    *        connection request initiated by the user is successfully 
@@ -165,7 +160,8 @@
    *        user should check this return value to confirm that the
    *        callback is supported.
    */
-  virtual bool SetDataSentCallback (Callback<void, Ptr<Socket>, uint32_t> dataSent);
+  virtual bool SetDataSentCallback (Callback<void, Ptr<Socket>, 
+                                    uint32_t> dataSent);
   /**
    * \brief Notify application when space in transmit buffer is added
    *
@@ -242,12 +238,26 @@
   virtual int Listen (uint32_t queueLimit) = 0;
 
   /**
+   * \brief Returns the number of bytes which can be sent in a single call
+   * to Send. 
+   * 
+   * For datagram sockets, this returns the number of bytes that
+   * can be passed atomically through the underlying protocol.
+   *
+   * For stream sockets, this returns the available space in bytes
+   * left in the transmit buffer.
+   */
+  virtual uint32_t GetTxAvailable (void) const = 0;
+ 
+  /**
    * \brief Send data (or dummy data) to the remote host
    *
    * This function matches closely in semantics to the send() function
    * call in the standard C library (libc):
    *   ssize_t send (int s, const void *msg, size_t len, int flags);
-   * except that the function call is asynchronous.
+   * except that the send I/O is asynchronous.  This is the
+   * primary Send method at this low-level API and must be implemented 
+   * by subclasses.
    * 
    * In a typical blocking sockets model, this call would block upon
    * lack of space to hold the message to be sent.  In ns-3 at this
@@ -272,96 +282,231 @@
    * split the Packet (based on information obtained from 
    * GetTxAvailable) and reattempt to send the data.
    *
+   * The flags argument is formed by or'ing one or more of the values:     
+   *        MSG_OOB        process out-of-band data 
+   *        MSG_DONTROUTE  bypass routing, use direct interface 
+   * These flags are _unsupported_ as of ns-3.1.  
+   *
    * \param p ns3::Packet to send
+   * \param flags Socket control flags
    * \returns the number of bytes accepted for transmission if no error
    *          occurs, and -1 otherwise.
-   */
-  virtual int Send (Ptr<Packet> p) = 0;
-  
-  /**
-   * \brief Returns the number of bytes which can be sent in a single call
-   * to Send. 
-   * 
-   * For datagram sockets, this returns the number of bytes that
-   * can be passed atomically through the underlying protocol.
    *
-   * For stream sockets, this returns the available space in bytes
-   * left in the transmit buffer.
+   * \see SetSendCallback
    */
-  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
-   * \param size the number of bytes to copy from the buffer
-   * 
-   * This is provided so as to have an API which is closer in appearance 
-   * to that of real network or BSD sockets.  
-   */
-  int Send (const uint8_t* buf, uint32_t size);
-  
-  /**
-   * \brief Send data to a specified peer.
-   * \param p packet to send
-   * \param address IP Address of remote host
-   * \returns -1 in case of error or the number of bytes copied in the 
-   *          internal buffer and accepted for transmission.
-   */
-  virtual int SendTo (Ptr<Packet> p, const Address &address) = 0;
+  virtual int Send (Ptr<Packet> p, uint32_t flags) = 0;
 
   /**
    * \brief Send data to a specified peer.
-   * \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 third parameter
-   * \param size the number of bytes to copy from the buffer
-   * \param address IP Address of remote host
+   *
+   * This method has similar semantics to Send () but subclasses may
+   * want to provide checks on socket state, so the implementation is
+   * pushed to subclasses.
+   *
+   * \param p packet to send
+   * \param flags Socket control flags
+   * \param toAddress IP Address of remote host
    * \returns -1 in case of error or the number of bytes copied in the 
    *          internal buffer and accepted for transmission.
-   *
-   * This is provided so as to have an API which is closer in appearance 
-   * to that of real network or BSD sockets.
    */
-  int SendTo (const uint8_t* buf, uint32_t size, const Address &address); 
+  virtual int SendTo (Ptr<Packet> p, uint32_t flags, 
+    const Address &toAddress) = 0;
 
   /**
-   * \brief Read a single packet from the socket
-   * \param maxSize reader will accept packet up to maxSize
-   * \param flags Socket recv flags
-   * \returns Ptr<Packet> of the next in-sequence packet.  Returns
-   * 0 if the socket cannot return a next in-sequence packet conforming
-   * to the maxSize and flags.
-   */
-  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
-  /**
-   * \brief Read a single packet from the socket
-   *
-   *      Overloaded version of Recv(maxSize, flags) with maxSize
-   *      implicitly set to maximum sized integer, and flags set to zero.
-   *
-   * \returns Ptr<Packet> of the next in-sequence packet.  Returns
-   * 0 if the socket cannot return a next in-sequence packet.
-   */
-   Ptr<Packet> Recv (void);
-  /**
-   * \brief Recv data (or dummy data) from the remote host
-   * \param buf A pointer to a raw byte buffer to write the data to. 
-   * If the underlying packet was carring null (fake) data, this buffer
-   * will be zeroed up to the length specified by the return value.
-   * \param size Number of bytes (at most) to copy to buf
-   * \param flags any flags to pass to the socket
-   * \returns number of bytes copied into buf
-   * 
-   * This is provided so as to have an API which is closer in appearance 
-   * to that of real network or BSD sockets.  
-   */
-  int Recv (uint8_t* buf, uint32_t size, uint32_t flags);
-  /**
    * 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.
    */
   virtual uint32_t GetRxAvailable (void) const = 0;
+
+  /**
+   * \brief Read data from the socket
+   *
+   * This function matches closely in semantics to the recv() function
+   * call in the standard C library (libc):
+   *   ssize_t recv (int s, void *buf, size_t len, int flags);
+   * except that the receive I/O is asynchronous.  This is the
+   * primary Recv method at this low-level API and must be implemented 
+   * by subclasses.
+   * 
+   * This method is normally used only on a connected socket.
+   * In a typical blocking sockets model, this call would block until
+   * at least one byte is returned or the connection closes.  
+   * In ns-3 at this API, the call returns immediately in such a case
+   * and returns 0 if nothing is available to be read.
+   * However, an application can set a callback, ns3::SetRecvCallback,
+   * to be notified of data being available to be read
+   * (when it conceptually unblocks); this is an asynchronous
+   * I/O model for recv().
+   * 
+   * This variant of Recv() uses class ns3::Packet to encapsulate
+   * data, rather than providing a raw pointer and length field.  
+   * This allows an ns-3 application to attach tags if desired (such
+   * as a flow ID) and may allow the simulator to avoid some data
+   * copies.  Despite the appearance of receiving Packets on a stream
+   * socket, just think of it as a fancy byte buffer with streaming
+   * semantics.    
+   *
+   * The semantics depend on the type of socket.  For a datagram socket,
+   * each Recv() returns the data from at most one Send(), and order
+   * is not necessarily preserved.  For a stream socket, the bytes
+   * are delivered in order, and on-the-wire packet boundaries are
+   * not preserved.  
+   * 
+   * The flags argument is formed by or'ing one or more of the values:     
+   *        MSG_OOB        process out-of-band data
+   *        MSG_PEEK       peek at incoming message
+   * These flags are _unsupported_ as of ns-3.1.  
+   *
+   * Some variants of Recv() are supported as additional API,
+   * including RecvFrom(), overloaded Recv() without arguments,
+   * and variants that use raw character buffers.
+   *
+   * \param maxSize reader will accept packet up to maxSize
+   * \param flags Socket control flags
+   * \returns Ptr<Packet> of the next in-sequence packet.  Returns
+   * 0 if the socket cannot return a next in-sequence packet conforming
+   * to the maxSize and flags.
+   *
+   * \see SetRecvCallback
+   */
+  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
+
+  /**
+   * \brief Read a single packet from the socket and retrieve the sender 
+   * address.
+   *
+   * Calls Recv(maxSize, flags) with maxSize
+   * implicitly set to maximum sized integer, and flags set to zero.
+   *
+   * This method has similar semantics to Recv () but subclasses may   
+   * want to provide checks on socket state, so the implementation is   
+   * pushed to subclasses.
+   *
+   * \param maxSize reader will accept packet up to maxSize
+   * \param flags Socket control flags
+   * \param fromAddress output parameter that will return the
+   * address of the sender of the received packet, if any.  Remains
+   * untouched if no packet is received.
+   * \returns Ptr<Packet> of the next in-sequence packet.  Returns
+   * 0 if the socket cannot return a next in-sequence packet.
+   */
+  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,  
+    Address &fromAddress) = 0;
+
+  /////////////////////////////////////////////////////////////////////
+  //   The remainder of these public methods are overloaded methods  //
+  //   or variants of Send() and Recv(), and they are non-virtual    //
+  /////////////////////////////////////////////////////////////////////
+ 
+  /**
+   * \brief Send data (or dummy data) to the remote host
+   * 
+   * Overloaded version of Send(..., flags) with flags set to zero.
+   *
+   * \param p ns3::Packet to send
+   * \returns the number of bytes accepted for transmission if no error
+   *          occurs, and -1 otherwise.
+   */
+  int Send (Ptr<Packet> p);
+
+  /**
+   * \brief Send data (or dummy data) to the remote host
+   * 
+   * This method is provided so as to have an API which is closer in 
+   * appearance to that of real network or BSD sockets.  
+   *
+   * \param buf A pointer to a raw byte buffer of some data to send.  If 
+   * this buffer is 0, we send dummy data whose size is specified by the 
+   * second parameter
+   * \param size the number of bytes to copy from the buffer
+   * \param flags Socket control flags
+   */
+  int Send (const uint8_t* buf, uint32_t size, uint32_t flags);
+  
+
+  /**
+   * \brief Send data to a specified peer.
+   *
+   * This method is provided so as to have an API which is closer in 
+   * appearance to that of real network or BSD sockets.  
+   *
+   * \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 
+   * third parameter
+   * \param size the number of bytes to copy from the buffer
+   * \param flags Socket control flags
+   * \param address IP Address of remote host
+   * \returns -1 in case of error or the number of bytes copied in the 
+   *          internal buffer and accepted for transmission.
+   *
+   */
+  int SendTo (const uint8_t* buf, uint32_t size, uint32_t flags, 
+              const Address &address); 
+
+  /**
+   * \brief Read a single packet from the socket
+   *
+   * Overloaded version of Recv(maxSize, flags) with maxSize
+   * implicitly set to maximum sized integer, and flags set to zero.
+   *
+   * \returns Ptr<Packet> of the next in-sequence packet.  Returns
+   * 0 if the socket cannot return a next in-sequence packet.
+   */
+   Ptr<Packet> Recv (void);
+
+  /**
+   * \brief Recv data (or dummy data) from the remote host
+   *
+   * This method is provided so as to have an API which is closer in 
+   * appearance to that of real network or BSD sockets.  
+   * 
+   * If the underlying packet was carring null (fake) data, this buffer
+   * will be zeroed up to the length specified by the return value.
+   *
+   * \param buf A pointer to a raw byte buffer to write the data to. 
+   * \param size Number of bytes (at most) to copy to buf
+   * \param flags any flags to pass to the socket
+   * \returns number of bytes copied into buf
+   */
+  int Recv (uint8_t* buf, uint32_t size, uint32_t flags);
+
+  /**
+   * \brief Read a single packet from the socket and retrieve the sender 
+   * address.
+   *
+   * Calls RecvFrom (maxSize, flags, fromAddress) with maxSize
+   * implicitly set to maximum sized integer, and flags set to zero.
+   *
+   * \param maxSize reader will accept packet up to maxSize
+   * \param flags Socket control flags
+   * \param fromAddress output parameter that will return the
+   * address of the sender of the received packet, if any.  Remains
+   * untouched if no packet is received.
+   * \returns Ptr<Packet> of the next in-sequence packet.  Returns
+   * 0 if the socket cannot return a next in-sequence packet.
+   */
+  Ptr<Packet> RecvFrom (Address &fromAddress);
+
+  /**
+   * \brief Read a single packet from the socket and retrieve the sender
+   * address.
+   *
+   * This method is provided so as to have an API which is closer in 
+   * appearance to that of real network or BSD sockets.  
+   * 
+   * \param buf A pointer to a raw byte buffer to write the data to. 
+   * If the underlying packet was carring null (fake) data, this buffer
+   * will be zeroed up to the length specified by the return value.
+   * \param size Number of bytes (at most) to copy to buf
+   * \param flags any flags to pass to the socket
+   * \param fromAddress output parameter that will return the
+   * address of the sender of the received packet, if any.  Remains
+   * untouched if no packet is received.
+   * \returns number of bytes copied into buf
+   */
+  int RecvFrom (uint8_t* buf, uint32_t size, uint32_t flags,
+                Address &fromAddress);
  
 protected:
   void NotifyCloseUnblocks (void);
@@ -391,13 +536,13 @@
 };
 
 /**
- * \brief This class implements a tag that carries the source address
- * of a packet across the receiving socket interface.
+ * \brief This class implements a tag that carries an address
+ * of a packet across the socket interface.
  */
-class SocketRxAddressTag : public Tag
+class SocketAddressTag : public Tag
 {
 public:
-  SocketRxAddressTag ();
+  SocketAddressTag ();
   void SetAddress (Address addr);
   Address GetAddress (void) const;
 
--- a/src/node/tcp-socket.h	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/node/tcp-socket.h	Mon Jun 09 06:40:21 2008 -0700
@@ -58,11 +58,15 @@
   virtual int ShutdownSend (void) = 0;
   virtual int ShutdownRecv (void) = 0;
   virtual int Connect (const Address &address) = 0;
-  virtual int Send (Ptr<Packet> p) = 0;
   virtual uint32_t GetTxAvailable (void) const = 0;
-  virtual int SendTo (Ptr<Packet> p, const Address &address) = 0;
+  virtual int Send (Ptr<Packet> p, uint32_t flags) = 0;
+  virtual int SendTo (Ptr<Packet> p, uint32_t flags, 
+    const Address &toAddress) = 0;
+  virtual uint32_t GetRxAvailable (void) const = 0;
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
-  virtual uint32_t GetRxAvailable (void) const = 0;
+  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
+    Address &fromAddress) = 0;
+
 
 private:
   // Indirect the attribute setting and getting through private virtual methods
--- a/src/node/udp-socket.h	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/node/udp-socket.h	Mon Jun 09 06:40:21 2008 -0700
@@ -57,11 +57,14 @@
   virtual int ShutdownSend (void) = 0;
   virtual int ShutdownRecv (void) = 0;
   virtual int Connect (const Address &address) = 0;
-  virtual int Send (Ptr<Packet> p) = 0;
   virtual uint32_t GetTxAvailable (void) const = 0;
-  virtual int SendTo (Ptr<Packet> p, const Address &address) = 0;
+  virtual int Send (Ptr<Packet> p, uint32_t flags) = 0;
+  virtual int SendTo (Ptr<Packet> p, uint32_t flags,
+    const Address &toAddress) = 0;
+  virtual uint32_t GetRxAvailable (void) const = 0;
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
-  virtual uint32_t GetRxAvailable (void) const = 0;
+  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
+    Address &fromAddress) = 0;
 
 private:
   // Indirect the attribute setting and getting through private virtual methods
--- a/src/routing/olsr/olsr-agent-impl.cc	Sat Jun 07 10:38:39 2008 -0700
+++ b/src/routing/olsr/olsr-agent-impl.cc	Mon Jun 09 06:40:21 2008 -0700
@@ -305,7 +305,7 @@
   Ptr<Packet> receivedPacket;
   receivedPacket = socket->Recv ();
 
-  SocketRxAddressTag tag;
+  SocketAddressTag tag;
   bool found;
   found = receivedPacket->FindFirstMatchingTag (tag);
   NS_ASSERT (found);