aronspring aronspring - 3 years ago 175
iOS Question

UDP Hole Punching on iOS

I've set up a networking project to communicate over LAN or WAN via hole punching. I'm using GCSAsyncUdpSocket for the clients. I have a rendezvous server which is port forwarded to be accessible from all incoming connections. My setup works like this:

Client A connects to the server.

Client B connects to the server.

Server observes the IP address and Port used by both clients.

Server tells Client A to communicate with public IP Address B and public Port B.

Server tells Client B to communicate with public IP Address A and public Port A.

Client A sends periodic data to Client B.

Client B sends periodic data to Client A.


This is where it goes a bit weird. While the clients are on the same network, which we've tried on both our networks, nothing works. But, if the devices are connected on different networks (both with different providers and are not linked directly) then one of the devices receive data, while the other does not.

This also fails to work on 3G completely.

What I can't understand is how it works 1-way with 1 device on each network, but not at all with both devices on the same network?

Answer Source

I've since found that one of our routers is detecting the messages being sent from one client to another contain different target IP addresses of that to the Server, and then our router decides that these messages should then be sent via a different external port. This is where the problem was coming from. Using a bit of port prediction, this hurdle can be overcome most of the time.

For those who are interested, most of the time if a connection cannot be found at the presumed port, it will most likely be at the very next port (ie. Port# + 1). If not, it gets a little bit complex from there to work out.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download