From: Victor Julien Date: Thu, 4 Jun 2020 19:12:15 +0000 (+0200) Subject: stream: app update from loop X-Git-Tag: suricata-6.0.0-beta1~98 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=57b75f89da8dbe8526434bfaf0cb883e3b107bbf;p=thirdparty%2Fsuricata.git stream: app update from loop When the stream engine has data ready for the app-layer it will call this API from a loop instead of just once. The loop is to ensure that if we have a very lossy stream where between 'app_progress' and 'last_ack' there are multiple chunks of data and multiple gaps we process all the chunks. --- diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 43bca85547..405fe48e3c 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2016 Open Information Security Foundation +/* Copyright (C) 2007-2020 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -1119,37 +1119,46 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv, mydata = NULL; mydata_len = 0; + SCLogDebug("%"PRIu64" got %p/%u", p->pcap_cnt, mydata, mydata_len); + break; } - SCLogDebug("%"PRIu64" got %p/%u", p->pcap_cnt, mydata, mydata_len); - break; - } - //PrintRawDataFp(stdout, mydata, mydata_len); + SCLogDebug("stream %p data in buffer %p of len %u and offset %"PRIu64, + *stream, &(*stream)->sb, mydata_len, app_progress); - SCLogDebug("stream %p data in buffer %p of len %u and offset %"PRIu64, - *stream, &(*stream)->sb, mydata_len, app_progress); + /* get window of data that is acked */ + mydata_len = AdjustToAcked(p, *stream, app_progress, mydata_len); + if (mydata_len == 0) + SCReturnInt(0); - /* get window of data that is acked */ - mydata_len = AdjustToAcked(p, *stream, app_progress, mydata_len); - - if ((p->flags & PKT_PSEUDO_STREAM_END) == 0 || ssn->state < TCP_CLOSED) { - if (mydata_len < (*stream)->data_required) { - if (gap_ahead) { - (*stream)->app_progress_rel += mydata_len; - (*stream)->data_required -= mydata_len; - // TODO send incomplete data to app-layer with special flag - // indicating its all there is for this rec? + if ((p->flags & PKT_PSEUDO_STREAM_END) == 0 || ssn->state < TCP_CLOSED) { + if (mydata_len < (*stream)->data_required) { + if (gap_ahead) { + SCLogDebug("GAP while expecting more data (expect %u, gap size %u)", + (*stream)->data_required, mydata_len); + (*stream)->app_progress_rel += mydata_len; + (*stream)->data_required -= mydata_len; + // TODO send incomplete data to app-layer with special flag + // indicating its all there is for this rec? + } else { + SCReturnInt(0); + } + app_progress = STREAM_APP_PROGRESS(*stream); + continue; } - SCReturnInt(0); } + (*stream)->data_required = 0; + + /* update the app-layer */ + (void)AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, + (uint8_t *)mydata, mydata_len, + StreamGetAppLayerFlags(ssn, *stream, p)); + AppLayerProfilingStore(ra_ctx->app_tctx, p); + uint64_t new_app_progress = STREAM_APP_PROGRESS(*stream); + if (new_app_progress == app_progress) + break; + app_progress = new_app_progress; } - (*stream)->data_required = 0; - - /* update the app-layer */ - (void)AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - (uint8_t *)mydata, mydata_len, - StreamGetAppLayerFlags(ssn, *stream, p)); - AppLayerProfilingStore(ra_ctx->app_tctx, p); SCReturnInt(0); }