I'm trying to to send a udp packet to a client across a NAT, both of us belong to a different NAT, we are familiar with the theory of STUN therefore the way to achieve this is to 'hole punch' our way through via a simple STUN server..

Basically the server just returns external IP address and port of another client that is 'connected' which I can then use it to send the packet to the client across the NAT... however though we managed to get each other's external ip and ports..we are still unable to receive anything from each other after sending... After searching through forums and many hours of head scratching we are still unable to come up with a solution...was wondering if anyone who is familiar with STUN to able to give us some pointers or advice on where we've gone wrong...

1 Answer
1

What you implemented is not the true STUN protocol, but will likely suffice. :)

But I think I see two problems in your code.

You aren't saving the local port number. After you get the response back from the stun server, you need to call socket.getLocalPort to find out what your internal port number that corresponds to the "mapped port". The mapped port is the port that your stun server sees you at. Your NAT will continue to map outbound traffic from your PC's IP, to that mapped port, but only if you use the same local port. So in your subsequent connection to your peer, create the datagram socket on that same port (after closing the original socket), or just reuse the same socket for a subsequent communication to a peer, as the socket is already binded.

Just because you know the remote host's external IP address and his port mapping for his local socket, doesn't mean his NAT is going to forward your packets. Most NATs run as "IP and port restricted". This means that it will only allow inbound traffic, including UDP packets, through the NAT if it knows that there was a corresponding outbound UDP packet for the same remote host's IP and port. If it didn't have this rule in place, it wouldn't know which PC behind the NAT to forward the packet to. Typical NAT traversal technique is for both peers to send simple 1-byte datagrams to each other at the same time, and to try repeatedly (more than once). The first packet tries to leave the host and out of its own NAT, but will likely get blocked by the remote NAT (because it doesn't know who you are). But it does cause your NAT to create a mapping and forwarding entry for the other side to successfully send to you. Eventually, both NATs will allow and forward traffic between both peers.

There are also types of NATs with unpredictable port mapping behavior. (Port mapping changes on a per-IP basis). These are difficult to traverse (with with STUN), but usually works out ok if the other side has a well behaved NAT. Fortunately, these types of NATs are rarer than they used to be.