p2p

package
v0.10.3 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2017 License: Apache-2.0 Imports: 32 Imported by: 0

README

tendermint/tendermint/p2p

CircleCI

tendermint/tendermint/p2p provides an abstraction around peer-to-peer communication.

Peer/MConnection/Channel

Each peer has one MConnection (multiplex connection) instance.

multiplex noun a system or signal involving simultaneous transmission of several messages along a single channel of communication.

Each MConnection handles message transmission on multiple abstract communication Channels. Each channel has a globally unique byte id. The byte id and the relative priorities of each Channel are configured upon initialization of the connection.

There are two methods for sending messages:

func (m MConnection) Send(chID byte, msg interface{}) bool {}
func (m MConnection) TrySend(chID byte, msg interface{}) bool {}

Send(chID, msg) is a blocking call that waits until msg is successfully queued for the channel with the given id byte chID. The message msg is serialized using the tendermint/wire submodule's WriteBinary() reflection routine.

TrySend(chID, msg) is a nonblocking call that returns false if the channel's queue is full.

Send() and TrySend() are also exposed for each Peer.

Switch/Reactor

The Switch handles peer connections and exposes an API to receive incoming messages on Reactors. Each Reactor is responsible for handling incoming messages of one or more Channels. So while sending outgoing messages is typically performed on the peer, incoming messages are received on the reactor.

// Declare a MyReactor reactor that handles messages on MyChannelID.
type MyReactor struct{}

func (reactor MyReactor) GetChannels() []*ChannelDescriptor {
    return []*ChannelDescriptor{ChannelDescriptor{ID:MyChannelID, Priority: 1}}
}

func (reactor MyReactor) Receive(chID byte, peer *Peer, msgBytes []byte) {
    r, n, err := bytes.NewBuffer(msgBytes), new(int64), new(error)
    msgString := ReadString(r, n, err)
    fmt.Println(msgString)
}

// Other Reactor methods omitted for brevity
...

switch := NewSwitch([]Reactor{MyReactor{}})

...

// Send a random message to all outbound connections
for _, peer := range switch.Peers().List() {
    if peer.IsOutbound() {
        peer.Send(MyChannelID, "Here's a random message")
    }
}
PexReactor/AddrBook

A PEXReactor reactor implementation is provided to automate peer discovery.

book := p2p.NewAddrBook(addrBookFilePath)
pexReactor := p2p.NewPEXReactor(book)
...
switch := NewSwitch([]Reactor{pexReactor, myReactor, ...})

Documentation

Overview

Uses nacl's secret_box to encrypt a net.Conn. It is (meant to be) an implementation of the STS protocol. Note we do not (yet) assume that a remote peer's pubkey is known ahead of time, and thus we are technically still vulnerable to MITM. (TODO!) See docs/sts-final.pdf for more info

Index

Constants

View Source
const (
	// FuzzModeDrop is a mode in which we randomly drop reads/writes, connections or sleep
	FuzzModeDrop = iota
	// FuzzModeDelay is a mode in which we randomly sleep
	FuzzModeDelay
)
View Source
const (
	// PexChannel is a channel for PEX messages
	PexChannel = byte(0x00)
)
View Source
const Version = "0.5.0"

Variables

View Source
var (
	ErrSwitchDuplicatePeer = errors.New("Duplicate peer")
)
View Source
var PanicOnAddPeerErr = false

Functions

func AddToIPRangeCounts added in v0.10.0

func AddToIPRangeCounts(counts map[string]int, ip string) map[string]int

TODO Test

func CheckIPRangeCounts added in v0.10.0

func CheckIPRangeCounts(counts map[string]int, limits []int) bool

TODO Test

func Connect2Switches

func Connect2Switches(switches []*Switch, i, j int)

Connect2Switches will connect switches i and j via net.Pipe() Blocks until a conection is established. NOTE: caller ensures i and j are within bounds

func FuzzConn

func FuzzConn(conn net.Conn) net.Conn

FuzzConn creates a new FuzzedConnection. Fuzzing starts immediately.

func FuzzConnAfter

func FuzzConnAfter(conn net.Conn, d time.Duration) net.Conn

FuzzConnAfter creates a new FuzzedConnection. Fuzzing starts when the duration elapses.

func FuzzConnAfterFromConfig

func FuzzConnAfterFromConfig(conn net.Conn, d time.Duration, config *FuzzConnConfig) net.Conn

FuzzConnAfterFromConfig creates a new FuzzedConnection from a config. Fuzzing starts when the duration elapses.

func FuzzConnFromConfig

func FuzzConnFromConfig(conn net.Conn, config *FuzzConnConfig) net.Conn

FuzzConnFromConfig creates a new FuzzedConnection from a config. Fuzzing starts immediately.

func StartSwitches

func StartSwitches(switches []*Switch) error

StartSwitches calls sw.Start() for each given switch. It returns the first encountered error.

Types

type AddrBook

type AddrBook struct {
	cmn.BaseService
	// contains filtered or unexported fields
}

AddrBook - concurrency safe peer address manager.

func NewAddrBook added in v0.10.0

func NewAddrBook(filePath string, routabilityStrict bool) *AddrBook

NewAddrBook creates a new address book. Use Start to begin processing asynchronous address updates.

func (*AddrBook) AddAddress

func (a *AddrBook) AddAddress(addr *NetAddress, src *NetAddress)

NOTE: addr must not be nil

func (*AddrBook) AddOurAddress

func (a *AddrBook) AddOurAddress(addr *NetAddress)

func (*AddrBook) GetSelection added in v0.10.0

func (a *AddrBook) GetSelection() []*NetAddress

GetSelection randomly selects some addresses (old & new). Suitable for peer-exchange protocols.

func (*AddrBook) MarkAttempt added in v0.10.0

func (a *AddrBook) MarkAttempt(addr *NetAddress)

func (*AddrBook) MarkBad added in v0.10.0

func (a *AddrBook) MarkBad(addr *NetAddress)

MarkBad currently just ejects the address. In the future, consider blacklisting.

func (*AddrBook) MarkGood

func (a *AddrBook) MarkGood(addr *NetAddress)

func (*AddrBook) NeedMoreAddrs added in v0.10.0

func (a *AddrBook) NeedMoreAddrs() bool

func (*AddrBook) OnStart added in v0.10.0

func (a *AddrBook) OnStart() error

OnStart implements Service.

func (*AddrBook) OnStop added in v0.10.0

func (a *AddrBook) OnStop()

OnStop implements Service.

func (*AddrBook) OurAddresses added in v0.10.0

func (a *AddrBook) OurAddresses() []*NetAddress

func (*AddrBook) PickAddress added in v0.10.0

func (a *AddrBook) PickAddress(newBias int) *NetAddress

Pick an address to connect to with new/old bias.

func (*AddrBook) RemoveAddress

func (a *AddrBook) RemoveAddress(addr *NetAddress)

RemoveAddress removes the address from the book.

func (*AddrBook) Save

func (a *AddrBook) Save()

Save saves the book.

func (*AddrBook) Size added in v0.10.0

func (a *AddrBook) Size() int

func (*AddrBook) Wait added in v0.10.0

func (a *AddrBook) Wait()

type BaseReactor

type BaseReactor struct {
	cmn.BaseService // Provides Start, Stop, .Quit
	Switch          *Switch
}

func NewBaseReactor

func NewBaseReactor(name string, impl Reactor) *BaseReactor

func (*BaseReactor) AddPeer

func (_ *BaseReactor) AddPeer(peer *Peer)

func (*BaseReactor) GetChannels

func (_ *BaseReactor) GetChannels() []*ChannelDescriptor

func (*BaseReactor) Receive

func (_ *BaseReactor) Receive(chID byte, peer *Peer, msgBytes []byte)

func (*BaseReactor) RemovePeer

func (_ *BaseReactor) RemovePeer(peer *Peer, reason interface{})

func (*BaseReactor) SetSwitch

func (br *BaseReactor) SetSwitch(sw *Switch)

type Channel added in v0.10.0

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

TODO: lowercase. NOTE: not goroutine-safe.

type ChannelDescriptor

type ChannelDescriptor struct {
	ID                  byte
	Priority            int
	SendQueueCapacity   int
	RecvBufferCapacity  int
	RecvMessageCapacity int
}

func (*ChannelDescriptor) FillDefaults added in v0.10.0

func (chDesc *ChannelDescriptor) FillDefaults()

type ChannelStatus added in v0.10.0

type ChannelStatus struct {
	ID                byte
	SendQueueCapacity int
	SendQueueSize     int
	Priority          int
	RecentlySent      int64
}

type ConnectionStatus

type ConnectionStatus struct {
	SendMonitor flow.Status
	RecvMonitor flow.Status
	Channels    []ChannelStatus
}

type DefaultListener added in v0.10.0

type DefaultListener struct {
	cmn.BaseService
	// contains filtered or unexported fields
}

Implements Listener

func (*DefaultListener) Connections added in v0.10.0

func (l *DefaultListener) Connections() <-chan net.Conn

A channel of inbound connections. It gets closed when the listener closes.

func (*DefaultListener) ExternalAddress added in v0.10.0

func (l *DefaultListener) ExternalAddress() *NetAddress

func (*DefaultListener) InternalAddress added in v0.10.0

func (l *DefaultListener) InternalAddress() *NetAddress

func (*DefaultListener) NetListener added in v0.10.0

func (l *DefaultListener) NetListener() net.Listener

NOTE: The returned listener is already Accept()'ing. So it's not suitable to pass into http.Serve().

func (*DefaultListener) OnStart added in v0.10.0

func (l *DefaultListener) OnStart() error

func (*DefaultListener) OnStop added in v0.10.0

func (l *DefaultListener) OnStop()

func (*DefaultListener) String added in v0.10.0

func (l *DefaultListener) String() string

type FuzzConnConfig added in v0.10.0

type FuzzConnConfig struct {
	Mode         int
	MaxDelay     time.Duration
	ProbDropRW   float64
	ProbDropConn float64
	ProbSleep    float64
}

FuzzConnConfig is a FuzzedConnection configuration.

func DefaultFuzzConnConfig added in v0.10.0

func DefaultFuzzConnConfig() *FuzzConnConfig

DefaultFuzzConnConfig returns the default config.

type FuzzedConnection

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

FuzzedConnection wraps any net.Conn and depending on the mode either delays reads/writes or randomly drops reads/writes/connections.

func (*FuzzedConnection) Close

func (fc *FuzzedConnection) Close() error

Close implements net.Conn.

func (*FuzzedConnection) Config

func (fc *FuzzedConnection) Config() *FuzzConnConfig

Config returns the connection's config.

func (*FuzzedConnection) LocalAddr

func (fc *FuzzedConnection) LocalAddr() net.Addr

LocalAddr implements net.Conn.

func (*FuzzedConnection) Read

func (fc *FuzzedConnection) Read(data []byte) (n int, err error)

Read implements net.Conn.

func (*FuzzedConnection) RemoteAddr

func (fc *FuzzedConnection) RemoteAddr() net.Addr

RemoteAddr implements net.Conn.

func (*FuzzedConnection) SetDeadline

func (fc *FuzzedConnection) SetDeadline(t time.Time) error

SetDeadline implements net.Conn.

func (*FuzzedConnection) SetReadDeadline

func (fc *FuzzedConnection) SetReadDeadline(t time.Time) error

SetReadDeadline implements net.Conn.

func (*FuzzedConnection) SetWriteDeadline

func (fc *FuzzedConnection) SetWriteDeadline(t time.Time) error

SetWriteDeadline implements net.Conn.

func (*FuzzedConnection) Write

func (fc *FuzzedConnection) Write(data []byte) (n int, err error)

Write implements net.Conn.

type IPeerSet

type IPeerSet interface {
	Has(key string) bool
	Get(key string) *Peer
	List() []*Peer
	Size() int
}

IPeerSet has a (immutable) subset of the methods of PeerSet.

type Listener added in v0.10.0

type Listener interface {
	Connections() <-chan net.Conn
	InternalAddress() *NetAddress
	ExternalAddress() *NetAddress
	String() string
	Stop() bool
}

func NewDefaultListener added in v0.10.0

func NewDefaultListener(protocol string, lAddr string, skipUPNP bool, logger log.Logger) Listener

skipUPNP: If true, does not try getUPNPExternalAddress()

type MConnConfig

type MConnConfig struct {
	SendRate int64 `mapstructure:"send_rate"`
	RecvRate int64 `mapstructure:"recv_rate"`
	// contains filtered or unexported fields
}

MConnConfig is a MConnection configuration.

func DefaultMConnConfig added in v0.10.0

func DefaultMConnConfig() *MConnConfig

DefaultMConnConfig returns the default config.

type MConnection added in v0.10.0

type MConnection struct {
	cmn.BaseService

	LocalAddress  *NetAddress
	RemoteAddress *NetAddress
	// contains filtered or unexported fields
}

Each peer has one `MConnection` (multiplex connection) instance.

__multiplex__ *noun* a system or signal involving simultaneous transmission of several messages along a single channel of communication.

Each `MConnection` handles message transmission on multiple abstract communication `Channel`s. Each channel has a globally unique byte id. The byte id and the relative priorities of each `Channel` are configured upon initialization of the connection.

There are two methods for sending messages:

func (m MConnection) Send(chID byte, msg interface{}) bool {}
func (m MConnection) TrySend(chID byte, msg interface{}) bool {}

`Send(chID, msg)` is a blocking call that waits until `msg` is successfully queued for the channel with the given id byte `chID`, or until the request times out. The message `msg` is serialized using the `tendermint/wire` submodule's `WriteBinary()` reflection routine.

`TrySend(chID, msg)` is a nonblocking call that returns false if the channel's queue is full.

Inbound message bytes are handled with an onReceive callback function.

func NewMConnection added in v0.10.0

func NewMConnection(conn net.Conn, chDescs []*ChannelDescriptor, onReceive receiveCbFunc, onError errorCbFunc) *MConnection

NewMConnection wraps net.Conn and creates multiplex connection

func NewMConnectionWithConfig added in v0.10.0

func NewMConnectionWithConfig(conn net.Conn, chDescs []*ChannelDescriptor, onReceive receiveCbFunc, onError errorCbFunc, config *MConnConfig) *MConnection

NewMConnectionWithConfig wraps net.Conn and creates multiplex connection with a config

func (*MConnection) CanSend added in v0.10.0

func (c *MConnection) CanSend(chID byte) bool

CanSend returns true if you can send more data onto the chID, false otherwise. Use only as a heuristic.

func (*MConnection) OnStart added in v0.10.0

func (c *MConnection) OnStart() error

OnStart implements BaseService

func (*MConnection) OnStop added in v0.10.0

func (c *MConnection) OnStop()

OnStop implements BaseService

func (*MConnection) Send added in v0.10.0

func (c *MConnection) Send(chID byte, msg interface{}) bool

Queues a message to be sent to channel.

func (*MConnection) Status added in v0.10.0

func (c *MConnection) Status() ConnectionStatus

func (*MConnection) String added in v0.10.0

func (c *MConnection) String() string

func (*MConnection) TrySend added in v0.10.0

func (c *MConnection) TrySend(chID byte, msg interface{}) bool

Queues a message to be sent to channel. Nonblocking, returns true if successful.

type NetAddress

type NetAddress struct {
	IP   net.IP
	Port uint16
	// contains filtered or unexported fields
}

NetAddress defines information about a peer on the network including its IP address, and port.

func NewNetAddress

func NewNetAddress(addr net.Addr) *NetAddress

NewNetAddress returns a new NetAddress using the provided TCP address. When testing, other net.Addr (except TCP) will result in using 0.0.0.0:0. When normal run, other net.Addr (except TCP) will panic. TODO: socks proxies?

func NewNetAddressIPPort

func NewNetAddressIPPort(ip net.IP, port uint16) *NetAddress

NewNetAddressIPPort returns a new NetAddress using the provided IP and port number.

func NewNetAddressString

func NewNetAddressString(addr string) (*NetAddress, error)

NewNetAddressString returns a new NetAddress using the provided address in the form of "IP:Port". Also resolves the host if host is not an IP.

func NewNetAddressStrings

func NewNetAddressStrings(addrs []string) ([]*NetAddress, error)

NewNetAddressStrings returns an array of NetAddress'es build using the provided strings.

func (*NetAddress) Dial

func (na *NetAddress) Dial() (net.Conn, error)

Dial calls net.Dial on the address.

func (*NetAddress) DialTimeout

func (na *NetAddress) DialTimeout(timeout time.Duration) (net.Conn, error)

DialTimeout calls net.DialTimeout on the address.

func (*NetAddress) Equals

func (na *NetAddress) Equals(other interface{}) bool

Equals reports whether na and other are the same addresses.

func (*NetAddress) Less added in v0.10.0

func (na *NetAddress) Less(other interface{}) bool

func (*NetAddress) Local

func (na *NetAddress) Local() bool

Local returns true if it is a local address.

func (*NetAddress) RFC1918

func (na *NetAddress) RFC1918() bool

func (*NetAddress) RFC3849

func (na *NetAddress) RFC3849() bool

func (*NetAddress) RFC3927

func (na *NetAddress) RFC3927() bool

func (*NetAddress) RFC3964

func (na *NetAddress) RFC3964() bool

func (*NetAddress) RFC4193

func (na *NetAddress) RFC4193() bool

func (*NetAddress) RFC4380

func (na *NetAddress) RFC4380() bool

func (*NetAddress) RFC4843

func (na *NetAddress) RFC4843() bool

func (*NetAddress) RFC4862

func (na *NetAddress) RFC4862() bool

func (*NetAddress) RFC6052

func (na *NetAddress) RFC6052() bool

func (*NetAddress) RFC6145

func (na *NetAddress) RFC6145() bool

func (*NetAddress) ReachabilityTo

func (na *NetAddress) ReachabilityTo(o *NetAddress) int

ReachabilityTo checks whenever o can be reached from na.

func (*NetAddress) Routable

func (na *NetAddress) Routable() bool

Routable returns true if the address is routable.

func (*NetAddress) String

func (na *NetAddress) String() string

String representation.

func (*NetAddress) Valid

func (na *NetAddress) Valid() bool

For IPv4 these are either a 0 or all bits set address. For IPv6 a zero address or one that matches the RFC3849 documentation address format.

type NodeInfo

type NodeInfo struct {
	PubKey     crypto.PubKeyEd25519 `json:"pub_key"`
	Moniker    string               `json:"moniker"`
	Network    string               `json:"network"`
	RemoteAddr string               `json:"remote_addr"`
	ListenAddr string               `json:"listen_addr"`
	Version    string               `json:"version"` // major.minor.revision
	Other      []string             `json:"other"`   // other application specific data
}

func (*NodeInfo) CompatibleWith added in v0.10.0

func (info *NodeInfo) CompatibleWith(other *NodeInfo) error

CONTRACT: two nodes are compatible if the major/minor versions match and network match

func (*NodeInfo) ListenHost added in v0.10.0

func (info *NodeInfo) ListenHost() string

func (*NodeInfo) ListenPort added in v0.10.0

func (info *NodeInfo) ListenPort() int

func (NodeInfo) String added in v0.10.0

func (info NodeInfo) String() string

type PEXReactor added in v0.10.0

type PEXReactor struct {
	BaseReactor
	// contains filtered or unexported fields
}

PEXReactor handles PEX (peer exchange) and ensures that an adequate number of peers are connected to the switch.

It uses `AddrBook` (address book) to store `NetAddress`es of the peers.

## Preventing abuse

For now, it just limits the number of messages from one peer to `defaultMaxMsgCountByPeer` messages per `msgCountByPeerFlushInterval` (1000 msg/hour).

NOTE [2017-01-17]:

Limiting is fine for now. Maybe down the road we want to keep track of the
quality of peer messages so if peerA keeps telling us about peers we can't
connect to then maybe we should care less about peerA. But I don't think
that kind of complexity is priority right now.

func NewPEXReactor added in v0.10.0

func NewPEXReactor(b *AddrBook) *PEXReactor

NewPEXReactor creates new PEX reactor.

func (*PEXReactor) AddPeer added in v0.10.0

func (r *PEXReactor) AddPeer(p *Peer)

AddPeer implements Reactor by adding peer to the address book (if inbound) or by requesting more addresses (if outbound).

func (*PEXReactor) GetChannels added in v0.10.0

func (r *PEXReactor) GetChannels() []*ChannelDescriptor

GetChannels implements Reactor

func (*PEXReactor) IncrementMsgCountForPeer added in v0.10.0

func (r *PEXReactor) IncrementMsgCountForPeer(addr string)

Increment or initialize the msg count for the peer in the CMap

func (*PEXReactor) OnStart added in v0.10.0

func (r *PEXReactor) OnStart() error

OnStart implements BaseService

func (*PEXReactor) OnStop added in v0.10.0

func (r *PEXReactor) OnStop()

OnStop implements BaseService

func (*PEXReactor) ReachedMaxMsgCountForPeer added in v0.10.0

func (r *PEXReactor) ReachedMaxMsgCountForPeer(addr string) bool

ReachedMaxMsgCountForPeer returns true if we received too many messages from peer with address `addr`. NOTE: assumes the value in the CMap is non-nil

func (*PEXReactor) Receive added in v0.10.0

func (r *PEXReactor) Receive(chID byte, src *Peer, msgBytes []byte)

Receive implements Reactor by handling incoming PEX messages.

func (*PEXReactor) RemovePeer added in v0.10.0

func (r *PEXReactor) RemovePeer(p *Peer, reason interface{})

RemovePeer implements Reactor.

func (*PEXReactor) RequestPEX added in v0.10.0

func (r *PEXReactor) RequestPEX(p *Peer)

RequestPEX asks peer for more addresses.

func (*PEXReactor) SendAddrs added in v0.10.0

func (r *PEXReactor) SendAddrs(p *Peer, addrs []*NetAddress)

SendAddrs sends addrs to the peer.

func (*PEXReactor) SetEnsurePeersPeriod added in v0.10.0

func (r *PEXReactor) SetEnsurePeersPeriod(d time.Duration)

SetEnsurePeersPeriod sets period to ensure peers connected.

func (*PEXReactor) SetMaxMsgCountByPeer added in v0.10.0

func (r *PEXReactor) SetMaxMsgCountByPeer(v uint16)

SetMaxMsgCountByPeer sets maximum messages one peer can send to us during 'msgCountByPeerFlushInterval'.

type Peer

type Peer struct {
	cmn.BaseService

	*NodeInfo
	Key  string
	Data *cmn.CMap // User data.
	// contains filtered or unexported fields
}

Peer could be marked as persistent, in which case you can use Redial function to reconnect. Note that inbound peers can't be made persistent. They should be made persistent on the other end.

Before using a peer, you will need to perform a handshake on connection.

func (*Peer) Addr added in v0.10.0

func (p *Peer) Addr() net.Addr

Addr returns peer's remote network address.

func (*Peer) CanSend added in v0.10.0

func (p *Peer) CanSend(chID byte) bool

CanSend returns true if the send queue is not full, false otherwise.

func (*Peer) CloseConn

func (p *Peer) CloseConn()

CloseConn should be used when the peer was created, but never started.

func (*Peer) Connection added in v0.10.0

func (p *Peer) Connection() *MConnection

Connection returns underlying MConnection.

func (*Peer) Equals added in v0.10.0

func (p *Peer) Equals(other *Peer) bool

Equals reports whenever 2 peers are actually represent the same node.

func (*Peer) Get

func (p *Peer) Get(key string) interface{}

Get the data for a given key.

func (*Peer) HandshakeTimeout added in v0.10.0

func (p *Peer) HandshakeTimeout(ourNodeInfo *NodeInfo, timeout time.Duration) error

HandshakeTimeout performs a handshake between a given node and the peer. NOTE: blocking

func (*Peer) IsOutbound

func (p *Peer) IsOutbound() bool

IsOutbound returns true if the connection is outbound, false otherwise.

func (*Peer) IsPersistent

func (p *Peer) IsPersistent() bool

IsPersistent returns true if the peer is persitent, false otherwise.

func (*Peer) OnStart added in v0.10.0

func (p *Peer) OnStart() error

OnStart implements BaseService.

func (*Peer) OnStop added in v0.10.0

func (p *Peer) OnStop()

OnStop implements BaseService.

func (*Peer) PubKey added in v0.10.0

func (p *Peer) PubKey() crypto.PubKeyEd25519

PubKey returns peer's public key.

func (*Peer) Send

func (p *Peer) Send(chID byte, msg interface{}) bool

Send msg to the channel identified by chID byte. Returns false if the send queue is full after timeout, specified by MConnection.

func (*Peer) String added in v0.10.0

func (p *Peer) String() string

String representation.

func (*Peer) TrySend

func (p *Peer) TrySend(chID byte, msg interface{}) bool

TrySend msg to the channel identified by chID byte. Immediately returns false if the send queue is full.

func (*Peer) WriteTo added in v0.10.0

func (p *Peer) WriteTo(w io.Writer) (n int64, err error)

WriteTo writes the peer's public key to w.

type PeerConfig added in v0.10.0

type PeerConfig struct {
	AuthEnc bool `mapstructure:"auth_enc"` // authenticated encryption

	// times are in seconds
	HandshakeTimeout time.Duration `mapstructure:"handshake_timeout"`
	DialTimeout      time.Duration `mapstructure:"dial_timeout"`

	MConfig *MConnConfig `mapstructure:"connection"`

	Fuzz       bool            `mapstructure:"fuzz"` // fuzz connection (for testing)
	FuzzConfig *FuzzConnConfig `mapstructure:"fuzz_config"`
}

PeerConfig is a Peer configuration.

func DefaultPeerConfig added in v0.10.0

func DefaultPeerConfig() *PeerConfig

DefaultPeerConfig returns the default config.

type PeerSet

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

PeerSet is a special structure for keeping a table of peers. Iteration over the peers is super fast and thread-safe.

func NewPeerSet

func NewPeerSet() *PeerSet

func (*PeerSet) Add

func (ps *PeerSet) Add(peer *Peer) error

Returns false if peer with key (PubKeyEd25519) is already set

func (*PeerSet) Get

func (ps *PeerSet) Get(peerKey string) *Peer

func (*PeerSet) Has

func (ps *PeerSet) Has(peerKey string) bool

func (*PeerSet) List

func (ps *PeerSet) List() []*Peer

threadsafe list of peers.

func (*PeerSet) Remove

func (ps *PeerSet) Remove(peer *Peer)

func (*PeerSet) Size

func (ps *PeerSet) Size() int

type PexMessage added in v0.10.0

type PexMessage interface{}

PexMessage is a primary type for PEX messages. Underneath, it could contain either pexRequestMessage, or pexAddrsMessage messages.

func DecodeMessage added in v0.10.0

func DecodeMessage(bz []byte) (msgType byte, msg PexMessage, err error)

DecodeMessage implements interface registered above.

type Reactor

type Reactor interface {
	cmn.Service // Start, Stop

	SetSwitch(*Switch)
	GetChannels() []*ChannelDescriptor
	AddPeer(peer *Peer)
	RemovePeer(peer *Peer, reason interface{})
	Receive(chID byte, peer *Peer, msgBytes []byte)
}

type SecretConnection added in v0.10.0

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

Implements net.Conn

func MakeSecretConnection added in v0.10.0

func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKeyEd25519) (*SecretConnection, error)

Performs handshake and returns a new authenticated SecretConnection. Returns nil if error in handshake. Caller should call conn.Close() See docs/sts-final.pdf for more information.

func (*SecretConnection) Close added in v0.10.0

func (sc *SecretConnection) Close() error

Implements net.Conn

func (*SecretConnection) LocalAddr added in v0.10.0

func (sc *SecretConnection) LocalAddr() net.Addr

func (*SecretConnection) Read added in v0.10.0

func (sc *SecretConnection) Read(data []byte) (n int, err error)

CONTRACT: data smaller than dataMaxSize is read atomically.

func (*SecretConnection) RemoteAddr added in v0.10.0

func (sc *SecretConnection) RemoteAddr() net.Addr

func (*SecretConnection) RemotePubKey added in v0.10.0

func (sc *SecretConnection) RemotePubKey() crypto.PubKeyEd25519

Returns authenticated remote pubkey

func (*SecretConnection) SetDeadline added in v0.10.0

func (sc *SecretConnection) SetDeadline(t time.Time) error

func (*SecretConnection) SetReadDeadline added in v0.10.0

func (sc *SecretConnection) SetReadDeadline(t time.Time) error

func (*SecretConnection) SetWriteDeadline added in v0.10.0

func (sc *SecretConnection) SetWriteDeadline(t time.Time) error

func (*SecretConnection) Write added in v0.10.0

func (sc *SecretConnection) Write(data []byte) (n int, err error)

Writes encrypted frames of `sealedFrameSize` CONTRACT: data smaller than dataMaxSize is read atomically.

type Switch

type Switch struct {
	cmn.BaseService
	// contains filtered or unexported fields
}

The `Switch` handles peer connections and exposes an API to receive incoming messages on `Reactors`. Each `Reactor` is responsible for handling incoming messages of one or more `Channels`. So while sending outgoing messages is typically performed on the peer, incoming messages are received on the reactor.

func MakeConnectedSwitches

func MakeConnectedSwitches(cfg *cfg.P2PConfig, n int, initSwitch func(int, *Switch) *Switch, connect func([]*Switch, int, int)) []*Switch

MakeConnectedSwitches returns n switches, connected according to the connect func. If connect==Connect2Switches, the switches will be fully connected. initSwitch defines how the ith switch should be initialized (ie. with what reactors). NOTE: panics if any switch fails to start.

func NewSwitch

func NewSwitch(config *cfg.P2PConfig) *Switch

func (*Switch) AddListener added in v0.10.0

func (sw *Switch) AddListener(l Listener)

AddListener adds the given listener to the switch for listening to incoming peer connections. NOTE: Not goroutine safe.

func (*Switch) AddPeer added in v0.10.0

func (sw *Switch) AddPeer(peer *Peer) error

AddPeer checks the given peer's validity, performs a handshake, and adds the peer to the switch and to all registered reactors. NOTE: This performs a blocking handshake before the peer is added. CONTRACT: If error is returned, peer is nil, and conn is immediately closed.

func (*Switch) AddReactor

func (sw *Switch) AddReactor(name string, reactor Reactor) Reactor

AddReactor adds the given reactor to the switch. NOTE: Not goroutine safe.

func (*Switch) Broadcast

func (sw *Switch) Broadcast(chID byte, msg interface{}) chan bool

Broadcast runs a go routine for each attempted send, which will block trying to send for defaultSendTimeoutSeconds. Returns a channel which receives success values for each attempted send (false if times out) NOTE: Broadcast uses goroutines, so order of broadcast may not be preserved. TODO: Something more intelligent.

func (*Switch) DialPeerWithAddress

func (sw *Switch) DialPeerWithAddress(addr *NetAddress, persistent bool) (*Peer, error)

DialPeerWithAddress dials the given peer and runs sw.AddPeer if it connects successfully. If `persistent == true`, the switch will always try to reconnect to this peer if the connection ever fails.

func (*Switch) DialSeeds added in v0.10.0

func (sw *Switch) DialSeeds(addrBook *AddrBook, seeds []string) error

DialSeeds dials a list of seeds asynchronously in random order

func (*Switch) FilterConnByAddr added in v0.10.0

func (sw *Switch) FilterConnByAddr(addr net.Addr) error

FilterConnByAddr returns an error if connecting to the given address is forbidden.

func (*Switch) FilterConnByPubKey added in v0.10.0

func (sw *Switch) FilterConnByPubKey(pubkey crypto.PubKeyEd25519) error

FilterConnByPubKey returns an error if connecting to the given public key is forbidden.

func (*Switch) IsDialing added in v0.10.0

func (sw *Switch) IsDialing(addr *NetAddress) bool

IsDialing returns true if the switch is currently dialing the given address.

func (*Switch) IsListening added in v0.10.0

func (sw *Switch) IsListening() bool

IsListening returns true if the switch has at least one listener. NOTE: Not goroutine safe.

func (*Switch) Listeners added in v0.10.0

func (sw *Switch) Listeners() []Listener

Listeners returns the list of listeners the switch listens on. NOTE: Not goroutine safe.

func (*Switch) NodeInfo

func (sw *Switch) NodeInfo() *NodeInfo

NodeInfo returns the switch's NodeInfo. NOTE: Not goroutine safe.

func (*Switch) NumPeers

func (sw *Switch) NumPeers() (outbound, inbound, dialing int)

NumPeers returns the count of outbound/inbound and outbound-dialing peers.

func (*Switch) OnStart

func (sw *Switch) OnStart() error

OnStart implements BaseService. It starts all the reactors, peers, and listeners.

func (*Switch) OnStop

func (sw *Switch) OnStop()

OnStop implements BaseService. It stops all listeners, peers, and reactors.

func (*Switch) Peers

func (sw *Switch) Peers() IPeerSet

Peers returns the set of peers the switch is connected to.

func (*Switch) Reactor

func (sw *Switch) Reactor(name string) Reactor

Reactor returns the reactor with the given name. NOTE: Not goroutine safe.

func (*Switch) Reactors

func (sw *Switch) Reactors() map[string]Reactor

Reactors returns a map of reactors registered on the switch. NOTE: Not goroutine safe.

func (*Switch) SetAddrFilter added in v0.10.0

func (sw *Switch) SetAddrFilter(f func(net.Addr) error)

SetAddrFilter sets the function for filtering connections by address.

func (*Switch) SetNodeInfo

func (sw *Switch) SetNodeInfo(nodeInfo *NodeInfo)

SetNodeInfo sets the switch's NodeInfo for checking compatibility and handshaking with other nodes. NOTE: Not goroutine safe.

func (*Switch) SetNodePrivKey added in v0.10.0

func (sw *Switch) SetNodePrivKey(nodePrivKey crypto.PrivKeyEd25519)

SetNodePrivKey sets the switche's private key for authenticated encryption. NOTE: Overwrites sw.nodeInfo.PubKey. NOTE: Not goroutine safe.

func (*Switch) SetPubKeyFilter added in v0.10.0

func (sw *Switch) SetPubKeyFilter(f func(crypto.PubKeyEd25519) error)

SetPubKeyFilter sets the function for filtering connections by public key.

func (*Switch) StopPeerForError

func (sw *Switch) StopPeerForError(peer *Peer, reason interface{})

StopPeerForError disconnects from a peer due to external error. If the peer is persistent, it will attempt to reconnect. TODO: make record depending on reason.

func (*Switch) StopPeerGracefully

func (sw *Switch) StopPeerGracefully(peer *Peer)

StopPeerGracefully disconnects from a peer gracefully. TODO: handle graceful disconnects.

type SwitchEventDonePeer added in v0.10.0

type SwitchEventDonePeer struct {
	Peer  *Peer
	Error interface{}
}

type SwitchEventNewPeer added in v0.10.0

type SwitchEventNewPeer struct {
	Peer *Peer
}

Directories

Path Synopsis
Taken from taipei-torrent Just enough UPnP to be able to forward ports
Taken from taipei-torrent Just enough UPnP to be able to forward ports

Jump to

Keyboard shortcuts

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