diff --git a/src/app-layer.c b/src/app-layer.c index 61fc26eb53..175953c646 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -29,6 +29,7 @@ #include "app-layer-detect-proto.h" #include "stream-tcp-reassemble.h" #include "stream-tcp-private.h" +#include "stream-tcp-inline.h" #include "flow.h" #include "flow-util.h" @@ -111,6 +112,12 @@ extern AlpProtoDetectCtx alp_proto_ctx; * \param data_len length of the data chunk * \param flags control flags * + * During detection this function can call the stream reassembly, + * inline or non-inline for the opposing direction, while already + * being called by the same stream reassembly for a particular + * direction. This should cause any issues, since processing of + * each stream is independent of the other stream. + * * \retval 0 ok * \retval -1 error */ @@ -203,27 +210,56 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream); /* if we have seen data from the other direction first, send - * data for that direction first to the parser */ + * data for that direction first to the parser. This shouldn't + * be an issue, since each stream processing happens + * independently of the other stream direction. At this point of + * call, you need to know that this function's already being + * called by the very same StreamReassembly() function that we + * will now call shortly for the opposing direction. */ if ((ssn->data_first_seen_dir & (STREAM_TOSERVER | STREAM_TOCLIENT)) && !(flags & ssn->data_first_seen_dir)) { TcpStream *opposing_stream = NULL; if (stream == &ssn->client) { opposing_stream = &ssn->server; - p->flowflags &= ~FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; + if (StreamTcpInlineMode()) { + p->flowflags &= ~FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_TOCLIENT; + } else { + p->flowflags &= ~FLOW_PKT_TOCLIENT; + p->flowflags |= FLOW_PKT_TOSERVER; + } } else { opposing_stream = &ssn->client; - p->flowflags &= ~FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; + if (StreamTcpInlineMode()) { + p->flowflags &= ~FLOW_PKT_TOCLIENT; + p->flowflags |= FLOW_PKT_TOSERVER; + } else { + p->flowflags &= ~FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_TOCLIENT; + } } - int ret = StreamTcpReassembleAppLayer(tv, ra_ctx, ssn, opposing_stream, p); + int ret; + if (StreamTcpInlineMode()) + ret = StreamTcpReassembleInlineAppLayer(tv, ra_ctx, ssn, opposing_stream, p); + else + ret = StreamTcpReassembleAppLayer(tv, ra_ctx, ssn, opposing_stream, p); if (stream == &ssn->client) { - p->flowflags &= ~FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; + if (StreamTcpInlineMode()) { + p->flowflags &= ~FLOW_PKT_TOCLIENT; + p->flowflags |= FLOW_PKT_TOSERVER; + } else { + p->flowflags &= ~FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_TOCLIENT; + } } else { - p->flowflags &= ~FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; + if (StreamTcpInlineMode()) { + p->flowflags &= ~FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_TOCLIENT; + } else { + p->flowflags &= ~FLOW_PKT_TOCLIENT; + p->flowflags |= FLOW_PKT_TOSERVER; + } } if (ret < 0) { r = -1; diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 94acf652e8..dbda9261ad 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -1839,11 +1839,18 @@ static void StreamTcpRemoveSegmentFromStream(TcpStream *stream, TcpSegment *seg) * * Reassembly is in the same direction of the packet. * + * One of the utilities called by this function AppLayerHandleTCPData(), + * has a feature where it will call this very same function for the + * stream opposing the stream it is called with. This shouldn't cause + * any issues, since processing of each stream is independent of the + * other stream. + * * \todo this function is too long, we need to break it up. It needs it BAD */ -static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv, - TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, - Packet *p) +int StreamTcpReassembleInlineAppLayer(ThreadVars *tv, + TcpReassemblyThreadCtx *ra_ctx, + TcpSession *ssn, TcpStream *stream, + Packet *p) { SCEnter(); @@ -2576,6 +2583,12 @@ void StreamTcpPruneSession(Flow *f, uint8_t flags) { * Stream is in the opposite direction of the packet, as the ACK-packet * is ACK'ing the stream. * + * One of the utilities call by this function AppLayerHandleTCPData(), + * has a feature where it will call this very same function for the + * stream opposing the stream it is called with. This shouldn't cause + * any issues, since processing of each stream is independent of the + * other stream. + * * \todo this function is too long, we need to break it up. It needs it BAD */ int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, diff --git a/src/stream-tcp-reassemble.h b/src/stream-tcp-reassemble.h index 47a06c1891..2fdb5be734 100644 --- a/src/stream-tcp-reassemble.h +++ b/src/stream-tcp-reassemble.h @@ -75,6 +75,10 @@ void StreamTcpReassembleFreeThreadCtx(TcpReassemblyThreadCtx *); int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p); +int StreamTcpReassembleInlineAppLayer(ThreadVars *tv, + TcpReassemblyThreadCtx *ra_ctx, + TcpSession *ssn, TcpStream *stream, + Packet *p); int StreamTcpReassembleProcessAppLayer(TcpReassemblyThreadCtx *); void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t);