Communication between two computers without opening ports, using a third computer to set up the connection - c++

Let's say I have a server, and two clients connected to it. (via TCP, but it doesn't matter)
My goal is to allow a direct connection between those two clients. This is to allow direct voice contact between two players, for example, or any other client plugin they may have installed which don't need server interaction (like playing some kind of random game between the two). The server can be there to help setting up the connection.
From duskwuff's answer, I got several leads:
http://en.wikipedia.org/wiki/STUN which describes an algorithm to do that, and
http://en.wikipedia.org/wiki/UDP_hole_punching
From those, I got more leads:
http://www.h-online.com/security/features/How-Skype-Co-get-round-firewalls-747197.html
http://nutss.gforge.cis.cornell.edu/stunt.php -- A possible STUN implementation with TCP
With time, I could surely work out something for my program. For now I'm using C++ and TCP (Qt Sockets or Boost sockets), but if needed I don't mind doing UDP in C and wrapping it.
The bounty is there for any programmer having experience with those in C and C++ that may give tips to make this easier, by linking to example programs, updated libraries, or any other useful information. A documented, flexible & working C++ TCP implementation would be the best but I'll take what I get!

Punching TCP holes in NAT is sometimes/often possible (it depends of the NAT behavior). This is not a simple subject to learn, but read the corresponding chapter about NAT traversal from Practical JXTA II (available online on Scribd) to understand the nature of the issues to solve.
Then, read this. It comes from the guy who wrote that: http://nutss.gforge.cis.cornell.edu/stunt.php (one of the links in your question).
I am not a C/C++ specialist, but the issues to solve are not language specific. As long as you have access to TCP from your code base, that's enough. Keep in mind that implementing UDP traversal is easier than TCP.
Hope these tips help.
P.S.: I am not aware of a C/C++ implementation of the solution. The code mentioned in Cornell's link is NOT operational as confirmed by the author. I tried to resuscitate it myself, but he let me know it was completely tweaked for research purposes and far from production ready.

I'm not aware of any way to reliably punch through firewalls for TCP, but there's a similar method for UDP traffic that's pretty well documented:
http://en.wikipedia.org/wiki/STUN
http://en.wikipedia.org/wiki/UDP_hole_punching

A few links to projects that might be of interest or helpful:
http://sourceforge.net/projects/stun/
http://udt.sourceforge.net/
http://www.telehash.org/

You're looking for rendezvous server for NAT hole punching: the server that is publicly accessible (not behind NAT/firewall or they are properly configured) to help computers behind NAT/firewall to establish peer-to-peer connection.
UDP is more popular in NAT punching because provides much better results than TCP. Clear and informative description of UDP NAT hole punching can be found here.
If you need reliable communication, you can use reliable protocols over UDP:
SCTP (libraries) - standardized one, or
one of many custom protocols, e.g. RakNet (I used this library, it's quite mature and feature-rich and has NAT punching implementation), Enet or many others (Q8)

Ephemeral ports won't magically eliminate the need to relay through the server, because they are only valid during the life of the session opened through a well known service port. Basically ephemeral ports depend on a server session.
You will need to use the server to relay communications between both clients, that is act as a proxy server. One option would be to setup a SSH tunnel through a SSH proxy server, with the added benefit of security.
Still this doesn't guarantee that the firewall won't block the connection. That depends on the firewall type and configuration. Most residential routers that act as firewalls, by default block all incoming connections. This is normally fine because most of the time the computers behind the firewall act only as clients, which initiate the connections to the outside. And this setup varies, because some restrict initiating connections only to well known service ports like HTTP, HTTPS, FTP, SFTP, SSH, etc., and if your proxy server uses a non-well-known-service port then the connection will be blocked.
But firewalls can be setup to block outgoing traffic also, this is most common in corporate networks, which don't even allow direct connections to web servers and route everything through proxy servers, in order to control resource usage.
You can also research on the use of UPnP to open ports dynamically.

Related

Allow people to host their own multiplayer without port forwarding?

There's lots of games on Steam nowadays (Table Top Simulator, SpeedRunners) that allows people to host their own online multiplayer matches/games without the need for port forwarding.
One thing I thought of of how they do it is they simply have one server that processes all the matches as separate threads.
But then I'm starting to wonder about getting bottle necked.
I then heard these games simply somehow allow TCP to be holepunched through their NAT, getting past the need for port forwarding.
But how in say, C++ using winsock, would one do this? Or GameMaker: Studio? Or just any game in general? How do you allow people to play without port forwarding? What's the process?
I see so many games on Steam do it nowadays it must not be too complicated.
As this question is explicitely related to steam, I think it's worth mentioning the steamworks API, especially SteamNetworking. It allows peer-to-peer connection relaying through steam servers:
https://partner.steamgames.com/doc/api/ISteamNetworking
bool AllowP2PPacketRelay( bool bAllow );
Allow or disallow P2P connections to fall back to being relayed
through the Steam servers if a direct connection or NAT-traversal
cannot be established.
One may use UPnP to automatically configure the router to do the port forwarding. There's a library for that in http://pupnp.sourceforge.net/
The alternative way is to have a external server managing all traffic, so that everyone connects there, thus avoiding nat issues.

implementing server for licencing management

I would like to implement the server side of a licence management software. I use C++ in LINUX OS.
When the software starts it must connect to a server that checks privileges and allows/disallow running of some features.
My question is about the implementation of the communication between client and server across internet:
The server will have a static IP on internet so is it enough to use a simple TCP/IP socket client that will connect to a TCP/IP socket server ( providing IP/PORT) ?
I am familiar with socket communication , but less with communication across internet so my question is whether this is the right approach or do I need to use a different mechanism like a http client server or other.
Regards
AFG
Here are some benefits to using HTTP as a transport:
easier to get right, more likely to work in production: Yes, you will probably have to add additional dependencies to deal with HTTP (client and server side), but it's still preferable to yet another homegrown protocol, which you have to implement, maintain, care about backwards compatibility, deal with multiplatform issues (eg. endianness), etc. In terms of implementation ease, using an HTTP based solution should be far easier in the common case (especially true if you build a REST style service API for license checking).
More help available: HTTP as the foundation of the web is one of the most widely used technologies today. Most (all?) problems you will run into are probably publicly documented with solutions/workarounds.
Encryption 'for free': Encryption is already a solved problem (HTTPS/SSL), both with regard to transport as well as with regard to what you have to implement on your end, and it's just a matter of setting it up.
Server Authentication 'for free': HTTPS/SSL doesn't only solve encryption but also server authentication, so that the client can verify whether it's actually talking to the right service.
Guaranteed to work on the internet: HTTP/HTTPS traffic is common on the internet, so you won't run into routing problems or firewalls which are hard to traverse. This might be a problem when using your own protocol.
Flexibility out of the box: You also put less constraints on clients communicating with your server, as it's very simple to build a client in many different environments, as long as they can talk HTTP (and maybe SSL), and they know how to issue the request to your server (ie. what your service API looks like).
Easy to integrate with administrative webapp: If you want to allow users to manage their accounts associated with licenses in some way (update contact info etc.), then you might even combine the license server with that application. You can also build the license administration UI part into the same app if that's useful.
And as a last remark (this puts additional constraints on your client side HTTPS/SSL implementation): you can even use client side SSL certificates, which essentially allow authenticating the client to the server. Depending on how you use them, client side certificates are harder to manage, but they can be eg. expired, or revoked, so to some extent they actually are licenses (to connect to the server).
HTTP is not a different mechanism. It is a protocol operated over TCP/IP connections.
Internet uses IP transport exclusively. You can use UDP, TCP or SCTP session (well, UDP is not much of a session) layer on top of it. TCP is the general choice.
Sockets are operating system interface. They are the only interface to network in most systems, but some systems have different interface. Nothing to do with the transport itself.
IP addresses are in practice tied to network topology, so I strongly discourage hardcoding the IP address into the server. If you have to change network provider for any reason, you won't be getting the same IP address. Use DNS, it's just one gethostbyname call.
And don't forget to authenticate the server; even with hardcoded IP it's too easy to redirect it.

TCP port access and C++

If a program is running on a Linux machine, is there a way for that program to scan for ports that are allowed through the firewall? for example, if a programmer wants to make a chat system, but the program needs to know what ports aren't being refused access to incoming connections by a user's firewall, is there a way to check for this in your code? A program may not fail to bind a socket to a port even if the firewall is blocking that same port from incoming connections. Is there a way to check for open firewall ports?
Sidenote: This is purely for educational purposes and free of bad intentions, to be clear I am writing a chat system, and during testing, I was unable to connect desktop->laptop until I manually opened a port via allowing it through my firewall. This seemed a bit off to me, and unlike something that a programmer's code should require a user to do. Not to mention I don't want to leave the few people using this code at risk (if leaving a port permanently open does so). So It seems like I would be better suited finding a way to utilize ports that are already open to incoming TCP connections.
sidesidenote: all clients are running fedora
You have stumbled onto the second biggest issue governing the creation of new Internet applications nowadays. The first biggest of course is NAT, which is a strongly related issue (and hopefully going away eventually because of IPv6).
And there is no easy answer. One good answer is UPnP, but that's not an easy answer, and by no means universal. My network doesn't run it.
Another answer is to somehow tunnel everything you do over https (or http if you must). But that's a huge pain for something like a chat application.

The most important basics of P2P

I've been reading around on the www but just can't get the most important basics of P2P.
The diagram is like this:
[peer1]<-->[dsl-router1]<-->[central server]<-->[dsl-router2]<-->[peer2]
I'm developing a chat software on the central server. Chat messages being transfered thru' the central server well by now, however, I need to make the p2p file sharing feature because the bandwidth (the cable bandwith, not the transfer limit) of the server supposed for transfering chat messages only.
The problem is that, my software on central server knows the IPs and ports of router1 and router2, but not the peer1 and peer2 as these peers are behind the routers and don't have IP addresses.
How to actually transfer some data from peer1 to peer2 and vice versa without having this data passing thru' central server?
(and the worst case is that there is a wireless router between peer and dsl-router)
There are two basic ways of doing this. The new way is to use IGDP (opening a port via uPnP). This is described quite well here:
http://www.codeproject.com/Articles/13285/Using-UPnP-for-Programmatic-Port-Forwardings-and-N
If neither of the two nodes have a router supporting uPnP then another alternative is TCP hole punching, which is not perfect but works quite well in practice. This is described here:
http://www.brynosaurus.com/pub/net/p2pnat/
During some situations, "routers" supplied by the ISP may run on bridge mode, which directly exposes the peer computer on the internet (the computer gets a public internet address). If at least one side has this configuration (or in a similar situation that the peer client is not behind another device), then things should be rather straight forward: simply assign the central server's job to whoever that have this privilege.
In the other case where both peers only have a local address (e.g. 192.168.0.2) assigned to their computers, it would then be rather difficult to get through the routers; clients behind routers are for the most part unreachable from the outside unless they originated the request. Then, one solution to the problem is port forwarding. By doing port forwarding, either through explicitly written rules or UPnP, some ports on the peer computer is exposed to the public internet, as in the first situation where instead of only some ports the entire computer is exposed.
If you are without either of these, then there is no simple way to avoid sending through the central server. Though you could, potentially, find other peers who have the capability to transfer for others.

Protocol/Infrastructure for communicating between applications over a network

I have a C++ application that currently uses a simple TCP/IP client/server model to communicate between 2 instances of itself. This works fine on a local network, but I would like this to be used across an external network. Currently, maybe due to firewall issues, it is not able to connect across an external network.
I am not an expert on networking, but I was thinking about having a dedicated server in the middle acting as a hub for communications. Will this mitigate firewall issues?
How do networked games communicate with each other? Is there usually a server in the middle or is it peer-to-peer?
In any case, I'd appreciate any advice on protocols and infrastructure to implement a network enabled application.
Regards
I think the problem is dedicated to the NAT as mentioned by cnicutar.
Maybe you want to have a look at libupnp for automatic port forwarding in the hardware firewalls (your router at home)
There is no de facto architecture for multiplayer network games. Both client-server (most MMOs, most PC FPS's and RTS's) and Peer-to-Peer (most console games) are valid approaches.
Juoni Smed's survey in his book "Algorithms and Networking for Computer Games" is a pretty good overview of the different architectures in the wild.
For the specific issues you're talking about, your need for a proxy server, as others have noted, is probably down to NAT issues - the two machines you're trying to get talking do not have public IP addresses. If you want to pursue a Peer-to-Peer architecture (or to have one of your clients act as the server, as many modern Client-Server games do) you will need your clients to talk directly to each other. This can be achieved with NAT Traversal, unfortunately this is a fiddly process.
Luckily you can use a modern framework like the excellent Raknet which includes State Synchronisation, Remote Procedure Calls AND NAT Traversal out of the box. It's free for hobbyist use and is incorporated in to several modern industrial-grade game engines.
The bane of modern internet communications is NAT. Due to NAT (which shouldn't be confused with a simple firewall) a large portion of hosts on the internet don't have a public address and thus can't (easily) accept incoming connections. NAT breaks the internet so badly that people are moving to a totally different scheme, with slightly different semantics, just to get rid of it.
There are basically two class of solutions
NAT traversal which is sometimes used for peer-to-peer communication. Usually NAT traversal schemes require some publicly accessible server for brokering the initial connection, but the actual communication is done peer-to-peer
Client-server communication. This is easier (since the server generally should have a publicly accessible address) but also kind of inefficient. For instance, say you've got a peer on the same 10Gb LAN. If you want to send him a file through the server (which happens to be in another country) it's going to take ages instead of seconds.
I'm not sure which one is "generally used". But think of it this way:
If there is the logical need for a "controller" (say 8 people are playing a strategy game) then you probably need a server
If any two peers can logically interact without a "controller", you probably want peer-to-peer communication
If you need to transfer LOTS of data fast (file transfer), you almost surely want p2p.
The easiest way to accomplish what you want is by using sockets(in case you are doing it differently). The way you are connecting your app is usually how it's done. Also if it work sin a local network and it does not over the Internet it must be a firewall issue so try opening ports in your router configuration.
You will have to give more info about your program in order to explain if you should go with peer-to-peer or with a server.