router

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Dec 30, 2014 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Let peer names be MACs...

MACs need to be unique across our network, or bad things will happen anyway. So they make pretty good candidates for peer names. And doing so is pretty efficient both computationally and network overhead wise.

Note that we do not mandate *what* MAC should be used as the peer name. In particular it doesn't actually have to be the MAC of, say, the network interface the peer is sniffing on.

Index

Constants

View Source
const (
	CSendTCP          = iota
	CSetEstablished   = iota
	CSetRemoteUDPAddr = iota
	CShutdown         = iota
)
View Source
const (
	InitialInterval = 5 * time.Second
	MaxInterval     = 10 * time.Minute
)
View Source
const (
	CMInitiate   = iota
	CMTerminated = iota
	CMRefresh    = iota
	CMStatus     = iota
)
View Source
const (
	Protocol           = "weave"
	ProtocolVersion    = 8
	EthernetOverhead   = 14
	UDPOverhead        = 28 // 20 bytes for IPv4, 8 bytes for UDP
	Port               = 6783
	HttpPort           = Port + 1
	DefaultPMTU        = 65535
	MaxUDPPacketSize   = 65536
	ChannelSize        = 16
	UDPNonceSendAt     = 8192
	FragTestSize       = 60001
	PMTUDiscoverySize  = 60000
	FastHeartbeat      = 500 * time.Millisecond
	SlowHeartbeat      = 10 * time.Second
	FetchAllInterval   = 30 * time.Second
	FragTestInterval   = 5 * time.Minute
	ReadTimeout        = 2 * FetchAllInterval
	PMTUVerifyAttempts = 8
	PMTUVerifyTimeout  = 10 * time.Millisecond // gets doubled with every attempt
	MaxDuration        = time.Duration(math.MaxInt64)
)
View Source
const (
	ProtocolConnectionEstablished  = iota
	ProtocolFragmentationReceived  = iota
	ProtocolStartFragmentationTest = iota
	ProtocolNonce                  = iota
	ProtocolFetchAll               = iota
	ProtocolUpdate                 = iota
	ProtocolPMTUVerified           = iota
)
View Source
const (
	PAddConnection         = iota
	PBroadcastTCP          = iota
	PDeleteConnection      = iota
	PConnectionEstablished = iota
)
View Source
const (
	PeerNameFlavour = "mac"
	NameSize        = 6
	UnknownPeerName = PeerName(0)
)
View Source
const (
	RRecalculate = iota
)

Variables

View Source
var (
	FragTest                           = make([]byte, FragTestSize)
	PMTUDiscovery                      = make([]byte, PMTUDiscoverySize)
	ProtocolConnectionEstablishedByte  = []byte{ProtocolConnectionEstablished}
	ProtocolFragmentationReceivedByte  = []byte{ProtocolFragmentationReceived}
	ProtocolStartFragmentationTestByte = []byte{ProtocolStartFragmentationTest}
	ProtocolNonceByte                  = []byte{ProtocolNonce}
	ProtocolFetchAllByte               = []byte{ProtocolFetchAll}
	ProtocolUpdateByte                 = []byte{ProtocolUpdate}
	ProtocolPMTUVerifiedByte           = []byte{ProtocolPMTUVerified}
)

Functions

func Concat

func Concat(elems ...[]byte) []byte

func DecodeNonce

func DecodeNonce(msg []byte) (bool, *[24]byte)

func DecryptPrefixNonce

func DecryptPrefixNonce(ciphertxt []byte, secret *[32]byte) ([]byte, bool)

func EncodeNonce

func EncodeNonce(df bool) (*[24]byte, []byte, error)

func EncodePeers

func EncodePeers(peers ...*Peer) []byte

func EncryptPrefixNonce

func EncryptPrefixNonce(plaintxt []byte, nonce *[24]byte, secret *[32]byte) []byte

func FormSessionKey

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

func GenerateKeyPair

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

func GenerateRandomNonce

func GenerateRandomNonce() ([24]byte, error)

func NewLocalConnection

func NewLocalConnection(connRemote *RemoteConnection, acceptNewPeer bool, tcpConn *net.TCPConn, udpAddr *net.UDPAddr, router *Router)

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

func NormalisePeerAddr

func NormalisePeerAddr(peerAddr string) string

given an address like '1.2.3.4:567', return the address if it has a port, otherwise return the address with weave's standard port number

func PosixError

func PosixError(err error) error

func SetNonceLow15Bits

func SetNonceLow15Bits(nonce *[24]byte, offset uint16)

Types

type Connection

type Connection interface {
	Local() *Peer
	Remote() *Peer
	RemoteTCPAddr() string
	Established() bool
	Shutdown()
}

type ConnectionInteraction

type ConnectionInteraction struct {
	Interaction
	// contains filtered or unexported fields
}

type ConnectionMaker

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

func StartConnectionMaker

func StartConnectionMaker(ourself *LocalPeer, peers *Peers) *ConnectionMaker

func (*ConnectionMaker) ConnectionTerminated

func (cm *ConnectionMaker) ConnectionTerminated(address string)

func (*ConnectionMaker) InitiateConnection

func (cm *ConnectionMaker) InitiateConnection(address string)

func (*ConnectionMaker) Refresh

func (cm *ConnectionMaker) Refresh()

func (*ConnectionMaker) String

func (cm *ConnectionMaker) String() string

type ConnectionMakerInteraction

type ConnectionMakerInteraction struct {
	Interaction
	// contains filtered or unexported fields
}

type Decryptor

type Decryptor interface {
	IterateFrames(FrameConsumer, *UDPPacket) error
	ReceiveNonce([]byte)
	Shutdown()
}

type EncryptedTCPMessage

type EncryptedTCPMessage struct {
	Number int
	Body   []byte
}

type EncryptedTCPReceiver

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

func NewEncryptedTCPReceiver

func NewEncryptedTCPReceiver(conn *LocalConnection) *EncryptedTCPReceiver

func (*EncryptedTCPReceiver) Decode

func (receiver *EncryptedTCPReceiver) Decode(msg []byte) ([]byte, error)

type EncryptedTCPSender

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

func NewEncryptedTCPSender

func NewEncryptedTCPSender(encoder *gob.Encoder, conn *LocalConnection) *EncryptedTCPSender

func (*EncryptedTCPSender) Send

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

type Encryptor

type Encryptor interface {
	FrameOverhead() int
	PacketOverhead() int
	IsEmpty() bool
	Bytes() []byte
	AppendFrame(*ForwardedFrame)
	TotalLen() int
}

type EthernetDecoder

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

func NewEthernetDecoder

func NewEthernetDecoder() *EthernetDecoder

func (*EthernetDecoder) CheckFrameTooBig

func (dec *EthernetDecoder) CheckFrameTooBig(err error, sendFrame func([]byte) error) error

func (*EthernetDecoder) DecodeLayers

func (dec *EthernetDecoder) DecodeLayers(data []byte) error

func (*EthernetDecoder) DropFrame

func (dec *EthernetDecoder) DropFrame() bool

func (*EthernetDecoder) IsPMTUVerify

func (dec *EthernetDecoder) IsPMTUVerify() bool

type ForwardedFrame

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

type Forwarder

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

func NewForwarder

func NewForwarder(conn *LocalConnection, ch <-chan *ForwardedFrame, stop <-chan interface{}, verifyPMTU <-chan int, enc Encryptor, udpSender UDPSender, pmtu int) *Forwarder

func (*Forwarder) Run

func (fwd *Forwarder) Run()

type FrameConsumer

type FrameConsumer func(*LocalConnection, *net.UDPAddr, []byte, []byte, uint16, []byte) error

type FrameTooBigError

type FrameTooBigError struct {
	EPMTU int // effective pmtu, i.e. what we tell packet senders
}

func (FrameTooBigError) Error

func (ftbe FrameTooBigError) Error() string

type Interaction

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

type ListOfPeers

type ListOfPeers []*Peer

func (ListOfPeers) Len

func (lop ListOfPeers) Len() int

func (ListOfPeers) Less

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

func (ListOfPeers) Swap

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

type LocalAddress

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

type LocalConnection

type LocalConnection struct {
	sync.RWMutex
	RemoteConnection
	TCPConn *net.TCPConn

	SessionKey *[32]byte

	Decryptor Decryptor
	Router    *Router
	UID       uint64
	// contains filtered or unexported fields
}

func (*LocalConnection) CheckFatal

func (conn *LocalConnection) CheckFatal(err error) error

Called by the forwarder processes in a few places (including crypto), but the connection TCP receiver process, and by the local peer actor process. Do not call this from the connection's actor process itself.

func (*LocalConnection) Established

func (conn *LocalConnection) Established() bool

func (*LocalConnection) Forward

func (conn *LocalConnection) Forward(df bool, frame *ForwardedFrame, dec *EthernetDecoder) error

Called from peer.Relay[Broadcast] which is itself invoked from router (both UDP listener process and sniffer process). Also called from connection's heartbeat process, and from the connection's TCP receiver process.

func (*LocalConnection) RemoteUDPAddr

func (conn *LocalConnection) RemoteUDPAddr() *net.UDPAddr

Read by the forwarder processes when in the UDP senders

func (*LocalConnection) SendTCP

func (conn *LocalConnection) SendTCP(msg []byte)

Async

func (*LocalConnection) SetEstablished

func (conn *LocalConnection) SetEstablished()

Async

func (*LocalConnection) SetRemoteUDPAddr

func (conn *LocalConnection) SetRemoteUDPAddr(remoteUDPAddr *net.UDPAddr)

Async

func (*LocalConnection) Shutdown

func (conn *LocalConnection) Shutdown()

Async

type LocalPeer

type LocalPeer struct {
	*Peer
	Router *Router
	// contains filtered or unexported fields
}

func StartLocalPeer

func StartLocalPeer(name PeerName, router *Router) *LocalPeer

func (*LocalPeer) AddConnection

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

Async: rely on the peer to shut us down if we shouldn't be adding ourselves, so therefore this can be async

func (*LocalPeer) Broadcast

func (peer *LocalPeer) Broadcast(df bool, frame []byte, dec *EthernetDecoder) error

func (*LocalPeer) BroadcastTCP

func (peer *LocalPeer) BroadcastTCP(msg []byte)

Async.

func (*LocalPeer) ConnectionEstablished

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

Async.

func (*LocalPeer) CreateConnection

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

func (*LocalPeer) DeleteConnection

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

Sync.

func (*LocalPeer) Forward

func (peer *LocalPeer) Forward(dstPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error

func (*LocalPeer) Relay

func (peer *LocalPeer) Relay(srcPeer, dstPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error

func (*LocalPeer) RelayBroadcast

func (peer *LocalPeer) RelayBroadcast(srcPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error

type MacCache

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

func NewMacCache

func NewMacCache(maxAge time.Duration, onExpiry func(net.HardwareAddr, *Peer)) *MacCache

func (*MacCache) Delete

func (cache *MacCache) Delete(peer *Peer) bool

func (*MacCache) Enter

func (cache *MacCache) Enter(mac net.HardwareAddr, peer *Peer) bool

func (*MacCache) Lookup

func (cache *MacCache) Lookup(mac net.HardwareAddr) (*Peer, bool)

func (*MacCache) String

func (cache *MacCache) String() string

type MacCacheEntry

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

type MsgTooBigError

type MsgTooBigError struct {
	PMTU int // actual pmtu, i.e. what the kernel told us
}

func (MsgTooBigError) Error

func (mtbe MsgTooBigError) Error() string

type NaClDecryptor

type NaClDecryptor struct {
	NonDecryptor
	// contains filtered or unexported fields
}

func NewNaClDecryptor

func NewNaClDecryptor(conn *LocalConnection) *NaClDecryptor

func (*NaClDecryptor) IterateFrames

func (nd *NaClDecryptor) IterateFrames(fun FrameConsumer, packet *UDPPacket) error

func (*NaClDecryptor) ReceiveNonce

func (nd *NaClDecryptor) ReceiveNonce(msg []byte)

func (*NaClDecryptor) Shutdown

func (nd *NaClDecryptor) Shutdown()

type NaClDecryptorInstance

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

type NaClEncryptor

type NaClEncryptor struct {
	NonEncryptor
	// contains filtered or unexported fields
}

func NewNaClEncryptor

func NewNaClEncryptor(prefix []byte, conn *LocalConnection, df bool) *NaClEncryptor

func (*NaClEncryptor) Bytes

func (ne *NaClEncryptor) Bytes() []byte

func (*NaClEncryptor) PacketOverhead

func (ne *NaClEncryptor) PacketOverhead() int

func (*NaClEncryptor) TotalLen

func (ne *NaClEncryptor) TotalLen() int

type NameCollisionError

type NameCollisionError struct {
	Name PeerName
}

func (NameCollisionError) Error

func (nce NameCollisionError) Error() string

type NonDecryptor

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

func NewNonDecryptor

func NewNonDecryptor(conn *LocalConnection) *NonDecryptor

func (*NonDecryptor) IterateFrames

func (nd *NonDecryptor) IterateFrames(fun FrameConsumer, packet *UDPPacket) error

func (*NonDecryptor) ReceiveNonce

func (nd *NonDecryptor) ReceiveNonce(msg []byte)

func (*NonDecryptor) Shutdown

func (nd *NonDecryptor) Shutdown()

type NonEncryptor

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

func NewNonEncryptor

func NewNonEncryptor(prefix []byte) *NonEncryptor

func (*NonEncryptor) AppendFrame

func (ne *NonEncryptor) AppendFrame(frame *ForwardedFrame)

func (*NonEncryptor) Bytes

func (ne *NonEncryptor) Bytes() []byte

func (*NonEncryptor) FrameOverhead

func (ne *NonEncryptor) FrameOverhead() int

func (*NonEncryptor) IsEmpty

func (ne *NonEncryptor) IsEmpty() bool

func (*NonEncryptor) PacketOverhead

func (ne *NonEncryptor) PacketOverhead() int

func (*NonEncryptor) TotalLen

func (ne *NonEncryptor) TotalLen() int

type PacketDecodingError

type PacketDecodingError struct {
	Fatal bool
	Desc  string
}

func (PacketDecodingError) Error

func (pde PacketDecodingError) Error() string

type PacketSink

type PacketSink interface {
	WritePacket([]byte) error
}

func NewPcapO

func NewPcapO(ifName string) (po PacketSink, err error)

type PacketSource

type PacketSource interface {
	ReadPacket() ([]byte, error)
}

type PacketSourceSink

type PacketSourceSink interface {
	PacketSource
	PacketSink
}

func NewPcapIO

func NewPcapIO(ifName string, bufSz int) (PacketSourceSink, error)

type PcapIO

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

func (*PcapIO) ReadPacket

func (pi *PcapIO) ReadPacket() (data []byte, err error)

func (*PcapIO) WritePacket

func (po *PcapIO) WritePacket(data []byte) error

type Peer

type Peer struct {
	sync.RWMutex
	Name     PeerName
	NameByte []byte
	UID      uint64
	// contains filtered or unexported fields
}

func NewPeer

func NewPeer(name PeerName, uid uint64, version uint64) *Peer

func (*Peer) ConnectionCount

func (peer *Peer) ConnectionCount() int

func (*Peer) ConnectionTo

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

func (*Peer) DecrementLocalRefCount

func (peer *Peer) DecrementLocalRefCount()

func (*Peer) ForEachConnection

func (peer *Peer) ForEachConnection(fun func(PeerName, Connection))

func (*Peer) IncrementLocalRefCount

func (peer *Peer) IncrementLocalRefCount()

func (*Peer) IsLocallyReferenced

func (peer *Peer) IsLocallyReferenced() bool

func (*Peer) Routes

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

Calculate 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 'symmetric' flag is set, only symmetric connections are considered, i.e. where both sides indicate they have a connection to the other.

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

We acquire read locks on peers as we encounter them during the traversal. This prevents the connectivity graph from changing underneath us in ways that would invalidate the result. Thus the answer returned may be out of date, but never inconsistent.

func (*Peer) SetVersionAndConnections

func (peer *Peer) SetVersionAndConnections(version uint64, connections map[PeerName]Connection)

func (*Peer) String

func (peer *Peer) String() string

func (*Peer) Version

func (peer *Peer) Version() uint64

type PeerInteraction

type PeerInteraction struct {
	Interaction
	// contains filtered or unexported fields
}

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

func PeerNameFromString

func PeerNameFromString(nameStr string) (PeerName, error)

func PeerNameFromUserInput

func PeerNameFromUserInput(userInput string) (PeerName, error)

func (PeerName) Bin

func (name PeerName) Bin() []byte

func (PeerName) String

func (name PeerName) String() string

type Peers

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

func NewPeers

func NewPeers(ourself *Peer, macs *MacCache, onGC func(*Peer)) *Peers

func (*Peers) ApplyUpdate

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

func (*Peers) EncodeAllPeers

func (peers *Peers) EncodeAllPeers() []byte

func (*Peers) Fetch

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

func (*Peers) FetchWithDefault

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

func (*Peers) ForEach

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

func (*Peers) GarbageCollect

func (peers *Peers) GarbageCollect() []*Peer

func (*Peers) String

func (peers *Peers) String() string

type RawUDPSender

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

func NewRawUDPSender

func NewRawUDPSender(conn *LocalConnection) (*RawUDPSender, error)

func (*RawUDPSender) Send

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

func (*RawUDPSender) Shutdown

func (sender *RawUDPSender) Shutdown() error

type RemoteConnection

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

func NewRemoteConnection

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

func (*RemoteConnection) Established

func (conn *RemoteConnection) Established() bool

func (*RemoteConnection) Local

func (conn *RemoteConnection) Local() *Peer

func (*RemoteConnection) Remote

func (conn *RemoteConnection) Remote() *Peer

func (*RemoteConnection) RemoteTCPAddr

func (conn *RemoteConnection) RemoteTCPAddr() string

func (*RemoteConnection) Shutdown

func (conn *RemoteConnection) Shutdown()

func (*RemoteConnection) String

func (conn *RemoteConnection) String() string

type Router

type Router struct {
	Iface           *net.Interface
	Ourself         *LocalPeer
	Macs            *MacCache
	Peers           *Peers
	Routes          *Routes
	ConnectionMaker *ConnectionMaker
	UDPListener     *net.UDPConn
	Password        *[]byte
	ConnLimit       int
	BufSz           int
	LogFrame        func(string, []byte, *layers.Ethernet)
}

func NewRouter

func NewRouter(iface *net.Interface, name PeerName, password []byte, connLimit int, bufSz int, logFrame func(string, []byte, *layers.Ethernet)) *Router

func (*Router) Start

func (router *Router) Start()

func (*Router) Status

func (router *Router) Status() string

func (*Router) UsingPassword

func (router *Router) UsingPassword() bool

type Routes

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

func StartRoutes

func StartRoutes(ourself *Peer, peers *Peers) *Routes

func (*Routes) Broadcast

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

func (*Routes) Recalculate

func (routes *Routes) Recalculate()

Async.

func (*Routes) String

func (routes *Routes) String() string

func (*Routes) Unicast

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

type SimpleTCPReceiver

type SimpleTCPReceiver struct {
}

func NewSimpleTCPReceiver

func NewSimpleTCPReceiver() *SimpleTCPReceiver

func (*SimpleTCPReceiver) Decode

func (receiver *SimpleTCPReceiver) Decode(msg []byte) ([]byte, error)

type SimpleTCPSender

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

func NewSimpleTCPSender

func NewSimpleTCPSender(encoder *gob.Encoder) *SimpleTCPSender

func (*SimpleTCPSender) Send

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

type SimpleUDPSender

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

func NewSimpleUDPSender

func NewSimpleUDPSender(conn *LocalConnection) *SimpleUDPSender

func (*SimpleUDPSender) Send

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

func (*SimpleUDPSender) Shutdown

func (sender *SimpleUDPSender) Shutdown() error

type TCPReceiver

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

type TCPSender

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

type Target

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

Information about an address where we may find a peer

type UDPPacket

type UDPPacket struct {
	Name   PeerName
	Packet []byte
	Sender *net.UDPAddr
}

func (UDPPacket) String

func (packet UDPPacket) String() string

type UDPSender

type UDPSender interface {
	Send([]byte) error
	Shutdown() error
}

type UnknownPeersError

type UnknownPeersError struct {
}

func (UnknownPeersError) Error

func (upe UnknownPeersError) Error() string

Jump to

Keyboard shortcuts

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