The NAT device will keep a table with currently open connections so that it can send return packets to the internal host that opened the connection. An entry in the state table could look something like this:
Internal Source IP | Internal S-Port | External S-Port | Destination IP | D-Port
192.168.1.12 10123 10123 203.0.113.1 5555
When a packet is received (from the external side) the NAT device will check the Source IP, Source Port and Destination Port of the packet and compare it to the Destination IP
, D-Port
and External S-Port
fields in its connection table. When it finds a match it will forward the packet to Internal Source IP
on Internal S-Port
.
UDP hole punching depends on the fact that Internal and External Source Ports are the same. This is normally the case unless you have a second internal host that uses the same Source port to connect to the same external Destination/D-Port combination.
When we assume that Internal and External S-Port are the same then both clients A,B can communicate their source port to the rendezvous server which will then relay the information back to the other client respectively.
The answer you are looking for can be found here
For completion reasons, I paste it here:
"First, the checksum calculation is defined in RFC 768 but hints as to how to calculate it efficiently are in RFC 1071. Both are worth reading and contain a much more in-depth description that I'm going to write here.
The basic idea is that the UDP checksum is a the complement of a 16-bit one's complement sum calculated over an IP "pseudo-header" and the actual UDP data. The IP pseudo-header is the source address, destination address, protocol (padded with a zero byte) and UDP length. So to take the example of this short packet, the source IP address is 152.1.51.27, and the destination IP address is 152.14.94.75. Divided into 16-bit quantities, these are 0x9801, 0x331b and 0x980e, 0x5e4b. If you add those together using two's complement (e.g. with Windows calculator), you get 0x1c175. Note that this overflows a 16-bit quantity, but we'll take care of that later. Next is to add in the protocol and UDP length. For this packet, the protocol is UDP so the protocol type byte is 17or 0x11. We pad that with zero to get 0x0011 and then add the UDP length which is 0x000a (10 bytes). So 0x1c175 + 0x0011 + 0x0! 00a = 0x1c190.
Now we add the entire UDP datagram, treating it all as 16-bit quantities and skipping the checksum (until we finish calculating it!). For this datagram, that's 0xa08f, 0x2694, 0x000a, 0x6262, so if we add all that to our running sum, we get 0x1c190 + 0xa08f + 0x2694 + 0x000a + 0x6262 = 0x2eb1f.
Now to convert to a ones complement 16-bit sum we just treat our current sum (0x2eb1f) as a 32-bit quantity and add the high half to the low half. 0x0002 + 0xeb1f = 0xeb21. (If that still had an overflow, we'd add the high and low halves again until there was no longer an overflow.) Now we complement that quantity (i.e. flip all the bits, or do a NOT operation) and we get a value of 0x14de which is exactly what the reported checksum shows in the packet."
Best Answer
Details vary but basically it goes something like.
This strategy will work reliablly with full cone, restricted cone or restricted port cone NATs. It will work most of the time with port-preservative symmetric NATs. It will not work with randomising symmetric NATs.