diff --git a/router/connection_maker.go b/router/connection_maker.go index d9820abb..61417feb 100644 --- a/router/connection_maker.go +++ b/router/connection_maker.go @@ -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] { diff --git a/router/crypto.go b/router/crypto.go index c4f29d26..3d7cad9e 100644 --- a/router/crypto.go +++ b/router/crypto.go @@ -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) { diff --git a/router/forwarder.go b/router/forwarder.go index 28f410e8..f1aeae3a 100644 --- a/router/forwarder.go +++ b/router/forwarder.go @@ -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 } diff --git a/router/json.go b/router/json.go index 81407fff..07e538e5 100644 --- a/router/json.go +++ b/router/json.go @@ -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) } diff --git a/router/peers.go b/router/peers.go index 62963e34..5edf5639 100644 --- a/router/peers.go +++ b/router/peers.go @@ -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 := "" diff --git a/router/router.go b/router/router.go index a78f020f..922c1009 100644 --- a/router/router.go +++ b/router/router.go @@ -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:])) diff --git a/router/routes.go b/router/routes.go index 8a20e62f..2c99e034 100644 --- a/router/routes.go +++ b/router/routes.go @@ -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 }