1) log more lifecycle events
- acceptance
- handshake completion
- added & removed (from our connection map)
The latter is a bit verbose but may help us track down the cause for
going to introduce here, then this would fall in the 'debug' category.
2) better error logging
- log error as part of "shutting down" log event rather than separately
- indicate "blocked UDP connectivity" as a possible cause when
getting a timeout on a not-fully-established connection.
The rationale for the latter is that inbound connections get
marked as established when first receiving a heartbeat frame over
UDP, which are the only frames that get transmitted prior to the
connection being fully established. Note that outbound
connections get marked as established when receiving the
ConnectionEstablished message over TCP, which is sent by the peer
when it first receives a heartbeat. See #342.
Closes #340.
269 lines
4.9 KiB
Go
269 lines
4.9 KiB
Go
package router
|
|
|
|
import (
|
|
"bytes"
|
|
"code.google.com/p/go-bit/bit"
|
|
"code.google.com/p/gopacket"
|
|
"code.google.com/p/gopacket/layers"
|
|
"encoding/gob"
|
|
"net"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
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)
|
|
}
|
|
|
|
type Connection interface {
|
|
Local() *Peer
|
|
Remote() *Peer
|
|
RemoteTCPAddr() string
|
|
Established() bool
|
|
Shutdown(error)
|
|
}
|
|
|
|
type RemoteConnection struct {
|
|
local *Peer
|
|
remote *Peer
|
|
remoteTCPAddr string
|
|
}
|
|
|
|
type LocalConnection struct {
|
|
sync.RWMutex
|
|
RemoteConnection
|
|
TCPConn *net.TCPConn
|
|
tcpSender TCPSender
|
|
remoteUDPAddr *net.UDPAddr
|
|
established bool
|
|
stackFrag bool
|
|
effectivePMTU int
|
|
SessionKey *[32]byte
|
|
heartbeat *time.Ticker
|
|
fetchAll *time.Ticker
|
|
fragTest *time.Ticker
|
|
forwardChan chan<- *ForwardedFrame
|
|
forwardChanDF chan<- *ForwardedFrame
|
|
stopForward chan<- interface{}
|
|
stopForwardDF chan<- interface{}
|
|
verifyPMTU chan<- int
|
|
Decryptor Decryptor
|
|
Router *Router
|
|
UID uint64
|
|
queryChan chan<- *ConnectionInteraction
|
|
}
|
|
|
|
type ConnectionInteraction struct {
|
|
Interaction
|
|
payload interface{}
|
|
}
|
|
|
|
type Forwarder struct {
|
|
conn *LocalConnection
|
|
ch <-chan *ForwardedFrame
|
|
stop <-chan interface{}
|
|
verifyPMTUTick <-chan time.Time
|
|
verifyPMTU <-chan int
|
|
pmtuVerifyCount uint
|
|
enc Encryptor
|
|
udpSender UDPSender
|
|
maxPayload int
|
|
pmtuVerified bool
|
|
highestGoodPMTU int
|
|
unverifiedPMTU int
|
|
lowestBadPMTU int
|
|
}
|
|
|
|
type UDPPacket struct {
|
|
Name PeerName
|
|
Packet []byte
|
|
Sender *net.UDPAddr
|
|
}
|
|
|
|
type EthernetDecoder struct {
|
|
eth layers.Ethernet
|
|
ip layers.IPv4
|
|
decoded []gopacket.LayerType
|
|
parser *gopacket.DecodingLayerParser
|
|
}
|
|
|
|
type MsgTooBigError struct {
|
|
PMTU int // actual pmtu, i.e. what the kernel told us
|
|
}
|
|
|
|
type FrameTooBigError struct {
|
|
EPMTU int // effective pmtu, i.e. what we tell packet senders
|
|
}
|
|
|
|
type UnknownPeersError struct {
|
|
}
|
|
|
|
type NameCollisionError struct {
|
|
Name PeerName
|
|
}
|
|
|
|
type PacketDecodingError struct {
|
|
Fatal bool
|
|
Desc string
|
|
}
|
|
|
|
type LocalAddress struct {
|
|
ip net.IP
|
|
network *net.IPNet
|
|
}
|
|
|
|
type ForwardedFrame struct {
|
|
srcPeer *Peer
|
|
dstPeer *Peer
|
|
frame []byte
|
|
}
|
|
|
|
type Interaction struct {
|
|
code int
|
|
resultChan chan<- interface{}
|
|
}
|
|
|
|
// UDPSender interface and implementations
|
|
|
|
type UDPSender interface {
|
|
Send([]byte) error
|
|
Shutdown() error
|
|
}
|
|
|
|
type SimpleUDPSender struct {
|
|
conn *LocalConnection
|
|
udpConn *net.UDPConn
|
|
}
|
|
|
|
type RawUDPSender struct {
|
|
ipBuf gopacket.SerializeBuffer
|
|
opts gopacket.SerializeOptions
|
|
udpHeader *layers.UDP
|
|
socket *net.IPConn
|
|
conn *LocalConnection
|
|
}
|
|
|
|
// TCPSender interface and implementations
|
|
|
|
type TCPSender interface {
|
|
Send([]byte) error
|
|
}
|
|
|
|
type SimpleTCPSender struct {
|
|
encoder *gob.Encoder
|
|
}
|
|
|
|
type EncryptedTCPSender struct {
|
|
sync.RWMutex
|
|
outerEncoder *gob.Encoder
|
|
innerEncoder *gob.Encoder
|
|
buffer *bytes.Buffer
|
|
conn *LocalConnection
|
|
msgCount int
|
|
}
|
|
|
|
type EncryptedTCPMessage struct {
|
|
Number int
|
|
Body []byte
|
|
}
|
|
|
|
// TCPReceiver interface and implementations
|
|
|
|
type TCPReceiver interface {
|
|
Decode([]byte) ([]byte, error)
|
|
}
|
|
|
|
type SimpleTCPReceiver struct {
|
|
}
|
|
|
|
type EncryptedTCPReceiver struct {
|
|
conn *LocalConnection
|
|
decoder *gob.Decoder
|
|
buffer *bytes.Buffer
|
|
msgCount int
|
|
}
|
|
|
|
// Encryptor interface and implementations
|
|
|
|
type Encryptor interface {
|
|
FrameOverhead() int
|
|
PacketOverhead() int
|
|
IsEmpty() bool
|
|
Bytes() []byte
|
|
AppendFrame(*ForwardedFrame)
|
|
TotalLen() int
|
|
}
|
|
|
|
type NonEncryptor struct {
|
|
buf []byte
|
|
bufTail []byte
|
|
buffered int
|
|
prefixLen int
|
|
}
|
|
|
|
type NaClEncryptor struct {
|
|
NonEncryptor
|
|
buf []byte
|
|
offset uint16
|
|
nonce *[24]byte
|
|
nonceChan chan *[24]byte
|
|
flags uint16
|
|
prefixLen int
|
|
conn *LocalConnection
|
|
df bool
|
|
}
|
|
|
|
// Decryptor interface and implementations
|
|
|
|
type FrameConsumer func(*LocalConnection, *net.UDPAddr, []byte, []byte, uint16, []byte) error
|
|
|
|
type Decryptor interface {
|
|
IterateFrames(FrameConsumer, *UDPPacket) error
|
|
ReceiveNonce([]byte)
|
|
Shutdown()
|
|
}
|
|
|
|
type NonDecryptor struct {
|
|
conn *LocalConnection
|
|
}
|
|
|
|
type NaClDecryptor struct {
|
|
NonDecryptor
|
|
instance *NaClDecryptorInstance
|
|
instanceDF *NaClDecryptorInstance
|
|
}
|
|
|
|
type NaClDecryptorInstance struct {
|
|
nonce *[24]byte
|
|
previousNonce *[24]byte
|
|
usedOffsets *bit.Set
|
|
previousUsedOffsets *bit.Set
|
|
highestOffsetSeen uint16
|
|
nonceChan chan *[24]byte
|
|
}
|
|
|
|
// Packet capture/inject interfaces
|
|
|
|
type PacketSource interface {
|
|
ReadPacket() ([]byte, error)
|
|
}
|
|
|
|
type PacketSink interface {
|
|
WritePacket([]byte) error
|
|
}
|
|
|
|
type PacketSourceSink interface {
|
|
PacketSource
|
|
PacketSink
|
|
}
|