]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: after missing segments, be liberal on RST
authorVictor Julien <vjulien@oisf.net>
Sun, 28 Nov 2021 18:20:58 +0000 (19:20 +0100)
committerVictor Julien <vjulien@oisf.net>
Mon, 13 Jun 2022 10:58:20 +0000 (12:58 +0200)
This avoids long lasting inactive flows because in the most likely
case the RST did in fact end the connection. However Suricata may
still consider it to be "established".

src/stream-tcp-list.c
src/stream-tcp-private.h
src/stream-tcp-reassemble.c
src/stream-tcp.c

index 5ead97834e52e14a579166e5afe810198fe5a28d..7dde2b0ea9343d7a62ab05bee5198a1e510bba87 100644 (file)
@@ -651,6 +651,9 @@ int StreamTcpReassembleInsertSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_
             StatsIncr(tv, ra_ctx->counter_tcp_reass_data_normal_fail);
             StreamTcpRemoveSegmentFromStream(stream, seg);
             StreamTcpSegmentReturntoPool(seg);
+            if (res == -1) {
+                SCReturnInt(-ENOMEM);
+            }
             SCReturnInt(-1);
         }
 
index 8f35c8264bd5074053f63b94e62f87db0ce56d74..8cc1cfca39522526baa0bad93890ba252df89eb9 100644 (file)
@@ -283,6 +283,7 @@ typedef struct TcpSession_ {
     /* coccinelle: TcpSession:flags:STREAMTCP_FLAG */
     uint16_t flags;
     uint32_t reassembly_depth;      /**< reassembly depth for the stream */
+    bool lossy_be_liberal;
     TcpStream server;
     TcpStream client;
     TcpStateQueue *queue;                   /**< list of SYN/ACK candidates */
index a986e27248edb5624ee6f824f01dd127db2e71ac..d3de6c054ed1fe861a365367b535e886fdf2a42e 100644 (file)
@@ -748,6 +748,7 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre
     if (seg == NULL) {
         SCLogDebug("segment_pool is empty");
         StreamTcpSetEvent(p, STREAM_REASSEMBLY_NO_SEGMENT);
+        ssn->lossy_be_liberal = true;
         SCReturnInt(-1);
     }
 
@@ -767,7 +768,12 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre
                 APPLAYER_PROTO_DETECTION_SKIPPED);
     }
 
-    if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, seg, p, TCP_GET_SEQ(p), p->payload, p->payload_len) != 0) {
+    int r = StreamTcpReassembleInsertSegment(
+            tv, ra_ctx, stream, seg, p, TCP_GET_SEQ(p), p->payload, p->payload_len);
+    if (r < 0) {
+        if (r == -ENOMEM) {
+            ssn->lossy_be_liberal = true;
+        }
         SCLogDebug("StreamTcpReassembleInsertSegment failed");
         SCReturnInt(-1);
     }
@@ -1204,6 +1210,7 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv,
 
             StreamTcpSetEvent(p, STREAM_REASSEMBLY_SEQ_GAP);
             StatsIncr(tv, ra_ctx->counter_tcp_reass_gap);
+            ssn->lossy_be_liberal = true;
 
             /* AppLayerHandleTCPData has likely updated progress. */
             const bool no_progress_update = (app_progress == STREAM_APP_PROGRESS(*stream));
index f083fe1af19169db544787ecf99300300a8912a5..41e2473e2ad0bd95a51f518ace37b63f73330bfa 100644 (file)
@@ -5468,6 +5468,10 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p)
 {
     uint8_t os_policy;
 
+    if (ssn->lossy_be_liberal) {
+        SCReturnInt(1);
+    }
+
     if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
         if (!StreamTcpValidateTimestamp(ssn, p)) {
             SCReturnInt(0);