package peer import ( "bufio" "context" "crypto/rand" "fmt" "io" "os" "github.com/arnaucube/slowlorisdb/config" "github.com/arnaucube/slowlorisdb/node" libp2p "github.com/libp2p/go-libp2p" crypto "github.com/libp2p/go-libp2p-crypto" inet "github.com/libp2p/go-libp2p-net" peerstore "github.com/libp2p/go-libp2p-peerstore" "github.com/multiformats/go-multiaddr" log "github.com/sirupsen/logrus" ) func handleStream(stream inet.Stream) { log.Info("Got a new stream!") rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) go readData(rw) go writeData(rw) } func readData(rw *bufio.ReadWriter) { for { str, err := rw.ReadString('\n') if err != nil { log.Error("Error reading from buffer") panic(err) } if str == "" { return } if str != "\n" { fmt.Printf("\x1b[32m%s\x1b[0m> ", str) } } } func writeData(rw *bufio.ReadWriter) { stdReader := bufio.NewReader(os.Stdin) for { fmt.Print("> ") sendData, err := stdReader.ReadString('\n') if err != nil { log.Error("Error reading from stdin") panic(err) } _, err = rw.WriteString(fmt.Sprintf("%s\n", sendData)) if err != nil { log.Error("Error writing to buffer") panic(err) } err = rw.Flush() if err != nil { log.Error("Error flushing buffer") panic(err) } } } type Peer struct { n *node.Node c *config.Config } func NewPeer(n *node.Node, conf *config.Config) *Peer { return &Peer{ n: n, c: conf, } } func (peer *Peer) Start() error { var port int = peer.c.Port var dest string = peer.c.Dest var r io.Reader r = rand.Reader prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r) if err != nil { return err } sourceMultiAddr, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", port)) host, err := libp2p.New( context.Background(), libp2p.ListenAddrs(sourceMultiAddr), libp2p.Identity(prvKey), ) if err != nil { return err } if dest == "" { host.SetStreamHandler("/slowlorisdb/0.0.1", handleStream) var port string for _, la := range host.Network().ListenAddresses() { if p, err := la.ValueForProtocol(multiaddr.P_TCP); err == nil { port = p break } } if port == "" { panic("was not able to find actual local port") } fmt.Printf("Run './slowlorisdb -d /ip4/127.0.0.1/tcp/%v/p2p/%s' on another console.\n", port, host.ID().Pretty()) fmt.Printf("\nWaiting for incoming connection\n\n") // Hang forever <-make(chan struct{}) } else { fmt.Println("This node's multiaddresses:") for _, la := range host.Addrs() { fmt.Printf(" - %v\n", la) } fmt.Println() maddr, err := multiaddr.NewMultiaddr(dest) if err != nil { log.Fatalln(err) } info, err := peerstore.InfoFromP2pAddr(maddr) if err != nil { log.Fatalln(err) } host.Peerstore().AddAddrs(info.ID, info.Addrs, peerstore.PermanentAddrTTL) s, err := host.NewStream(context.Background(), info.ID, "/slowlorisdb/0.0.1") if err != nil { panic(err) } rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s)) go writeData(rw) go readData(rw) select {} } return nil }