You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

154 lines
3.1 KiB

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
}