147 lines
3.8 KiB
Go
147 lines
3.8 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"time"
|
||
|
|
||
|
"github.com/go-redis/redis/v8"
|
||
|
"github.com/libp2p/go-libp2p"
|
||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||
|
"github.com/libp2p/go-libp2p/p2p/muxer/mplex"
|
||
|
"github.com/libp2p/go-libp2p/p2p/muxer/yamux"
|
||
|
"github.com/libp2p/go-libp2p/p2p/protocol/ping"
|
||
|
noise "github.com/libp2p/go-libp2p/p2p/security/noise"
|
||
|
libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls"
|
||
|
libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
|
||
|
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
|
||
|
"github.com/libp2p/go-libp2p/p2p/transport/websocket"
|
||
|
ma "github.com/multiformats/go-multiaddr"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
var (
|
||
|
transport = os.Getenv("transport")
|
||
|
secureChannel = os.Getenv("security")
|
||
|
muxer = os.Getenv("muxer")
|
||
|
isDialerStr = os.Getenv("is_dialer")
|
||
|
ip = os.Getenv("ip")
|
||
|
redis_addr = os.Getenv("REDIS_ADDR")
|
||
|
)
|
||
|
|
||
|
if redis_addr == "" {
|
||
|
redis_addr = "redis:6379"
|
||
|
}
|
||
|
|
||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||
|
defer cancel()
|
||
|
|
||
|
// Get peer information via redis
|
||
|
rClient := redis.NewClient(&redis.Options{
|
||
|
Addr: redis_addr,
|
||
|
Password: "",
|
||
|
DB: 0,
|
||
|
})
|
||
|
defer rClient.Close()
|
||
|
|
||
|
for {
|
||
|
// Wait for redis to be ready
|
||
|
_, err := rClient.Ping(ctx).Result()
|
||
|
if err == nil {
|
||
|
break
|
||
|
}
|
||
|
time.Sleep(100 * time.Millisecond)
|
||
|
}
|
||
|
|
||
|
is_dialer := isDialerStr == "true"
|
||
|
|
||
|
options := []libp2p.Option{}
|
||
|
|
||
|
var listenAddr string
|
||
|
switch transport {
|
||
|
case "ws":
|
||
|
options = append(options, libp2p.Transport(websocket.New))
|
||
|
listenAddr = fmt.Sprintf("/ip4/%s/tcp/0/ws", ip)
|
||
|
case "tcp":
|
||
|
options = append(options, libp2p.Transport(tcp.NewTCPTransport))
|
||
|
listenAddr = fmt.Sprintf("/ip4/%s/tcp/0", ip)
|
||
|
case "quic":
|
||
|
options = append(options, libp2p.Transport(libp2pquic.NewTransport))
|
||
|
listenAddr = fmt.Sprintf("/ip4/%s/udp/0/quic", ip)
|
||
|
default:
|
||
|
panic("Unsupported transport")
|
||
|
}
|
||
|
options = append(options, libp2p.ListenAddrStrings(listenAddr))
|
||
|
|
||
|
switch secureChannel {
|
||
|
case "tls":
|
||
|
options = append(options, libp2p.Security(libp2ptls.ID, libp2ptls.New))
|
||
|
case "noise":
|
||
|
options = append(options, libp2p.Security(noise.ID, noise.New))
|
||
|
case "quic":
|
||
|
default:
|
||
|
panic("Unsupported secure channel")
|
||
|
}
|
||
|
|
||
|
switch muxer {
|
||
|
case "yamux":
|
||
|
options = append(options, libp2p.Muxer("/yamux/1.0.0", yamux.DefaultTransport))
|
||
|
case "mplex":
|
||
|
options = append(options, libp2p.Muxer("/mplex/6.7.0", mplex.DefaultTransport))
|
||
|
case "quic":
|
||
|
default:
|
||
|
panic("Unsupported muxer")
|
||
|
}
|
||
|
|
||
|
host, err := libp2p.New(options...)
|
||
|
|
||
|
if err != nil {
|
||
|
panic(fmt.Sprintf("failed to instantiate libp2p instance: %s", err))
|
||
|
}
|
||
|
defer host.Close()
|
||
|
|
||
|
if is_dialer {
|
||
|
val, err := rClient.BLPop(ctx, 10*time.Second, "listenerAddr").Result()
|
||
|
if err != nil {
|
||
|
panic("Failed to wait for listener to be ready")
|
||
|
}
|
||
|
otherMa := ma.StringCast(val[1])
|
||
|
fmt.Println("My multiaddr is: ", host.Addrs())
|
||
|
fmt.Println("Other peer multiaddr is: ", otherMa)
|
||
|
otherMa, p2pComponent := ma.SplitLast(otherMa)
|
||
|
otherPeerId, err := peer.Decode(p2pComponent.Value())
|
||
|
if err != nil {
|
||
|
panic("Failed to get peer id from multiaddr")
|
||
|
}
|
||
|
err = host.Connect(ctx, peer.AddrInfo{
|
||
|
ID: otherPeerId,
|
||
|
Addrs: []ma.Multiaddr{otherMa},
|
||
|
})
|
||
|
if err != nil {
|
||
|
panic("Failed to connect to other peer")
|
||
|
}
|
||
|
|
||
|
ping := ping.NewPingService(host)
|
||
|
|
||
|
res := <-ping.Ping(ctx, otherPeerId)
|
||
|
if res.Error != nil {
|
||
|
panic(res.Error)
|
||
|
}
|
||
|
|
||
|
fmt.Println("Ping successful: ", res.RTT)
|
||
|
|
||
|
rClient.RPush(ctx, "dialerDone", "").Result()
|
||
|
} else {
|
||
|
_, err := rClient.RPush(ctx, "listenerAddr", host.Addrs()[0].Encapsulate(ma.StringCast("/p2p/"+host.ID().String())).String()).Result()
|
||
|
if err != nil {
|
||
|
panic("Failed to send listener address")
|
||
|
}
|
||
|
_, err = rClient.BLPop(ctx, 4*time.Second, "dialerDone").Result()
|
||
|
if err != nil {
|
||
|
panic("Failed to wait for dialer conclusion")
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|