From: Victor Julien Date: Sat, 25 Feb 2017 12:33:40 +0000 (+0100) Subject: stream: allow raw reassembly catch up X-Git-Tag: suricata-4.0.0-beta1~163 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7c56c9ada0a9db67c6ca0fc8736a1cc46cbf52d5;p=thirdparty%2Fsuricata.git stream: allow raw reassembly catch up If raw reassembly falls behind, for example because no raw mpm is active, then we need to sync up to the app progress if that is available, or to the generic tcp tracking otherwise. --- diff --git a/src/detect.c b/src/detect.c index ae8d803f53..973aa370e4 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1432,8 +1432,7 @@ end: } /* update inspected tracker for raw reassembly */ - if (p->proto == IPPROTO_TCP && pflow->protoctx != NULL && - det_ctx->raw_stream_progress > 0) + if (p->proto == IPPROTO_TCP && pflow->protoctx != NULL) { StreamReassembleRawUpdateProgress(pflow->protoctx, p, det_ctx->raw_stream_progress); diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 60fc2e6b05..75e6b28278 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -1237,7 +1237,14 @@ bool StreamReassembleRawHasDataReady(TcpSession *ssn, Packet *p) return false; } -/** \brief Update stream after inspection has run +/** \brief update stream engine after detection + * + * Tasked with progressing the 'progress' for Raw reassembly. + * 2 main scenario's: + * 1. progress is != 0, so we use this + * 2. progress is 0, meaning the detect engine didn't touch + * raw at all. In this case we need to look into progressing + * raw anyway. */ void StreamReassembleRawUpdateProgress(TcpSession *ssn, Packet *p, uint64_t progress) { @@ -1252,6 +1259,48 @@ void StreamReassembleRawUpdateProgress(TcpSession *ssn, Packet *p, uint64_t prog uint32_t slide = progress - STREAM_RAW_PROGRESS(stream); stream->raw_progress_rel += slide; stream->flags &= ~STREAMTCP_STREAM_FLAG_TRIGGER_RAW; + + /* if app is active and beyond raw, sync raw to app */ + } else if (progress == 0 && + STREAM_APP_PROGRESS(stream) > STREAM_RAW_PROGRESS(stream) && + !(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) && + !(stream->flags & STREAMTCP_STREAM_FLAG_GAP)) + { + /* if trigger raw is set we sync the 2 trackers */ + if (stream->flags & STREAMTCP_STREAM_FLAG_TRIGGER_RAW) + { + uint32_t slide = STREAM_APP_PROGRESS(stream) - STREAM_RAW_PROGRESS(stream); + stream->raw_progress_rel += slide; + stream->flags &= ~STREAMTCP_STREAM_FLAG_TRIGGER_RAW; + + /* otherwise mix in the tcp window */ + } else { + uint64_t tcp_window = stream->window; + if (tcp_window > 0 && STREAM_APP_PROGRESS(stream) > tcp_window) { + uint64_t new_raw = STREAM_APP_PROGRESS(stream) - tcp_window; + if (new_raw > STREAM_RAW_PROGRESS(stream)) { + uint32_t slide = new_raw - STREAM_RAW_PROGRESS(stream); + stream->raw_progress_rel += slide; + } + } + } + /* app is dead */ + } else if (progress == 0) { + uint64_t tcp_window = stream->window; + uint64_t stream_right_edge = STREAM_BASE_OFFSET(stream) + stream->sb.buf_offset; + if (tcp_window < stream_right_edge) { + uint64_t new_raw = stream_right_edge - tcp_window; + if (new_raw > STREAM_RAW_PROGRESS(stream)) { + uint32_t slide = new_raw - STREAM_RAW_PROGRESS(stream); + stream->raw_progress_rel += slide; + } + } + stream->flags &= ~STREAMTCP_STREAM_FLAG_TRIGGER_RAW; + + } else { + SCLogDebug("p->pcap_cnt %u: progress %u app %u raw %u tcp win %u", + (uint)p->pcap_cnt, (uint)progress, (uint)STREAM_APP_PROGRESS(stream), + (uint)STREAM_RAW_PROGRESS(stream), (uint)stream->window); } SCLogDebug("stream raw progress now %"PRIu64, STREAM_RAW_PROGRESS(stream));