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.

138 lines
2.8 KiB

  1. package peer
  2. import (
  3. "bufio"
  4. "context"
  5. "crypto/rand"
  6. "fmt"
  7. "io"
  8. "os"
  9. "github.com/libp2p/go-libp2p"
  10. crypto "github.com/libp2p/go-libp2p-crypto"
  11. inet "github.com/libp2p/go-libp2p-net"
  12. peerstore "github.com/libp2p/go-libp2p-peerstore"
  13. "github.com/multiformats/go-multiaddr"
  14. log "github.com/sirupsen/logrus"
  15. )
  16. func handleStream(stream inet.Stream) {
  17. log.Info("Got a new stream!")
  18. rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))
  19. go readData(rw)
  20. go writeData(rw)
  21. }
  22. func readData(rw *bufio.ReadWriter) {
  23. for {
  24. str, err := rw.ReadString('\n')
  25. if err != nil {
  26. log.Error("Error reading from buffer")
  27. panic(err)
  28. }
  29. if str == "" {
  30. return
  31. }
  32. if str != "\n" {
  33. fmt.Printf("\x1b[32m%s\x1b[0m> ", str)
  34. }
  35. }
  36. }
  37. func writeData(rw *bufio.ReadWriter) {
  38. stdReader := bufio.NewReader(os.Stdin)
  39. for {
  40. fmt.Print("> ")
  41. sendData, err := stdReader.ReadString('\n')
  42. if err != nil {
  43. log.Error("Error reading from stdin")
  44. panic(err)
  45. }
  46. _, err = rw.WriteString(fmt.Sprintf("%s\n", sendData))
  47. if err != nil {
  48. log.Error("Error writing to buffer")
  49. panic(err)
  50. }
  51. err = rw.Flush()
  52. if err != nil {
  53. log.Error("Error flushing buffer")
  54. panic(err)
  55. }
  56. }
  57. }
  58. func Start(port int, dest string) error {
  59. var r io.Reader
  60. r = rand.Reader
  61. prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r)
  62. if err != nil {
  63. return err
  64. }
  65. sourceMultiAddr, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", port))
  66. host, err := libp2p.New(
  67. context.Background(),
  68. libp2p.ListenAddrs(sourceMultiAddr),
  69. libp2p.Identity(prvKey),
  70. )
  71. if err != nil {
  72. return err
  73. }
  74. if dest == "" {
  75. host.SetStreamHandler("/slowlorisdb/0.0.1", handleStream)
  76. var port string
  77. for _, la := range host.Network().ListenAddresses() {
  78. if p, err := la.ValueForProtocol(multiaddr.P_TCP); err == nil {
  79. port = p
  80. break
  81. }
  82. }
  83. if port == "" {
  84. panic("was not able to find actual local port")
  85. }
  86. fmt.Printf("Run './slowlorisdb -d /ip4/127.0.0.1/tcp/%v/p2p/%s' on another console.\n", port, host.ID().Pretty())
  87. fmt.Printf("\nWaiting for incoming connection\n\n")
  88. // Hang forever
  89. <-make(chan struct{})
  90. } else {
  91. fmt.Println("This node's multiaddresses:")
  92. for _, la := range host.Addrs() {
  93. fmt.Printf(" - %v\n", la)
  94. }
  95. fmt.Println()
  96. maddr, err := multiaddr.NewMultiaddr(dest)
  97. if err != nil {
  98. log.Fatalln(err)
  99. }
  100. info, err := peerstore.InfoFromP2pAddr(maddr)
  101. if err != nil {
  102. log.Fatalln(err)
  103. }
  104. host.Peerstore().AddAddrs(info.ID, info.Addrs, peerstore.PermanentAddrTTL)
  105. s, err := host.NewStream(context.Background(), info.ID, "/slowlorisdb/0.0.1")
  106. if err != nil {
  107. panic(err)
  108. }
  109. rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s))
  110. go writeData(rw)
  111. go readData(rw)
  112. select {}
  113. }
  114. return nil
  115. }