0

Using C++ I create a single UDP socket, supplying both an IPv4 address and port. I run this on Ubuntu and have both a wlan0 and eth0 interface up and running. Apparently something decides that both interfaces should be used, I appreciate that. Sending and receiving using a different interface does create a kind of a pickle (NAT traversal???) for me though. Using Wireshark I can see packages coming in, but my application does not register them.

To clarify:

I have a tracker which will supply me with a peer. The tracker will also contact that peer to send me a message. In order to overcome NAT traversal issues, I will send a puncture message. The problem now is that the puncture messages is sent over wlan (I am testing locally with two machines), whereas the messages from the peer are coming in over eth.

So, I think the simplest solution would be to simply use one interface. (Or both one socket)

EDIT:

I will try what is mentioned here on specifying a single interface.

@Barmar, pointed out that UDP sockets may change interface when sendto is called with a destination address that would benefit from it. I am still fuzzy on the reason for my problem though. Can someone explain why this is an issue in the first place?

EDIT2:

The above mentioned solution of forcing one interface for the socket bind did not work. Apparently the sendto method will choose to ignore this and still go for the other interface if it feels that that will work better. Does anyone know how to make sure that socket sticks to the interface it was assigned to?

Community
  • 1
  • 1
Vincent Ketelaars
  • 1,069
  • 1
  • 14
  • 35
  • 1
    Is this a TCP or UDP socket? The interface is normally chosen based on the destination address, and that doesn't change for TCP, but it can change for UDP with each `sendto()`. – Barmar Oct 18 '13 at 14:46
  • @Barmar, it's a UDP socket. – Vincent Ketelaars Oct 18 '13 at 14:48
  • Is the problem you're having that the source address of replies doesn't match the destination address of requests? If so, the portable solution is to bind a different socket to each interface address; when a request comes in on socket N, send the reply out through that socket. – Barmar Oct 18 '13 at 14:54
  • @Barmar, I hopefully clarified my post – Vincent Ketelaars Oct 18 '13 at 15:08
  • The reason is that the Internet is asymmetric. Just because the best way to get from A to B is via interface X, it doesn't mean that the best way to get from B to A is also via interface X. Also, since end devices don't participate in Internet routing protocols, they don't necessary know the _best_ path, often they have an arbitrary default, which may not match the reverse path. – Barmar Oct 18 '13 at 15:12
  • @Barmar, multiple interfaces becomes a problem because they have different IP's as well. Which makes this asymmetric sending and receiving characteristic a problem for me. So I need to force the socket to stick to one interface.. So far I have not been succesful. Suggestions? – Vincent Ketelaars Oct 21 '13 at 10:45

1 Answers1

0

If you need to ensure that UDP replies come from the same address that the request was sent to, the solution is to use multiple sockets. You open one socket for each IP of the server (this may be more than one socket per interface, because of interface aliases), and bind the socket to that IP. Then you use select() or poll() to wait for requests on all sockets at once. When a request comes in on a particular socket, you send the reply out through that same socket, and its source IP will match the original packet's destination.

Barmar
  • 741,623
  • 53
  • 500
  • 612