Skip to content
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

NAT traversal #2

Closed
8 of 10 tasks
iduartgomez opened this issue Sep 1, 2021 · 11 comments
Closed
8 of 10 tasks

NAT traversal #2

iduartgomez opened this issue Sep 1, 2021 · 11 comments
Labels
A-networking-ring Area: Ring protocol and ops. C-tracking-issue Category: A tracking issue for some feature or set of issue. planned This has been synced to PT for triage

Comments

@iduartgomez
Copy link
Collaborator

iduartgomez commented Sep 1, 2021

This is a general tracking issue to monitor the status of the different techniques that will help with clients behind NAT when it comes to establishing direct connection between peers.

Prelude

One of the problems of NAT traversal is the variance in the network characteristics and configurations when trying to establish a connection between two peers, at every layer of the network and from the pov of both hw (router configuration, LAN, ISP, etc.) and software (for example, is a browser handling the connection for you or do you have direct access to the interface?). A good overview and taxonomy of the different scenarios can be read here.

Some important/interesting resources re. NAT traversal status within libp2p:

rust-libp2p status

Overall tracking issue in their repo: libp2p/rust-libp2p#2052

For more detail check their tracking issue.

Notes

Solutions

Working on top of UDP to add our own solutions disqualifies a big chunk of libp2p, as is not possible to use UDP directly as transport protocol in libp2p (support is under development but only in the Go impl, and is just a prototype). There may be an option, in theory, to build up our own protocol and plugin it in the libp2p (is all based around traits/interfaces so I believe is doable, but we would have to look up) and to use other components that we find useful (e.g. all the identity protocol).

However this would mean building up a significant part of the plumbing and packet handling libp2p does for you and would be a large effort so I would say this should be a last option (unless we decide we don't want to use libp2p at all). Then there is the obvious caveat: If a higher number of developers with more resources have taken a long time to tackle this and haven't succeeded (yet) why would we be faster moving? This would be a major distraction from building our core logic, so if we have to at least would be nice to have the support of other developers. Then, I would favor an other approach, that is:

  • Identify what additional functionalities/methods are beneficial regarding the efforts to add NAT traversal capabilities.
  • Monitor their implementation, and if necessary contribute upstream and help the libp2p folks to push them through the finish line (this would have the added benefit of gaining familiarity with libp2p internals). A bunch of the work to be done has not been done at all, but there is a lot of work which is near completion so I expect within reasonable time there will be more improvements. I believe their idea is to extend Project Flare aka. decentralised hole punching protocol/web3-dev-team#21 (e.g. Go impl: Project Flare(decentralised Hole Punching) Phase1 Meta Issue libp2p/go-libp2p#1039) to all implementations (including Rust) so that is what we can use as guideline and to be the end status when it comes to NAT traversal support in libp2p.
    • If necessary fork and replace/modify whatever parts we deem necessary, however that would be a last option too, ideally we want to to contribute any work upstream and have synergies with the libp2p team and benefit from their expertise.

So we can continue with the current efforts and focus on other areas which are core to our project and make a reasonable assumption that, within reasonable time this will be improved, and if necessary help upstream to improve the situation re. NAT when we run into practical problems as we test.

@iduartgomez iduartgomez added the C-feature Category: New feature or request label Sep 1, 2021
@iduartgomez
Copy link
Collaborator Author

For the record I am, right now at least, behind a normal (full-cone) NAT, which is the most usual case for home routers and the reason hole-punching is relatively successful apparently.

https://dh2i.com/kbs/kbs-2961448-understanding-different-nat-types-and-hole-punching/

@iduartgomez
Copy link
Collaborator Author

iduartgomez commented Sep 1, 2021

Other options we have been pondering is working directly with a QUIC implementation, this way we could add NAT traversal functionality ourselves and they have encryption built-in:

  • the cons is that we would lose some of the libp2p building blocks and it's modular architecture; we would have to include a layer for reliably identifying and connecting peers.
  • the pros is that we would have more control from the interface up while leveraging all the goods that the implementations give us (like built-in encryption). That means we could even potentially add UPnP along hole punching.
    We would be using one of this two crates to build on top:

@mxinden
Copy link

mxinden commented Sep 2, 2021

👋 Max here, maintainer of (rust-) libp2p. It is great to see interest in libp2p and great to see the many tracking issues and specifications being useful. Feel free to reach out in case you have any questions.

In theory the Identify protocol (which we will be using) helps with this since it provides the observed addresses to anyone querying, so they can communicate through those addresses back (this is handled automatically by libp2p AFAIK).

👍 though the identify is not sufficient in all cases, as e.g. NAT mappings need to be kept alive. Long term we need to support AutoNAT in rust-libp2p.

Lack of concurrent attempts is a hindrance towards successful hole punching and there is an outstanding issue to address this: core/: Concurrent connection attempts - aka. happy eyeball libp2p/rust-libp2p#1896 (comment)

My current work item ;)

@iduartgomez
Copy link
Collaborator Author

iduartgomez commented Sep 2, 2021

Hi @mxinden, thanks for answering! Do you have a rough estimate on when we could see AutoNAT land? And QUIC? (Correct me if wrong but when QUIC is added it will indirectly unblock some of the NAT traversal stuff.)

Likewise, there is anything we can do to help things move re. NAT traversal (helping implementing any of the issues, even if is something easy to get started).

@mxinden
Copy link

mxinden commented Sep 6, 2021

Do you have a rough estimate on when we could see AutoNAT land?

It is hard to estimate when AutoNAT will land. Though note that AutoNAT is only a small piece of the puzzle and that basic hole punching does not depend on it. I hope for basic hole punching (libp2p/rust-libp2p#2059, libp2p/rust-libp2p#2076, libp2p/rust-libp2p#1896) to be merged and released by end of this year.

And QUIC? (Correct me if wrong but when QUIC is added it will indirectly unblock some of the NAT traversal stuff.)

While not as successful as QUIC, NAT hole punching via TCP is already a great win. In other words, NAT hole punching is not blocked on QUIC support in rust-libp2p. That said, we definitely want to support QUIC, among other things for its increased NAT hole punching success rate.

Likewise, there is anything we can do to help things move re. NAT traversal (helping implementing any of the issues, even if is something easy to get started).

Help is always very much appreciated.

@iduartgomez
Copy link
Collaborator Author

iduartgomez commented Sep 7, 2021

Does not the relay protocol depend on having one server which is not behind NAT listening? In our use case this is not a reliable strategy (although could be fit somehow to cover the extra peers which are behind symmetric NAT maybe).

Help is always very much appreciated. ...

Awesome, I will report any issues I have (none so far, except for this current issue, and I like the modular nature quite a bit) and will try to help out contributing.

@mxinden
Copy link

mxinden commented Sep 8, 2021

Does not the relay protocol depend on having one server which is not behind NAT listening? In our use case this is not a reliable strategy (although could be fit somehow to cover the extra peers which are behind symmetric NAT maybe).

Yes, libp2p-circuit-relay requires the relay server to be publicly routable. Note however that there is no need to restrict a network to a single central relay server. Instead all public nodes of a network can act as such a server. With libp2p-circuit-relay-v2 the overhead for a server is small. Non public nodes can discover relay servers via e.g. the Kademlia DHT, e.g. looking for the 20 closest public relay servers to their own peer id. This allows us to do hole punching in a decentralized fashion.

I am not aware of any hole punching mechanism that does not require some TURN-like mechanism via some public nodes. E.g. WebRTC requires some mechanism to exchange SDP packets.

@sanity sanity added C-proposal Category: A proposal seeking feedback and removed C-feature Category: New feature or request labels Sep 20, 2021
@sanity sanity changed the title Tracking Issue for NAT traversal NAT traversal Sep 20, 2021
@iduartgomez iduartgomez added C-tracking-issue Category: A tracking issue for some feature or set of issue. and removed C-proposal Category: A proposal seeking feedback labels Sep 22, 2021
@iduartgomez iduartgomez added the A-networking-ring Area: Ring protocol and ops. label Jan 23, 2022
iduartgomez added a commit that referenced this issue Aug 28, 2022
Improve packaging of web files
@iduartgomez iduartgomez added the planned This has been synced to PT for triage label Jan 11, 2023
@github-actions
Copy link

Pivotal Tracker story: https://www.pivotaltracker.com/story/show/184207067

@PrParadoxy
Copy link

PrParadoxy commented Aug 12, 2023

This is a great project but I am afraid the bottom to top approach for solving NAT issues wouldn't make it very fruitful in some countries in a long run.

TL; DR: I had more technical insights to add, but this post has already become too long. Nevertheless, what I want to say is that the real underlying issue of NAT is actually the naked exposure of relaying/signal/etc server to consumers, not the underlying protocol of doing so.

In a nutshell we have 2 scenarios,

  1. Either both peers or at least one of them have accessible public IP address, in this case p2p is easy.
  2. Both of peers are behind NAT, in which case we need some form of hole punching, relaying server, signal server, etc to make communication between peers possible. This is hard, and the very reason as to why many p2p projects has failed so far.

From here onward I will talk about second scenario. To solve this issue, the bottom to top approach (which I see here) is to study different protocol, network configuration, etc to find some ways to pass through firewall and NAT. This is great and all, but only for less restrictive countries, where we have no whitelist approach for censorship. In these countries however, the very need of p2p is not usually felt by people. From the perspective of developers, developing p2p services is not commercially (usually) justified and why should one learn new frameworks in the first place?, and from the view point of consumers, whatever works, works, why seek alternatives? If they want privacy, well of course they can use any form of hidden services, which is not censored (Tor, for example), so it is a bit hard to convince people to use p2p in the first place, and let's be honest, p2p works the best when there are a lot of people and developers (or better said, content) in it.

At the moment p2p is needed the most in middle east (Iran, to be more specific), China, and other similar restrictive countries. I am sure any "working" p2p project would immediately attract generate a lot of attention, because it solves an underlying issue that has been going on for more than a decade or two (please just look at projects like Xray-core, V2fly, etc to see this need of censor free internet, in these countries).

Let me become more specific, in a country like Iran, the censorship itself is based on protocol. UDP is completely blocked (with a few exception) so let's forget about QUIC and anything similar to it. As for TCP, only TCP connection that is encrypted by SSL (with some specific fingerprints, at that!) can pass through firewall. Literally nothing else, not even obfuscated TCP goes unnoticed. Blocking SSL would come at a huge cost for government, so it is not going to happen. In a bottom to top approach that is followed here (and similar projects), one would develop N different ways to pass through a non-restrictive firewall, and the project would then become mature, so mature that developing a new layer on top of these ways to mimic SSL behaviour in p2p becomes way too hard (I tried to make old freenet to make use of a TLS proxy, with no success). And even somehow one manages to do that, it is only matter of time until government blocks every known relay/signal/stun/etc server. So this project would end up working only on some less restrictive countries, just like old Freenet (hyphanet), whereas it could possibly gain much more love that it actually deserves. to where it actually belongs.

In a top to bottom approach, one would ask themselves:

  1. Who is going to be our consumers? Why would they need this product?
  2. Can we make some features commercialized and make a revenue while attracting new developers for faster development?
  3. What is the underlying issue? Can we maintain the product, when there is a larger adversary (e.g. government) at work and being open source at the same time?
  4. ...

From what I saw in "How we will decentralize the Internet with Freenet" talk, I got the feeling that perhaps I could give a different perspective in some possible, interesting uses of this project, but I don't know if anyone can share my perspective, so I stop here.

@alexlyee
Copy link

@PrParadoxy Your comment was very thoughtful and well said. I agree that it is an extremely important thing to try and get right to make p2p available for those without the privilege of a non-NAT'ed connection to the internet

@iduartgomez
Copy link
Collaborator Author

I am closing the issue and will follow up on pivotal tracker: ##5207398.The scope of this task was/is rather limited to implementing NAT traversal over our freenet protocol. Since we have our own DHT implementation, connection protocol etc. seems the more sensible approach for us will be creating our own NAT hole punching procedure integrated with our connection protocol, we will leverage libp2p as much as possible for

Re. all things p2p communication, bypassing goverment controls, etc. feel free to open new discussions to discuss them, seems like valuable input. For now we need to start somewhere and get the network running so will focus on making connectivity possible working around NAT issues as much as possible, in the future we can improve all things when it comes to establishing connectivity between peers with whatever approaches are available (this may also mean more departures with libp2p so in that regard is good we start decoupling both things as much as possible).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-networking-ring Area: Ring protocol and ops. C-tracking-issue Category: A tracking issue for some feature or set of issue. planned This has been synced to PT for triage
Projects
None yet
Development

No branches or pull requests

5 participants