main.go 3.49 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
	net "github.com/libp2p/go-libp2p-net"
Jeromy's avatar
Jeromy committed
14
15
	peer "github.com/libp2p/go-libp2p-peer"
	pstore "github.com/libp2p/go-libp2p-peerstore"
Jeromy's avatar
Jeromy committed
16
	swarm "github.com/libp2p/go-libp2p-swarm"
Hector Sanjuan's avatar
Hector Sanjuan committed
17
	bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
Jeromy's avatar
Jeromy committed
18
	testutil "github.com/libp2p/go-testutil"
Jeromy's avatar
Jeromy committed
19
	ma "github.com/multiformats/go-multiaddr"
Hector Sanjuan's avatar
Hector Sanjuan committed
20
	gologging "github.com/whyrusleeping/go-logging"
Jeromy's avatar
Jeromy committed
21
22
23
)

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

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

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

	// create a new swarm to be used by the service host
Jeromy's avatar
Jeromy committed
54
	netw, err := swarm.NewNetwork(ctx, []ma.Multiaddr{addr}, pid, ps, nil)
Jeromy's avatar
Jeromy committed
55
56
57
58
59
60
61
62
63
	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
64
	golog.SetAllLoggers(gologging.INFO) // Change to DEBUG for extra info
Jeromy's avatar
Jeromy committed
65
66
	listenF := flag.Int("l", 0, "wait for incoming connections")
	target := flag.String("d", "", "target peer to dial")
Jeromy's avatar
Jeromy committed
67
68
	secio := flag.Bool("secio", false, "enable secio")

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

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

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

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

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

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

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

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

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

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

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

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

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

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