From 165f129c61c74d18deff78449636c5880e997bcc Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Fri, 11 Apr 2014 10:08:55 +0200 Subject: [PATCH] stream: detect data gap at stream start In midstream mode we may encounter a case where the data we is beyond the isn, but below last_ack. This means we're missing some data, that is already acked so it won't be retransmitted. Therefore, we can conclude it's a data gap. --- src/stream-tcp-reassemble.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 386eb96ba2..4e9bc440fc 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -2895,6 +2895,33 @@ int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, /* loop through the segments and fill one or more msgs */ TcpSegment *seg = stream->seg_list; SCLogDebug("pre-loop seg %p", seg); + + /* Check if we have a gap at the start of the list. If last_ack is + * bigger than the list start and the list start is bigger than + * next_seq, we know we are missing data that has been ack'd. That + * won't get retransmitted, so it's a data gap. + */ + if (!(p->flow->flags & FLOW_NO_APPLAYER_INSPECTION)) { + if (SEQ_GT(seg->seq, next_seq) && SEQ_LT(seg->seq, stream->last_ack)) { + /* send gap signal */ + STREAM_SET_FLAGS(ssn, stream, p, flags); + AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, + NULL, 0, flags|STREAM_GAP); + AppLayerProfilingStore(ra_ctx->app_tctx, p); + + /* set a GAP flag and make sure not bothering this stream anymore */ + SCLogDebug("STREAMTCP_STREAM_FLAG_GAP set"); + stream->flags |= STREAMTCP_STREAM_FLAG_GAP; + + StreamTcpSetEvent(p, STREAM_REASSEMBLY_SEQ_GAP); + SCPerfCounterIncr(ra_ctx->counter_tcp_reass_gap, tv->sc_perf_pca); +#ifdef DEBUG + dbg_app_layer_gap++; +#endif + SCReturnInt(0); + } + } + for (; seg != NULL && SEQ_LT(seg->seq, stream->last_ack);) { SCLogDebug("seg %p, SEQ %"PRIu32", LEN %"PRIu16", SUM %"PRIu32,