refactor(ish) of special frame processing in udp frame handler

- pull all special frame handling in one place
- generalise the condition for detecting special frames
- add some explanation
This commit is contained in:
Matthias Radestock committed 2015-01-17 16:48:00 +00:00
1 parent c6898de4c0
commit aceaa66903
2 files changed
+31 -29

No files matched your search

+3 -3
View File
@@ -75,7 +75,7 @@ func (dec *EthernetDecoder) DropFrame() bool {
return bytes.Equal(stpMACPrefix, dec.eth.DstMAC[:len(stpMACPrefix)])
}
func (dec *EthernetDecoder) IsPMTUVerify() bool {
return bytes.Equal(zeroMAC, dec.eth.SrcMAC) &&
bytes.Equal(zeroMAC, dec.eth.DstMAC)
func (dec *EthernetDecoder) IsSpecial() bool {
return dec.eth.Length == 0 && dec.eth.EthernetType == layers.EthernetTypeLLC &&
bytes.Equal(zeroMAC, dec.eth.SrcMAC) && bytes.Equal(zeroMAC, dec.eth.DstMAC)
}
+28 -26
View File
@@ -247,13 +247,38 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
dec.DecodeLayers(frame)
decodedLen := len(dec.decoded)
// Handle special frames produced internally (rather than
// captured/forwarded) by the remote router.
//
// We really shouldn't be decoding these above, since they are
// not genuine Ethernet frames. However, it is actually more
// efficient to do so, as we want to optimise for the common
// (i.e. non-special) frames. These always need decoding, and
// detecting special frames is cheaper post decoding than pre.
if decodedLen == 0 || (decodedLen == 1 && dec.IsSpecial()) {
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
}
if frameLen == 0 {
relayConn.ReceivedHeartbeat(sender)
} else if frameLen == FragTestSize && bytes.Equal(frame, FragTest) {
relayConn.SendTCP(ProtocolFragmentationReceivedByte)
} else if frameLen == PMTUDiscoverySize && bytes.Equal(frame, PMTUDiscovery) {
} else if decodedLen == 1 {
frameLenBytes := []byte{0, 0}
binary.BigEndian.PutUint16(frameLenBytes, uint16(frameLen-EthernetOverhead))
relayConn.SendTCP(Concat(ProtocolPMTUVerifiedByte, frameLenBytes))
}
return nil
}
df := decodedLen == 2 && (dec.ip.Flags&layers.IPv4DontFragment != 0)
if dstPeer != router.Ourself.Peer {
// it's not for us, we're just relaying it
if decodedLen == 0 {
return nil
}
if df {
router.LogFrame("Relaying DF", frame, &dec.eth)
} else {
@@ -262,29 +287,6 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
return checkFrameTooBig(router.Ourself.Relay(srcPeer, dstPeer, df, frame, dec), srcPeer)
}
if relayConn.Remote() == srcPeer {
if frameLen == 0 {
relayConn.ReceivedHeartbeat(sender)
return nil
} else if frameLen == FragTestSize && bytes.Equal(frame, FragTest) {
relayConn.SendTCP(ProtocolFragmentationReceivedByte)
return nil
} else if frameLen == PMTUDiscoverySize && bytes.Equal(frame, PMTUDiscovery) {
return nil
}
}
if decodedLen == 0 {
return nil
}
if dec.IsPMTUVerify() && relayConn.Remote() == srcPeer {
frameLenBytes := []byte{0, 0}
binary.BigEndian.PutUint16(frameLenBytes, uint16(frameLen-EthernetOverhead))
relayConn.SendTCP(Concat(ProtocolPMTUVerifiedByte, frameLenBytes))
return nil
}
srcMac := dec.eth.SrcMAC
dstMac := dec.eth.DstMAC