mesh

package module
v0.0.0-...-e6ab365 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 26, 2016 License: Apache-2.0 Imports: 18 Imported by: 0

README

mesh GoDoc Circle CI

Mesh is a tool for building distributed applications.

Mesh implements a gossip protocol that provide membership, unicast, and broadcast functionality with eventually-consistent semantics. In CAP terms, it is AP: highly-available and partition-tolerant.

Mesh works in a wide variety of network setups, including thru NAT and firewalls, and across clouds and datacenters. It works in situations where there is only partial connectivity, i.e. data is transparently routed across multiple hops when there is no direct connection between peers. It copes with partitions and partial network failure. It can be easily bootstrapped, typically only requiring knowledge of a single existing peer in the mesh to join. It has built-in shared-secret authentication and encryption. It scales to on the order of 100 peers, and has no dependencies.

Using

Mesh is currently distributed as a Go package. See the API documentation.

We plan to offer Mesh as a standalone service + an easy-to-use API. We will support multiple deployment scenarios, including as a standalone binary, as a container, as an ambassador or sidecar component to an existing container, and as an infrastructure service in popular platforms.

Developing

Building

go build ./...

Testing

go test ./...

Dependencies

Mesh is a library, designed to be imported into a binary package. Vendoring is currently the best way for binary package authors to ensure reliable, reproducible builds. Therefore, we strongly recommend our users use vendoring for all of their dependencies, including Mesh. To avoid compatibility and availability issues, Mesh doesn't vendor its own dependencies, and doesn't recommend use of third-party import proxies.

There are several tools to make vendoring easier, including gb, gvt, and glide. Also, consider using the GO15VENDOREXPERIMENT method supported in Go 1.5 and set to become standard in Go 1.6.

Workflow

Mesh follows a typical PR workflow. All contributions should be made as pull requests that satisfy the guidelines, below.

Guidelines
  • All code must abide Go Code Review Comments
  • Names should abide What's in a name
  • Code must build on both Linux and Darwin, via plain go build
  • Code should have appropriate test coverage, invoked via plain go test

In addition, several mechanical checks are enforced. See the lint script for details.

Note that the existing codebase is still being refactored to abide these rules.

Documentation

Index

Constants

View Source
const (
	// InitialInterval is the lower bound on backoff between connection retries.
	// TODO(pb): does this need to be exported?
	InitialInterval = 2 * time.Second

	// MaxInterval is the upper bound on backoff between connection retries.
	// TODO(pb): does this need to be exported?
	MaxInterval = 6 * time.Minute

	// ResetAfter is the time after which a connection waiting for a retry is
	// immediately retried.
	// TODO(pb): does this need to be exported?
	ResetAfter = 1 * time.Minute
)
View Source
const (
	// PeerNameFlavour is the type of peer names we use.
	PeerNameFlavour = "mac"
	// NameSize is the number of bytes in a peer name.
	NameSize = 6
	// UnknownPeerName is used as a sentinel value.
	UnknownPeerName = PeerName(0)
)
View Source
const (
	// Protocol identifies a sort of major version of the protocol.
	Protocol = "weave"

	// ProtocolMinVersion establishes the lowest protocol version among peers
	// that we're willing to try to communicate with.
	ProtocolMinVersion = 1

	// ProtocolMaxVersion establishes the highest protocol version among peers
	// that we're willing to try to communicate with.
	ProtocolMaxVersion = 2
)
View Source
const (
	// ProtocolHeartbeat identifies a heartbeat msg.
	ProtocolHeartbeat = iota
	// ProtocolReserved1 is a legacy overly control message.
	ProtocolReserved1
	// ProtocolReserved2 is a legacy overly control message.
	ProtocolReserved2
	// ProtocolReserved3 is a legacy overly control message.
	ProtocolReserved3
	// ProtocolGossip identifies a pure gossip msg.
	ProtocolGossip
	// ProtocolGossipUnicast identifies a gossip (unicast) msg.
	ProtocolGossipUnicast
	// ProtocolGossipBroadcast identifies a gossip (broadcast) msg.
	ProtocolGossipBroadcast
	// ProtocolOverlayControlMsg identifies a control msg.
	ProtocolOverlayControlMsg
)
View Source
const (
	// Port is the port used for all mesh communication.
	// TODO(pb): this should either not be exported, or made var
	Port = 6783

	// ChannelSize is the buffer size used by so-called actor goroutines
	// throughout mesh.
	// TODO(pb): this should either not be exported, or made var
	ChannelSize = 16

	// TCPHeartbeat is how often a mesh connection will heartbeat.
	// TODO(pb): this should either not be exported, or made var
	TCPHeartbeat = 30 * time.Second

	// GossipInterval is how often peers will broadcast their accumulated
	// gossip.
	// TODO(pb): this should either not be exported, or made var
	GossipInterval = 30 * time.Second

	// MaxDuration is a stand-in for forever.
	// TODO(pb): this should not be exported
	MaxDuration = time.Duration(math.MaxInt64)
)
View Source
const MaxTCPMsgSize = 10 * 1024 * 1024

MaxTCPMsgSize is the hard limit on sends and receives. Larger messages will result in errors. This applies to the LengthPrefixTCP{Sender,Receiver} i.e. V2 of the protocol. TODO(pb): unexport

View Source
const PeerShortIDBits = 12

PeerShortIDBits is the usable bitsize of a PeerShortID. TODO(pb): does this need to be exported?

Variables

View Source
var (
	// ProtocolBytes is the protocol identifier in byte-slice form.
	ProtocolBytes = []byte(Protocol)

	// HeaderTimeout defines how long we're willing to wait for the handshake
	// phase of protocol negotiation.
	HeaderTimeout = 10 * time.Second

	// ProtocolV1Features enumerate all of the version 1 features, so they may
	// be special-cased the introduction phase. See filterV1Features.
	ProtocolV1Features = []string{
		"ConnID",
		"Name",
		"NickName",
		"PeerNameFlavour",
		"UID",
	}

	// ErrExpectedCrypto is returned by the handshake when this peer expects
	// to do encryption, but remote peers do not.
	ErrExpectedCrypto = fmt.Errorf("password specified, but peer requested an unencrypted connection")

	// ErrExpectedNoCrypto is returned by the handshake when this peer does
	// not expect to do encryption, but remote peers do.
	ErrExpectedNoCrypto = fmt.Errorf("no password specificed, but peer requested an encrypted connection")
)
View Source
var ErrConnectToSelf = fmt.Errorf("Cannot connect to ourself")

ErrConnectToSelf will be unexported soon. TODO(pb): does this need to be exported?

Functions

func FormSessionKey

func FormSessionKey(remotePublicKey, localPrivateKey *[32]byte, secretKey []byte) *[32]byte

FormSessionKey is used during encrypted protocol introduction. TODO(pb): unexport

func GenerateKeyPair

func GenerateKeyPair() (publicKey, privateKey *[32]byte, err error)

GenerateKeyPair is used during encrypted protocol introduction. TODO(pb): unexport

func GobEncode

func GobEncode(items ...interface{}) []byte

GobEncode gob-encodes each item and returns the resulting byte slice. TODO(pb): does this need to be exported?

func NewTargetSlice

func NewTargetSlice(cm *ConnectionMaker) []string

NewTargetSlice takes a snapshot of the active targets (direct peers) in the ConnectionMaker. TODO(pb): unexport and rename as Make

func NewTrustedSubnetsSlice

func NewTrustedSubnetsSlice(trustedSubnets []*net.IPNet) []string

NewTrustedSubnetsSlice makes a human-readable copy of the trustedSubnets. TODO(pb): unexport and rename as Make

func StartLocalConnection

func StartLocalConnection(connRemote *RemoteConnection, tcpConn *net.TCPConn, router *Router, acceptNewPeer bool)

StartLocalConnection does not return anything. If the connection is successful, it will end up in the local peer's connections map.

Types

type BroadcastRouteStatus

type BroadcastRouteStatus struct {
	Source string
	Via    []string
}

BroadcastRouteStatus is the current state of an established broadcast route.

func NewBroadcastRouteStatusSlice

func NewBroadcastRouteStatusSlice(routes *Routes) []BroadcastRouteStatus

NewBroadcastRouteStatusSlice takes a snapshot of the broadcast routes in routes. TODO(pb): unexport and rename as Make

type Config

type Config struct {
	Port               int
	ProtocolMinVersion byte
	Password           []byte
	ConnLimit          int
	PeerDiscovery      bool
	TrustedSubnets     []*net.IPNet
}

Config defines dimensions of configuration for the router. TODO(pb): provide usable defaults in NewRouter

type Connection

type Connection interface {
	Local() *Peer
	Remote() *Peer
	RemoteTCPAddr() string
	Outbound() bool
	Established() bool
	BreakTie(Connection) ConnectionTieBreak
	Shutdown(error)
	Log(args ...interface{})
}

Connection is the commonality of LocalConnection and RemoteConnection. TODO(pb): does this need to be exported?

type ConnectionAction

type ConnectionAction func() error

ConnectionAction is the actor closure used by LocalConnection. If an action returns an error, it will terminate the actor loop, which terminates the connection in turn. TODO(pb): does this need to be exported?

type ConnectionMaker

type ConnectionMaker struct {
	// contains filtered or unexported fields
}

ConnectionMaker initiates and manages connections to peers.

func NewConnectionMaker

func NewConnectionMaker(ourself *LocalPeer, peers *Peers, port int, discovery bool) *ConnectionMaker

NewConnectionMaker returns a usable ConnectionMaker, seeded with peers, listening on port. If discovery is true, ConnectionMaker will attempt to initiate new connections with peers it's not directly connected to.

func (*ConnectionMaker) ConnectionAborted

func (cm *ConnectionMaker) ConnectionAborted(address string, err error)

ConnectionAborted marks the target identified by address as broken, and puts it in the TargetWaiting state. TODO(pb): does this need to be exported?

func (*ConnectionMaker) ConnectionCreated

func (cm *ConnectionMaker) ConnectionCreated(conn Connection)

ConnectionCreated registers the passed connection, and marks the target identified by conn.RemoteTCPAddr() as established, and puts it in the TargetConnected state. TODO(pb): does this need to be exported?

func (*ConnectionMaker) ConnectionTerminated

func (cm *ConnectionMaker) ConnectionTerminated(conn Connection, err error)

ConnectionTerminated unregisters the passed connection, and marks the target identified by conn.RemoteTCPAddr() as Waiting. TODO(pb): does this need to be exported?

func (*ConnectionMaker) ForgetConnections

func (cm *ConnectionMaker) ForgetConnections(peers []string)

ForgetConnections removes direct connections to the provided peers, specified in host:port format. TODO(pb): invoked only by Weave Net

func (*ConnectionMaker) InitiateConnections

func (cm *ConnectionMaker) InitiateConnections(peers []string, replace bool) []error

InitiateConnections creates new connections to the provided peers, specified in host:port format. If replace is true, any existing direct peers are forgotten. TODO(pb): invoked only by Weave Net

func (*ConnectionMaker) Refresh

func (cm *ConnectionMaker) Refresh()

Refresh sends a no-op action into the ConnectionMaker, purely so that the ConnectionMaker will check the state of its targets and reconnect to relevant candidates. TODO(pb): does this need to be exported?

type ConnectionMakerAction

type ConnectionMakerAction func() bool

ConnectionMakerAction is the actor closure used by ConnectionMaker. If an action returns true, the ConnectionMaker will check the state of its targets, and reconnect to relevant candidates. TODO(pb): does this need to be exported?

type ConnectionSet

type ConnectionSet map[Connection]struct{}

ConnectionSet is an set of connection objects.

type ConnectionStatus

type ConnectionStatus struct {
	Name        string
	NickName    string
	Address     string
	Outbound    bool
	Established bool
}

ConnectionStatus is the current state of a connection to a peer.

type ConnectionSummary

type ConnectionSummary struct {
	NameByte      []byte
	RemoteTCPAddr string
	Outbound      bool
	Established   bool
}

ConnectionSummary collects details about a connection.

type ConnectionTieBreak

type ConnectionTieBreak int

ConnectionTieBreak describes the outcome of a tiebreaking contest between two connections. TODO(pb): does this need to be exported?

const (
	// TieBreakWon indicates the candidate has won the tiebreak.
	// TODO(pb): does this need to be exported?
	TieBreakWon ConnectionTieBreak = iota

	// TieBreakLost indicates the candidate has lost the tiebreak.
	// TODO(pb): does this need to be exported?
	TieBreakLost

	// TieBreakTied indicates the tiebreaking contest had no winner.
	// TODO(pb): does this need to be exported?
	TieBreakTied
)

type EncryptedTCPReceiver

type EncryptedTCPReceiver struct {
	// contains filtered or unexported fields
}

EncryptedTCPReceiver implements TCPReceiver by wrapping a TCPReceiver with TCPCryptoState. TODO(pb): unexport

func NewEncryptedTCPReceiver

func NewEncryptedTCPReceiver(receiver TCPReceiver, sessionKey *[32]byte, outbound bool) *EncryptedTCPReceiver

NewEncryptedTCPReceiver returns a usable EncryptedTCPReceiver.

func (*EncryptedTCPReceiver) Receive

func (receiver *EncryptedTCPReceiver) Receive() ([]byte, error)

Receive implements TCPReceiver by reading from the wrapped TCPReceiver and unboxing the encrypted message, returning the decoded message.

type EncryptedTCPSender

type EncryptedTCPSender struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

EncryptedTCPSender implements TCPSender by wrapping an existing TCPSender with TCPCryptoState.

func NewEncryptedTCPSender

func NewEncryptedTCPSender(sender TCPSender, sessionKey *[32]byte, outbound bool) *EncryptedTCPSender

NewEncryptedTCPSender returns a usable EncryptedTCPSender.

func (*EncryptedTCPSender) Send

func (sender *EncryptedTCPSender) Send(msg []byte) error

Send implements TCPSender by sealing and sending the as-is.

type GobTCPReceiver

type GobTCPReceiver struct {
	// contains filtered or unexported fields
}

GobTCPReceiver implements TCPReceiver and is used in the V1 protocol. TODO(pb): unexport

func NewGobTCPReceiver

func NewGobTCPReceiver(decoder *gob.Decoder) *GobTCPReceiver

NewGobTCPReceiver returns a usable GobTCPReceiver. TODO(pb): unexport

func (*GobTCPReceiver) Receive

func (receiver *GobTCPReceiver) Receive() ([]byte, error)

Receive implements TCPReciever by Gob decoding into a byte slice directly.

type GobTCPSender

type GobTCPSender struct {
	// contains filtered or unexported fields
}

GobTCPSender implements TCPSender and is used in the V1 protocol. TODO(pb): unexport

func NewGobTCPSender

func NewGobTCPSender(encoder *gob.Encoder) *GobTCPSender

NewGobTCPSender returns a usable GobTCPSender.

func (*GobTCPSender) Send

func (sender *GobTCPSender) Send(msg []byte) error

Send implements TCPSender by encoding the msg.

type Gossip

type Gossip interface {
	// GossipUnicast emits a single message to a peer in the mesh.
	// TODO(pb): rename to Unicast?
	//
	// Unicast takes []byte instead of GossipData because "to date there has
	// been no compelling reason [in practice] to do merging on unicast."
	// But there may be some motivation to have unicast Mergeable; see
	// https://github.com/weaveworks/weave/issues/1764
	// TODO(pb): for uniformity of interface, rather take GossipData?
	GossipUnicast(dst PeerName, msg []byte) error

	// GossipBroadcast emits a message to all peers in the mesh.
	// TODO(pb): rename to Broadcast?
	GossipBroadcast(update GossipData)
}

Gossip is the sending interface. TODO(pb): rename to e.g. Sender

type GossipChannel

type GossipChannel struct {
	// contains filtered or unexported fields
}

GossipChannel is a logical communication channel within a physical mesh. TODO(pb): does this need to be exported?

func NewGossipChannel

func NewGossipChannel(channelName string, ourself *LocalPeer, routes *Routes, g Gossiper) *GossipChannel

NewGossipChannel returns a named, usable channel. It delegates receiving duties to the passed Gossiper. TODO(pb): does this need to be exported?

func (*GossipChannel) GossipBroadcast

func (c *GossipChannel) GossipBroadcast(update GossipData)

GossipBroadcast implements Gossip, relaying update to all members of the channel.

func (*GossipChannel) GossipUnicast

func (c *GossipChannel) GossipUnicast(dstPeerName PeerName, msg []byte) error

GossipUnicast implements Gossip, relaying msg to dst, which must be a member of the channel.

func (*GossipChannel) Send

func (c *GossipChannel) Send(data GossipData)

Send relays data into the channel topology via random neighbours.

func (*GossipChannel) SendDown

func (c *GossipChannel) SendDown(conn Connection, data GossipData)

SendDown relays data into the channel topology via conn.

type GossipChannels

type GossipChannels map[string]*GossipChannel

GossipChannels is an index of channel name to gossip channel. TODO(pb): does this need to be exported?

type GossipConnection

type GossipConnection interface {
	GossipSenders() *GossipSenders
}

GossipConnection describes something that can yield multiple GossipSenders. TODO(pb): does this need to be exported?

type GossipData

type GossipData interface {
	// Encode encodes the data into multiple byte-slices.
	Encode() [][]byte

	// Merge combines another GossipData into this one and returns the result.
	// TODO(pb): does it need to be leave the original unmodified?
	Merge(GossipData) GossipData
}

GossipData is a merge-able dataset. Think: log-structured data.

type GossipSender

type GossipSender struct {
	sync.Mutex
	// contains filtered or unexported fields
}

GossipSender accumulates GossipData that needs to be sent to one destination, and sends it when possible. GossipSender is one-to-one with a channel.

func NewGossipSender

func NewGossipSender(
	makeMsg func(msg []byte) ProtocolMsg,
	makeBroadcastMsg func(srcName PeerName, msg []byte) ProtocolMsg,
	sender ProtocolSender,
	stop <-chan struct{},
) *GossipSender

NewGossipSender constructs a usable GossipSender.

func (*GossipSender) Broadcast

func (s *GossipSender) Broadcast(srcName PeerName, data GossipData)

Broadcast accumulates the GossipData under the given srcName and will send it eventually. Send and Broadcast accumulate into different buckets.

func (*GossipSender) Flush

func (s *GossipSender) Flush() bool

Flush sends all pending data, and returns true if anything was sent since the previous flush. For testing.

func (*GossipSender) Send

func (s *GossipSender) Send(data GossipData)

Send accumulates the GossipData and will send it eventually. Send and Broadcast accumulate into different buckets.

type GossipSenders

type GossipSenders struct {
	sync.Mutex
	// contains filtered or unexported fields
}

GossipSenders wraps a ProtocolSender (e.g. a LocalConnection) and yields per-channel GossipSenders. TODO(pb): may be able to remove this and use makeGossipSender directly

func NewGossipSenders

func NewGossipSenders(sender ProtocolSender, stop <-chan struct{}) *GossipSenders

NewGossipSenders returns a usable GossipSenders leveraging the ProtocolSender. TODO(pb): is stop chan the best way to do that?

func (*GossipSenders) Flush

func (gs *GossipSenders) Flush() bool

Flush flushes all managed senders. Used for testing.

func (*GossipSenders) Sender

func (gs *GossipSenders) Sender(channelName string, makeGossipSender func(sender ProtocolSender, stop <-chan struct{}) *GossipSender) *GossipSender

Sender yields the GossipSender for the named channel. It will use the factory function if no sender yet exists.

type Gossiper

type Gossiper interface {
	// OnGossipUnicast merges received data into state.
	// TODO(pb): rename to e.g. OnUnicast
	OnGossipUnicast(src PeerName, msg []byte) error

	// OnGossipBroadcast merges received data into state and returns a
	// representation of the received data, for further propagation.
	// TODO(pb): rename to e.g. OnBroadcast
	OnGossipBroadcast(src PeerName, update []byte) (GossipData, error)

	// Gossip returns the state of everything we know; gets called periodically.
	Gossip() GossipData

	// OnGossip merges received data into state and returns "everything new
	// I've just learnt", or nil if nothing in the received data was new.
	OnGossip(msg []byte) (GossipData, error)
}

Gossiper is the receiving interface. TODO(pb): rename to e.g. Receiver

type LengthPrefixTCPReceiver

type LengthPrefixTCPReceiver struct {
	// contains filtered or unexported fields
}

LengthPrefixTCPReceiver implements TCPReceiver, used in the V2 protocol. TODO(pb): unexport

func NewLengthPrefixTCPReceiver

func NewLengthPrefixTCPReceiver(reader io.Reader) *LengthPrefixTCPReceiver

NewLengthPrefixTCPReceiver returns a usable LengthPrefixTCPReceiver, wrapping the passed reader.

func (*LengthPrefixTCPReceiver) Receive

func (receiver *LengthPrefixTCPReceiver) Receive() ([]byte, error)

Receive implements TCPReceiver by making a length-limited read into a byte buffer.

type LengthPrefixTCPSender

type LengthPrefixTCPSender struct {
	// contains filtered or unexported fields
}

LengthPrefixTCPSender implements TCPSender and is used in the V2 protocol. TODO(pb): unexport

func NewLengthPrefixTCPSender

func NewLengthPrefixTCPSender(writer io.Writer) *LengthPrefixTCPSender

NewLengthPrefixTCPSender returns a usable LengthPrefixTCPSender.

func (*LengthPrefixTCPSender) Send

func (sender *LengthPrefixTCPSender) Send(msg []byte) error

Send implements TCPSender by writing the size of the msg as a big-endian uint32 before the msg. msgs larger than MaxTCPMsgSize are rejected.

type ListOfPeers

type ListOfPeers []*Peer

ListOfPeers implements sort.Interface on a slice of Peers. TODO(pb): does this need to be exported?

func (ListOfPeers) Len

func (lop ListOfPeers) Len() int

Len implements sort.Interface.

func (ListOfPeers) Less

func (lop ListOfPeers) Less(i, j int) bool

Less implements sort.Interface.

func (ListOfPeers) Swap

func (lop ListOfPeers) Swap(i, j int)

Swap implements sort.Interface.

type LocalConnection

type LocalConnection struct {
	sync.RWMutex
	RemoteConnection
	TCPConn         *net.TCPConn
	TrustRemote     bool // is remote on a trusted subnet?
	TrustedByRemote bool // does remote trust us?

	SessionKey *[32]byte

	Router *Router

	OverlayConn OverlayConnection
	// contains filtered or unexported fields
}

LocalConnection is the local side of a connection. It implements ProtocolSender, and manages per-channel GossipSenders. TODO(pb): does this need to be exported?

func (*LocalConnection) BreakTie

func (conn *LocalConnection) BreakTie(dupConn Connection) ConnectionTieBreak

BreakTie conducts a tiebreaking contest between two connections.

func (*LocalConnection) Established

func (conn *LocalConnection) Established() bool

Established returns true if the connection is established. TODO(pb): data race?

func (*LocalConnection) GossipSenders

func (conn *LocalConnection) GossipSenders() *GossipSenders

GossipSenders implements GossipConnection.

func (*LocalConnection) SendProtocolMsg

func (conn *LocalConnection) SendProtocolMsg(m ProtocolMsg) error

SendProtocolMsg implements ProtocolSender.

func (*LocalConnection) Shutdown

func (conn *LocalConnection) Shutdown(err error)

Shutdown is non-blocking. TODO(pb): must be?

func (*LocalConnection) Untrusted

func (conn *LocalConnection) Untrusted() bool

Untrusted returns true if either we don't trust our remote, or are not trusted by our remote. TODO(pb): does this need to be exported?

type LocalConnectionStatus

type LocalConnectionStatus struct {
	Address  string
	Outbound bool
	State    string
	Info     string
}

LocalConnectionStatus is the current state of a physical connection to a peer.

func NewLocalConnectionStatusSlice

func NewLocalConnectionStatusSlice(cm *ConnectionMaker) []LocalConnectionStatus

NewLocalConnectionStatusSlice takes a snapshot of the active local connections in the ConnectionMaker. TODO(pb): unexport and rename as Make

type LocalPeer

type LocalPeer struct {
	sync.RWMutex
	*Peer
	// contains filtered or unexported fields
}

LocalPeer is the only "active" peer in the mesh. It extends Peer with additional behaviors, mostly to retrieve and manage connection state.

func NewLocalPeer

func NewLocalPeer(name PeerName, nickName string, router *Router) *LocalPeer

NewLocalPeer returns a usable LocalPeer.

func (*LocalPeer) AddConnection

func (peer *LocalPeer) AddConnection(conn *LocalConnection) error

AddConnection adds the connection to the peer. Synchronous.

func (*LocalPeer) ConnectionEstablished

func (peer *LocalPeer) ConnectionEstablished(conn *LocalConnection)

ConnectionEstablished marks the connection as established within the peer. Asynchronous.

func (*LocalPeer) ConnectionTo

func (peer *LocalPeer) ConnectionTo(name PeerName) (Connection, bool)

ConnectionTo returns the connection to the named peer, if any.

func (*LocalPeer) Connections

func (peer *LocalPeer) Connections() ConnectionSet

Connections returns all the connections that the local peer is aware of.

func (*LocalPeer) ConnectionsTo

func (peer *LocalPeer) ConnectionsTo(names []PeerName) []Connection

ConnectionsTo returns all known connections to the named peers.

func (*LocalPeer) CreateConnection

func (peer *LocalPeer) CreateConnection(peerAddr string, acceptNewPeer bool) error

CreateConnection creates a new connection to peerAddr. If acceptNewPeer is false, peerAddr must already be a member of the mesh.

func (*LocalPeer) DeleteConnection

func (peer *LocalPeer) DeleteConnection(conn *LocalConnection)

DeleteConnection removes the connection from the peer. Synchronous.

func (*LocalPeer) Encode

func (peer *LocalPeer) Encode(enc *gob.Encoder)

Encode writes the peer to the encoder.

type LocalPeerAction

type LocalPeerAction func()

LocalPeerAction is the actor closure used by LocalPeer. TODO(pb): does this need to be exported?

type NullOverlay

type NullOverlay struct{}

NullOverlay implements Overlay and OverlayConnection with no-ops.

func (NullOverlay) AddFeaturesTo

func (NullOverlay) AddFeaturesTo(map[string]string)

AddFeaturesTo implements Overlay.

func (NullOverlay) Confirm

func (NullOverlay) Confirm()

Confirm implements OverlayConnection.

func (NullOverlay) ControlMessage

func (NullOverlay) ControlMessage(byte, []byte)

ControlMessage implements OverlayConnection.

func (NullOverlay) Diagnostics

func (NullOverlay) Diagnostics() interface{}

Diagnostics implements Overlay.

func (NullOverlay) DisplayName

func (NullOverlay) DisplayName() string

DisplayName implements OverlayConnection.

func (NullOverlay) ErrorChannel

func (NullOverlay) ErrorChannel() <-chan error

ErrorChannel implements OverlayConnection.

func (NullOverlay) EstablishedChannel

func (NullOverlay) EstablishedChannel() <-chan struct{}

EstablishedChannel implements OverlayConnection.

func (NullOverlay) PrepareConnection

PrepareConnection implements Overlay.

func (NullOverlay) Stop

func (NullOverlay) Stop()

Stop implements OverlayConnection.

type Overlay

type Overlay interface {
	// Enhance a features map with overlay-related features
	AddFeaturesTo(map[string]string)

	// Prepare on overlay connection. The connection should remain
	// passive until it has been Confirm()ed.
	PrepareConnection(OverlayConnectionParams) (OverlayConnection, error)

	// Obtain diagnostic information specific to the overlay
	Diagnostics() interface{}
}

Overlay yields OverlayConnections.

type OverlayConnection

type OverlayConnection interface {
	// Confirm that the connection is really wanted, and so the
	// Overlay should begin heartbeats etc. to verify the operation of
	// the overlay connection.
	Confirm()

	// EstablishedChannel returns a channel that will be closed when the
	// overlay connection is established, i.e. its operation has been
	// confirmed.
	EstablishedChannel() <-chan struct{}

	// ErrorChannel returns a channel that forwards errors from the overlay
	// connection. The overlay connection is not expected to be operational
	// after the first error, so the channel only needs to buffer a single
	// error.
	ErrorChannel() <-chan error

	// Stop terminates the connection.
	Stop()

	// ControlMessage handles a message from the remote peer. 'tag' exists for
	// compatibility, and should always be ProtocolOverlayControlMessage for
	// non-sleeve overlays.
	ControlMessage(tag byte, msg []byte)

	// DisplayName returns the user-facing overlay name.
	DisplayName() string
}

OverlayConnection describes all of the machinery to manage overlay connectivity to a particular peer.

type OverlayConnectionParams

type OverlayConnectionParams struct {
	RemotePeer *Peer

	// The local address of the corresponding TCP connection. Used to
	// derive the local IP address for sending. May differ for
	// different overlay connections.
	LocalAddr *net.TCPAddr

	// The remote address of the corresponding TCP connection. Used to
	// determine the address to send to, but only if the TCP
	// connection is outbound. Otherwise the Overlay needs to discover
	// it (e.g. from incoming datagrams).
	RemoteAddr *net.TCPAddr

	// Is the corresponding TCP connection outbound?
	Outbound bool

	// Unique identifier for this connection
	ConnUID uint64

	// Session key, if connection is encrypted; nil otherwise.
	//
	// NB: overlay connections must take care not to use nonces which
	// may collide with those of the main connection. These nonces are
	// 192 bits, with the top most bit unspecified, the next bit set
	// to 1, followed by 126 zero bits, and a message sequence number
	// in the lowest 64 bits.
	SessionKey *[32]byte

	// Function to send a control message to the counterpart
	// overlay connection.
	SendControlMessage func(tag byte, msg []byte) error

	// Features passed at connection initiation
	Features map[string]string
}

OverlayConnectionParams are used to set up overlay connections.

type Peer

type Peer struct {
	Name PeerName
	PeerSummary
	// contains filtered or unexported fields
}

Peer is a local representation of a peer, including connections to other peers. By itself, it is a remote peer.

func NewPeer

func NewPeer(name PeerName, nickName string, uid PeerUID, version uint64, shortID PeerShortID) *Peer

NewPeer constructs a new Peer object with no connections from the provided composite parts.

func NewPeerFrom

func NewPeerFrom(peer *Peer) *Peer

NewPeerFrom constructs a new Peer object that is a copy of the passed peer. Primarily used for tests.

func NewPeerFromSummary

func NewPeerFromSummary(summary PeerSummary) *Peer

NewPeerFromSummary constructs a new Peer object with no connections from the provided summary.

func NewPeerPlaceholder

func NewPeerPlaceholder(name PeerName) *Peer

NewPeerPlaceholder constructs a partial Peer object with only the passed name. Useful when we get a strange update from the mesh.

func (*Peer) Encode

func (peer *Peer) Encode(enc *gob.Encoder)

Encode writes the peer to the encoder.

func (*Peer) ForEachConnectedPeer

func (peer *Peer) ForEachConnectedPeer(establishedAndSymmetric bool, exclude map[PeerName]PeerName, f func(*Peer))

ForEachConnectedPeer applies f to all peers reachable by peer. If establishedAndSymmetric is true, only peers with established bidirectional connections will be selected. The exclude maps is treated as a set of remote peers to blacklist. TODO(pb): change exclude to map[PeerName]struct{}?

func (*Peer) Routes

func (peer *Peer) Routes(stopAt *Peer, establishedAndSymmetric bool) (bool, map[PeerName]PeerName)

Routes calculates the routing table from this peer to all peers reachable from it, returning a "next hop" map of PeerNameX -> PeerNameY, which says "in order to send a message to X, the peer should send the message to its neighbour Y".

Because currently we do not have weightings on the connections between peers, there is no need to use a minimum spanning tree algorithm. Instead we employ the simpler and cheaper breadth-first widening. The computation is deterministic, which ensures that when it is performed on the same data by different peers, they get the same result. This is important since otherwise we risk message loss or routing cycles.

When the 'establishedAndSymmetric' flag is set, only connections that are marked as 'established' and are symmetric (i.e. where both sides indicate they have a connection to the other) are considered.

When a non-nil stopAt peer is supplied, the widening stops when it reaches that peer. The boolean return indicates whether that has happened.

NB: This function should generally be invoked while holding a read lock on Peers and LocalPeer.

func (*Peer) String

func (peer *Peer) String() string

String returns the peer name and nickname.

type PeerName

type PeerName uint64

PeerName is used as a map key. Since net.HardwareAddr isn't suitable for that - it's a slice, and slices can't be map keys - we convert that to/from uint64.

func PeerNameFromBin

func PeerNameFromBin(nameByte []byte) PeerName

PeerNameFromBin parses PeerName from a byte slice. TODO(pb): does this need to be exported?

func PeerNameFromString

func PeerNameFromString(nameStr string) (PeerName, error)

PeerNameFromString parses PeerName from a generic string. TODO(pb): does this need to be exported?

func PeerNameFromUserInput

func PeerNameFromUserInput(userInput string) (PeerName, error)

PeerNameFromUserInput parses PeerName from a user-provided string. TODO(pb): does this need to be exported?

func (PeerName) Bin

func (name PeerName) Bin() []byte

Bin encodes PeerName as a byte slice.

func (PeerName) String

func (name PeerName) String() string

String encodes PeerName as a string.

type PeerNameSet

type PeerNameSet map[PeerName]struct{}

PeerNameSet is a set of PeerNames used internally throughout mesh. TODO(pb): does this need to be exported?

type PeerShortID

type PeerShortID uint16

PeerShortID exists for the sake of fast datapath. They are 12 bits, randomly assigned, but we detect and recover from collisions. This does limit us to 4096 peers, but that should be sufficient for a while. TODO(pb): does this need to be exported?

type PeerStatus

type PeerStatus struct {
	Name        string
	NickName    string
	UID         PeerUID
	ShortID     PeerShortID
	Version     uint64
	Connections []ConnectionStatus
}

PeerStatus is the current state of a peer in the mesh.

func NewPeerStatusSlice

func NewPeerStatusSlice(peers *Peers) []PeerStatus

NewPeerStatusSlice takes a snapshot of the state of peers. TODO(pb): unexport and rename as Make

type PeerSummary

type PeerSummary struct {
	NameByte   []byte
	NickName   string
	UID        PeerUID
	Version    uint64
	ShortID    PeerShortID
	HasShortID bool
}

PeerSummary is a collection of identifying information for a peer.

type PeerUID

type PeerUID uint64

PeerUID uniquely identifies a peer in a mesh.

func ParsePeerUID

func ParsePeerUID(s string) (PeerUID, error)

ParsePeerUID parses a decimal peer UID from a string.

type Peers

type Peers struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Peers collects all of the known peers in the mesh, including ourself.

func NewPeers

func NewPeers(ourself *LocalPeer) *Peers

NewPeers constructs a new, empty Peers.

func (*Peers) ApplyUpdate

func (peers *Peers) ApplyUpdate(update []byte) (PeerNameSet, PeerNameSet, error)

ApplyUpdate merges an incoming update with our own topology.

We add peers hitherto unknown to us, and update peers for which the update contains a more recent version than known to us. The return value is a) a representation of the received update, and b) an "improved" update containing just these new/updated elements.

func (*Peers) Dereference

func (peers *Peers) Dereference(peer *Peer)

Dereference decrements the refcount of the matching peer. TODO(pb): this is an awkward way to use the mutex; consider refactoring

func (*Peers) EncodePeers

func (peers *Peers) EncodePeers(names PeerNameSet) []byte

EncodePeers returns a Gob-encoded set of known peers.

func (*Peers) Fetch

func (peers *Peers) Fetch(name PeerName) *Peer

Fetch returns a peer matching the passed name, without incrementing its refcount. If no matching peer is found, Fetch returns nil.

func (*Peers) FetchAndAddRef

func (peers *Peers) FetchAndAddRef(name PeerName) *Peer

FetchAndAddRef returns a peer matching the passed name, and increments its refcount. If no matching peer is found, FetchAndAddRef returns nil.

func (*Peers) FetchByShortID

func (peers *Peers) FetchByShortID(shortID PeerShortID) *Peer

FetchByShortID returns a peer matching the passed short ID. If no matching peer is found, FetchByShortID returns nil.

func (*Peers) FetchWithDefault

func (peers *Peers) FetchWithDefault(peer *Peer) *Peer

FetchWithDefault will use reference fields of the passed peer object to look up and return an existing, matching peer. If no matching peer is found, the passed peer is saved and returned.

func (*Peers) ForEach

func (peers *Peers) ForEach(fun func(*Peer))

ForEach applies fun to each peer under a read lock.

func (*Peers) GarbageCollect

func (peers *Peers) GarbageCollect()

GarbageCollect takes a lock, triggers a GC, and invokes the accumulated GC callbacks.

func (*Peers) Names

func (peers *Peers) Names() PeerNameSet

Names allocates and returns a set of all peer names.

func (*Peers) OnGC

func (peers *Peers) OnGC(callback func(*Peer))

OnGC adds a new function to be set of functions that will be executed on all subsequent GC runs, receiving the GC'd peer.

func (*Peers) OnInvalidateShortIDs

func (peers *Peers) OnInvalidateShortIDs(callback func())

OnInvalidateShortIDs adds a new function to a set of functions that will be executed on all subsequent GC runs, when the mapping from short IDs to peers has changed.

type PeersPendingNotifications

type PeersPendingNotifications struct {
	// contains filtered or unexported fields
}

PeersPendingNotifications due to changes to Peers that need to be sent out once the Peers is unlocked. TODO(pb): unexport

type ProtocolIntroConn

type ProtocolIntroConn interface {
	// io.Reader
	Read(b []byte) (n int, err error)

	// io.Writer
	Write(b []byte) (n int, err error)

	// net.Conn's deadline methods
	SetDeadline(t time.Time) error
	SetReadDeadline(t time.Time) error
	SetWriteDeadline(t time.Time) error
}

ProtocolIntroConn collect the parts of the net.TCPConn we require to do the protocol intro, to support testing. TODO(pb): does this need to be exported?

type ProtocolIntroParams

type ProtocolIntroParams struct {
	MinVersion byte
	MaxVersion byte
	Features   map[string]string
	Conn       ProtocolIntroConn
	Password   []byte
	Outbound   bool
}

ProtocolIntroParams capture the params necessary to negotiate a protocol intro with a remote peer.

func (ProtocolIntroParams) DoIntro

func (params ProtocolIntroParams) DoIntro() (res ProtocolIntroResults, err error)

DoIntro executes the protocol introduction. TODO(pb): eliminate named return params?

type ProtocolIntroResults

type ProtocolIntroResults struct {
	Features   map[string]string
	Receiver   TCPReceiver
	Sender     TCPSender
	SessionKey *[32]byte
	Version    byte
}

ProtocolIntroResults capture the results from a successful protocol intro.

type ProtocolMsg

type ProtocolMsg struct {
	// contains filtered or unexported fields
}

ProtocolMsg combines a tag and encoded msg.

type ProtocolSender

type ProtocolSender interface {
	SendProtocolMsg(m ProtocolMsg) error
}

ProtocolSender describes anything that can emit a ProtocolMsg on the wire.

type ProtocolTag

type ProtocolTag byte

ProtocolTag identifies the type of msg encoded in a ProtocolMsg.

type RemoteConnection

type RemoteConnection struct {
	// contains filtered or unexported fields
}

RemoteConnection is a local representation of the remote side of a connection. It has limited capabilities compared to LocalConnection. TODO(pb): does this need to be exported?

func NewRemoteConnection

func NewRemoteConnection(from, to *Peer, tcpAddr string, outbound bool, established bool) *RemoteConnection

NewRemoteConnection returns a usable RemoteConnection.

func (*RemoteConnection) BreakTie

BreakTie implements Connection.

func (*RemoteConnection) ErrorLog

func (conn *RemoteConnection) ErrorLog(args ...interface{})

ErrorLog is the same as log. TODO(pb): remove.

func (*RemoteConnection) Established

func (conn *RemoteConnection) Established() bool

Established implements Connection.

func (*RemoteConnection) Local

func (conn *RemoteConnection) Local() *Peer

Local implements Connection.

func (*RemoteConnection) Log

func (conn *RemoteConnection) Log(args ...interface{})

Log implements Connection.

func (*RemoteConnection) Outbound

func (conn *RemoteConnection) Outbound() bool

Outbound implements Connection.

func (*RemoteConnection) Remote

func (conn *RemoteConnection) Remote() *Peer

Remote implements Connection.

func (*RemoteConnection) RemoteTCPAddr

func (conn *RemoteConnection) RemoteTCPAddr() string

RemoteTCPAddr implements Connection.

func (*RemoteConnection) Shutdown

func (conn *RemoteConnection) Shutdown(error)

Shutdown implements Connection.

type Router

type Router struct {
	Config
	Overlay         Overlay
	Ourself         *LocalPeer
	Peers           *Peers
	Routes          *Routes
	ConnectionMaker *ConnectionMaker

	TopologyGossip Gossip
	// contains filtered or unexported fields
}

Router manages communication between this peer and the rest of the mesh. Router implements Gossiper.

func NewRouter

func NewRouter(config Config, name PeerName, nickName string, overlay Overlay) *Router

NewRouter returns a new router. It must be started.

func (*Router) BroadcastTopologyUpdate

func (router *Router) BroadcastTopologyUpdate(update []*Peer)

BroadcastTopologyUpdate is invoked whenever there is a change to the mesh topology, and broadcasts the new set of peers to the mesh.

func (*Router) Gossip

func (router *Router) Gossip() GossipData

Gossip yields the current topology as GossipData.

func (*Router) NewGossip

func (router *Router) NewGossip(channelName string, g Gossiper) Gossip

NewGossip constructs and returns a usable GossipChannel from the router. TODO(pb): rename? TODO(pb): move all of these methods to router.go

func (*Router) OnGossip

func (router *Router) OnGossip(update []byte) (GossipData, error)

OnGossip receives broadcasts of TopologyGossipData. It returns an "improved" version of the received update. See peers.ApplyUpdate.

func (*Router) OnGossipBroadcast

func (router *Router) OnGossipBroadcast(_ PeerName, update []byte) (GossipData, error)

OnGossipBroadcast receives broadcasts of TopologyGossipData. It returns the received update unchanged.

func (*Router) OnGossipUnicast

func (router *Router) OnGossipUnicast(sender PeerName, msg []byte) error

OnGossipUnicast implements Gossiper, but always returns an error, as a router should only receive gossip broadcasts of TopologyGossipData.

func (*Router) SendAllGossip

func (router *Router) SendAllGossip()

SendAllGossip relays all pending gossip data for each channel via random neighbours.

func (*Router) SendAllGossipDown

func (router *Router) SendAllGossipDown(conn Connection)

SendAllGossipDown relays all pending gossip data for each channel via conn.

func (*Router) Start

func (router *Router) Start()

Start listening for TCP connections. This is separate from NewRouter so that gossipers can register before we start forming connections.

func (*Router) Stop

func (router *Router) Stop() error

Stop shuts down the router. In theory.

func (*Router) Trusts

func (router *Router) Trusts(remote *RemoteConnection) bool

Trusts returns true if the remote connection is in a trusted subnet.

func (*Router) UsingPassword

func (router *Router) UsingPassword() bool

UsingPassword returns true if a password is set. Passwords are used to establish encrypted connections.

type Routes

type Routes struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Routes aggregates unicast and broadcast routes for our peer.

func NewRoutes

func NewRoutes(ourself *LocalPeer, peers *Peers) *Routes

NewRoutes returns a usable Routes based on the LocalPeer and existing Peers.

func (*Routes) Broadcast

func (routes *Routes) Broadcast(name PeerName) []PeerName

Broadcast returns the set of peer names that should be notified when we receive a broadcast message originating from the named peer based on established and symmetric connections.

func (*Routes) BroadcastAll

func (routes *Routes) BroadcastAll(name PeerName) []PeerName

BroadcastAll returns the set of peer names that should be notified when we receive a broadcast message originating from the named peer based on all connections.

func (*Routes) EnsureRecalculated

func (routes *Routes) EnsureRecalculated()

EnsureRecalculated waits for any preceding Recalculate requests to finish.

func (*Routes) OnChange

func (routes *Routes) OnChange(callback func())

OnChange appends callback to the functions that will be called whenever the routes are recalculated.

func (*Routes) PeerNames

func (routes *Routes) PeerNames() PeerNameSet

PeerNames returns the peers that are accountd for in the routes.

func (*Routes) RandomNeighbours

func (routes *Routes) RandomNeighbours(except PeerName) []PeerName

RandomNeighbours chooses min(log2(n_peers), n_neighbouring_peers) neighbours, with a random distribution that is topology-sensitive, favouring neighbours at the end of "bottleneck links". We determine the latter based on the unicast routing table. If a neighbour appears as the value more frequently than others - meaning that we reach a higher proportion of peers via that neighbour than other neighbours - then it is chosen with a higher probability.

Note that we choose log2(n_peers) *neighbours*, not peers. Consequently, on sparsely connected peers this function returns a higher proportion of neighbours than elsewhere. In extremis, on peers with fewer than log2(n_peers) neighbours, all neighbours are returned.

func (*Routes) Recalculate

func (routes *Routes) Recalculate()

Recalculate requests recalculation of the routing table. This is async but can effectively be made synchronous with a subsequent call to EnsureRecalculated.

func (*Routes) Unicast

func (routes *Routes) Unicast(name PeerName) (PeerName, bool)

Unicast returns the next hop on the unicast route to the named peer, based on established and symmetric connections.

func (*Routes) UnicastAll

func (routes *Routes) UnicastAll(name PeerName) (PeerName, bool)

UnicastAll returns the next hop on the unicast route to the named peer, based on all connections.

type ShortIDPeers

type ShortIDPeers struct {
	// contains filtered or unexported fields
}

ShortIDPeers is a short reference type used internally within Peers. TODO(pb): unexport

type Status

type Status struct {
	Protocol           string
	ProtocolMinVersion int
	ProtocolMaxVersion int
	Encryption         bool
	PeerDiscovery      bool
	Name               string
	NickName           string
	Port               int
	Peers              []PeerStatus
	UnicastRoutes      []UnicastRouteStatus
	BroadcastRoutes    []BroadcastRouteStatus
	Connections        []LocalConnectionStatus
	Targets            []string
	OverlayDiagnostics interface{}
	TrustedSubnets     []string
}

Status is our current state as a peer, as taken from a router.

func NewStatus

func NewStatus(router *Router) *Status

NewStatus returns a Status object, taken as a snapshot from the router.

type SurrogateGossipData

type SurrogateGossipData struct {
	// contains filtered or unexported fields
}

SurrogateGossipData is a simple in-memory GossipData. TODO(pb): should this be exported?

func NewSurrogateGossipData

func NewSurrogateGossipData(msg []byte) *SurrogateGossipData

NewSurrogateGossipData returns a new SurrogateGossipData.

func (*SurrogateGossipData) Encode

func (d *SurrogateGossipData) Encode() [][]byte

Encode implements GossipData.

func (*SurrogateGossipData) Merge

func (d *SurrogateGossipData) Merge(other GossipData) GossipData

Merge implements GossipData.

type SurrogateGossiper

type SurrogateGossiper struct{}

SurrogateGossiper ignores unicasts and relays broadcasts and gossips. TODO(pb): should this be exported?

func (*SurrogateGossiper) Gossip

func (*SurrogateGossiper) Gossip() GossipData

Gossip implements Gossiper.

func (*SurrogateGossiper) OnGossip

func (*SurrogateGossiper) OnGossip(update []byte) (GossipData, error)

OnGossip implements Gossiper.

func (*SurrogateGossiper) OnGossipBroadcast

func (*SurrogateGossiper) OnGossipBroadcast(_ PeerName, update []byte) (GossipData, error)

OnGossipBroadcast implements Gossiper.

func (*SurrogateGossiper) OnGossipUnicast

func (*SurrogateGossiper) OnGossipUnicast(sender PeerName, msg []byte) error

OnGossipUnicast implements Gossiper.

type TCPCryptoState

type TCPCryptoState struct {
	// contains filtered or unexported fields
}

TCPCryptoState stores session key, nonce, and sequence state.

The lowest 64 bits of the nonce contain the message sequence number. The top most bit indicates the connection polarity at the sender - '1' for outbound; the next indicates protocol type - '1' for TCP. The remaining 126 bits are zero. The polarity is needed so that the two ends of a connection do not use the same nonces; the protocol type so that the TCP connection nonces are distinct from nonces used by overlay connections, if they share the session key. This is a requirement of the NaCl Security Model; see http://nacl.cr.yp.to/box.html.

func NewTCPCryptoState

func NewTCPCryptoState(sessionKey *[32]byte, outbound bool) *TCPCryptoState

NewTCPCryptoState returns a valid TCPCryptoState.

type TCPReceiver

type TCPReceiver interface {
	Receive() ([]byte, error)
}

TCPReceiver describes anything that can receive byte buffers. It abstracts over the different protocol version receivers. TODO(pb): does this need to be exported?

type TCPSender

type TCPSender interface {
	Send([]byte) error
}

TCPSender describes anything that can send byte buffers. It abstracts over the different protocol version senders. TODO(pb): does this need to be exported?

type Target

type Target struct {
	// contains filtered or unexported fields
}

Target contains information about an address where we may find a peer.

type TargetState

type TargetState int

TargetState describes the connection state of a remote target. TODO(pb): does this need to be exported?

const (
	// TargetWaiting means we are waiting to connect there.
	// TODO(pb): does this need to be exported?
	TargetWaiting TargetState = iota

	// TargetAttempting means we are attempting to connect there.
	// TODO(pb): does this need to be exported?
	TargetAttempting

	// TargetConnected means we are connected to there.
	// TODO(pb): does this need to be exported?
	TargetConnected
)

type TokenBucket

type TokenBucket struct {
	// contains filtered or unexported fields
}

TokenBucket acts as a rate-limiter. It is not safe for concurrent use by multiple goroutines. TODO(pb): should this be exported?

func NewTokenBucket

func NewTokenBucket(capacity int64, tokenInterval time.Duration) *TokenBucket

NewTokenBucket returns a bucket containing capacity tokens, refilled at a rate of one token per tokenInterval.

func (*TokenBucket) Wait

func (tb *TokenBucket) Wait()

Wait blocks until there is a token available. Wait is not safe for concurrent use by multiple goroutines.

type TopologyGossipData

type TopologyGossipData struct {
	// contains filtered or unexported fields
}

TopologyGossipData is the set of peers in the mesh network. It is gossiped just like anything else.

func (*TopologyGossipData) Encode

func (d *TopologyGossipData) Encode() [][]byte

Encode implements GossipData.

func (*TopologyGossipData) Merge

func (d *TopologyGossipData) Merge(other GossipData) GossipData

Merge implements GossipData.

type UnicastRouteStatus

type UnicastRouteStatus struct {
	Dest, Via string
}

UnicastRouteStatus is the current state of an established unicast route.

func NewUnicastRouteStatusSlice

func NewUnicastRouteStatusSlice(routes *Routes) []UnicastRouteStatus

NewUnicastRouteStatusSlice takes a snapshot of the unicast routes in routes. TODO(pb): unexport and rename as Make

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL