Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // makeBasicHost creates a LibP2P host with a random peer ID listening on the
- // given multiaddress. It will use secio if secio is true.
- func makeBasicHost(listenPort int, secio bool, randseed int64) (host.Host, error) {
- // If the seed is zero, use real cryptographic randomness. Otherwise, use a
- // deterministic randomness source to make generated keys stay the same
- // across multiple runs
- var r io.Reader
- if randseed == 0 {
- r = rand.Reader
- } else {
- r = mrand.New(mrand.NewSource(randseed))
- }
- // Generate a key pair for this host. We will use it
- // to obtain a valid host ID.
- priv, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r)
- if err != nil {
- return nil, err
- }
- opts := []libp2p.Option{
- libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", listenPort)),
- libp2p.Identity(priv),
- }
- basicHost, err := libp2p.New(context.Background(), opts...)
- if err != nil {
- return nil, err
- }
- // Build host multiaddress
- hostAddr, _ := ma.NewMultiaddr(fmt.Sprintf("/ipfs/%s", basicHost.ID().Pretty()))
- // Now we can build a full multiaddress to reach this host
- // by encapsulating both addresses:
- addrs := basicHost.Addrs()
- var addr ma.Multiaddr
- // select the address starting with "ip4"
- for _, i := range addrs {
- if strings.HasPrefix(i.String(), "/ip4") {
- addr = i
- break
- }
- }
- fullAddr := addr.Encapsulate(hostAddr)
- log.Printf("I am %s\n", fullAddr)
- if secio {
- log.Printf("Now run \"go run p2pblock.go -l %d -d %s -secio\" on a different terminal\n", listenPort+1, fullAddr)
- } else {
- log.Printf("Now run \"go run p2pblock.go -l %d -d %s\" on a different terminal\n", listenPort+1, fullAddr)
- }
- return basicHost, nil
- }
- func handleStream(s net.Stream) {
- log.Println("Got a new stream!")
- // Create a buffer stream for non blocking read and write.
- rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s))
- go readData(rw)
- go writeData(rw)
- // stream 's' will stay open until you close it (or the other side closes it).
- }
- func main() {
- // Parse options from the command line
- listenF := flag.Int("l", 0, "wait for incoming connections")
- target := flag.String("d", "", "target peer to dial")
- secio := flag.Bool("secio", false, "enable secio")
- seed := flag.Int64("seed", 0, "set random seed for id generation")
- flag.Parse()
- if *listenF == 0 {
- log.Fatal("Please provide a port to bind on with -l")
- }
- // Make a host that listens on the given multiaddress
- ha, err := makeBasicHost(*listenF, *secio, *seed)
- if err != nil {
- log.Fatal(err)
- }
- if *target == "" {
- log.Println("listening for connections")
- // Set a stream handler on host A. /p2p/1.0.0 is
- // a user-defined protocol name.
- ha.SetStreamHandler("/p2p/1.0.0", handleStream)
- select {} // hang forever
- /**** This is where the listener code ends ****/
- } else {
- ha.SetStreamHandler("/p2p/1.0.0", handleStream)
- // The following code extracts target's peer ID from the
- // given multiaddress
- ipfsaddr, err := ma.NewMultiaddr(*target)
- if err != nil {
- log.Fatalln(err)
- }
- pid, err := ipfsaddr.ValueForProtocol(ma.P_IPFS)
- if err != nil {
- log.Fatalln(err)
- }
- peerid, err := peer.IDB58Decode(pid)
- if err != nil {
- log.Fatalln(err)
- }
- // Decapsulate the /ipfs/<peerID> part from the target
- // /ip4/<a.b.c.d>/ipfs/<peer> becomes /ip4/<a.b.c.d>
- targetPeerAddr, _ := ma.NewMultiaddr(
- fmt.Sprintf("/ipfs/%s", peer.IDB58Encode(peerid)))
- targetAddr := ipfsaddr.Decapsulate(targetPeerAddr)
- // We have a peer ID and a targetAddr so we add it to the peerstore
- // so LibP2P knows how to contact it
- ha.Peerstore().AddAddr(peerid, targetAddr, pstore.PermanentAddrTTL)
- log.Println("opening stream")
- // make a new stream from host B to host A
- // it should be handled on host A by the handler we set above because
- // we use the same /p2p/1.0.0 protocol
- s, err := ha.NewStream(context.Background(), peerid, "/p2p/1.0.0")
- if err != nil {
- log.Fatalln(err)
- }
- // Create a buffered stream so that read and writes are non blocking.
- rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s))
- // Create a thread to read and write data.
- go writeData(rw)
- go readData(rw)
- select {} // hang forever
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement