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
- Variables
- func Concat(elems ...[]byte) []byte
- func DecodeNonce(msg []byte) (bool, *[24]byte)
- func DecryptPrefixNonce(ciphertxt []byte, secret *[32]byte) ([]byte, bool)
- func EncodeNonce(df bool) (*[24]byte, []byte, error)
- func EncodePeers(peers ...*Peer) []byte
- func EncryptPrefixNonce(plaintxt []byte, nonce *[24]byte, secret *[32]byte) []byte
- func FormSessionKey(remotePublicKey, localPrivateKey *[32]byte, secretKey *[]byte) *[32]byte
- func GenerateKeyPair() (publicKey, privateKey *[32]byte, err error)
- func GenerateRandomNonce() ([24]byte, error)
- func NewLocalConnection(connRemote *RemoteConnection, acceptNewPeer bool, tcpConn *net.TCPConn, ...)
- func NormalisePeerAddr(peerAddr string) string
- func PosixError(err error) error
- func SetNonceLow15Bits(nonce *[24]byte, offset uint16)
- type Connection
- type ConnectionInteraction
- type ConnectionMaker
- type ConnectionMakerInteraction
- type Decryptor
- type EncryptedTCPMessage
- type EncryptedTCPReceiver
- type EncryptedTCPSender
- type Encryptor
- type EthernetDecoder
- type ForwardedFrame
- type Forwarder
- type FrameConsumer
- type FrameTooBigError
- type Interaction
- type ListOfPeers
- type LocalAddress
- type LocalConnection
- func (conn *LocalConnection) CheckFatal(err error) error
- func (conn *LocalConnection) Established() bool
- func (conn *LocalConnection) Forward(df bool, frame *ForwardedFrame, dec *EthernetDecoder) error
- func (conn *LocalConnection) RemoteUDPAddr() *net.UDPAddr
- func (conn *LocalConnection) SendTCP(msg []byte)
- func (conn *LocalConnection) SetEstablished()
- func (conn *LocalConnection) SetRemoteUDPAddr(remoteUDPAddr *net.UDPAddr)
- func (conn *LocalConnection) Shutdown()
- type LocalPeer
- func (peer *LocalPeer) AddConnection(conn *LocalConnection)
- func (peer *LocalPeer) Broadcast(df bool, frame []byte, dec *EthernetDecoder) error
- func (peer *LocalPeer) BroadcastTCP(msg []byte)
- func (peer *LocalPeer) ConnectionEstablished(conn *LocalConnection)
- func (peer *LocalPeer) CreateConnection(peerAddr string, acceptNewPeer bool) error
- func (peer *LocalPeer) DeleteConnection(conn *LocalConnection)
- func (peer *LocalPeer) Forward(dstPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error
- func (peer *LocalPeer) Relay(srcPeer, dstPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error
- func (peer *LocalPeer) RelayBroadcast(srcPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error
- type MacCache
- type MacCacheEntry
- type MsgTooBigError
- type NaClDecryptor
- type NaClDecryptorInstance
- type NaClEncryptor
- type NameCollisionError
- type NonDecryptor
- type NonEncryptor
- type PacketDecodingError
- type PacketSink
- type PacketSource
- type PacketSourceSink
- type PcapIO
- type Peer
- func (peer *Peer) ConnectionCount() int
- func (peer *Peer) ConnectionTo(name PeerName) (Connection, bool)
- func (peer *Peer) DecrementLocalRefCount()
- func (peer *Peer) ForEachConnection(fun func(PeerName, Connection))
- func (peer *Peer) IncrementLocalRefCount()
- func (peer *Peer) IsLocallyReferenced() bool
- func (peer *Peer) Routes(stopAt *Peer, symmetric bool) (bool, map[PeerName]PeerName)
- func (peer *Peer) SetVersionAndConnections(version uint64, connections map[PeerName]Connection)
- func (peer *Peer) String() string
- func (peer *Peer) Version() uint64
- type PeerInteraction
- type PeerName
- type Peers
- func (peers *Peers) ApplyUpdate(update []byte) ([]byte, error)
- func (peers *Peers) EncodeAllPeers() []byte
- func (peers *Peers) Fetch(name PeerName) (*Peer, bool)
- func (peers *Peers) FetchWithDefault(peer *Peer) *Peer
- func (peers *Peers) ForEach(fun func(PeerName, *Peer))
- func (peers *Peers) GarbageCollect() []*Peer
- func (peers *Peers) String() string
- type RawUDPSender
- type RemoteConnection
- type Router
- type Routes
- type SimpleTCPReceiver
- type SimpleTCPSender
- type SimpleUDPSender
- type TCPReceiver
- type TCPSender
- type Target
- type UDPPacket
- type UDPSender
- type UnknownPeersError
Constants ¶
const ( CSendTCP = iota CSetEstablished = iota CSetRemoteUDPAddr = iota CShutdown = iota )
const ( InitialInterval = 5 * time.Second MaxInterval = 10 * time.Minute )
const ( CMInitiate = iota CMTerminated = iota CMRefresh = iota CMStatus = iota )
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) )
const ( ProtocolConnectionEstablished = iota ProtocolFragmentationReceived = iota ProtocolStartFragmentationTest = iota ProtocolNonce = iota ProtocolFetchAll = iota ProtocolUpdate = iota ProtocolPMTUVerified = iota )
const ( PAddConnection = iota PBroadcastTCP = iota PDeleteConnection = iota PConnectionEstablished = iota )
const ( PeerNameFlavour = "mac" NameSize = 6 UnknownPeerName = PeerName(0) )
const (
RRecalculate = iota
)
Variables ¶
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 DecodeNonce ¶
func DecryptPrefixNonce ¶
func EncodePeers ¶
func EncryptPrefixNonce ¶
func FormSessionKey ¶
func GenerateKeyPair ¶
func GenerateRandomNonce ¶
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 ¶
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 SetNonceLow15Bits ¶
Types ¶
type Connection ¶
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 EncryptedTCPReceiver ¶
type EncryptedTCPReceiver struct {
// contains filtered or unexported fields
}
func NewEncryptedTCPReceiver ¶
func NewEncryptedTCPReceiver(conn *LocalConnection) *EncryptedTCPReceiver
type EncryptedTCPSender ¶
func NewEncryptedTCPSender ¶
func NewEncryptedTCPSender(encoder *gob.Encoder, conn *LocalConnection) *EncryptedTCPSender
func (*EncryptedTCPSender) Send ¶
func (sender *EncryptedTCPSender) Send(msg []byte) error
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
type FrameConsumer ¶
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) SetRemoteUDPAddr ¶
func (conn *LocalConnection) SetRemoteUDPAddr(remoteUDPAddr *net.UDPAddr)
Async
type LocalPeer ¶
func StartLocalPeer ¶
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) ConnectionEstablished ¶
func (peer *LocalPeer) ConnectionEstablished(conn *LocalConnection)
Async.
func (*LocalPeer) CreateConnection ¶
func (*LocalPeer) DeleteConnection ¶
func (peer *LocalPeer) DeleteConnection(conn *LocalConnection)
Sync.
func (*LocalPeer) RelayBroadcast ¶
type MacCache ¶
func NewMacCache ¶
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 ¶
func (PacketDecodingError) Error ¶
func (pde PacketDecodingError) Error() string
type PacketSink ¶
func NewPcapO ¶
func NewPcapO(ifName string) (po PacketSink, err error)
type PacketSource ¶
type PacketSourceSink ¶
type PacketSourceSink interface { PacketSource PacketSink }
type PcapIO ¶
type PcapIO struct {
// contains filtered or unexported fields
}
func (*PcapIO) ReadPacket ¶
func (*PcapIO) WritePacket ¶
type Peer ¶
type Peer struct { sync.RWMutex Name PeerName NameByte []byte UID uint64 // contains filtered or unexported fields }
func (*Peer) ConnectionCount ¶
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) Routes ¶
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)
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 PeerNameFromString ¶
func PeerNameFromUserInput ¶
type Peers ¶
func (*Peers) EncodeAllPeers ¶
func (*Peers) FetchWithDefault ¶
func (*Peers) GarbageCollect ¶
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 (*Router) UsingPassword ¶
type Routes ¶
func StartRoutes ¶
type SimpleTCPReceiver ¶
type SimpleTCPReceiver struct { }
func NewSimpleTCPReceiver ¶
func NewSimpleTCPReceiver() *SimpleTCPReceiver
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 Target ¶
type Target struct {
// contains filtered or unexported fields
}
Information about an address where we may find a peer
type UnknownPeersError ¶
type UnknownPeersError struct { }
func (UnknownPeersError) Error ¶
func (upe UnknownPeersError) Error() string