]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: improve midstream reassembly gap detection
authorVictor Julien <victor@inliniac.net>
Fri, 11 Apr 2014 08:11:04 +0000 (10:11 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 22 Apr 2014 08:19:42 +0000 (10:19 +0200)
The reassembly gap detection makes use of the window. However, in
midstream mode the window size we use is unreliable, as we have to
assume window scaling is in place. This patch improves midstream
handling of those cases.

src/stream-tcp-reassemble.c

index 4e9bc440fca68833648ca10786be3e1429b8f7e9..c7540fa7f4a9b9f72a432f164e2259830c151337 100644 (file)
@@ -2998,9 +2998,20 @@ int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
                 data_len = 0;
             }
 
+            /* in midstream the window is unreliable as we don't know if
+             * window scaling is used. Therefore we assume max wscale and
+             * the window likely much larger than it should be. In our
+             * gap calc we cap it at 25k */
+            uint32_t window = stream->window;
+            if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) {
+                window = stream->window > 25000 ? 25000 : stream->window;
+                SCLogDebug("midstream: window for gap determination %u (%u)",
+                        window, stream->window);
+            }
+
             /* don't conclude it's a gap straight away. If ra_base_seq is lower
              * than last_ack - the window, we consider it a gap. */
-            if (SEQ_GT((stream->last_ack - stream->window), ra_base_seq) ||
+            if (SEQ_GT((stream->last_ack - window), ra_base_seq) ||
                 ssn->state > TCP_ESTABLISHED)
             {
                 /* see what the length of the gap is, gap length is seg->seq -
@@ -3355,9 +3366,20 @@ static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx,
                 smsg = NULL;
             }
 
+            /* in midstream the window is unreliable as we don't know if
+             * window scaling is used. Therefore we assume max wscale and
+             * the window likely much larger than it should be. In our
+             * gap calc we cap it at 25k */
+            uint32_t window = stream->window;
+            if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) {
+                window = stream->window > 25000 ? 25000 : stream->window;
+                SCLogDebug("midstream: window for gap determination %u (%u)",
+                        window, stream->window);
+            }
+
             /* don't conclude it's a gap straight away. If ra_base_seq is lower
              * than last_ack - the window, we consider it a gap. */
-            if (SEQ_GT((stream->last_ack - stream->window), ra_base_seq) ||
+            if (SEQ_GT((stream->last_ack - window), ra_base_seq) ||
                 ssn->state > TCP_ESTABLISHED)
             {
                 /* see what the length of the gap is, gap length is seg->seq -