main.go 3.53 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"
Jeromy's avatar
Jeromy committed
9
	"strings"
Jeromy's avatar
Jeromy committed
10

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

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

Jeromy's avatar
Jeromy committed
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
	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
50
51
	}

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

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

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

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

Jeromy's avatar
Jeromy committed
70
71
	flag.Parse()

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

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

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

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

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

Jeromy's avatar
Jeromy committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
	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
112
	// This creates a MA with the "/ip4/ipaddr/tcp/port" part of the target
Jeromy's avatar
Jeromy committed
113
	tptmaddr, err := ma.NewMultiaddr(tptaddr)
Jeromy's avatar
Jeromy committed
114
115
116
117
	if err != nil {
		log.Fatalln(err)
	}

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

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

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

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

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

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

Lars Gierth's avatar
Lars Gierth committed
153
154
155
156
157
	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
158
159
	}
}