UDP – How to Listen to a Busy Port with UDP Hole Punching

udp

Good day everyone!

I am developing a network application that is extremely time sensitive and having an intermediary server is not an option. Therefore, I decided to implement a udp hole punching algorithm. To simplify, I explain my problem using two points. Let's say A sends something to B. As far as I understand, when A sends something to B, A doesn't not have a lot of choice of which port to use (for sending). OS allocates that port automatically. B however can see port from which A send a packet. Now B tries to send a packet back on that port so that A can read it.

Here is an issues/questions that I ran into:

  1. When trying to use a netcat(for testing) on point A listening to port that was used to send packets I get a message that the port is busy. Am i listening to the wrong port? I thought that UDP protocol is connection less and multiple program can use same port at the same time.

  2. Is there a way (c#) to see the port that my application is using to send a packet?

The following "diagram" shows a more detailed portion of what I am trying to implement

A ———> R ————> C

When UDP packet recieved on point C it can see the external port of the router at point R. That is where C send a udp packet. Upon receiving a packet the router sends it to A. My problem is how to read that packet on A? Thank you for help

Best Answer

By default, establishing a Socket connection in your code will chose an arbitrary ephemeral source port (1024-65535), however this can be overridden:

DNS for example uses UDP and both source AND destination port 53 for transmission.

Regarding your other questions:

  1. UDP is connectionless, but don't confuse this with multiple applications being able to bind to the same socket - if a packet comes in on a specific port, then it can only be delivered to a single application (The exception being applications such as Wireshark which don't specifically bind to a port, but apply a special filter to an interface that copies all traffic sent to it.) In your case, your application and netcat cannot both bind to the same port.

  2. When s is a Socket, you can pull this information from LocalEndPoint.
    Console.WriteLine (""I am connected on port number " + ((IPEndPoint)s.LocalEndPoint).Port.ToString ()); More information here: https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.localendpoint(v=vs.110).aspx

  3. This is an inherent issue with NAT (Network Address Translation) - the only way to get around it is to specifically configure R to port-forward your traffic back to A.