swarm_net.go 4.65 KB
Newer Older
1
2
3
4
5
package swarm

import (
	"fmt"

Jeromy's avatar
Jeromy committed
6
	peer "github.com/ipfs/go-libp2p-peer"
Jeromy's avatar
Jeromy committed
7
	pstore "github.com/ipfs/go-libp2p-peerstore"
Jeromy's avatar
Jeromy committed
8
	metrics "github.com/ipfs/go-libp2p/p2p/metrics"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
9
	inet "github.com/ipfs/go-libp2p/p2p/net"
10

Jeromy's avatar
Jeromy committed
11
12
13
	ma "github.com/jbenet/go-multiaddr"
	"github.com/jbenet/goprocess"
	context "golang.org/x/net/context"
14
15
16
17
18
19
20
21
22
)

// Network implements the inet.Network interface.
// It is simply a swarm, with a few different functions
// to implement inet.Network.
type Network Swarm

// NewNetwork constructs a new network and starts listening on given addresses.
func NewNetwork(ctx context.Context, listen []ma.Multiaddr, local peer.ID,
Jeromy's avatar
Jeromy committed
23
	peers pstore.Peerstore, bwc metrics.Reporter) (*Network, error) {
24

Jeromy's avatar
Jeromy committed
25
	s, err := NewSwarm(ctx, listen, local, peers, bwc)
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
	if err != nil {
		return nil, err
	}

	return (*Network)(s), nil
}

// DialPeer attempts to establish a connection to a given peer.
// Respects the context.
func (n *Network) DialPeer(ctx context.Context, p peer.ID) (inet.Conn, error) {
	log.Debugf("[%s] network dialing peer [%s]", n.local, p)
	sc, err := n.Swarm().Dial(ctx, p)
	if err != nil {
		return nil, err
	}

	log.Debugf("network for %s finished dialing %s", n.local, p)
	return inet.Conn(sc), nil
}

46
47
48
// Process returns the network's Process
func (n *Network) Process() goprocess.Process {
	return n.proc
49
50
51
52
53
54
55
56
57
58
59
60
}

// Swarm returns the network's peerstream.Swarm
func (n *Network) Swarm() *Swarm {
	return (*Swarm)(n)
}

// LocalPeer the network's LocalPeer
func (n *Network) LocalPeer() peer.ID {
	return n.Swarm().LocalPeer()
}

Lars Gierth's avatar
Lars Gierth committed
61
// Peers returns the known peer IDs from the Peerstore
62
63
64
65
func (n *Network) Peers() []peer.ID {
	return n.Swarm().Peers()
}

Lars Gierth's avatar
Lars Gierth committed
66
// Peers returns the Peerstore, which tracks known peers
Jeromy's avatar
Jeromy committed
67
func (n *Network) Peerstore() pstore.Peerstore {
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
	return n.Swarm().peers
}

// Conns returns the connected peers
func (n *Network) Conns() []inet.Conn {
	conns1 := n.Swarm().Connections()
	out := make([]inet.Conn, len(conns1))
	for i, c := range conns1 {
		out[i] = inet.Conn(c)
	}
	return out
}

// ConnsToPeer returns the connections in this Netowrk for given peer.
func (n *Network) ConnsToPeer(p peer.ID) []inet.Conn {
	conns1 := n.Swarm().ConnectionsToPeer(p)
	out := make([]inet.Conn, len(conns1))
	for i, c := range conns1 {
		out[i] = inet.Conn(c)
	}
	return out
}

// ClosePeer connection to peer
func (n *Network) ClosePeer(p peer.ID) error {
	return n.Swarm().CloseConnection(p)
}

// close is the real teardown function
func (n *Network) close() error {
	return n.Swarm().Close()
}

// Close calls the ContextCloser func
func (n *Network) Close() error {
103
	return n.Swarm().proc.Close()
104
105
}

106
107
108
109
110
// Listen tells the network to start listening on given multiaddrs.
func (n *Network) Listen(addrs ...ma.Multiaddr) error {
	return n.Swarm().Listen(addrs...)
}

111
112
113
114
115
116
117
118
119
// ListenAddresses returns a list of addresses at which this network listens.
func (n *Network) ListenAddresses() []ma.Multiaddr {
	return n.Swarm().ListenAddresses()
}

// InterfaceListenAddresses returns a list of addresses at which this network
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces.
func (n *Network) InterfaceListenAddresses() ([]ma.Multiaddr, error) {
120
	return n.Swarm().InterfaceListenAddresses()
121
122
123
124
125
126
}

// Connectedness returns a state signaling connection capabilities
// For now only returns Connected || NotConnected. Expand into more later.
func (n *Network) Connectedness(p peer.ID) inet.Connectedness {
	c := n.Swarm().ConnectionsToPeer(p)
John Steidley's avatar
John Steidley committed
127
	if len(c) > 0 {
128
129
130
131
132
133
134
		return inet.Connected
	}
	return inet.NotConnected
}

// NewStream returns a new stream to given peer p.
// If there is no connection to p, attempts to create one.
135
func (n *Network) NewStream(ctx context.Context, p peer.ID) (inet.Stream, error) {
136
	log.Debugf("[%s] network opening stream to peer [%s]", n.local, p)
137
	s, err := n.Swarm().NewStreamWithPeer(ctx, p)
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
	if err != nil {
		return nil, err
	}

	return inet.Stream(s), nil
}

// SetHandler sets the protocol handler on the Network's Muxer.
// This operation is threadsafe.
func (n *Network) SetStreamHandler(h inet.StreamHandler) {
	n.Swarm().SetStreamHandler(h)
}

// SetConnHandler sets the conn handler on the Network.
// This operation is threadsafe.
func (n *Network) SetConnHandler(h inet.ConnHandler) {
	n.Swarm().SetConnHandler(func(c *Conn) {
		h(inet.Conn(c))
	})
}

// String returns a string representation of Network.
func (n *Network) String() string {
	return fmt.Sprintf("<Network %s>", n.LocalPeer())
}
163
164
165
166
167
168
169
170
171
172

// Notify signs up Notifiee to receive signals when events happen
func (n *Network) Notify(f inet.Notifiee) {
	n.Swarm().Notify(f)
}

// StopNotify unregisters Notifiee fromr receiving signals
func (n *Network) StopNotify(f inet.Notifiee) {
	n.Swarm().StopNotify(f)
}