Remove some layers of indirection around FrameTooBigError handling
This commit is contained in:
1 parent
e543bff1ba
commit
5b66daf1e4
3 files changed
+33
-49
No files matched your search
+5
-8
@@ -245,7 +245,7 @@ func (ne *NaClEncryptor) TotalLen() int {
|
||||
|
||||
// Frame Decryptors
|
||||
|
||||
type FrameConsumer func(*LocalConnection, *net.UDPAddr, []byte, []byte, uint16, []byte) error
|
||||
type FrameConsumer func(*LocalConnection, *net.UDPAddr, []byte, []byte, uint16, []byte)
|
||||
|
||||
type Decryptor interface {
|
||||
IterateFrames(FrameConsumer, *UDPPacket) error
|
||||
@@ -281,7 +281,7 @@ func NewNonDecryptor(conn *LocalConnection) *NonDecryptor {
|
||||
return &NonDecryptor{conn: conn}
|
||||
}
|
||||
|
||||
func (nd *NonDecryptor) IterateFrames(fun FrameConsumer, packet *UDPPacket) error {
|
||||
func (nd *NonDecryptor) IterateFrames(consumer FrameConsumer, packet *UDPPacket) error {
|
||||
buf := packet.Packet
|
||||
for len(buf) >= (2 + NameSize + NameSize) {
|
||||
srcNameByte := buf[:NameSize]
|
||||
@@ -295,10 +295,7 @@ func (nd *NonDecryptor) IterateFrames(fun FrameConsumer, packet *UDPPacket) erro
|
||||
}
|
||||
frame := buf[:length]
|
||||
buf = buf[length:]
|
||||
err := fun(nd.conn, packet.Sender, srcNameByte, dstNameByte, length, frame)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
consumer(nd.conn, packet.Sender, srcNameByte, dstNameByte, length, frame)
|
||||
}
|
||||
if len(buf) > 0 {
|
||||
return PacketDecodingError{Desc: fmt.Sprintf("%d octets of trailing garbage", len(buf))}
|
||||
@@ -348,13 +345,13 @@ func (nd *NaClDecryptor) ReceiveNonce(msg []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
func (nd *NaClDecryptor) IterateFrames(fun FrameConsumer, packet *UDPPacket) error {
|
||||
func (nd *NaClDecryptor) IterateFrames(consumer FrameConsumer, packet *UDPPacket) error {
|
||||
buf, err := nd.decrypt(packet.Packet)
|
||||
if err != nil {
|
||||
return PacketDecodingError{Fatal: true, Desc: fmt.Sprint("decryption failed; ", err)}
|
||||
}
|
||||
packet.Packet = buf
|
||||
return nd.NonDecryptor.IterateFrames(fun, packet)
|
||||
return nd.NonDecryptor.IterateFrames(consumer, packet)
|
||||
}
|
||||
|
||||
func (nd *NaClDecryptor) decrypt(buf []byte) ([]byte, error) {
|
||||
|
||||
@@ -25,21 +25,7 @@ func (dec *EthernetDecoder) DecodeLayers(data []byte) error {
|
||||
return dec.parser.DecodeLayers(data, &dec.decoded)
|
||||
}
|
||||
|
||||
func (dec *EthernetDecoder) CheckFrameTooBig(err error, sendFrame func([]byte) error) error {
|
||||
if ftbe, ok := err.(FrameTooBigError); ok {
|
||||
// we know: 1. ip is valid, 2. it was ip and DF was set
|
||||
icmpFrame, err := dec.formICMPMTUPacket(ftbe.EPMTU)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Sending ICMP 3,4 (%v -> %v): PMTU= %v\n", dec.ip.DstIP, dec.ip.SrcIP, ftbe.EPMTU)
|
||||
return sendFrame(icmpFrame)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (dec *EthernetDecoder) formICMPMTUPacket(mtu int) ([]byte, error) {
|
||||
func (dec *EthernetDecoder) sendICMPFragNeeded(mtu int, sendFrame func([]byte) error) error {
|
||||
buf := gopacket.NewSerializeBuffer()
|
||||
opts := gopacket.SerializeOptions{
|
||||
FixLengths: true,
|
||||
@@ -67,9 +53,11 @@ func (dec *EthernetDecoder) formICMPMTUPacket(mtu int) ([]byte, error) {
|
||||
Seq: uint16(mtu)},
|
||||
&payload)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
return err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
|
||||
log.Printf("Sending ICMP 3,4 (%v -> %v): PMTU= %v\n", dec.ip.DstIP, dec.ip.SrcIP, mtu)
|
||||
return sendFrame(buf.Bytes())
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
+23
-24
@@ -105,8 +105,6 @@ func (router *Router) sniff(pio PacketSourceSink) {
|
||||
log.Println("Sniffing traffic on", router.Iface)
|
||||
|
||||
dec := NewEthernetDecoder()
|
||||
injectFrame := func(frame []byte) error { return pio.WritePacket(frame) }
|
||||
checkFrameTooBig := func(err error) error { return dec.CheckFrameTooBig(err, injectFrame) }
|
||||
mac := router.Iface.HardwareAddr
|
||||
if router.Macs.Enter(mac, router.Ourself.Peer) {
|
||||
log.Println("Discovered our MAC", mac)
|
||||
@@ -116,12 +114,12 @@ func (router *Router) sniff(pio PacketSourceSink) {
|
||||
pkt, err := pio.ReadPacket()
|
||||
checkFatal(err)
|
||||
router.LogFrame("Sniffed", pkt, nil)
|
||||
checkWarn(router.handleCapturedPacket(pkt, dec, checkFrameTooBig))
|
||||
checkWarn(router.handleCapturedPacket(pkt, dec, pio))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (router *Router) handleCapturedPacket(frameData []byte, dec *EthernetDecoder, checkFrameTooBig func(error) error) error {
|
||||
func (router *Router) handleCapturedPacket(frameData []byte, dec *EthernetDecoder, po PacketSink) error {
|
||||
dec.DecodeLayers(frameData)
|
||||
decodedLen := len(dec.decoded)
|
||||
if decodedLen == 0 {
|
||||
@@ -163,7 +161,11 @@ func (router *Router) handleCapturedPacket(frameData []byte, dec *EthernetDecode
|
||||
router.Ourself.Broadcast(df, frameCopy, dec)
|
||||
return nil
|
||||
} else {
|
||||
return checkFrameTooBig(router.Ourself.Forward(dstPeer, df, frameCopy, dec))
|
||||
err := router.Ourself.Forward(dstPeer, df, frameCopy, dec)
|
||||
if ftbe, ok := err.(FrameTooBigError); ok {
|
||||
err = dec.sendICMPFragNeeded(ftbe.EPMTU, po.WritePacket)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,32 +269,22 @@ func (router *Router) udpReader(conn *net.UDPConn, po PacketSink) {
|
||||
}
|
||||
|
||||
func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) FrameConsumer {
|
||||
checkFrameTooBig := func(err error, srcPeer *Peer) error {
|
||||
if err == nil { // optimisation: avoid closure creation in common case
|
||||
return nil
|
||||
}
|
||||
return dec.CheckFrameTooBig(err,
|
||||
func(icmpFrame []byte) error {
|
||||
return router.Ourself.Forward(srcPeer, false, icmpFrame, nil)
|
||||
})
|
||||
}
|
||||
|
||||
return func(relayConn *LocalConnection, sender *net.UDPAddr, srcNameByte, dstNameByte []byte, frameLen uint16, frame []byte) error {
|
||||
return func(relayConn *LocalConnection, sender *net.UDPAddr, srcNameByte, dstNameByte []byte, frameLen uint16, frame []byte) {
|
||||
srcName := PeerNameFromBin(srcNameByte)
|
||||
dstName := PeerNameFromBin(dstNameByte)
|
||||
srcPeer, found := router.Peers.Fetch(srcName)
|
||||
if !found {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
dstPeer, found := router.Peers.Fetch(dstName)
|
||||
if !found {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
dec.DecodeLayers(frame)
|
||||
decodedLen := len(dec.decoded)
|
||||
if decodedLen == 0 {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
// Handle special frames produced internally (rather than
|
||||
// captured/forwarded) by the remote router.
|
||||
@@ -306,7 +298,7 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
|
||||
if srcPeer != relayConn.Remote() || dstPeer != router.Ourself.Peer {
|
||||
// A special frame not originating from the remote, or
|
||||
// not for us? How odd; let's just drop it.
|
||||
return nil
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case frameLen == EthernetOverhead+8:
|
||||
@@ -319,7 +311,7 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
|
||||
binary.BigEndian.PutUint16(frameLenBytes, uint16(frameLen-EthernetOverhead))
|
||||
relayConn.SendProtocolMsg(ProtocolMsg{ProtocolPMTUVerified, frameLenBytes})
|
||||
}
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
df := decodedLen == 2 && (dec.ip.Flags&layers.IPv4DontFragment != 0)
|
||||
@@ -331,7 +323,16 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
|
||||
} else {
|
||||
router.LogFrame("Relaying", frame, &dec.eth)
|
||||
}
|
||||
return checkFrameTooBig(router.Ourself.Relay(srcPeer, dstPeer, df, frame, dec), srcPeer)
|
||||
|
||||
err := router.Ourself.Relay(srcPeer, dstPeer, df, frame, dec)
|
||||
if ftbe, ok := err.(FrameTooBigError); ok {
|
||||
err = dec.sendICMPFragNeeded(ftbe.EPMTU, func(icmpFrame []byte) error {
|
||||
return router.Ourself.Forward(srcPeer, false, icmpFrame, nil)
|
||||
})
|
||||
}
|
||||
|
||||
checkWarn(err)
|
||||
return
|
||||
}
|
||||
|
||||
srcMac := dec.eth.SrcMAC
|
||||
@@ -348,8 +349,6 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
|
||||
router.LogFrame("Relaying broadcast", frame, &dec.eth)
|
||||
router.Ourself.RelayBroadcast(srcPeer, df, frame, dec)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user