TCP NAT traversal

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
13
81
www.markbetz.net
We've been working on this app for a client that involves using xmpp as a backbone to pass application data, and also as a session initiation protocol transport for file transfers and media streams.

We initially prototyped using Google's libjingle. Earlier versions had support for p2p rtp and a proprietary p2p file transfer protocol based on http. Later versions seem to have dropped the support for reliable transport over tcp, while retaining the rtp support. My assumption is that they will add SOCKS5 support for tcp streams at some point, but given the fact that we found the lib really obtuse and hard to work with, we decided to experiment with another approach.

We began working with gloox, which has a pretty decent implementation of an xmpp client, and supports sip for initiating S5B streams over tcp. It supports disco and is more or less designed to work with an S5B proxy, however, we want to implement p2p S5B. Gloox gives us all the methods we need to establish our list of stream host addresses, but it doesn't address NAT traversal. If we want to make this work then the last piece we need is reliable tcp NAT traversal, with a fallback to either a S5B proxy or a TURN relay if we can't punch through.

And that's the problem. ICE-TCP is just in early work as far as I can tell, and the only implementation of STUNT that I can find is the nutts library from Cornell, and it hasn't been actively worked on or really discussed since 2006. It's almost like this problem hasn't been talked about much in the last five years. We just don't come up with much when we search.

Some other options we've looked at are: using pseudo-tcp over udp - there are a couple of libraries that support this (libnice comes to mind) but we're not sure we can integrate their pseudo socket model into gloox, which is used to managing it's own connections; we've also thought about using rtp for media streams and in-band xmpp transfers for file data - basically we'd chunk it and base64 it and send it as stanzas with a hash... but we really don't want to do that.

Basically what I was hoping to find is some current work or source code implementing either ICE-TCP or STUNT with examples, or at least some creative ideas on what the hell we should do here. Maybe give jingle another look, as bad as it is? Any thoughts would be appreciated.
 
Last edited:

Cogman

Lifer
Sep 19, 2000
10,277
125
106
Looks like nobody has really dealt with this issue..

Quick question, why would you base64 encode data? Email is about the last place where base64 encoding was really needed.

VGhvdWdoLCBJIGd1ZXNzIHlvdSBjb3VsZCB1c2UgaXQgdG8gZGlzdHJpYnV0ZSBkYXRlIG9uIGludGVybmV0IGZvcnVtcyBpZiB5b3Ugc28gZGVzaXJlZC4=
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
13
81
www.markbetz.net
T3IgdG8gc2VuZCB0aGUgZGF0YSBhcyB0ZXh0IGluIGFuIFhNUFAgc3RhbnphLg==

The XMPP In-band Bytestreams consist of the data encoded into text stanzas. I haven't given any thought to what encoding is appropriate, because we really don't want to go that route, but I have seen base64 referred to in a number of explanations.

I'm kind of amazed that nutts seems to be the last real attempt at a library for tcp NAT traversal, and it hasn't been really even looked at in five years. I must be missing something in the big picture. Udp isn't sufficient for stateful and reliable transport, so someone must have run into the "I need to punch a tcp connection through a NAT" problem, right? Google Talk file transfers use a proprietary pseudo-tcp http protocol, so they likely do STUN/udp. Skype transfers are dead slow, and I suspect they are pushing them through a supernode that acts as a relay server. Not sure, though.
 
Last edited:

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
13
81
www.markbetz.net

qinjin

Junior Member
Dec 5, 2011
1
0
0
Yeah we've pretty much settled on having to use pseudo-tcp over udp. We're in the process of trying to rip out libjingle's pseudo-tcp stack so we can use that with C# xmpp and stun clients... but libjingle is just effing horrible.

Hi, I've recently implemented a data transfer app on top of libjingle pseudo tcp, but the performance is really bad. When I test it on localhost, I could just achieve 3-4 MB/s throughput. Have you implemented it? how about your performance?

Please find my problem here: http://code.google.com/p/libjingle/issues/detail?id=214, and I would like to discuss the implementation details with you :)
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
13
81
www.markbetz.net
It's been a couple of months since I even thought about it. The project got yanked around in a few different directions and hasn't gotten beyond the prototyping phase yet. Last thing we did was implement a UDP broadcast-based local area network layer that did device detection and implemented a custom file transfer layer.

The problem with commenting on Jingle's performance is that there are different versions and among the different versions there are different approaches to pseudo-tcp and nat traversal. We got absolutely abysmal performance using Jingle's native pseudo-tcp. The performance of socks5 bytestreams was better, but the client didn't want to host a proxy. When we implemented our own LAN streaming protocol over tcp the performance was dozens of times better, but then it didn't deal with ninety percent of the stuff Jingle has to deal with.