]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream/tcp: allow tcp session reuse on null sessions
authorVictor Julien <vjulien@oisf.net>
Thu, 2 Feb 2023 13:45:30 +0000 (14:45 +0100)
committerVictor Julien <vjulien@oisf.net>
Fri, 3 Feb 2023 06:18:24 +0000 (07:18 +0100)
When a "stream starter" packet finds an existing TCP flow, the flow will be
evaluated for reuse.

The following scenario wasn't handled well:

1. Suricata starts after a tool has just stopped using lots of connections
   (e.g. ab stress testing a webserver)
2. even though the client is closed already, the server is still doing
   connection cleanup sending many FINs and later RSTs
3. Suricata creates flows for these packets, but no TCP sessions
4. client resumes testing, creating flows that have the same 5 tuple as the
   flows created for the FIN/RST packets
5. Suricata refuses to "reuse" the flows as the condition "tcp flow w/o session"
   is not considered valid for session reuse
6. new TCP connection is not properly tracked and evaluated in parsing and
   detection

There may be other vectors into this, like a flow w/o session because of
memcap issues.

Bug: #5843.

src/stream-tcp.c

index 2ab8ef081c967c099c54f7eff884a14d94929d9f..cac98ce3d7053bbcabd0763ee436d190e7d86bcf 100644 (file)
@@ -5241,8 +5241,10 @@ static int TcpSessionReuseDoneEnoughSyn(const Packet *p, const Flow *f, const Tc
 {
     if (FlowGetPacketDirection(f, p) == TOSERVER) {
         if (ssn == NULL) {
-            SCLogDebug("steam starter packet %"PRIu64", ssn %p null. No reuse.", p->pcap_cnt, ssn);
-            return 0;
+            /* most likely a flow that was picked up after the 3whs, or a flow that
+             * does not have a session due to memcap issues. */
+            SCLogDebug("steam starter packet %" PRIu64 ", ssn %p null. Reuse.", p->pcap_cnt, ssn);
+            return 1;
         }
         if (SEQ_EQ(ssn->client.isn, TCP_GET_SEQ(p))) {
             SCLogDebug("steam starter packet %"PRIu64", ssn %p. Packet SEQ == Stream ISN. Retransmission. Don't reuse.", p->pcap_cnt, ssn);