diff --git a/src/flow-hash.c b/src/flow-hash.c index a2ce5708c9..1fea10a67d 100644 --- a/src/flow-hash.c +++ b/src/flow-hash.c @@ -390,10 +390,37 @@ static inline int FlowCompareICMPv4(Flow *f, const Packet *p) return 0; } +int TcpSessionPacketSsnReuse(const Packet *p, void *tcp_ssn); + static inline int FlowCompare(Flow *f, const Packet *p) { if (p->proto == IPPROTO_ICMP) { return FlowCompareICMPv4(f, p); + } else if (p->proto == IPPROTO_TCP) { + if (CMP_FLOW(f, p) == 0) + return 0; + + /* if this session is 'reused', we don't return it anymore, + * so return false on the compare */ + if (f->flags & FLOW_TCP_REUSED) + return 0; + + /* lets see if we need to consider the existing session for + * reuse: only considering SYN packets. */ + int syn = (p->tcph && ((p->tcph->th_flags & TH_SYN) == TH_SYN)); + int has_protoctx = ((f->protoctx != NULL)); + + /* syn on existing state, need to see if we need to 'reuse' */ + if (unlikely(syn && has_protoctx && FlowGetPacketDirection(f,p) == TOSERVER)) { + if (unlikely(TcpSessionPacketSsnReuse(p, f->protoctx) == 1)) { + /* okay, we need to setup a new flow for this packet. + * Flag the flow that it's been replaced by a new one */ + f->flags |= FLOW_TCP_REUSED; + SCLogDebug("flow obsolete: TCP reuse will use a new flow"); + return 0; + } + } + return 1; } else { return CMP_FLOW(f, p); } diff --git a/src/flow.h b/src/flow.h index bf38fa5543..0570adbc4d 100644 --- a/src/flow.h +++ b/src/flow.h @@ -46,9 +46,8 @@ typedef struct AppLayerParserState_ AppLayerParserState; #define FLOW_TO_SRC_SEEN 0x00000001 /** At least on packet from the destination address was seen */ #define FLOW_TO_DST_SEEN 0x00000002 - -// vacany 1x - +/** Don't return this from the flow hash. It has been replaced. */ +#define FLOW_TCP_REUSED 0x00000004 /** no magic on files in this flow */ #define FLOW_FILE_NO_MAGIC_TS 0x00000008 #define FLOW_FILE_NO_MAGIC_TC 0x00000010 diff --git a/src/stream-tcp.c b/src/stream-tcp.c index f0952719f2..f6d79eaf96 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -4386,6 +4386,17 @@ static int StreamTcpPacketIsBadWindowUpdate(TcpSession *ssn, Packet *p) return 0; } +int TcpSessionPacketSsnReuse(const Packet *p, void *tcp_ssn) +{ + TcpSession *ssn = tcp_ssn; + if (ssn->state == TCP_CLOSED) { + if(!(SEQ_EQ(ssn->client.isn, TCP_GET_SEQ(p)))) + { + return 1; + } + } + return 0; +} /* flow is and stays locked */ int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,