Bugzilla – Bug 1527
Ipv4RawSocket's BindToNetDevice not doing anything
Last modified: 2012-11-28 15:38:00 UTC
The Ipv4RawSocket has a BindToNetDevice function (inherited by Socket class), however it does nothing. The proof is: grab a node with two interfaces. Open two raw sockets with the same address and bind them to the respective NetDevices. Now watch the node receive the packets on *both* sockets. The same packet too... Why the big has never (so far) been spotted: you don't really want two NetDevices with the same IPv4 address. Unless it's a multicast address... DOH! Patch incoming. T.
Created attachment 1463 [details] Patch to enable IPv4 raw sockets to obey to BindToNetDevice This is drycoded. I tested the same code on IPv6 Raw Sockets and it works.
Created attachment 1469 [details] test progam The test program is simple: grab a node with 2 interfaces and bind an IPv4RawSocket to each interface in the node (there are 3, one is the loopback). Then ask a node to send 2 multicast packets :P Without the patch: reate nodes. Build Topology. Add IP Stack. Assign IP Addresses. Configure multicasting. Create Applications. Configure Tracing. Run Simulation. Socket 0x7fa111479f90 - Received a packet from 10.1.1.1, pointer 0x7fa11147a800, size 172, content ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 0 protocol 17 offset (bytes) 0 flags [none] length: 156 10.1.1.1 > 225.1.2.4) ns3::UdpHeader (length: 136 49153 > 9) Payload (size=128) Socket 0x7fa11147a050 - Received a packet from 10.1.1.1, pointer 0x7fa11147a800, size 172, content ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 0 protocol 17 offset (bytes) 0 flags [none] length: 156 10.1.1.1 > 225.1.2.4) ns3::UdpHeader (length: 136 49153 > 9) Payload (size=128) Socket 0x7fa11147a160 - Received a packet from 10.1.1.1, pointer 0x7fa11147a800, size 172, content ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 0 protocol 17 offset (bytes) 0 flags [none] length: 156 10.1.1.1 > 225.1.2.4) ns3::UdpHeader (length: 136 49153 > 9) Payload (size=128) Socket 0x7fa111479f90 - Received a packet from 10.1.1.1, pointer 0x7fa11147a800, size 172, content ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 1 protocol 17 offset (bytes) 0 flags [none] length: 156 10.1.1.1 > 225.1.2.4) ns3::UdpHeader (length: 136 49153 > 9) Payload (size=128) Socket 0x7fa11147a050 - Received a packet from 10.1.1.1, pointer 0x7fa11147a800, size 172, content ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 1 protocol 17 offset (bytes) 0 flags [none] length: 156 10.1.1.1 > 225.1.2.4) ns3::UdpHeader (length: 136 49153 > 9) Payload (size=128) Socket 0x7fa11147a160 - Received a packet from 10.1.1.1, pointer 0x7fa11147a800, size 172, content ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 1 protocol 17 offset (bytes) 0 flags [none] length: 156 10.1.1.1 > 225.1.2.4) ns3::UdpHeader (length: 136 49153 > 9) Payload (size=128) Done. 6 packets received. Nasty ! With the patch: Create nodes. Build Topology. Add IP Stack. Assign IP Addresses. Configure multicasting. Create Applications. Configure Tracing. Run Simulation. Socket 0x7fb530c7a050 - Received a packet from 10.1.1.1, pointer 0x7fb530c7a800, size 172, content ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 0 protocol 17 offset (bytes) 0 flags [none] length: 156 10.1.1.1 > 225.1.2.4) ns3::UdpHeader (length: 136 49153 > 9) Payload (size=128) Socket 0x7fb530c7a050 - Received a packet from 10.1.1.1, pointer 0x7fb530c7a800, size 172, content ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 1 protocol 17 offset (bytes) 0 flags [none] length: 156 10.1.1.1 > 225.1.2.4) ns3::UdpHeader (length: 136 49153 > 9) Payload (size=128) Done. 2 packets received. Much better. T.
(In reply to comment #0) > The Ipv4RawSocket has a BindToNetDevice function (inherited by Socket > class), however it does nothing. > The proof is: grab a node with two interfaces. Open two raw sockets with the > same address and bind them to the respective NetDevices. > Now watch the node receive the packets on *both* sockets. The same packet > too... > > Why the big has never (so far) been spotted: you don't really want two > NetDevices with the same IPv4 address. Unless it's a multicast address... > DOH! > > Patch incoming. > > T. Curious to know: 1. I thought we prevent one Ipv4Addresses from being re-used anywhere else. 2. If there are two different sockets bound to two different netdevices which participate in the same multicast group, why shouldn't both sockets get the packet? Neither socket has knowledge of the other and by the nature of multicast are not connection oriented. Different hosts can handle this in different ways ( to me there does not seem to be a well-defined RFC way for this), 1. prevent two interfaces from belonging to the same subnet 2. prevent two interfaces from subscribing to the same multicast group, unless it was intentional to handle fault-tolerance links (one link goes down, other link can still work)
Maybe the network description wasn't so clear :P // Network topology // // Lan1 // ====== // | | // n0 n1 n2 // | | // ====== // Lan0 // // - Multicast source is at node n0; The node with multiple Ipv4RawSockets is n1, so the sockets are on different physical networks. The "v4" use case is kinda hard to figure out, but the v6 one is much easier to see. On IPv6 it's pretty much usual to have the same IPv6 multicast address open on different interfaces, and you could want to open different sockets bound to each NetDevice. Anyway, despite the use-case, I think that BindToNetDevice should do what's meant to do even on Raw sockets, isn't it ? Cheers, T. PS: the pactch doesn't break any test.
Yes, I see your point, if the socket is bound, the packet should only go up the stack to a bound socket for the matching incoming interface . One packet entering only one interface delivered to two sockets in the same host, seems intuitively incorrect. (In reply to comment #4) > Maybe the network description wasn't so clear :P > > // Network topology > // > // Lan1 > // ====== > // | | > // n0 n1 n2 > // | | > // ====== > // Lan0 > // > // - Multicast source is at node n0; > > The node with multiple Ipv4RawSockets is n1, so the sockets are on different > physical networks. > > The "v4" use case is kinda hard to figure out, but the v6 one is much easier > to see. On IPv6 it's pretty much usual to have the same IPv6 multicast > address open on different interfaces, and you could want to open different > sockets bound to each NetDevice. > > Anyway, despite the use-case, I think that BindToNetDevice should do what's > meant to do even on Raw sockets, isn't it ? > > Cheers, > T. > > PS: the pactch doesn't break any test.
Applied in changeset 9147 - e9af93287335