network.go 5.73 KB
Newer Older
tavit ohanian's avatar
tavit ohanian committed
1
// Package network provides core networking abstractions for p2p.
2 3
//
// The network package provides the high-level Network interface for interacting
tavit ohanian's avatar
tavit ohanian committed
4
// with other p2p peers, which is the primary public API for initiating and
5 6 7 8 9 10
// accepting connections to remote peers.
package network

import (
	"context"
	"io"
11
	"time"
12 13

	"github.com/jbenet/goprocess"
tavit ohanian's avatar
tavit ohanian committed
14 15
	"gitlab.dms3.io/p2p/go-p2p-core/peer"
	"gitlab.dms3.io/p2p/go-p2p-core/peerstore"
16

tavit ohanian's avatar
tavit ohanian committed
17
	ma "gitlab.dms3.io/mf/go-multiaddr"
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
)

// MessageSizeMax is a soft (recommended) maximum for network messages.
// One can write more, as the interface is a stream. But it is useful
// to bunch it up into multiple read/writes when the whole message is
// a single, large serialized object.
const MessageSizeMax = 1 << 22 // 4 MB

// Direction represents which peer in a stream initiated a connection.
type Direction int

const (
	// DirUnknown is the default direction.
	DirUnknown Direction = iota
	// DirInbound is for when the remote peer initiated a connection.
	DirInbound
	// DirOutbound is for when the local peer initiated a connection.
	DirOutbound
)

38 39 40 41 42 43 44 45
func (d Direction) String() string {
	str := [...]string{"Unknown", "Inbound", "Outbound"}
	if d < 0 || int(d) >= len(str) {
		return "(unrecognized)"
	}
	return str[d]
}

46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
// Connectedness signals the capacity for a connection with a given node.
// It is used to signal to services and other peers whether a node is reachable.
type Connectedness int

const (
	// NotConnected means no connection to peer, and no extra information (default)
	NotConnected Connectedness = iota

	// Connected means has an open, live connection to peer
	Connected

	// CanConnect means recently connected to peer, terminated gracefully
	CanConnect

	// CannotConnect means recently attempted connecting but failed to connect.
	// (should signal "made effort, failed")
	CannotConnect
)

65 66 67 68 69 70 71 72
func (c Connectedness) String() string {
	str := [...]string{"NotConnected", "Connected", "CanConnect", "CannotConnect"}
	if c < 0 || int(c) >= len(str) {
		return "(unrecognized)"
	}
	return str[c]
}

73 74
// Reachability indicates how reachable a node is.
type Reachability int
75 76

const (
77 78
	// ReachabilityUnknown indicates that the reachability status of the
	// 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 87 88
	// public internet.
	//
	// NOTE: This node may _still_ be reachable via relays.
89
	ReachabilityPrivate
90 91
)

92 93 94 95 96 97 98 99
func (r Reachability) String() string {
	str := [...]string{"Unknown", "Public", "Private"}
	if r < 0 || int(r) >= len(str) {
		return "(unrecognized)"
	}
	return str[r]
}

100 101
// Stat stores metadata pertaining to a given Stream/Conn.
type Stat struct {
102
	// Direction specifies whether this is an inbound or an outbound connection.
103
	Direction Direction
104 105
	// Opened is the timestamp when this connection was opened.
	Opened time.Time
vyzo's avatar
vyzo committed
106
	// Transient indicates that this connection is transient and may be closed soon.
vyzo's avatar
vyzo committed
107
	Transient bool
108 109
	// Extra stores additional metadata about this connection.
	Extra map[interface{}]interface{}
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
}

// StreamHandler is the type of function used to listen for
// streams opened by the remote side.
type StreamHandler func(Stream)

// ConnHandler is the type of function used to listen for
// connections opened by the remote side.
type ConnHandler func(Conn)

// Network is the interface used to connect to the outside world.
// It dials and listens for connections. it uses a Swarm to pool
// connections (see swarm pkg, and peerstream.Swarm). Connections
// are encrypted with a TLS-like protocol.
type Network interface {
	Dialer
	io.Closer

	// SetStreamHandler sets the handler for new streams opened by the
	// remote side. This operation is threadsafe.
	SetStreamHandler(StreamHandler)

	// SetConnHandler sets the handler for new connections opened by the
	// remote side. This operation is threadsafe.
	SetConnHandler(ConnHandler)

	// NewStream returns a new stream to given peer p.
	// If there is no connection to p, attempts to create one.
	NewStream(context.Context, peer.ID) (Stream, error)

	// Listen tells the network to start listening on given multiaddrs.
	Listen(...ma.Multiaddr) error

	// ListenAddresses returns a list of addresses at which this network listens.
	ListenAddresses() []ma.Multiaddr

	// 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.
	InterfaceListenAddresses() ([]ma.Multiaddr, error)

	// Process returns the network's Process
	Process() goprocess.Process
}

// Dialer represents a service that can dial out to peers
// (this is usually just a Network, but other services may not need the whole
// stack, and thus it becomes easier to mock)
type Dialer interface {
	// Peerstore returns the internal peerstore
	// This is useful to tell the dialer about a new address for a peer.
	// Or use one of the public keys found out over the network.
	Peerstore() peerstore.Peerstore

	// LocalPeer returns the local peer associated with this network
	LocalPeer() peer.ID

	// DialPeer establishes a connection to a given peer
	DialPeer(context.Context, peer.ID) (Conn, error)

	// ClosePeer closes the connection to a given peer
	ClosePeer(peer.ID) error

	// Connectedness returns a state signaling connection capabilities
	Connectedness(peer.ID) Connectedness

	// Peers returns the peers connected
	Peers() []peer.ID

	// Conns returns the connections in this Netowrk
	Conns() []Conn

	// ConnsToPeer returns the connections in this Netowrk for given peer.
	ConnsToPeer(p peer.ID) []Conn

	// Notify/StopNotify register and unregister a notifiee for signals
	Notify(Notifiee)
	StopNotify(Notifiee)
}