6

I'm developing a client-server game in python and I want to know more about port forwarding.

What I'm doing for instance is going to my router (192.168.0.1) and configure it to allow request for my real IP-adress to be redirected to my local adress 192.168.0.X. It works really well. But I'm wondering if I can do it by coding something automatically ?

I think skype works like a kind of p2p and I can see in my router that skype is automatically port forwarded to my pc adress. Can I do it in Python too?

doniyor
  • 36,596
  • 57
  • 175
  • 260
Waroulolz
  • 297
  • 9
  • 23
  • skype users are clients connecting to the skpye server. You dont need port forwarding when you are starting the "conversation". Check out http://stackoverflow.com/questions/1539339/how-does-skype-work-without-port-forwarding – cmd Jul 31 '14 at 21:20
  • 2
    http://en.wikipedia.org/wiki/NAT_traversal for a general overview of the different possible techniques. It's a hard problem. Don't worry about it until the rest of your game is finished. – Sven Marnach Jul 31 '14 at 21:33

4 Answers4

13

There are different solutions here, but most are not trivial, and you'll have to do some reading, and you'll need some kind of fallback.


UPnP/IGD is the simplest. If your router supports it, and is configured to allow it, and you know how to write either low-level networking code or old-fashioned SOAP web service code, you can ask the router to assign you a port. If it responds with success, start using that port and you're basically done.


If you can run a (very low-bandwidth) server with a public address for all of your users, Hole punching may solve the problem.

Think about how a behind-the-NAT client talks to a public server. You make a request to some IP and port, but the server is seeing your router's IP, not yours (which is a good thing, because yours isn't accessible). When it replies, your router has to know to forward it to you—which it does just by remembering that you're the behind-the-NAT client that just sent a request to that server.

What if, instead of talking to a public server, you talk to some other peer behind his own separate NAT? Well, Your router doesn't know the difference; as long as you get a response from the same place, it'll get through. But how do you get a response, when your message isn't going to get through his NAT? He does the same thing, of course. One of the messages may get lost, but the other one will get through, and then you're both set and can communicate. You will need to send keep-alives regularly so the router doesn't forget you were communicating, but other than that, there's really nothing tricky.

The only problem is that you need to know the public IP address for the other peer, and the port that he's expecting you to come from, and he needs to know the same about you. That's why you need a server—to act as an introducer between peers.

Hole punching will work with UDP from most home networks. It won't work with TCP from many home networks, or with either UDP or TCP from many corporate networks. (Also, in corporate networks, you may have multiple layers of NATs, which means you need introducers at every interface rather than just one on the internet, or symmetric NATs, which can't be punched.)


You can use STUN (or similar) services like ICE or TURN. This only works if there is an ICE, TURN, etc. service to use—which is generally not the case for two peers on different home NATs, unless you deploy your own server and build an introducer to help out, and if you're going to do that, you can just use hole punching. But in a corporate environment, this can be the best way to provide connectivity for P2P apps.


Finally, you can make the user configure port-forwarding manually and enter the forwarded port number into your problem. This is not ideal, but you should always provide it as a fallback (except maybe for apps meant only for corporate deployment), because nothing else is going to work for all of your users.


I believe Skype uses all of these. If you enable UPnP, it tries to IGD your router. Or you can configure it to use a TURN server. Or you can just enter a specific port that you've forwarded manually. If you do none of the above, it tries to use UDP hole punching, with an introducer that Skype runs.

abarnert
  • 354,177
  • 51
  • 601
  • 671
2

So your application needs to do TCP/UDP networking if I understand correctly. That means that at least one of the connecting clients needs a properly open port, and if both of them is behind NAT (a router) and have no configured open ports, your clients cannot connect.

There are several possible solutions for this, but not all are reliable: UPnP, as suggested here, can open ports on demand but isn't supported (or enabled) on all routers (and it is a security threat), and P2P solutions are complex and still require open ports on some clients.

The only reliable solution is to have a dedicated server that all clients can connect to that will negotiate the connections, and possibly proxy between them.

Yuval Adam
  • 161,610
  • 92
  • 305
  • 395
0

You could look at something like this (assuming your router supports it): http://en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal

Tom Dalton
  • 6,122
  • 24
  • 35
-1

For implementing port forwarding using python, there's a fantastic ActriveState recipe that does asynchronous port forwarding server using only Python standard library (socket, syncope). Look at

http://code.activestate.com/recipes/483732-asynchronous-port-forwarding/

Abhinav Nair
  • 116
  • 10