Advertisement
thecowmilk

Untitled

Jul 28th, 2021
1,126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 4.27 KB | None | 0 0
  1. // makeBasicHost creates a LibP2P host with a random peer ID listening on the
  2. // given multiaddress. It will use secio if secio is true.
  3. func makeBasicHost(listenPort int, secio bool, randseed int64) (host.Host, error) {
  4.  
  5.     // If the seed is zero, use real cryptographic randomness. Otherwise, use a
  6.     // deterministic randomness source to make generated keys stay the same
  7.     // across multiple runs
  8.     var r io.Reader
  9.     if randseed == 0 {
  10.         r = rand.Reader
  11.     } else {
  12.         r = mrand.New(mrand.NewSource(randseed))
  13.     }
  14.  
  15.     // Generate a key pair for this host. We will use it
  16.     // to obtain a valid host ID.
  17.     priv, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r)
  18.     if err != nil {
  19.         return nil, err
  20.     }
  21.  
  22.     opts := []libp2p.Option{
  23.         libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", listenPort)),
  24.         libp2p.Identity(priv),
  25.     }
  26.  
  27.     basicHost, err := libp2p.New(context.Background(), opts...)
  28.     if err != nil {
  29.         return nil, err
  30.     }
  31.  
  32.     // Build host multiaddress
  33.     hostAddr, _ := ma.NewMultiaddr(fmt.Sprintf("/ipfs/%s", basicHost.ID().Pretty()))
  34.  
  35.     // Now we can build a full multiaddress to reach this host
  36.     // by encapsulating both addresses:
  37.     addrs := basicHost.Addrs()
  38.     var addr ma.Multiaddr
  39.     // select the address starting with "ip4"
  40.     for _, i := range addrs {
  41.         if strings.HasPrefix(i.String(), "/ip4") {
  42.             addr = i
  43.             break
  44.         }
  45.     }
  46.     fullAddr := addr.Encapsulate(hostAddr)
  47.     log.Printf("I am %s\n", fullAddr)
  48.     if secio {
  49.         log.Printf("Now run \"go run p2pblock.go -l %d -d %s -secio\" on a different terminal\n", listenPort+1, fullAddr)
  50.     } else {
  51.         log.Printf("Now run \"go run p2pblock.go -l %d -d %s\" on a different terminal\n", listenPort+1, fullAddr)
  52.     }
  53.  
  54.     return basicHost, nil
  55. }
  56.  
  57. func handleStream(s net.Stream) {
  58.  
  59.     log.Println("Got a new stream!")
  60.  
  61.     // Create a buffer stream for non blocking read and write.
  62.     rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s))
  63.  
  64.     go readData(rw)
  65.     go writeData(rw)
  66.  
  67.     // stream 's' will stay open until you close it (or the other side closes it).
  68. }
  69.  
  70.  
  71. func main() {
  72.  
  73.     // Parse options from the command line
  74.     listenF := flag.Int("l", 0, "wait for incoming connections")
  75.     target := flag.String("d", "", "target peer to dial")
  76.     secio := flag.Bool("secio", false, "enable secio")
  77.     seed := flag.Int64("seed", 0, "set random seed for id generation")
  78.     flag.Parse()
  79.  
  80.     if *listenF == 0 {
  81.         log.Fatal("Please provide a port to bind on with -l")
  82.     }
  83.  
  84.     // Make a host that listens on the given multiaddress
  85.     ha, err := makeBasicHost(*listenF, *secio, *seed)
  86.     if err != nil {
  87.         log.Fatal(err)
  88.     }
  89.  
  90.     if *target == "" {
  91.         log.Println("listening for connections")
  92.         // Set a stream handler on host A. /p2p/1.0.0 is
  93.         // a user-defined protocol name.
  94.         ha.SetStreamHandler("/p2p/1.0.0", handleStream)
  95.  
  96.         select {} // hang forever
  97.         /**** This is where the listener code ends ****/
  98.     } else {
  99.         ha.SetStreamHandler("/p2p/1.0.0", handleStream)
  100.  
  101.         // The following code extracts target's peer ID from the
  102.         // given multiaddress
  103.         ipfsaddr, err := ma.NewMultiaddr(*target)
  104.         if err != nil {
  105.             log.Fatalln(err)
  106.         }
  107.  
  108.         pid, err := ipfsaddr.ValueForProtocol(ma.P_IPFS)
  109.         if err != nil {
  110.             log.Fatalln(err)
  111.         }
  112.  
  113.         peerid, err := peer.IDB58Decode(pid)
  114.         if err != nil {
  115.             log.Fatalln(err)
  116.         }
  117.  
  118.         // Decapsulate the /ipfs/<peerID> part from the target
  119.         // /ip4/<a.b.c.d>/ipfs/<peer> becomes /ip4/<a.b.c.d>
  120.         targetPeerAddr, _ := ma.NewMultiaddr(
  121.             fmt.Sprintf("/ipfs/%s", peer.IDB58Encode(peerid)))
  122.         targetAddr := ipfsaddr.Decapsulate(targetPeerAddr)
  123.  
  124.         // We have a peer ID and a targetAddr so we add it to the peerstore
  125.         // so LibP2P knows how to contact it
  126.         ha.Peerstore().AddAddr(peerid, targetAddr, pstore.PermanentAddrTTL)
  127.  
  128.         log.Println("opening stream")
  129.         // make a new stream from host B to host A
  130.         // it should be handled on host A by the handler we set above because
  131.         // we use the same /p2p/1.0.0 protocol
  132.         s, err := ha.NewStream(context.Background(), peerid, "/p2p/1.0.0")
  133.         if err != nil {
  134.             log.Fatalln(err)
  135.         }
  136.         // Create a buffered stream so that read and writes are non blocking.
  137.         rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s))
  138.  
  139.         // Create a thread to read and write data.
  140.         go writeData(rw)
  141.         go readData(rw)
  142.  
  143.         select {} // hang forever
  144.  
  145.     }
  146. }
  147.  
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement