1// Package network provides core networking abstractions for libp2p.
2//
3// The network package provides the high-level Network interface for interacting
4// with other libp2p peers, which is the primary public API for initiating and
5// accepting connections to remote peers.
6package network
7
8import (
9	"context"
10	"io"
11	"time"
12
13	"github.com/jbenet/goprocess"
14	"github.com/libp2p/go-libp2p-core/peer"
15	"github.com/libp2p/go-libp2p-core/peerstore"
16
17	ma "github.com/multiformats/go-multiaddr"
18)
19
20// MessageSizeMax is a soft (recommended) maximum for network messages.
21// One can write more, as the interface is a stream. But it is useful
22// to bunch it up into multiple read/writes when the whole message is
23// a single, large serialized object.
24const MessageSizeMax = 1 << 22 // 4 MB
25
26// Direction represents which peer in a stream initiated a connection.
27type Direction int
28
29const (
30	// DirUnknown is the default direction.
31	DirUnknown Direction = iota
32	// DirInbound is for when the remote peer initiated a connection.
33	DirInbound
34	// DirOutbound is for when the local peer initiated a connection.
35	DirOutbound
36)
37
38func (d Direction) String() string {
39	str := [...]string{"Unknown", "Inbound", "Outbound"}
40	if d < 0 || int(d) >= len(str) {
41		return "(unrecognized)"
42	}
43	return str[d]
44}
45
46// Connectedness signals the capacity for a connection with a given node.
47// It is used to signal to services and other peers whether a node is reachable.
48type Connectedness int
49
50const (
51	// NotConnected means no connection to peer, and no extra information (default)
52	NotConnected Connectedness = iota
53
54	// Connected means has an open, live connection to peer
55	Connected
56
57	// CanConnect means recently connected to peer, terminated gracefully
58	CanConnect
59
60	// CannotConnect means recently attempted connecting but failed to connect.
61	// (should signal "made effort, failed")
62	CannotConnect
63)
64
65func (c Connectedness) String() string {
66	str := [...]string{"NotConnected", "Connected", "CanConnect", "CannotConnect"}
67	if c < 0 || int(c) >= len(str) {
68		return "(unrecognized)"
69	}
70	return str[c]
71}
72
73// Reachability indicates how reachable a node is.
74type Reachability int
75
76const (
77	// ReachabilityUnknown indicates that the reachability status of the
78	// node is unknown.
79	ReachabilityUnknown Reachability = iota
80
81	// ReachabilityPublic indicates that the node is reachable from the
82	// public internet.
83	ReachabilityPublic
84
85	// ReachabilityPrivate indicates that the node is not reachable from the
86	// public internet.
87	//
88	// NOTE: This node may _still_ be reachable via relays.
89	ReachabilityPrivate
90)
91
92func (r Reachability) String() string {
93	str := [...]string{"Unknown", "Public", "Private"}
94	if r < 0 || int(r) >= len(str) {
95		return "(unrecognized)"
96	}
97	return str[r]
98}
99
100// Stat stores metadata pertaining to a given Stream/Conn.
101type Stat struct {
102	// Direction specifies whether this is an inbound or an outbound connection.
103	Direction Direction
104	// Opened is the timestamp when this connection was opened.
105	Opened time.Time
106	// Transient indicates that this connection is transient and may be closed soon.
107	Transient bool
108	// Extra stores additional metadata about this connection.
109	Extra map[interface{}]interface{}
110}
111
112// StreamHandler is the type of function used to listen for
113// streams opened by the remote side.
114type StreamHandler func(Stream)
115
116// ConnHandler is the type of function used to listen for
117// connections opened by the remote side.
118type ConnHandler func(Conn)
119
120// Network is the interface used to connect to the outside world.
121// It dials and listens for connections. it uses a Swarm to pool
122// connections (see swarm pkg, and peerstream.Swarm). Connections
123// are encrypted with a TLS-like protocol.
124type Network interface {
125	Dialer
126	io.Closer
127
128	// SetStreamHandler sets the handler for new streams opened by the
129	// remote side. This operation is threadsafe.
130	SetStreamHandler(StreamHandler)
131
132	// SetConnHandler sets the handler for new connections opened by the
133	// remote side. This operation is threadsafe.
134	SetConnHandler(ConnHandler)
135
136	// NewStream returns a new stream to given peer p.
137	// If there is no connection to p, attempts to create one.
138	NewStream(context.Context, peer.ID) (Stream, error)
139
140	// Listen tells the network to start listening on given multiaddrs.
141	Listen(...ma.Multiaddr) error
142
143	// ListenAddresses returns a list of addresses at which this network listens.
144	ListenAddresses() []ma.Multiaddr
145
146	// InterfaceListenAddresses returns a list of addresses at which this network
147	// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
148	// use the known local interfaces.
149	InterfaceListenAddresses() ([]ma.Multiaddr, error)
150
151	// Process returns the network's Process
152	Process() goprocess.Process
153}
154
155// Dialer represents a service that can dial out to peers
156// (this is usually just a Network, but other services may not need the whole
157// stack, and thus it becomes easier to mock)
158type Dialer interface {
159	// Peerstore returns the internal peerstore
160	// This is useful to tell the dialer about a new address for a peer.
161	// Or use one of the public keys found out over the network.
162	Peerstore() peerstore.Peerstore
163
164	// LocalPeer returns the local peer associated with this network
165	LocalPeer() peer.ID
166
167	// DialPeer establishes a connection to a given peer
168	DialPeer(context.Context, peer.ID) (Conn, error)
169
170	// ClosePeer closes the connection to a given peer
171	ClosePeer(peer.ID) error
172
173	// Connectedness returns a state signaling connection capabilities
174	Connectedness(peer.ID) Connectedness
175
176	// Peers returns the peers connected
177	Peers() []peer.ID
178
179	// Conns returns the connections in this Netowrk
180	Conns() []Conn
181
182	// ConnsToPeer returns the connections in this Netowrk for given peer.
183	ConnsToPeer(p peer.ID) []Conn
184
185	// Notify/StopNotify register and unregister a notifiee for signals
186	Notify(Notifiee)
187	StopNotify(Notifiee)
188}
189