main.go 3.55 KB
Newer Older
Jeromy's avatar
Jeromy committed
1
2
3
package main

import (
4
	"context"
Jeromy's avatar
Jeromy committed
5
6
7
8
	"flag"
	"fmt"
	"io/ioutil"
	"log"
9
	"math/rand"
Jeromy's avatar
Jeromy committed
10
	"strings"
11
	"time"
Jeromy's avatar
Jeromy committed
12

Hector Sanjuan's avatar
Hector Sanjuan committed
13
	golog "github.com/ipfs/go-log"
Jeromy's avatar
Jeromy committed
14
	host "github.com/libp2p/go-libp2p-host"
Jeromy's avatar
Jeromy committed
15
	net "github.com/libp2p/go-libp2p-net"
Jeromy's avatar
Jeromy committed
16
17
	peer "github.com/libp2p/go-libp2p-peer"
	pstore "github.com/libp2p/go-libp2p-peerstore"
Jeromy's avatar
Jeromy committed
18
	swarm "github.com/libp2p/go-libp2p-swarm"
Hector Sanjuan's avatar
Hector Sanjuan committed
19
	bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
Jeromy's avatar
Jeromy committed
20
	testutil "github.com/libp2p/go-testutil"
Jeromy's avatar
Jeromy committed
21
	ma "github.com/multiformats/go-multiaddr"
Hector Sanjuan's avatar
Hector Sanjuan committed
22
	gologging "github.com/whyrusleeping/go-logging"
Jeromy's avatar
Jeromy committed
23
24
25
)

// create a 'Host' with a random peer to listen on the given address
Hector Sanjuan's avatar
Hector Sanjuan committed
26
func makeBasicHost(listen string, secio bool) (host.Host, error) {
Jeromy's avatar
Jeromy committed
27
28
29
30
31
	addr, err := ma.NewMultiaddr(listen)
	if err != nil {
		return nil, err
	}

Jeromy's avatar
Jeromy committed
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	ps := pstore.NewPeerstore()
	var pid peer.ID

	if secio {
		ident, err := testutil.RandIdentity()
		if err != nil {
			return nil, err
		}

		ident.PrivateKey()
		ps.AddPrivKey(ident.ID(), ident.PrivateKey())
		ps.AddPubKey(ident.ID(), ident.PublicKey())
		pid = ident.ID()
	} else {
		fakepid, err := testutil.RandPeerID()
		if err != nil {
			return nil, err
		}
		pid = fakepid
Jeromy's avatar
Jeromy committed
51
52
	}

Jeromy's avatar
Jeromy committed
53
	ctx := context.Background()
Jeromy's avatar
Jeromy committed
54
55

	// create a new swarm to be used by the service host
Jeromy's avatar
Jeromy committed
56
	netw, err := swarm.NewNetwork(ctx, []ma.Multiaddr{addr}, pid, ps, nil)
Jeromy's avatar
Jeromy committed
57
58
59
60
61
62
63
64
65
	if err != nil {
		return nil, err
	}

	log.Printf("I am %s/ipfs/%s\n", addr, pid.Pretty())
	return bhost.New(netw), nil
}

func main() {
66
	rand.Seed(time.Now().UnixNano())
Hector Sanjuan's avatar
Hector Sanjuan committed
67
	golog.SetAllLoggers(gologging.INFO) // Change to DEBUG for extra info
Jeromy's avatar
Jeromy committed
68
69
	listenF := flag.Int("l", 0, "wait for incoming connections")
	target := flag.String("d", "", "target peer to dial")
Jeromy's avatar
Jeromy committed
70
71
	secio := flag.Bool("secio", false, "enable secio")

Jeromy's avatar
Jeromy committed
72
73
	flag.Parse()

Hector Sanjuan's avatar
Hector Sanjuan committed
74
75
76
77
	if *listenF == 0 {
		log.Fatal("Please provide a port to bind on with -l")
	}

Lars Gierth's avatar
Lars Gierth committed
78
	listenaddr := fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", *listenF)
Jeromy's avatar
Jeromy committed
79

Hector Sanjuan's avatar
Hector Sanjuan committed
80
	ha, err := makeBasicHost(listenaddr, *secio)
Jeromy's avatar
Jeromy committed
81
82
83
84
85
	if err != nil {
		log.Fatal(err)
	}

	// Set a stream handler on host A
Jeromy's avatar
Jeromy committed
86
	ha.SetStreamHandler("/echo/1.0.0", func(s net.Stream) {
Hector Sanjuan's avatar
Hector Sanjuan committed
87
		log.Println("Got a new stream!")
Jeromy's avatar
Jeromy committed
88
		defer s.Close()
Hector Sanjuan's avatar
Hector Sanjuan committed
89
		doEcho(s)
Jeromy's avatar
Jeromy committed
90
91
92
	})

	if *target == "" {
Lars Gierth's avatar
Lars Gierth committed
93
		log.Println("listening for connections")
Jeromy's avatar
Jeromy committed
94
		select {} // hang forever
Jeromy's avatar
Jeromy committed
95
	}
Hector Sanjuan's avatar
Hector Sanjuan committed
96
	// This is where the listener code ends
Jeromy's avatar
Jeromy committed
97

Jeromy's avatar
Jeromy committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
	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)
	}

	tptaddr := strings.Split(ipfsaddr.String(), "/ipfs/")[0]
Hector Sanjuan's avatar
Hector Sanjuan committed
114
	// This creates a MA with the "/ip4/ipaddr/tcp/port" part of the target
Jeromy's avatar
Jeromy committed
115
	tptmaddr, err := ma.NewMultiaddr(tptaddr)
Jeromy's avatar
Jeromy committed
116
117
118
119
	if err != nil {
		log.Fatalln(err)
	}

Hector Sanjuan's avatar
Hector Sanjuan committed
120
121
	// We need to add the target to our peerstore, so we know how we can
	// contact it
122
	ha.Peerstore().AddAddr(peerid, tptmaddr, pstore.PermanentAddrTTL)
Jeromy's avatar
Jeromy committed
123

Lars Gierth's avatar
Lars Gierth committed
124
	log.Println("opening stream")
Jeromy's avatar
Jeromy committed
125
	// make a new stream from host B to host A
Hector Sanjuan's avatar
Hector Sanjuan committed
126
	// it should be handled on host A by the handler we set above
Lars Gierth's avatar
Lars Gierth committed
127
	s, err := ha.NewStream(context.Background(), peerid, "/echo/1.0.0")
Jeromy's avatar
Jeromy committed
128
129
130
131
	if err != nil {
		log.Fatalln(err)
	}

Lars Gierth's avatar
Lars Gierth committed
132
	_, err = s.Write([]byte("Hello, world!"))
Jeromy's avatar
Jeromy committed
133
134
135
136
	if err != nil {
		log.Fatalln(err)
	}

Jeromy's avatar
Jeromy committed
137
138
139
140
141
	out, err := ioutil.ReadAll(s)
	if err != nil {
		log.Fatalln(err)
	}

Lars Gierth's avatar
Lars Gierth committed
142
	log.Printf("read reply: %q\n", out)
Jeromy's avatar
Jeromy committed
143
}
Jeromy's avatar
Jeromy committed
144

Hector Sanjuan's avatar
Hector Sanjuan committed
145
146
// doEcho reads some data from a stream, writes it back and closes the
// stream.
147
func doEcho(s net.Stream) {
Jeromy's avatar
Jeromy committed
148
	buf := make([]byte, 1024)
Lars Gierth's avatar
Lars Gierth committed
149
150
151
152
153
	n, err := s.Read(buf)
	if err != nil {
		log.Println(err)
		return
	}
Jeromy's avatar
Jeromy committed
154

Lars Gierth's avatar
Lars Gierth committed
155
156
157
158
159
	log.Printf("read request: %q\n", buf[:n])
	_, err = s.Write(buf[:n])
	if err != nil {
		log.Println(err)
		return
Jeromy's avatar
Jeromy committed
160
161
	}
}