8

I've got some questions regarding hole punching with UDP. Based on the wiki http://en.wikipedia.org/wiki/UDP_hole_punching

1) To set up a UDP session between two parties (the client which is behind NAT, server which is non-NAT) does the client simply have to send a packet to the server and then the session is allowed both ways (send & receieve) through the firewall? Meaning the client can receive too from the server.

2) UDP Hole punching: Two clients first conenct to the server, then the server gives a client port / ip on to other clients, so the clients send packets to each other on those ports. Is this coorrect?

3) if #2 is true, Why would firewalls allow data to be received from another IP than the one used in making the connection on that very port? Sounds like a big security hole that should easly be filtered? I understand that source IP spoofing would trick it, but this?

Thanks in advance, Johan

KaiserJohaan
  • 9,028
  • 20
  • 112
  • 199

2 Answers2

5

1) Yes, with most reasonable firewalls, unless you configure it in extremely paranoid mode.

2) Not exactly. This article explains it in more detail, but the idea is that one of the clients first sends a datagram to the other's public IP. Then this datagram is discarded, but the other client knows that it was sent because the first one told it through the server. Then the other client sends a datagram back to the first one to the same port from which the first datagram originated. Since NAT at the first client remembers that there was a packet from that port, it considers the incoming datagram to be a reply to the first one. The problem here is to figure out which public port NAT will choose to send the first datagram, but most NATs do it in a predictable way so it almost always works fine, sometimes just not from the first try.

Sergei Tachenov
  • 24,345
  • 8
  • 57
  • 73
  • So as I understand it theres actuall two different ports used when a user sends data; first the port he has bind() (the client's 'private' port) and the actual port he is sending on (the client's 'public' port). So I need to tell each client what the other clients Public ports are, it wouldn't work to if they try to communicate with their Private port? (for example I bind() all ports to 12340, other clients cant just send stuff to other clients IP + 12340?) – KaiserJohaan Jan 24 '11 at 11:14
  • @Kaiser, usually it won't work. You'll have to figure out which public port is mapped to your private port. As far as I understand it, it is done by first sending something to a server from this private port, then the server tells this port to both sides. But it is still worth trying to communicate to the private port, using the private IP too. This will work if both clients accidentally happen to be behind the same NAT so they can communicate through the LAN. – Sergei Tachenov Jan 24 '11 at 11:25
2

1) Yes. However, you don't need hole punching if you're contacting a non-NATted server. Your client application just behaves normally.

2) Yes.

3) Some NATs do indeed restrict a public port to just one sender-receiver pair. If you need to hole-punch in such a scenario, your only chance is to guess the public port the NAT will choose for the direct connection.

However, NAT is not a security feature. Therefore, accepting any packets to the public port is not a security hole as there is no difference to the simple case of a client directly connected to the internet.

phihag
  • 278,196
  • 72
  • 453
  • 469
  • So private port (the bind() port in the application) is different from the public port (which is actually sent on). When the clients connect to the server, will the server see the public or the private port? Do I need to relay the public port, and not the private port, to other clients to allow them to communicate? – KaiserJohaan Jan 24 '11 at 11:16
  • @KaiserJohaan Yes, the private port is irrelevant for public communication – phihag Jan 24 '11 at 12:17