9
\$\begingroup\$

I'm trying to add networking functionality to my game. I want any user to be able to host the game, and anyone to be able to connect as a client. The client sends info to the host about their player's position, etc. When the host receives a message, it validates it and then broadcasts it to its other clients. I will primarily be dealing with UDP, but will also need TCP for chat & lobby stuff.

The problem is that I can't seem to get a packet sent from the client to the host or the other way around without enabling port forwarding on my router. But I don't think this is necessary. I believe the reason I need port forwarding is because I want to send a packet from 1 computer on a LAN to another computer on a different LAN, but neither of them have a global ip address since they're in a LAN. So really, I can only send packets targeting the other network's router, which must forward it on to the machine I want to reach. So how can I do this without port forwarding? Somehow a web server can communicate with my computer, which doesn't have a global ip, without port forwarding. And I've played plenty of multi-player games that don't require me to enable port forwarding. So it must be possible.

Btw, I'm using SDL_Net. I don't think this will change anything though.

\$\endgroup\$
1
  • \$\begingroup\$ The web server has a global IP (or whatever devices in front of it). \$\endgroup\$ Mar 20, 2011 at 16:44

3 Answers 3

13
\$\begingroup\$

Many to one NAT (many computers with private addresses behind one public address) works like this: The router keeps track of outbound packets and when an answer is received it can send it to the internal computer which sent the original request. So this works fine, if you visit a website with a public ip-address.

It is, however, not possible to send an initial packet from the outside to one specific computer on the inside, unless a forwarding rule is defined on the router: There is no way to address a specific computer and the router does not have information in his connection table because it is not an reply.

Skype made a technique popular that is called firewall hole punching: A server with a public address is contacted by the clients. Then it sends an answer back to client A telling it to send udp packages to the router of client B on a port it expect the router of client B to use as source port for the next outbound packet. And it tells client B to send a packet to the router to client A on a port it expects the router of A to use as source port for its next outbound packet. If the prediction is correct, A and B can now talk directly which each other.

Firewall hole punching requires a server with a public ip address to act as a moderator. And it requires a lot of knowledge about the implementations of common NAT router to predict the outbound source ports correctly. Although there are open source implementations available, you should try to avoid this technique because it is unreliable and causes lots of headache. Skye falls back to using the server with the public ip address to relay all packets if the predictions fail.

\$\endgroup\$
4
\$\begingroup\$

Somehow a web server can communicate with my computer, which doesn't have a global ip, without port forwarding

Importantly, the web server itself has a global IP/port pair, that uniquely identifies it. Your computer connects to the web server, which sends the information back along the same channel.

This technique is obviously not available if both sides are behind some kind of NAT, as is the common case for peer-to-peer games. So instead, you need to trick the NAT.

The technique you are looking for is called hole punching or punch-through, in particular UDP hole punching or TCP hole punching. In this case both clients connect to a global server, which in turn tells them how to connect to each other, through the "hole punched" in the firewall by the existing connection.

Hole punching does require a public server with a global IP/port to handle the initial connection and hand-off, but the bandwidth / processing requirements are minuscule. If you have a global lobby server, it should be able to handle it easily.

\$\endgroup\$
4
\$\begingroup\$

Google Talk uses libjingle to achieve the same thing.

Other libraries for ICE/STUN/TURN include PJNATH and libnice

\$\endgroup\$
1
  • \$\begingroup\$ Link not working \$\endgroup\$ Aug 3, 2018 at 11:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .