Bug 51 - Allow UDP sockets to receive broadcast
Allow UDP sockets to receive broadcast
Status: RESOLVED FIXED
Product: ns-3
Classification: Unclassified
Component: network
pre-release
PC All
: P1 normal
Assigned To: ns-bugs
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2007-07-15 19:05 EDT by Gustavo J. A. M. Carneiro
Modified: 2007-09-24 06:02 EDT (History)
0 users

See Also:


Attachments
a sample python program (489 bytes, text/plain)
2007-07-15 19:09 EDT, Gustavo J. A. M. Carneiro
Details
proposed patch (7.97 KB, patch)
2007-07-15 19:11 EDT, Gustavo J. A. M. Carneiro
Details | Diff
patch to fix (allows limited broadcast to be received on multiple sockets) (11.99 KB, patch)
2007-09-21 14:46 EDT, Gustavo J. A. M. Carneiro
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Gustavo J. A. M. Carneiro 2007-07-15 19:05:53 EDT
Some context:

For my OLSR code, I need to use two UDP sockets, bound to the same OLSR port.  One is bound to address 0.0.0.0 in order to receive OLSR packets on all interfaces.  Another one is bound the "main address", which is the address of one of the node netdevices.  This second socket is used for sending OLSR packets, and binding it to the main address is needed to ensure that OLSR packets are always sent with that address as source, regardless of the interface that actually transmits it.  This is required by the OLSR protocol.

Now the problem; it is two fold:

1. Currently, UDP sockets are not receiving broadcast packets;
2. NS-3 is allowing multiple sockets bound to the same port, but only allows one of them to actually receive the packets, which is clearly wrong.
Comment 1 Gustavo J. A. M. Carneiro 2007-07-15 19:09:53 EDT
Created attachment 29 [details]
a sample python program

The point of this (python, but python sockets API is exactly the same as in C/unix) program is to demonstrate that in a real system sockets can send broadcast packets, although it does require the line:

    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

In addition, multiple sockets can be bound to the same port, although it requires a socket option:

    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

Afterwards, we can have multiple sockets listening on the same port and they will all receive a copy of the same packets.
Comment 2 Gustavo J. A. M. Carneiro 2007-07-15 19:11:38 EDT
Created attachment 30 [details]
proposed patch
Comment 3 Gustavo J. A. M. Carneiro 2007-08-02 10:01:29 EDT
This is already merged.
Comment 4 Gustavo J. A. M. Carneiro 2007-09-21 09:43:51 EDT
This bug re-surfaced lately.  Again UDP sockets are not receiving broadcast packets... :-(

I'll try to add a unit test for this specific problem so that hopefully it gets fixed sooner next time :)
Comment 5 Gustavo J. A. M. Carneiro 2007-09-21 10:55:42 EDT
Unit test pushed to ns-3-dev.  Now I'll try to fix it...
Comment 6 Gustavo J. A. M. Carneiro 2007-09-21 12:28:19 EDT
My code is:

NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("255.255.255.255"), 1234), Packet (123)), 0);

But:

std::list<ns3::Ipv4EndPoint*, std::allocator<ns3::Ipv4EndPoint*> > ns3::Ipv4EndPointDemux::Lookup(ns3::Ipv4Address, uint16_t, ns3::Ipv4Address, uint16_t) ==> (daddr=10.0.255.255, dport=1234, saddr=10.0.0.2, sport=49153)

So, something is transforming the destination address 255.255.255.255 into 10.0.255.255.  Is this correct?
Comment 7 Gustavo J. A. M. Carneiro 2007-09-21 12:33:33 EDT
(In reply to comment #6)
> My code is:
> 
> NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress
> (Ipv4Address("255.255.255.255"), 1234), Packet (123)), 0);
> 
> But:
> 
> std::list<ns3::Ipv4EndPoint*, std::allocator<ns3::Ipv4EndPoint*> >
> ns3::Ipv4EndPointDemux::Lookup(ns3::Ipv4Address, uint16_t, ns3::Ipv4Address,
> uint16_t) ==> (daddr=10.0.255.255, dport=1234, saddr=10.0.0.2, sport=49153)
> 
> So, something is transforming the destination address 255.255.255.255 into
> 10.0.255.255.  Is this correct?
> 

OK, I made a small real world experiment and when I ping -b 255.255.255.255, a receiving node in the same LAN receives a packet to 255.255.255.255.  So NS-3 is wrong.
Comment 8 Gustavo J. A. M. Carneiro 2007-09-21 12:42:48 EDT
The source of the problem is udp-socket.cc, UdpSocket::DoSendTo:

  if (dest.IsBroadcast ())
    {
      NS_LOG_LOGIC ("Limited broadcast");
      for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
        {
          Ipv4Address addri = ipv4->GetAddress (i);
          Ipv4Mask maski = ipv4->GetNetworkMask (i);
          m_udp->Send (p, addri, addri.GetSubnetDirectedBroadcast (maski),
                       m_endPoint->GetLocalPort (), port);
          NotifyDataSent (p.GetSize ());
        }
    }

This "addri.GetSubnetDirectedBroadcast (maski)" is changing the 255.255.255.255 address to 10.0.255.255.  This behavior does not match my real world experience.  Replacing "addri.GetSubnetDirectedBroadcast (maski)" with "dest" fixes the problem.  Any comments?
Comment 9 Tom Henderson 2007-09-21 13:45:34 EDT
Response to your question in comment #6:  

There appear to be different possible correct behaviors, one of which is what is implemented in ns-3.  Note that it differs from Linux.  

From Stevens, UNP, vol 1, ed. 3, p. 532.

"What does a host do when sending UDP to 255.255.255.255?  Most hosts allow this and convert the destination address to the subnet-directed broadcast address of the outgoing interface.  It is often necessary to access the datalink directly to send a packet to 255.255.255.255.

Another question is:  What does a multihomed host do when the application sends UDP to 255.255.255.255?  Some systems send a single broadcast on the primary interface with destination set to subnet-directed broadcast.  Other systems send one copy out from each broadcast-capabile interface.  Section 3.3.6 of RFC 1122 "takes no stand" on this issue.  For portability, however, applications that want to broadcast to all interfaces should obtain the interface configuration and do one sendto() for each interface with destination set to that interface's broadcast address."
Comment 10 Gustavo J. A. M. Carneiro 2007-09-21 14:46:16 EDT
Created attachment 66 [details]
patch to fix (allows limited broadcast to be received on multiple sockets)
Comment 11 Gustavo J. A. M. Carneiro 2007-09-21 14:53:33 EDT
(In reply to comment #9)
> Response to your question in comment #6:  
> 
> There appear to be different possible correct behaviors, one of which is what
> is implemented in ns-3.  Note that it differs from Linux.  
> 
> From Stevens, UNP, vol 1, ed. 3, p. 532.

The project as a whole has to decide whether to be thoroughly pedantic, or to be as easy to program as possible.  After deciding that, document the decision  and with time enforce it everywhere.  What NS-3 should NOT do is change behavior over time, since it breaks code maintained outside of ns-3-dev, like the olsr code.

In this case I also don't think the behavior or 255.255.255.255 is not fully specified in RFCs because "sockets" are mostly a Operating System concept, not a protocol issue.

Finally, keep in mind that if we don't allow the flexibility of multiple sockets being able to receive broadcast packets then I would have to stop using sockets for OLSR (explanation of why is in my first comment), which would be a pity...
Comment 12 Tom Henderson 2007-09-24 02:24:40 EDT
Gustavo, can you please split out your patch into two (LOG_M modifications, and the logic fix to Ipv4EndPointDemux::Lookup (and related unit tests), and apply the latter to fix the current ns-3-dev build, and close out this bug?  Perhaps take the LOG_M proposal to another tracker item or the list.
Comment 13 Gustavo J. A. M. Carneiro 2007-09-24 06:02:19 EDT
(In reply to comment #12)
> Gustavo, can you please split out your patch into two (LOG_M modifications, and
> the logic fix to Ipv4EndPointDemux::Lookup (and related unit tests), and apply
> the latter to fix the current ns-3-dev build, and close out this bug?  Perhaps
> take the LOG_M proposal to another tracker item or the list.

Committed without the G_LOG_M stuff.