You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
Port reuse in TCP. Implemented. We should enable this and should help.
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).
Circuit Relay v1 (spec). Completed and we could use it in theory. The problem with TURN like strategies is one of scalability and cost though. Not a reliable long term solution probably.
Also worth mentioning is QUIC support, which we could use instead of TCP, QUIC builds on top of UDP and will make NAT traversal issues easier too. On top I believe is an straight upgrade in our case since our use case will trend towards a high number of connections but relatively short-lived and small in size on average, and here QUIC will be a good improvement over TCP, and I don't see any downsides to using it over TCP really. QUIC support within rust-libp2p seems to be finally near completion: Libp2p quic second attempt libp2p/rust-libp2p#2159
Hole punching success rate in QUIC is higher that over TCP and equivalent to that of UDP, without having to deal with all the quirks of UDP cause those are handled by QUIC (and is encrypted by default too). 80% according to (MIT paper on Hole Punching, 2006).
Multistream select is important for hole punching, since both peers are attempting to initiate the connection and this is at odds to how is currently implemented (there must be one initiator). Ongoing effort to extend the protocol to allow for multiple initiators:
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.
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:
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.