// GapInStream is called by TCP layer when a packets are missing from the tcp // stream. func (mc *Memcache) GapInStream( tcptuple *common.TcpTuple, dir uint8, nbytes int, private protos.ProtocolData, ) (priv protos.ProtocolData, drop bool) { debug("memcache(tcp) stream gap detected") defer logp.Recover("GapInStream(memcache) exception") if !isMemcacheConnection(private) { return private, false } conn := private.(*tcpConnectionData) stream := conn.Streams[dir] parser := stream.parser msg := parser.message if msg != nil { if msg.IsRequest { msg.AddNotes(NoteRequestPacketLoss) } else { msg.AddNotes(NoteResponsePacketLoss) } } // If we are about to read binary data (length) encoded, but missing gab // does fully cover data area, we might be able to continue processing the // stream + transactions inData := parser.state == parseStateDataBinary || parser.state == parseStateIncompleteDataBinary || parser.state == parseStateData || parser.state == parseStateIncompleteData if inData { if msg == nil { logp.WTF("parser message is nil on data load") return private, true } alreadyRead := stream.Buf.Len() - int(msg.bytesLost) dataRequired := int(msg.bytes) - alreadyRead if nbytes <= dataRequired { // yay, all bytes included in message binary data part. // just drop binary data part and recover parsing. if msg.isBinary { parser.state = parseStateIncompleteDataBinary } else { parser.state = parseStateIncompleteData } msg.bytesLost += uint(nbytes) return private, false } } // need to drop TCP stream. But try to publish all cached trancsactions first mc.pushAllTCPTrans(conn.connection) return private, true }
func requiresCounterpart(tuple *icmpTuple, msg *icmpMessage) bool { if tuple.IcmpVersion == 4 { return icmp4PairTypes[msg.Type] } if tuple.IcmpVersion == 6 { return icmp6PairTypes[msg.Type] } logp.WTF("icmp", "Invalid ICMP version[%d]", tuple.IcmpVersion) return false }
func isError(tuple *icmpTuple, msg *icmpMessage) bool { if tuple.IcmpVersion == 4 { return icmp4ErrorTypes[msg.Type] } if tuple.IcmpVersion == 6 { return icmp6ErrorTypes[msg.Type] } logp.WTF("icmp", "Invalid ICMP version[%d]", tuple.IcmpVersion) return true }
func isRequest(tuple *icmpTuple, msg *icmpMessage) bool { if tuple.IcmpVersion == 4 { return !icmp4ResponseTypes[msg.Type] } if tuple.IcmpVersion == 6 { return !icmp6ResponseTypes[msg.Type] } logp.WTF("icmp", "Invalid ICMP version[%d]", tuple.IcmpVersion) return true }
func humanReadable(tuple *icmpTuple, msg *icmpMessage) string { if tuple.IcmpVersion == 4 { return layers.ICMPv4TypeCode(binary.BigEndian.Uint16([]byte{msg.Type, msg.Code})).String() } if tuple.IcmpVersion == 6 { return layers.ICMPv6TypeCode(binary.BigEndian.Uint16([]byte{msg.Type, msg.Code})).String() } logp.WTF("icmp", "Invalid ICMP version[%d]", tuple.IcmpVersion) return "" }
func extractTrackingData(icmpVersion uint8, msgType uint8, baseLayer *layers.BaseLayer) (uint16, uint16) { if icmpVersion == 4 { if icmp4PairTypes[msgType] { id := binary.BigEndian.Uint16(baseLayer.Contents[4:6]) seq := binary.BigEndian.Uint16(baseLayer.Contents[6:8]) return id, seq } return 0, 0 } if icmpVersion == 6 { if icmp6PairTypes[msgType] { id := binary.BigEndian.Uint16(baseLayer.Contents[4:6]) seq := binary.BigEndian.Uint16(baseLayer.Contents[6:8]) return id, seq } return 0, 0 } logp.WTF("icmp", "Invalid ICMP version[%d]", icmpVersion) return 0, 0 }
func (mc *Memcache) InitDefaults() { if err := mc.Ports.Init(11211); err != nil { logp.WTF("memcache default port number invalid") } mc.handler = mc }