109 lines
2.7 KiB
Go
109 lines
2.7 KiB
Go
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()
|
|
|
|
}
|