From: Victor Julien Date: Sat, 18 Feb 2017 23:54:45 +0000 (+0100) Subject: stream: set 'trigger raw' per direction X-Git-Tag: suricata-4.0.0-beta1~170 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d223b69cd74f5afbed24c309cb355a4de65ba97;p=thirdparty%2Fsuricata.git stream: set 'trigger raw' per direction --- diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 5b8e61c25f..3588a9e88b 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -1974,7 +1974,7 @@ static int HTPCallbackRequest(htp_tx_t *tx) /* request done, do raw reassembly now to inspect state and stream * at the same time. */ - AppLayerParserTriggerRawStreamReassembly(hstate->f); + AppLayerParserTriggerRawStreamReassembly(hstate->f, STREAM_TOSERVER); SCReturnInt(HTP_OK); } @@ -2010,7 +2010,7 @@ static int HTPCallbackResponse(htp_tx_t *tx) /* response done, do raw reassembly now to inspect state and stream * at the same time. */ - AppLayerParserTriggerRawStreamReassembly(hstate->f); + AppLayerParserTriggerRawStreamReassembly(hstate->f, STREAM_TOCLIENT); SCReturnInt(HTP_OK); } diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index 49975175eb..483724d480 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -1153,12 +1153,13 @@ int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto) SCReturnInt(r); } -void AppLayerParserTriggerRawStreamReassembly(Flow *f) +void AppLayerParserTriggerRawStreamReassembly(Flow *f, int direction) { SCEnter(); + SCLogDebug("f %p tcp %p direction %d", f, f ? f->protoctx : NULL, direction); if (f != NULL && f->protoctx != NULL) - StreamTcpReassembleTriggerRawReassembly(f->protoctx); + StreamTcpReassembleTriggerRawReassembly(f->protoctx, direction); SCReturn; } diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index 29e668ce7f..c31a9d9a96 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -207,7 +207,7 @@ int AppLayerParserProtocolIsTxAware(uint8_t ipproto, AppProto alproto); int AppLayerParserProtocolIsTxEventAware(uint8_t ipproto, AppProto alproto); int AppLayerParserProtocolSupportsTxs(uint8_t ipproto, AppProto alproto); int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto); -void AppLayerParserTriggerRawStreamReassembly(Flow *f); +void AppLayerParserTriggerRawStreamReassembly(Flow *f, int direction); void AppLayerParserSetStreamDepth(uint8_t ipproto, AppProto alproto, uint32_t stream_depth); uint32_t AppLayerParserGetStreamDepth(uint8_t ipproto, AppProto alproto); diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index 2397739819..47c3e9ef60 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -1286,7 +1286,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, } SCLogDebug("trigger RAW! (post HS)"); - AppLayerParserTriggerRawStreamReassembly(ssl_state->f); + AppLayerParserTriggerRawStreamReassembly(ssl_state->f, + direction == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT); return parsed; } @@ -1317,7 +1318,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, } SCLogDebug("record complete, trigger RAW"); - AppLayerParserTriggerRawStreamReassembly(ssl_state->f); + AppLayerParserTriggerRawStreamReassembly(ssl_state->f, + direction == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT); /* looks like we have another record */ uint32_t diff = ssl_state->curr_connp->record_length + diff --git a/src/stream-tcp-private.h b/src/stream-tcp-private.h index f51e8ac8ff..9569be4edb 100644 --- a/src/stream-tcp-private.h +++ b/src/stream-tcp-private.h @@ -150,7 +150,7 @@ enum #define STREAMTCP_FLAG_SACKOK 0x0400 /** Flag for triggering RAW reassembly before the size limit is reached or the stream reaches EOF. */ -#define STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY 0x0800 +//#define STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY 0x0800 /** 3WHS confirmed by server -- if suri sees 3whs ACK but server doesn't (pkt * is lost on the way to server), SYN/ACK is retransmitted. If server sends * normal packet we assume 3whs to be completed. Only used for SYN/ACK resend @@ -171,7 +171,8 @@ enum #define STREAMTCP_STREAM_FLAG_KEEPALIVE 0x0004 /** Stream has reached it's reassembly depth, all further packets are ignored */ #define STREAMTCP_STREAM_FLAG_DEPTH_REACHED 0x0008 -// vacancy +/** Trigger reassembly next time we need 'raw' */ +#define STREAMTCP_STREAM_FLAG_TRIGGER_RAW 0x0010 /** Stream supports TIMESTAMP -- used to set ssn STREAMTCP_FLAG_TIMESTAMP * flag. */ #define STREAMTCP_STREAM_FLAG_TIMESTAMP 0x0020 diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 48587b7efc..39e9ea9ea5 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -701,7 +701,7 @@ static uint8_t StreamGetAppLayerFlags(TcpSession *ssn, TcpStream *stream, * \retval 0 don't reassemble yet * \retval 1 do reassemble */ -static int StreamTcpReassembleRawCheckLimit(TcpSession *ssn, +static int StreamTcpReassembleRawCheckLimit(const TcpSession *ssn, const TcpStream *stream, const Packet *p) { SCEnter(); @@ -711,9 +711,8 @@ static int StreamTcpReassembleRawCheckLimit(TcpSession *ssn, SCReturnInt(1); } - if (ssn->flags & STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY) { - SCLogDebug("reassembling now as STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY is set"); - ssn->flags &= ~STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY; + if (stream->flags & STREAMTCP_STREAM_FLAG_TRIGGER_RAW) { + SCLogDebug("reassembling now as STREAMTCP_STREAM_FLAG_TRIGGER_RAW is set"); SCReturnInt(1); } @@ -1205,6 +1204,7 @@ void StreamReassembleRawUpdateProgress(TcpSession *ssn, Packet *p, uint64_t prog if (progress > STREAM_RAW_PROGRESS(stream)) { uint32_t slide = progress - STREAM_RAW_PROGRESS(stream); stream->raw_progress_rel += slide; + stream->flags &= ~STREAMTCP_STREAM_FLAG_TRIGGER_RAW; } SCLogDebug("stream raw progress now %"PRIu64, STREAM_RAW_PROGRESS(stream)); @@ -1249,6 +1249,13 @@ int StreamReassembleRaw(TcpSession *ssn, const Packet *p, stream = &ssn->server; } + if (StreamTcpInlineMode() == FALSE && + StreamTcpReassembleRawCheckLimit(ssn, stream, p) == 0) + { + *progress_out = STREAM_RAW_PROGRESS(stream); + return 0; + } + StreamingBufferBlock *iter = NULL; uint64_t progress = STREAM_RAW_PROGRESS(stream); uint64_t last_ack_abs = 0; /* absolute right edge of ack'd data */ @@ -1482,21 +1489,25 @@ TcpSegment *StreamTcpGetSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx) * reassembly from the applayer, for example upon completion of a * HTTP request. * - * Works by setting a flag in the TcpSession that is unset as soon - * as it's checked. Since everything happens when operating under - * a single lock period, no side effects are expected. + * It sets a flag in the stream so that the next Raw call will return + * the data. * * \param ssn TcpSession */ -void StreamTcpReassembleTriggerRawReassembly(TcpSession *ssn) +void StreamTcpReassembleTriggerRawReassembly(TcpSession *ssn, int direction) { #ifdef DEBUG BUG_ON(ssn == NULL); #endif if (ssn != NULL) { + if (direction == STREAM_TOSERVER) { + ssn->client.flags |= STREAMTCP_STREAM_FLAG_TRIGGER_RAW; + } else { + ssn->server.flags |= STREAMTCP_STREAM_FLAG_TRIGGER_RAW; + } + SCLogDebug("flagged ssn %p for immediate raw reassembly", ssn); - ssn->flags |= STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY; } } diff --git a/src/stream-tcp-reassemble.h b/src/stream-tcp-reassemble.h index f2bbf277e5..d8aaad15f0 100644 --- a/src/stream-tcp-reassemble.h +++ b/src/stream-tcp-reassemble.h @@ -101,7 +101,7 @@ TcpSegment *StreamTcpGetSegment(ThreadVars *, TcpReassemblyThreadCtx *); void StreamTcpReturnStreamSegments(TcpStream *); void StreamTcpSegmentReturntoPool(TcpSegment *); -void StreamTcpReassembleTriggerRawReassembly(TcpSession *); +void StreamTcpReassembleTriggerRawReassembly(TcpSession *, int direction); void StreamTcpPruneSession(Flow *, uint8_t); int StreamTcpReassembleDepthReached(Packet *p);