libp2p / go-libp2p

libp2p implementation in Go
MIT License
6.07k stars 1.07k forks source link

Nat traversal with one peer behind a Firewall/Nat #2152

Closed Albert0sans closed 7 months ago

Albert0sans commented 1 year ago

Hi,

I am writing a proyect for college on P2P networks and i am using libp2p for it. The application currently works if Host A (azure VM with all ports opened) connects first to the dht, and later Host B (windows machine, posibly behind firewall) connects to it, but not the other way.

I am not sure how to get it working or in which examples can i base on. I dont know into using a relay server that simply aids in the connection establishent and how can i do it. Sorry for english.

Code for Host:

        h, err := libp2p.New(
    // Use the keypair we generated
    libp2p.Identity(priv),

    // Multiple listen addresses
    libp2p.ListenAddrStrings("/ip4/0.0.0.0/udp/0/quic", "/ip4/0.0.0.0/tcp/0"),

    // support TLS connections
    libp2p.Security(libp2ptls.ID, libp2ptls.New),
    // support noise connections
    libp2p.Security(noise.ID, noise.New),

    // support any other default transports (TCP,quic)
    DefaultTransports,
    libp2p.ResourceManager(rcm),
    libp2p.NATPortMap(),
    libp2p.EnableRelay(),
    libp2p.EnableHolePunching(),

    libp2p.ChainOptions(
        libp2p.Muxer("/yamux/1.0.0", yamux.DefaultTransport),
        libp2p.Muxer("/mplex/6.7.0", mplex.DefaultTransport),
    ),
    libp2p.EnableNATService(),
)

Code for init the DHT:

   kademliaDHT, err := dht.New(ctx, h)
if err != nil {
    panic(err)
}
if err = kademliaDHT.Bootstrap(ctx); err != nil {
    panic(err)
}
var wg sync.WaitGroup
for _, peerAddr := range dht.DefaultBootstrapPeers {
    peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr)
    wg.Add(1)
    go func() {
        defer wg.Done()
        if err := h.Connect(ctx, *peerinfo); err != nil {

        }
    }()
}
wg.Wait()

Code for connecting:

routingDiscovery := drouting.NewRoutingDiscovery(kademliaDHT)

// Advertise this node, so that it will be found by others but only once
dutil.Advertise(ctx, routingDiscovery, RendezvousString)
// Look for others who have announced and attempt to connect to them

fmt.Println("\t [*] Searching for peers in DHT [", RendezvousString, "]")

peers, err := routingDiscovery.FindPeers(ctx, RendezvousString)
if err != nil {
    panic(err)
}
MarcoPolo commented 7 months ago

Host B is behind a firewall. You'll need a relay server to coordinate hole punching.