-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Closed
Description
I hope to get help.
I found similar issus, but my problem was not solved.
#2761
#2630
Below is the sample code I wrote and the running steps and results.
package main
import (
"context"
"flag"
"fmt"
"log"
"time"
"github.com/libp2p/go-libp2p"
dht "github.com/libp2p/go-libp2p-kad-dht"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
drouting "github.com/libp2p/go-libp2p/p2p/discovery/routing"
dutil "github.com/libp2p/go-libp2p/p2p/discovery/util"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay"
ma "github.com/multiformats/go-multiaddr"
)
var op = flag.String("op", "", "relay and bootstrap server")
var relayAddr = flag.String("relay", "", "relay Addr")
func main() {
flag.Parse()
if *op == "relay" {
runRelayAndBootstrapServer()
} else if *op == "conn" {
runNode()
}
}
func runRelayAndBootstrapServer() {
relay1, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/9876"))
if err != nil {
log.Printf("Failed to create relay1: %v", err)
return
}
_, err = relay.New(relay1)
if err != nil {
log.Printf("Failed to instantiate the relay: %v", err)
return
}
_, err = dht.New(context.Background(), relay1, dht.Mode(dht.ModeServer)) //
if err != nil {
log.Printf("Failed to create DHT: %v", err)
return
}
// _, err = autonat.New(relay1)
// if err != nil {
// log.Printf("Failed to create AutoNAT: %v", err)
// return
// }
fmt.Printf("[*] Your Bootstrap ID Is: /ip4/%s/tcp/%v/p2p/%s\n", "0.0.0.0", 9876, relay1.ID().String())
select {}
}
func runNode() {
maRelayAddr, _ := ma.NewMultiaddr(*relayAddr)
relay1info, _ := peer.AddrInfoFromP2pAddr(maRelayAddr)
conn1, err := libp2p.New(
libp2p.EnableRelay(),
libp2p.NATPortMap(),
libp2p.EnableHolePunching(),
// libp2p.ForceReachabilityPrivate(),
libp2p.EnableAutoRelayWithStaticRelays([]peer.AddrInfo{*relay1info}),
)
if err != nil {
fmt.Println("Failed to create unreachable1: ", err)
return
}
conn1.SetStreamHandler("/customprotocol", func(s network.Stream) {
log.Println("Awesome! We're now communicating via the relay!")
buf := make([]byte, 1024*64)
for {
_, err := s.Read(buf)
if err != nil {
log.Println("Failed to read from stream")
break
}
}
s.Close()
})
// err = conn1.Connect(context.Background(), *relay1info)
// if err != nil {
// log.Printf("Failed to connect to relay1: %v", err)
// return
// }
// fmt.Println("Successfully connected to relay1!")
ctx := context.Background()
kademliaDHT, err := dht.New(ctx, conn1, dht.BootstrapPeers(*relay1info))
fmt.Println("Bootstrapping the DHT")
if err = kademliaDHT.Bootstrap(ctx); err != nil {
panic(err)
}
// // Wait a bit to let bootstrapping finish (really bootstrap should block until it's ready, but that isn't the case yet.)
time.Sleep(1 * time.Second)
// We use a rendezvous point "meet me here" to announce our location.
// This is like telling your friends to meet you at the Eiffel Tower.
fmt.Println("Announcing ourselves...")
routingDiscovery := drouting.NewRoutingDiscovery(kademliaDHT)
dutil.Advertise(ctx, routingDiscovery, "test")
fmt.Println("Successfully announced!")
fmt.Println("Searching for other peers...")
peerChan, err := routingDiscovery.FindPeers(ctx, "test")
if err != nil {
panic(err)
}
for peer := range peerChan {
if peer.ID == conn1.ID() {
continue
}
fmt.Println("Found And Connecting to peer:", peer)
s, err := conn1.NewStream(ctx, peer.ID, "/customprotocol")
if err != nil {
fmt.Println("Connection failed:", err)
continue
}
fmt.Println("Connected to:", peer)
go func() {
buf := make([]byte, 1024*64)
for {
_, err := s.Write(buf)
if err != nil {
log.Println("Unexpected error here. Failed to write: ", err)
break
}
time.Sleep(70 * time.Millisecond)
}
s.Close()
}()
}
select {}
}go build -o relay .
- step 1:
Run./relay -op relayon a server with a public IP.
The terminal will output:
[*] Your Bootstrap ID Is: /ip4/0.0.0.0/tcp/9876/p2p/12D3KooWPnMh1ibwK39Y8AuZQtogs2FoQ72JnTEDr6H1JEpVw4Bi
- step 2:
Using two hosts, Host A and Host B are behind different firewalls and both are Cone NAT.
They run simultaneously:
relay -op conn -relay /ip4/public_ip/tcp/9876/p2p/12D3KooWPnMh1ibwK39Y8AuZQtogs2FoQ72JnTEDr6H1JEpVw4Bi
Host A and Host B, terminal Output:
Connection failed: failed to dial: failed to dial 12D3KooWGvYWA3R5TSr8d6ozuja1Nhy1URd3hQGmVyziSs5PNF4A: all dials failed
* [/ip6/::1/tcp/7334] dial tcp6 [::1]:7334: connectex: No connection could be made because the target machine actively refused it.
* [/ip6/::1/udp/62311/quic-v1] context deadline exceeded
* [/ip6/240e:3b7:3248:7a1:e423:e7e:6217:a354/udp/62311/quic-v1] timeout: no recent network activity
* [/ip4/127.0.0.1/tcp/7333] dial tcp4 127.0.0.1:7333: connectex: No connection could be made because the target machine actively refused it.
* [/ip4/10.0.0.16/udp/62309/quic-v1] timeout: no recent network activity
* [/ip4/10.0.0.16/udp/62310/quic-v1/webtransport/certhash/uEiAzQuWpYHXEkiVhAYOohxId2kLmyXS5m3TcFdPPRX2uxw/certhash/uEiA0Ixeot0LRUq6TydJo-NRHlGAOcSHufpALjXNI-ib-Fg] timeout: no recent network activity
* [/ip4/127.0.0.1/udp/62309/quic-v1] timeout: no recent network activity
* [/ip6/::1/udp/62312/quic-v1/webtransport/certhash/uEiAzQuWpYHXEkiVhAYOohxId2kLmyXS5m3TcFdPPRX2uxw/certhash/uEiA0Ixeot0LRUq6TydJo-NRHlGAOcSHufpALjXNI-ib-Fg] context deadline exceeded
* [/ip4/127.0.0.1/udp/62310/quic-v1/webtransport/certhash/uEiAzQuWpYHXEkiVhAYOohxId2kLmyXS5m3TcFdPPRX2uxw/certhash/uEiA0Ixeot0LRUq6TydJo-NRHlGAOcSHufpALjXNI-ib-Fg] context deadline exceeded
* [/ip4/10.0.0.16/tcp/7333] dial tcp4 0.0.0.0:20934->10.0.0.16:7333: i/o timeout
* [/ip6/240e:3b7:3248:7a1:e423:e7e:6217:a354/udp/62312/quic-v1/webtransport/certhash/uEiAzQuWpYHXEkiVhAYOohxId2kLmyXS5m3TcFdPPRX2uxw/certhash/uEiA0Ixeot0LRUq6TydJo-NRHlGAOcSHufpALjXNI-ib-Fg] timeout: no recent network activity
The output addresses do not contain the addresses of the holepunching, they are all their own local addresses.
How should I modify this code to make HolePunching work ?
Metadata
Metadata
Assignees
Labels
No labels