Merge pull request #496 from dpw/router-cleanups

Router cleanups
This commit is contained in:
rade committed 2015-03-27 18:38:43 +00:00
commit 94cf05a897
7 files changed
+45 -66

No files matched your search

+1 -1
View File
@@ -132,7 +132,7 @@ func (cm *ConnectionMaker) checkStateAndAttemptConnections() time.Duration {
// Add targets for peers that someone else is connected to, but we
// aren't
cm.peers.ForEach(func(name PeerName, peer *Peer) {
cm.peers.ForEach(func(peer *Peer) {
for _, conn := range peer.Connections() {
otherPeer := conn.Remote().Name
if otherPeer == cm.ourself.Name || ourConnectedPeers[otherPeer] {
+28 -32
View File
@@ -11,7 +11,6 @@ import (
"encoding/gob"
"fmt"
"log"
"net"
"sync"
)
@@ -107,7 +106,7 @@ type Encryptor interface {
PacketOverhead() int
IsEmpty() bool
Bytes() []byte
AppendFrame(*ForwardedFrame)
AppendFrame(src []byte, dst []byte, frame []byte)
TotalLen() int
}
@@ -159,18 +158,17 @@ func (ne *NonEncryptor) Bytes() []byte {
return buf
}
func (ne *NonEncryptor) AppendFrame(frame *ForwardedFrame) {
func (ne *NonEncryptor) AppendFrame(src []byte, dst []byte, frame []byte) {
bufTail := ne.bufTail
srcLen := copy(bufTail, frame.srcPeer.NameByte)
srcLen := copy(bufTail, src)
bufTail = bufTail[srcLen:]
dstLen := copy(bufTail, frame.dstPeer.NameByte)
dstLen := copy(bufTail, dst)
bufTail = bufTail[dstLen:]
frameLen := len(frame.frame)
binary.BigEndian.PutUint16(bufTail, uint16(frameLen))
binary.BigEndian.PutUint16(bufTail, uint16(len(frame)))
bufTail = bufTail[2:]
copy(bufTail, frame.frame)
ne.bufTail = bufTail[frameLen:]
ne.buffered += srcLen + dstLen + 2 + frameLen
copy(bufTail, frame)
ne.bufTail = bufTail[len(frame):]
ne.buffered += srcLen + dstLen + 2 + len(frame)
}
func (ne *NonEncryptor) TotalLen() int {
@@ -245,10 +243,10 @@ func (ne *NaClEncryptor) TotalLen() int {
// Frame Decryptors
type FrameConsumer func(*LocalConnection, *net.UDPAddr, []byte, []byte, uint16, []byte)
type FrameConsumer func(conn *LocalConnection, src []byte, dst []byte, frame []byte)
type Decryptor interface {
IterateFrames(FrameConsumer, *UDPPacket) error
IterateFrames([]byte, FrameConsumer) error
ReceiveNonce([]byte)
Shutdown()
}
@@ -281,24 +279,23 @@ func NewNonDecryptor(conn *LocalConnection) *NonDecryptor {
return &NonDecryptor{conn: conn}
}
func (nd *NonDecryptor) IterateFrames(consumer FrameConsumer, packet *UDPPacket) error {
buf := packet.Packet
for len(buf) >= (2 + NameSize + NameSize) {
srcNameByte := buf[:NameSize]
buf = buf[NameSize:]
dstNameByte := buf[:NameSize]
buf = buf[NameSize:]
length := binary.BigEndian.Uint16(buf[:2])
buf = buf[2:]
if len(buf) < int(length) {
return PacketDecodingError{Desc: fmt.Sprintf("too short; expected frame of length %d, got %d", length, len(buf))}
func (nd *NonDecryptor) IterateFrames(packet []byte, consumer FrameConsumer) error {
for len(packet) >= (2 + NameSize + NameSize) {
srcNameByte := packet[:NameSize]
packet = packet[NameSize:]
dstNameByte := packet[:NameSize]
packet = packet[NameSize:]
length := binary.BigEndian.Uint16(packet[:2])
packet = packet[2:]
if len(packet) < int(length) {
return PacketDecodingError{Desc: fmt.Sprintf("too short; expected frame of length %d, got %d", length, len(packet))}
}
frame := buf[:length]
buf = buf[length:]
consumer(nd.conn, packet.Sender, srcNameByte, dstNameByte, length, frame)
frame := packet[:length]
packet = packet[length:]
consumer(nd.conn, srcNameByte, dstNameByte, frame)
}
if len(buf) > 0 {
return PacketDecodingError{Desc: fmt.Sprintf("%d octets of trailing garbage", len(buf))}
if len(packet) > 0 {
return PacketDecodingError{Desc: fmt.Sprintf("%d octets of trailing garbage", len(packet))}
}
return nil
}
@@ -345,13 +342,12 @@ func (nd *NaClDecryptor) ReceiveNonce(msg []byte) {
}
}
func (nd *NaClDecryptor) IterateFrames(consumer FrameConsumer, packet *UDPPacket) error {
buf, err := nd.decrypt(packet.Packet)
func (nd *NaClDecryptor) IterateFrames(packet []byte, consumer FrameConsumer) error {
buf, err := nd.decrypt(packet)
if err != nil {
return PacketDecodingError{Fatal: true, Desc: fmt.Sprint("decryption failed; ", err)}
}
packet.Packet = buf
return nd.NonDecryptor.IterateFrames(consumer, packet)
return nd.NonDecryptor.IterateFrames(buf, consumer)
}
func (nd *NaClDecryptor) decrypt(buf []byte) ([]byte, error) {
+3 -6
View File
@@ -281,11 +281,8 @@ func (fwd *Forwarder) verifyEffectivePMTU(newUnverifiedPMTU int) {
}
func (fwd *Forwarder) attemptVerifyEffectivePMTU() {
pmtuVerifyFrame := &ForwardedFrame{
srcPeer: fwd.conn.local,
dstPeer: fwd.conn.remote,
frame: make([]byte, fwd.unverifiedPMTU+EthernetOverhead)}
fwd.enc.AppendFrame(pmtuVerifyFrame)
fwd.enc.AppendFrame(fwd.conn.local.NameByte, fwd.conn.remote.NameByte,
make([]byte, fwd.unverifiedPMTU+EthernetOverhead))
fwd.flush()
if fwd.verifyPMTUTick == nil {
fwd.verifyPMTUTick = time.After(PMTUVerifyTimeout << (PMTUVerifyAttempts - fwd.pmtuVerifyCount))
@@ -337,7 +334,7 @@ func (fwd *Forwarder) appendFrame(frame *ForwardedFrame) bool {
if fwd.enc.TotalLen()+fwd.enc.FrameOverhead()+frameLen > fwd.maxPayload {
return false
}
fwd.enc.AppendFrame(frame)
fwd.enc.AppendFrame(frame.srcPeer.NameByte, frame.dstPeer.NameByte, frame.frame)
return true
}
+1 -1
View File
@@ -36,7 +36,7 @@ func (cache *MacCache) MarshalJSON() ([]byte, error) {
func (peers *Peers) MarshalJSON() ([]byte, error) {
var ps []*Peer
peers.ForEach(func(_ PeerName, peer *Peer) { ps = append(ps, peer) })
peers.ForEach(func(peer *Peer) { ps = append(ps, peer) })
return json.Marshal(ps)
}
+4 -4
View File
@@ -55,11 +55,11 @@ func (peers *Peers) Fetch(name PeerName) (*Peer, bool) {
return peer, found // GRRR, why can't I inline this!?
}
func (peers *Peers) ForEach(fun func(PeerName, *Peer)) {
func (peers *Peers) ForEach(fun func(*Peer)) {
peers.RLock()
defer peers.RUnlock()
for name, peer := range peers.table {
fun(name, peer)
for _, peer := range peers.table {
fun(peer)
}
}
@@ -129,7 +129,7 @@ func (peers *Peers) GarbageCollect() []*Peer {
func (peers *Peers) String() string {
var buf bytes.Buffer
peers.ForEach(func(name PeerName, peer *Peer) {
peers.ForEach(func(peer *Peer) {
fmt.Fprint(&buf, peer, "\n")
for _, conn := range peer.Connections() {
established := ""
+6 -20
View File
@@ -213,20 +213,9 @@ func (router *Router) listenUDP(localPort int, po PacketSink) *net.UDPConn {
return conn
}
type UDPPacket struct {
Name PeerName
Packet []byte
Sender *net.UDPAddr
}
func (packet UDPPacket) String() string {
return fmt.Sprintf("UDP Packet\n name: %s\n sender: %v\n payload: % X", packet.Name, packet.Sender, packet.Packet)
}
func (router *Router) udpReader(conn *net.UDPConn, po PacketSink) {
defer conn.Close()
dec := NewEthernetDecoder()
handleUDPPacket := router.handleUDPPacketFunc(dec, po)
buf := make([]byte, MaxUDPPacketSize)
for {
n, sender, err := conn.ReadFromUDP(buf)
@@ -242,10 +231,6 @@ func (router *Router) udpReader(conn *net.UDPConn, po PacketSink) {
name := PeerNameFromBin(buf[:NameSize])
packet := make([]byte, n-NameSize)
copy(packet, buf[NameSize:n])
udpPacket := &UDPPacket{
Name: name,
Packet: packet,
Sender: sender}
peerConn, found := router.Ourself.ConnectionTo(name)
if !found {
continue
@@ -254,7 +239,7 @@ func (router *Router) udpReader(conn *net.UDPConn, po PacketSink) {
if !ok {
continue
}
err = relayConn.Decryptor.IterateFrames(handleUDPPacket, udpPacket)
err = relayConn.Decryptor.IterateFrames(packet, router.handleUDPPacketFunc(dec, sender, po))
if pde, ok := err.(PacketDecodingError); ok {
if pde.Fatal {
relayConn.Shutdown(pde)
@@ -267,8 +252,8 @@ func (router *Router) udpReader(conn *net.UDPConn, po PacketSink) {
}
}
func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) FrameConsumer {
return func(relayConn *LocalConnection, sender *net.UDPAddr, srcNameByte, dstNameByte []byte, frameLen uint16, frame []byte) {
func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, sender *net.UDPAddr, po PacketSink) FrameConsumer {
return func(relayConn *LocalConnection, srcNameByte, dstNameByte []byte, frame []byte) {
srcPeer, found := router.Peers.Fetch(PeerNameFromBin(srcNameByte))
if !found {
return
@@ -293,7 +278,7 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
// detecting special frames is cheaper post decoding than pre.
if decodedLen == 1 && dec.IsSpecial() {
if srcPeer == relayConn.Remote() && dstPeer == router.Ourself.Peer {
handleSpecialFrame(relayConn, sender, frameLen, frame)
handleSpecialFrame(relayConn, sender, frame)
}
}
@@ -335,7 +320,8 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
}
}
func handleSpecialFrame(relayConn *LocalConnection, sender *net.UDPAddr, frameLen uint16, frame []byte) {
func handleSpecialFrame(relayConn *LocalConnection, sender *net.UDPAddr, frame []byte) {
frameLen := len(frame)
switch {
case frameLen == EthernetOverhead+8:
relayConn.ReceivedHeartbeat(sender, binary.BigEndian.Uint64(frame[EthernetOverhead:]))
+2 -2
View File
@@ -124,7 +124,7 @@ func (routes *Routes) calculateBroadcast() map[PeerName][]PeerName {
broadcast := make(map[PeerName][]PeerName)
ourself := routes.ourself
routes.peers.ForEach(func(name PeerName, peer *Peer) {
routes.peers.ForEach(func(peer *Peer) {
hops := []PeerName{}
if found, reached := peer.Routes(ourself, true); found {
// This is rather similar to the inner loop on
@@ -143,7 +143,7 @@ func (routes *Routes) calculateBroadcast() map[PeerName][]PeerName {
}
}
}
broadcast[name] = hops
broadcast[peer.Name] = hops
})
return broadcast
}