func (tcp *Tcp) Process(tcphdr *layers.TCP, pkt *protos.Packet) { // This Recover should catch all exceptions in // protocol modules. defer logp.Recover("FollowTcp exception") stream, exists := tcp.streamsMap[pkt.Tuple.Hashable()] var original_dir uint8 = TcpDirectionOriginal created := false if !exists { stream, exists = tcp.streamsMap[pkt.Tuple.RevHashable()] if !exists { protocol := tcp.decideProtocol(&pkt.Tuple) if protocol == protos.UnknownProtocol { // don't follow return } logp.Debug("tcp", "Stream doesn't exists, creating new") // create stream = &TcpStream{id: tcp.getId(), tuple: &pkt.Tuple, protocol: protocol, tcp: tcp} stream.tcptuple = common.TcpTupleFromIpPort(stream.tuple, stream.id) tcp.streamsMap[pkt.Tuple.Hashable()] = stream created = true } else { original_dir = TcpDirectionReverse } } tcp_start_seq := tcphdr.Seq tcp_seq := tcp_start_seq + uint32(len(pkt.Payload)) logp.Debug("tcp", "pkt.start_seq=%v pkt.last_seq=%v stream.last_seq=%v (len=%d)", tcp_start_seq, tcp_seq, stream.lastSeq[original_dir], len(pkt.Payload)) if len(pkt.Payload) > 0 && stream.lastSeq[original_dir] != 0 { if TcpSeqBeforeEq(tcp_seq, stream.lastSeq[original_dir]) { logp.Debug("tcp", "Ignoring what looks like a retrasmitted segment. pkt.seq=%v len=%v stream.seq=%v", tcphdr.Seq, len(pkt.Payload), stream.lastSeq[original_dir]) return } if TcpSeqBefore(stream.lastSeq[original_dir], tcp_start_seq) { if !created { logp.Debug("tcp", "Gap in tcp stream. last_seq: %d, seq: %d", stream.lastSeq[original_dir], tcp_start_seq) drop := stream.GapInStream(original_dir, int(tcp_start_seq-stream.lastSeq[original_dir])) if drop { logp.Debug("tcp", "Dropping stream because of gap") stream.Expire() } } } } stream.lastSeq[original_dir] = tcp_seq stream.AddPacket(pkt, tcphdr, original_dir) }
func (tcp *Tcp) Process(tcphdr *layers.TCP, pkt *protos.Packet) { // This Recover should catch all exceptions in // protocol modules. defer logp.Recover("Process tcp exception") stream := tcp.getStream(pkt.Tuple.Hashable()) var original_dir uint8 = TcpDirectionOriginal created := false if stream == nil { stream = tcp.getStream(pkt.Tuple.RevHashable()) if stream == nil { protocol := tcp.decideProtocol(&pkt.Tuple) if protocol == protos.UnknownProtocol { // don't follow return } timeout := time.Duration(0) mod := tcp.protocols.GetTcp(protocol) if mod != nil { timeout = mod.ConnectionTimeout() } logp.Debug("tcp", "Stream doesn't exist, creating new") // create stream = &TcpStream{id: tcp.getId(), tuple: &pkt.Tuple, protocol: protocol, tcp: tcp} stream.tcptuple = common.TcpTupleFromIpPort(stream.tuple, stream.id) tcp.streams.PutWithTimeout(pkt.Tuple.Hashable(), stream, timeout) created = true } else { original_dir = TcpDirectionReverse } } tcp_start_seq := tcphdr.Seq tcp_seq := tcp_start_seq + uint32(len(pkt.Payload)) logp.Debug("tcp", "pkt.start_seq=%v pkt.last_seq=%v stream.last_seq=%v (len=%d)", tcp_start_seq, tcp_seq, stream.lastSeq[original_dir], len(pkt.Payload)) if len(pkt.Payload) > 0 && stream.lastSeq[original_dir] != 0 { if tcpSeqBeforeEq(tcp_seq, stream.lastSeq[original_dir]) { logp.Debug("tcp", "Ignoring what looks like a retransmitted segment. pkt.seq=%v len=%v stream.seq=%v", tcphdr.Seq, len(pkt.Payload), stream.lastSeq[original_dir]) return } if tcpSeqBefore(stream.lastSeq[original_dir], tcp_start_seq) { if !created { logp.Debug("tcp", "Gap in tcp stream. last_seq: %d, seq: %d", stream.lastSeq[original_dir], tcp_start_seq) drop := stream.gapInStream(original_dir, int(tcp_start_seq-stream.lastSeq[original_dir])) if drop { logp.Debug("tcp", "Dropping stream because of gap") tcp.streams.Delete(stream.tuple.Hashable()) } } } } stream.lastSeq[original_dir] = tcp_seq stream.addPacket(pkt, tcphdr, original_dir) }