On Mon, Oct 8, 2012 at 2:33 PM, Cole Mickens wrote:
For reference, I'm using the mentioned 'nat' library. It has made
establishing a UDP session very easy after David assisted me with some
slice copying mistakes I had made. After that I have some logic that does
some maintenance (heartbeat, timeouts) and another set of logic that has a
list of supposed-peers and logic that resolves that list with the
connections I really have established and active.
I don't know that this still works, as I extracted this from a private
project and used it to debug with David (and has thus been neglected since
I got it working last), but it may serve as a useful starting point for
This includes the
server for sideband channel used to send the initial signaling messages as
well as an example client that can be used to test that two peers can
connect. Additionally, if anyone is curious about details I'd be happy to
It may be off topic but I am casually interested in more about CurveCP or
why IPv6 won't help the NAT scene (aside from the fact that router
manufacturers and corp networks will happily still use NAT).
[warning, rant ahead]
CurveCP, I'd rather let its creator talk about it: http://vimeo.com/18417770
The basic highlights is that it's meant as a replacement of TCP that offers
high end to end security at decent performance. It's implemented on top of
UDP and has a whole bunch of rather nice security properties (mutual
authentication, confidentiality, integrity and better availability than TCP
in the face of attacks).
The reality is slightly less rosy than the website makes it out to be.
Notably, the congestion control algorithm (Chicago) still seems to fare
poorly in real world networks dominated by hostile TCP algorithms, despite
the original claims that it manages to wrangle a fair share of bandwidth.
But still, it's a neat protocol. The hard bits of its implementation are
the crypto primitives (an elliptic curve, a stream cipher and a couple
other bits and pieces) and the congestion control algorithm (mostly because
it's not specified other than in the code for the reference implementation).
Why won't IPv6 solve anything? Basically, "NAT traversal" is actually two
different problems smushed together. One is conntrack traversal, i.e.
tricking a firewall's connection tracking logic to let in outside traffic
without a formal client-to-server handshake. NAT adds an extra layer of
difficulty by making the address and port of the connection hard to figure
IPv6 will eliminate NAT, for the most part. However, it very likely won't
eliminate connection tracking firewalls from the picture, especially in
consumer-grade equipment where the expectation is that you run no servers,
and thus only want to allow traffic related to LAN-initiated connections
back into the LAN. In theory IPv6 would be all about end-host firewalling,
but I sincerely doubt consumer grade equipment will ever give up and be
just a dumb router. Dumb routers with no feature checklist don't sell.
Also, IPv6 won't eliminate NAT. There are several NAT mechanisms specified:
for v4 to v6, for v6 to v4, and even v6 to v6 for enterprisey multihoming
using "unique local addresses", which are the philosophical equivalent to
the v4 private IP ranges, only without the risk of inter-LAN collisions
when you merge networks. As long as one of these mechanisms still exists, a
traversal library that wants to maximize the probability of success needs
to handle NATs anyway.
So, while IPv6 will mostly eliminate NATs, it won't significantly ease
establishment of peer to peer connections from networks you don't fully
control. Fortunately, the ICE algorithm, stripped of all the VoIP-specific
stuff, works just fine in IPv4 and IPv6, and is pretty damn close to
working everywhere (it still fails in a few specific cases, typically
involving two enterprise networks with symmetric NATs).
Your other options besides doing this sort of STUN+signaling is to have
your clients open a port to the outside world (via upnp or manually). Not
Note that UPnP and NAT-PMP can still fail in situations where ICE would
succeed, even if the router on your network understands and complies with
your request. If you have nested NATs (e.g. an ISP's modem+router with a
consumer wifi router plugged into it, and machines hooked off of that),
UPnP/NAT-PMP will only "see" the inner NAT device, and will only open a
pinhole on it. The second NAT device will still scramble the address/port,
making the connection fail.
ICE would succeed in this scenario, because it obtains NATed address
information from the public internet, which is assumed (mostly correctly)
to be the no-man's-land between all the layers of NATing. ICE doesn't
really care about how many NATs are on the way to the target, as long as it
can query a server on the internet for what the front-most NAT is doing.
But, of course, there's also a couple of cases where ICE would fail and
UPnP/NAT-PMP would work. Sometimes, the nested NATs are intentional. This
often happens on university dorm networks, where the dorm as a whole is
NATed to the world, and each student has their own wifi router. In this
case, if two students wanted to connect, using UPnP/NAT-PMP on their
personal routers would allow them to connect through the "middle NAT",
never touching the university's NAT device. ICE on the other hand would
decide that the public address for both students is on the university's
NAT, and the connection would very likely fail, because few NAT devices
support "hairpinning" back into the LAN.
The most ideal scenario would be to use UPnP/NAT-PMP to obtain a pinhole,
and provide that pinhole address in ICE's handshaking logic. That would
enable ICE to connect two students, or a student and an external party.
Even better, ICE would likely (depending on tuning params) pick the optimal
network path for each type of connection, without having the user specify
what their network topology is.
Did I mention how much hatred I have for all this crap that prevents two
computers who want to talk from just talking? :-)
On Monday, October 8, 2012 3:46:23 PM UTC-5, David Anderson wrote:
I wrote https://code.google.com/**p/nat/
>specifically to deal with the NAT traversal problem. It's poorly
documented, so you'll have to figure stuff out from the source. Basically,
it requires a low bandwidth proxied connection (via a publicly reachable
server), and uses that to create a peer to peer connection. It's a slight
variant on ICE, which is what most VOIP systems use to establish p2p
After that, you still have the problem of getting a reliable connection
running on top of the UDP socket. My horrible linux-only hack for that ishttp://code.google.com/p/**tcpoveranything<http://code.google.com/p/tcpoveranything
>. Again, you'll have to figure it out from the source (none of these
libraries are really ready for widespread release - they work, but lack
An alternative would be to implement CurveCP (http://curvecp.org) for
Go. agl very graciously implemented the NaCL crypto primitives needed, athttp://code.google.com/p/**go/source/browse?repo=crypto#**hg%2Fnacl<http://code.google.com/p/go/source/browse?repo=crypto#hg%2Fnacl
>. You'll still have to write the rest, including Chicago congestion
control, which is poorly documented (do you see a pattern here?).
Finally, another option to consider is to implement UPnP and NAT-PMP
clients, so that you can discover consumer-grade routers on the local
network and ask them to open a TCP pinhole back to your machine. This is
what quite a few video games do these days, but I haven't implemented any
of those protocols (warning: UPnP is a horrible, horrible protocol).
NAT traversal is one of my hobbies, as you can possibly tell. But be
warned, it's a hard problem to solve in the general case, as you need to
bring together a lot of different techniques and protocols. If it's at all
possible, it's *really* simpler to have clients just connect to a
publicly accessible server (or set of servers).
(For bonus points, ask me why IPv6 won't solve any of this madness, even
though it theoretically puts an end to the need for NAT)
On Mon, Oct 8, 2012 at 1:32 PM, ISockGo wrote:
Can one suggest the best way to communicate and transfer data over
peer to peer connections?* And how to create for peer to peer
sockets. Specially when clients don't have public ip.*
Like Skype and flash does.