package main import ( "bufio" "context" "fmt" "log" mrand "math/rand" "time" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/network" relayv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay" libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic" "github.com/libp2p/go-libp2p/p2p/transport/tcp" ma "github.com/multiformats/go-multiaddr" ) func main() { run() } // NOTE: For more examples, go to https://github.com/libp2p/go-libp2p/tree/master/examples/libp2p-host func run() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Create a libp2p host, able to be a relay // Should connect other clients together r := mrand.New(mrand.NewSource(time.Now().UnixMicro())) // Generate a key pair for this host. We will use it at least // to obtain a valid host ID. priv, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r) if err != nil { log.Printf("Error creating key pair: %v\n", err) return } // Create a host h1 that is a relay h1, err := libp2p.New(libp2p.DisableRelay(), // Set transports libp2p.Transport(tcp.NewTCPTransport), libp2p.Transport(libp2pquic.NewTransport), libp2p.Identity(priv), // Set listenaddrs libp2p.ListenAddrStrings( "/ip4/0.0.0.0/tcp/6666", "/ip4/0.0.0.0/udp/6666/quic", ), ) if err != nil { log.Printf("Failed to create h1: %v", err) return } defer h1.Close() // Print host ID to terminal log.Printf("Host ID: %s\n", h1.ID().String()) for _, addr := range h1.Addrs() { fmt.Printf("Listening on: %s\n", addr.String()) } _, err = relayv1.NewRelay(h1) if err != nil { log.Printf("Failed to create r1: %v", err) return } h1.SetStreamHandler("/echo/1.0.0", func(s network.Stream) { log.Println("listener received new stream") // Read whatever comes in and print it out // from https://github.com/libp2p/go-libp2p/blob/621eafcecde611b27bbb42dda4b8bbc97b66e907/examples/echo/main.go#L197 if err := func(s network.Stream) error { buf := bufio.NewReader(s) str, err := buf.ReadString('\n') if err != nil { log.Printf("error reading stream: %v\n", err) return err } log.Printf("read: %s", str) _, err = s.Write([]byte(str)) return err }(s); err != nil { log.Println(err) s.Reset() } else { s.Close() } }) fullAddr := func(ha host.Host) string { // Build host multiaddress hostAddr, _ := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s", ha.ID().Pretty())) // Now we can build a full multiaddress to reach this host // by encapsulating both addresses: addr := ha.Addrs()[0] return addr.Encapsulate(hostAddr).String() }(h1) log.Printf("I am %s\n", fullAddr) // Listen until die <-ctx.Done() }