Bug 2762

Summary: BindToNetDevice behaviour is not coherent with Linux
Product: ns-3 Reporter: Tommaso Pecorella <tommaso.pecorella>
Component: internetAssignee: Tommaso Pecorella <tommaso.pecorella>
Status: RESOLVED FIXED    
Severity: enhancement CC: ns-bugs, tomh
Priority: P3    
Version: ns-3-dev   
Hardware: All   
OS: All   
Attachments: Patch
test program
New patch

Description Tommaso Pecorella 2017-06-26 18:16:30 UTC
Created attachment 2879 [details]
Patch

First and foremost, it shouldn't call Bind. That's not how Linux works.

Second, it should be possible to Bind two (or more) sockets to the same address, with BindToNetDevice discriminating among them.

The patch does exactly this.
The checks about duplicate EndPoints (previously done in BindToNetDevice) are now delayed and done in the packet reception.
In this way, one can (for example) open multiple sockets listening to any:some (any address, some port) on different NetDevices without too many troubles.

the run-time check is a simple check on the size of a list, and it should be harmless in terms of performance.
Comment 1 Tommaso Pecorella 2017-07-02 20:35:39 UTC
A clarification about the checks being moved to run-time.

If we allow a complete freedom in Bind and BindToNetDevice order, then it is impossible to perform the checks when you create the EndPoint (i.e., in Bind), because you don't know yet if the socket is going to be bound to a specific NetDevice.

The following code must run without errors:

socket0->Bind (ipv4Address::Any (), 9);
socket1->Bind (ipv4Address::Any (), 9);
socket2->Bind (ipv4Address::Any (), 9);

// socket0 will receive packets from all the NetDevices except device1 and device2
socket1->BindToNetDevice (device1);
socket2->BindToNetDevice (device2);
Comment 2 Tommaso Pecorella 2017-07-05 19:35:19 UTC
Created attachment 2885 [details]
test program

Never have doubts, or if you have one... try.
In this case, I made a small UDP server program and I tested it on a Linux box with 2 interfaces.

The result is this:

Binding on the same address/port is allowed PROVIDED THAT the socket is *already* bound to a NetDevice.
Different interfaces are allowed, but NOT a "general" one.

In other terms, it seems that the duplicated Endpoint check is performed at Bind time. You can use BindToNetDevice later on, but this won't help in the actual socket check.

Now, the question is: should we replicate exactly this behavior?
It would mean that the (mild) suggestion will become: Use BindToNetDevice *before* Bind. The exact opposite of what we suggested before.
Note that in this case, it would be only a suggestion.
Comment 3 Tommaso Pecorella 2017-07-07 16:44:57 UTC
Created attachment 2888 [details]
New patch

This patch is a bit more complex than the previous one because you need to pass the socket bound NetDevice to the Ipv[4,6]EndPointDemux in order to check if there's another conflicting Endpoint already in place.

Nevertheless, now the sockets are working as in Linux.
Comment 4 Tom Henderson 2017-07-12 01:48:10 UTC
(In reply to Tommaso Pecorella from comment #3)
> Created attachment 2888 [details]
> New patch
> 
> This patch is a bit more complex than the previous one because you need to
> pass the socket bound NetDevice to the Ipv[4,6]EndPointDemux in order to
> check if there's another conflicting Endpoint already in place.
> 
> Nevertheless, now the sockets are working as in Linux.

+1
Comment 5 Tommaso Pecorella 2017-07-12 13:56:11 UTC
Pushed in changeset: 12958:6e192ac0b562