NAT Traversal rust-libp2p

We are building a decentralized peer-to-peer network using rust-libp2p and i saw there are many changes happened in rust-libp2p to add all the protocols for NAT traversal. But i wanted to know is there any guide, configuration or project to enable NAT traversal using these protocols. I saw one thing was mentioned “to have users get NAT traversal capability out of the box with libp2p lib with minimal configuration” is it documented somewhere?

:wave: Hi @mitalib,

You can find a tutorial here:

Let us know if that helps.

Hey :wave: @mxinden ,

I did see that tutorial later in the evening and i am testing that as of now. I have seen the best NAT traversal technique as of now we have in rust-libp2p is hole punching using dcUTR which has ~60% success connection rate, i have some questions:

  1. I saw there is some progress made towards QUIC implementation and i see this crate https://crates.io/crates/libp2p-quic which is WIP i guess, how is the roadmap looks like for QUIC in rust and when can we start playing with that?

  2. do we have any feature to support multiple protocol for ex., if a firewall/router does not support one particular protocol then the network switches to another to get connected.

Hey @mxinden ,

I was trying hole-punching using the tutorial
GCP VM Machine-1 ( relay server)
GCP VM Machine-2 (Listenig client)
My local machine (dialing client)

from dialing client → relay server ( i am able to ping, telnet but libp2p-lookup fails from dialing client)
libp2p-lookup direct --address /ip4/
and hence
from listening client → relay server ( fails)
with no records found !!

Any pointer to debug this? am i missing something?

It’s still true that the relay node could be any one of the TOR bridge nodes, if someone writes the software for it.

I was actually able to make libp2p-lookup-direct successful, the commands listed in the tutorial are not correct (it uses dns4 as protocol but ask to put ip_address) and the dialing client is able to make momentarily connection to listening client using relay but when it tries to upgrade to direct connection (which is hole punching) it errors out with “connection reset by peer”

[2022-03-09T19:15:15Z INFO  client] Outgoing connection error to Some(PeerId("12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X")): Transport([("/ip4/**.**.***.**/tcp/44971/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X", Other(Custom { kind: Other, error: A(B(Select(ProtocolError(IoError(Os { code: 54, kind: ConnectionReset, message: "Connection reset by peer" }))))) }))])

On the listening client i see error as " MultiaddrNotSupported"

2022-03-09T19:15:14Z INFO  client] InitiatedDirectConnectionUpgrade { remote_peer_id: PeerId("12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3"), local_relayed_addr: "/ip4/**********/tcp/4001/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN/p2p-circuit" }
[2022-03-09T19:15:15Z INFO  client] Received { peer_id: PeerId("12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3"), info: IdentifyInfo { public_key: Ed25519(PublicKey(compressed): 6b79c57e6a95239282c4818e96112f3f3a401ba97a564c23852a3f1ea5fc), protocol_version: "/TODO/0.0.1", agent_version: "rust-libp2p/0.35.0", listen_addrs: ["/ip4/52.9.243.19/tcp/21478", "/ip4/127.0.0.1/tcp/53606", "/ip4/192.168.1.104/tcp/53606", "/ip4/100.64.0.1/tcp/53606"], protocols: ["/libp2p/circuit/relay/0.2.0/stop", "/ipfs/ping/1.0.0", "/ipfs/id/1.0.0", "/ipfs/id/push/1.0.0", "/libp2p/dcutr"], observed_addr: "/ip4/34.105.31.119/tcp/4001/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN/p2p-circuit/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X" } }
[2022-03-09T19:15:15Z INFO  client] Sent { peer_id: PeerId("12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3") }

[2022-03-09T19:15:46Z INFO  client] **Outgoing connection error to Some(PeerId("12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3"))**: Transport([("/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN/p2p/12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3", Other(Custom { kind: Other, error: A(A(B(MultiaddrNotSupported("/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN/p2p/12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3")))) })), ("/ip4/52.9.243.19/tcp/21478/p2p/12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3", Other(Custom { kind: Other, error: A(A(B(Transport(Os { code: 110, kind: TimedOut, message: "Connection timed out" })))) }))])

@mxinden any pointers?

Good catch. Mind sending in a pull request @mitalib?

This is the relevant part of the error message:

("/ip4/52.9.243.19/tcp/21478/p2p/12D3KooWH3uVF6wv47WnArKHk5p6cvgCJEb74UTmxztmQDc298L3", Other(Custom { kind: Other, error: A(A(B(Transport(Os { code: 110, kind: TimedOut, message: "Connection timed out" }

In other words, the outgoing TCP connection timed out, unable to connect to the dialing client.

Does the hole punch failure continuously, or are you able to sometimes succeed?

I did raise PR for correction of commands.

And no hole punching does not succeed, it keeps on timing out.

Can you post the logs (RUST_LOG=debug) of all 3 nodes?