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);
}
#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
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,