Allow UDP sockets to receive broadcast (bug #51)
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Thu, 26 Jul 2007 12:27:49 +0100
changeset 1715 b51c9c412844
parent 1714 9623867334c3
child 1716 9757633a85da
child 1717 61831be6aede
Allow UDP sockets to receive broadcast (bug #51)
src/internet-node/ipv4-end-point-demux.cc
src/internet-node/ipv4-end-point-demux.h
src/internet-node/udp-l4-protocol.cc
--- a/src/internet-node/ipv4-end-point-demux.cc	Thu Jul 26 12:26:21 2007 +0100
+++ b/src/internet-node/ipv4-end-point-demux.cc	Thu Jul 26 12:27:49 2007 +0100
@@ -21,9 +21,12 @@
 
 #include "ipv4-end-point-demux.h"
 #include "ipv4-end-point.h"
+#include "ns3/debug.h"
 
 namespace ns3{
 
+NS_DEBUG_COMPONENT_DEFINE ("Ipv4EndPointDemux");
+
 Ipv4EndPointDemux::Ipv4EndPointDemux ()
   : m_ephemeral (1025)
 {}
@@ -68,9 +71,11 @@
 Ipv4EndPoint *
 Ipv4EndPointDemux::Allocate (void)
 {
+  NS_DEBUG ("Ipv4EndPointDemux::Allocate ()");
   uint16_t port = AllocateEphemeralPort ();
   if (port == 0) 
     {
+      NS_DEBUG ("Ipv4EndPointDemux::Allocate ephemeral port allocation failed.");
       return 0;
     }
   Ipv4EndPoint *endPoint = new Ipv4EndPoint (Ipv4Address::GetAny (), port);
@@ -80,9 +85,11 @@
 Ipv4EndPoint *
 Ipv4EndPointDemux::Allocate (Ipv4Address address)
 {
+  NS_DEBUG ("Ipv4EndPointDemux::Allocate (address=" << address << ")");
   uint16_t port = AllocateEphemeralPort ();
   if (port == 0) 
     {
+      NS_DEBUG ("Ipv4EndPointDemux::Allocate ephemeral port allocation failed.");
       return 0;
     }
   Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
@@ -97,8 +104,11 @@
 Ipv4EndPoint *
 Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
 {
+  NS_DEBUG ("Ipv4EndPointDemux::Allocate (address=" << address
+            << ", port=" << port << ")");
   if (LookupLocal (address, port)) 
     {
+      NS_DEBUG ("Ipv4EndPointDemux::Allocate duplicate address/port; failing.");
       return 0;
     }
   Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
@@ -110,6 +120,10 @@
 Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort,
 			     Ipv4Address peerAddress, uint16_t peerPort)
 {
+  NS_DEBUG ("Ipv4EndPointDemux::Allocate (localAddress=" << localAddress
+            << ", localPort=" << localPort
+            << ", peerAddress=" << peerAddress
+            << ", peerPort=" << peerPort << ")");
   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
     {
       if ((*i)->GetLocalPort () == localPort &&
@@ -117,6 +131,7 @@
           (*i)->GetPeerPort () == peerPort &&
           (*i)->GetPeerAddress () == peerAddress) 
         {
+          NS_DEBUG ("Ipv4EndPointDemux::Allocate: no way we can allocate this end-point.");
           /* no way we can allocate this end-point. */
           return 0;
         }
@@ -147,35 +162,46 @@
  * Otherwise, if we find a generic match, we return it.
  * Otherwise, we return 0.
  */
-Ipv4EndPoint *
+Ipv4EndPointDemux::EndPoints
 Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport, 
-                              Ipv4Address saddr, uint16_t sport)
+                           Ipv4Address saddr, uint16_t sport)
 {
   uint32_t genericity = 3;
   Ipv4EndPoint *generic = 0;
-  //TRACE ("lookup " << daddr << ":" << dport << " " << saddr << ":" << sport);
+  EndPoints retval;
+
+  NS_DEBUG ("Ipv4EndPointDemux::Lookup (daddr=" << daddr << ", dport=" << dport
+            << ", saddr=" << saddr << ", sport=" << sport
+            << ")");
   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
     {
-#if 0
-      TRACE ("against " << 
-             (*i)->GetLocalAddress ()
-             << ":" << 
-             (*i)->GetLocalPort () 
-             << " " << 
-             (*i)->GetPeerAddress () 
-             << ":" 
-             << (*i)->GetPeerPort ());
-#endif
+      NS_DEBUG ("Ipv4EndPointDemux::Lookup against " << 
+                (*i)->GetLocalAddress ()
+                << ":" << 
+                (*i)->GetLocalPort () 
+                << " " << 
+                (*i)->GetPeerAddress () 
+                << ":" 
+                << (*i)->GetPeerPort ());
       if ((*i)->GetLocalPort () != dport) 
         {
           continue;
         }
-      if ((*i)->GetLocalAddress () == daddr &&
-          (*i)->GetPeerPort () == sport &&
-          (*i)->GetPeerAddress () == saddr) 
+      NS_DEBUG ("Ipv4EndPointDemux::Lookup local address matches: "
+                << bool ((*i)->GetLocalAddress () == daddr || daddr.IsBroadcast ()));
+      NS_DEBUG ("Ipv4EndPointDemux::Lookup peer port matches: "
+                << bool ((*i)->GetPeerPort () == sport || sport == 0));
+      NS_DEBUG ("Ipv4EndPointDemux::Lookup peer address matches: "
+                << bool ((*i)->GetPeerAddress () == saddr ||
+                         (*i)->GetPeerAddress () == Ipv4Address::GetAny ()));
+      
+      if ( ((*i)->GetLocalAddress () == daddr || daddr.IsBroadcast ())
+           && ((*i)->GetPeerPort () == sport || (*i)->GetPeerPort () == 0)
+           && ((*i)->GetPeerAddress () == saddr || (*i)->GetPeerAddress () == Ipv4Address::GetAny ()))
         {
+          NS_DEBUG ("Ipv4EndPointDemux::Lookup MATCH");
           /* this is an exact match. */
-          return *i;
+          retval.push_back (*i);
         }
       uint32_t tmp = 0;
       if ((*i)->GetLocalAddress () == Ipv4Address::GetAny ()) 
@@ -192,7 +218,11 @@
           genericity = tmp;
         }
     }
-  return generic;
+  if (retval.size () == 0 && generic != 0)
+    {
+      retval.push_back (generic);
+    }
+  return retval;
 }
 
 uint16_t
--- a/src/internet-node/ipv4-end-point-demux.h	Thu Jul 26 12:26:21 2007 +0100
+++ b/src/internet-node/ipv4-end-point-demux.h	Thu Jul 26 12:27:49 2007 +0100
@@ -32,15 +32,18 @@
 
 class Ipv4EndPointDemux {
 public:
+  typedef std::list<Ipv4EndPoint *> EndPoints;
+  typedef std::list<Ipv4EndPoint *>::iterator EndPointsI;
+
   Ipv4EndPointDemux ();
   ~Ipv4EndPointDemux ();
 
   bool LookupPortLocal (uint16_t port);
   bool LookupLocal (Ipv4Address addr, uint16_t port);
-  Ipv4EndPoint *Lookup (Ipv4Address daddr, 
-                        uint16_t dport, 
-                        Ipv4Address saddr, 
-                        uint16_t sport);
+  EndPoints Lookup (Ipv4Address daddr, 
+                    uint16_t dport, 
+                    Ipv4Address saddr, 
+                    uint16_t sport);
 
   Ipv4EndPoint *Allocate (void);
   Ipv4EndPoint *Allocate (Ipv4Address address);
@@ -55,8 +58,6 @@
 
  private:
   uint16_t AllocateEphemeralPort (void);
-  typedef std::list<Ipv4EndPoint *> EndPoints;
-  typedef std::list<Ipv4EndPoint *>::iterator EndPointsI;
 
   uint16_t m_ephemeral;
   EndPoints m_endPoints;
--- a/src/internet-node/udp-l4-protocol.cc	Thu Jul 26 12:26:21 2007 +0100
+++ b/src/internet-node/udp-l4-protocol.cc	Thu Jul 26 12:27:49 2007 +0100
@@ -113,13 +113,14 @@
 {
   UdpHeader udpHeader;
   packet.RemoveHeader (udpHeader);
-  Ipv4EndPoint *endPoint = m_endPoints->Lookup (destination, udpHeader.GetDestination (),
-                                                source, udpHeader.GetSource ());
-  if (endPoint == 0)
+  Ipv4EndPointDemux::EndPoints endPoints =
+    m_endPoints->Lookup (destination, udpHeader.GetDestination (),
+                         source, udpHeader.GetSource ());
+  for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
+       endPoint != endPoints.end (); endPoint++)
     {
-      return;
+      (*endPoint)->ForwardUp (packet, source, udpHeader.GetSource ());
     }
-  endPoint->ForwardUp (packet, source, udpHeader.GetSource ());
 }
 
 void