From ed46fd715d6e5a2a01441efd661221a5c000cf12 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Fri, 11 Apr 2014 10:11:04 +0200 Subject: [PATCH] stream: improve midstream reassembly gap detection 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 | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 4e9bc440fc..c7540fa7f4 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -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 -