1

I know p2p software like Skype is using UDP hole punching for that. But what if one of the clients is a web browser which needs to download a file from another client (TCP connection instead of UDP)? Is there any technique for such case?

I can have an intermediate public server which can marry the clients but I can't afford all the traffic between these clients go through this server. The public server can only establish the connection between the clients, like Skype does, and that's all. And this must work via TCP (more exactly, HTTP) to let the downloading client be a web browser.

Both clients must not be required to setup anything in their routers or anything like that.

I'll plan to code this in C/C++ but at the point I'm wondering if this idea is possible at all.

Alex
  • 2,469
  • 3
  • 28
  • 61
  • the library stunovertcp looks promising, I'll take a look. – Alex Dec 11 '12 at 17:23
  • Shameless plug - use Stuntman. It's actively supported and supports multiple configurations of STUN including TCP. www.stunprotocol.org – selbie Dec 12 '12 at 08:31
  • Thanks. One more question - is it possible (at least in theory) to use this if only one side is aware of all this STUN stuff? In my situation I have a server-peer and public server with dedicated IP address aware of the specifics of the communication while the 3rd party (client peer downloading the file) is a regular browser working via HTTP. Is it possible to use STUN in such scenario? Or, it assumes all the parties must communicate via this protocol? – Alex Dec 12 '12 at 10:22

2 Answers2

3

I previously wrote up a very consolidated rough answer on how P2P roughly works with some discussion on various protocols and corresponding open-source libraries. You can read it here.

The reliability of P2P is ultimately a result of how much you invest in it from both a client coding perspective and a service configuration (i.e. signaling servers and relays). You can settle for easy NAT traversal of UDP with no firewall support. Maybe a little more effort and you get TCP connectivity. And you can go "all the way" and have relays that have HTTPS listeners for clients behind the hardest of firewalls to traverse.

As to the answer of your question about firewalls. Depends on how the Firewall is configured. Many firewalls are just glorified NATs with security to restrict traffic to certain ports and block unsolicited incoming connections. Others are extremely restrictive and just allow HTTP/HTTPS traffic over a proxy.

The video conference apps will ultimately fallback to emulating an HTTPS connection over the PC's configured proxy server to port 443 (or 80) of a remote relay server if it can't get directly connected. (And in some cases, the remote client will try to listen on port 80 or port 443 so it can connect direct).

You are absolutely right to assume that having all the clients going through a relay will be expensive to maintain. If your goal is 100% connectivity no matter what type of firewall the clients is behind, some relay solution will have to exist. If you don't support a relay solution, you can invest heavily in getting the direct connectivity to work reliably and only have a small percentage of clients blocked.

Hope this helps.

Community
  • 1
  • 1
selbie
  • 100,020
  • 15
  • 103
  • 173
  • Thanks, just one question (the same as for other commenter). Can this (at least in theory) work when one of the peers is just an HTTP browser with no knowledge of STUN, TURN, etc? Because having the client be a regular browser is a MUST for this case (and another MUST is that the actual file traffic cannot be relayed through the public server, at least in majority of cases). If it's not possible, it would be time waste to dig into details of how to traverse through NATs because I'm not trying to make yet another p2p app. If the receiving party cannot be a web browser, that's the end of story. – Alex Dec 12 '12 at 10:28
  • Hmmm... I was about to type "likely not", but then I thought of this. The browser could hit a web service that redirects the browser with 30x message to connect to a remote peer emulating a web server. But that will be a challenge to traverse past the remote peer's NAT. The browser will likely pick a different local tcp port for each subsequent connection... which makes it difficult to get past the other end's NAT... So "likely not". :( What is your scenario that you are attempting to achieve? – selbie Dec 12 '12 at 10:39
  • BTW, I wouldn't mind the scenario with two public servers where 1st server is rendezvous while 2nd one (residing in another network) is used to test if the connection with the sending peer can be established (hole punching step). When the connection succeeds, the settings obtained (port and IP) can be passed to the receiving party (which is a web browser which cannot do hole punching and thus needs some help with this). Of course, this assumes that the receiving party can then use the same endpoint as 2nd public server just did to connect to the sending party. Not sure if it can work or not. – Alex Dec 12 '12 at 10:48
  • Thanks, you're fast! My goal is to let a person which only has a web browser download a file another person shared from their local computer, without relaying (preferably, the file traffic through any public resource). – Alex Dec 12 '12 at 10:53
  • I don't think this will work unless the host serving the file is on the public internet and not behind a NAT. A second server can detect if connectivity is possible, but will not likely be able to do the hole punching step since it has a completely different IP than the browser client attempting to connect. – selbie Dec 14 '12 at 10:30
  • You might be able to use UPNP to punch a TCP hole in the NAT for the browser on the remote client to access. Trying to do any sort of ICE-like connectivity with a browser might be difficult because a browser will pick a random port for every subsequent connection. I'm still thinking about this. – selbie Dec 14 '12 at 10:36
  • I also tried FTP ALG approach (ftp hole punching) but it only works when the same IP address to which the client holding the file connects is then used to make the counter connection in response to PORT command. If I try to connect to the client with an open hole from another IP address (such as the browser's client), it won't work. I guess NAT remembers the IP address which is allowed to get through the hole. – Alex Dec 18 '12 at 13:08
  • Most NATs will only allow incoming traffic from nodes that have the same IP address and port number as the outbound traffic came from. I'll read up on FTP ALG over the holidays. Maybe there's something I can think of... – selbie Dec 18 '12 at 23:16
2

PeerConnection, part of WebRTC solves this in modern browsers.

Under the hood it uses ICE which is an RFC for NAT hole-punching.

For older browsers, it is possible to use the P2P support in Flash.

Community
  • 1
  • 1
user239558
  • 6,964
  • 1
  • 28
  • 35