-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should have NAT Traversal #57
Comments
The good news is I found a very promising approach for nat traversal, which takes its ICE implementation directly from the chromium src (like i want to do in jbenet/random-ideas#13). It's https://github.com/getlantern/natty with go bindings at https://github.com/getlantern/go-natty. I can get OSX processes to connect to each other using their https://github.com/getlantern/waddell signaling server, and the https://github.com/getlantern/nattywad client, using a very crappy test script: https://gist.github.com/jbenet/632d9459414b996e9457 i wrote (but when I went to test linux I got getlantern/nattywad#1). Pros:
Cons
|
Got farther with natty: https://github.com/jbenet/go-netcatnat/ |
Ok the roadmap for NAT traversal is: 1. For now
[1] this is a convoluted example, and there's probably simpler ways, but maybe:
This says "connect to 2. Down the road
|
I reiterate here that we cannot rely on others' systems for nat traversal. It's an important enough piece and should not rely on public stun servers, as our traffic needs to not depend on pieces of infrastructure that might {fail, rate limit, block ipfs} unexpectedly. ipfs must sustain itself. |
Where do you put UDP on our priority list? |
@whyrusleeping ah right, natty is currently for udp only, so i guess we're switching now. We can find the simplest reliability protocol on top of udp, and aim for uTP or SCTP, and then QUIC once its implementations settle. |
Update: now that we have UDT (#58), I can move ahead on this. My next thing will be adding Natty and UDT. these are two C++ libs, that will add significant size (and noise) to the binary. These are stopgaps to get the right functionality, in the end native Go impls, or Cgo compiled things will probably be less problematic to use. |
this makes me kinda sad, since now we cant just distribute binaries... |
@whyrusleeping oh we can. cross compilation :) |
ehhh, not quite what i was hoping for though, with pure go, you can build once for each system and go. Once you mix in cgo and other linking stuff, you have to worry more about the specific system and their version of libc |
@whyrusleeping yeah, it's painful. Pure Go impl of {UTP, UDT, SCTP, and QUIC} in the horizon. in due time. For now, I much prefer my ipfs node able to talk yours, (almost) no matter where it is. |
Oh yeah, im much more happy about UDP and NAT working than i am sad about not being pure Go |
Alpha: NAT or RelayNAT traversal is non trivial, the roadmap looks like this:
The blocker is reliable transport. Our options so far have been:
Of these, Reliable transport a really big deal for us, and hard to get right:
@whyrusleeping pre-empting your call for "Lets Implement UTP!", we should not roll our own right now-- it will take us weeks to get reasonable robustness, speed, flow control, memory consumption, etc. We are good hackers, but it's taken the broader community years to make the few implementations there are. this is not to be underestimated. I totally want to have native go implementations of these transports (see my related emails to go-nuts mailing list), but we cannot afford the implementation cost right now. another option TCP/UDP tunnelAnd, frankly, I'm seriously considering doing the following horrible hack that might actually work robustly and be much quicker to pull off that
This is a mad science(tm) hack that gets around the awful realities of the network and the awful realities of software: simple things outside of specific rails is too fucking hard to do. Looking at http://golang.org/pkg/net/#IPConn -- it should be possible, my concern is making sure Resources:
Relay past NAT -- easy cop-out for nowThe easiest thing to do for now is to just relay all traffic. Would get us around NAT, but would certainly increase load of nodes. We'll have to relay some traffic, as not all NAT is hole punching. Sometimes we do have to use relaying. This could actually be done with Bitswap in mind, and be governed by the standard bitswap decision engine: relay for those nodes who are useful to us. In lieu of using natty and hole-punching, we could start with the big guns (which will work for everything and we have to do anyway) and optimize later. My Knuth VM is telling me to optimize later. |
I think a combination of relays, and NAT hole punching (NAT-PMP, uPnP) could be our best option (at least short term). I found a PMP library: https://github.com/jackpal/go-nat-pmp, and there was a few promising uPnP libraries around, which should get us through a decent number of networks, and the rest can be relayed. |
the big guns being relay? |
yeah |
Since I don't think I've seen this mentioned yet, and it's good overview: https://tools.ietf.org/html/rfc5128 |
Any update on where you're at on this issue? |
closing this for now, basic NAT traversal has been implemented as well as utp in dev0.4.0. Further discussion on relays and more advanced traversal should start a new issue |
Awesome, well done guys! |
Hey @whyrusleeping and @jbenet can you describe the NAT traversal implementation in 0.4.0 or link to more details? Exciting stuff. |
@myleshorton @whyrusleeping @jbenet Yes, I am interested in how it works for the purposes of my own decentralized application. My application would require IPFS anyway, and I am wondering if I can just piggyback on the NAT traversal that IPFS uses, and then just specify a different a different port? |
I just came back to this link again. Does anyone have an answer? |
@Cole128 check https://libp2p.io, the networking layer of IPFS that, among other things, provides solutions for NAT Traversal. |
@Cole128 there are two implementations of libp2p, one in js and one in go (and a work in progress one in rust). The issue you linked was for js. NAT traversal works pretty well in go (although we're still missing a few pieces). If you just want to piggyback on ipfs's NAT traversal, you may be interested in https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#ipfs-p2p There's some improved documentation in #4894 but it's blocked on actually making this feature behave according to that documentation... (i.e., how one would expect). If you're still having trouble with NAT traversal, you may also be interested in the circuit relay feature: https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#circuit-relay |
@Stebalien thanks a lot, I'll check all those links out. |
use key size constraints defined in libp2p
…size use key size constraints defined in libp2p
…size use key size constraints defined in libp2p
…size use key size constraints defined in libp2p
Peers behind nats need a way for other peers in the network to connect to them. It would be nice to also have webrtc, but until a go library for that exists, this will have to do.
The text was updated successfully, but these errors were encountered: