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:
1 parent
c6898de4c0
commit
aceaa66903
2 files changed
+31
-29
No files matched your search
@@ -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
@@ -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
|
||||
|
||||
|
||||
Reference in new issue
Block a user