diff --git a/src/decode.h b/src/decode.h index e32acf9bc0..f846790ed1 100644 --- a/src/decode.h +++ b/src/decode.h @@ -225,7 +225,7 @@ typedef struct Packet_ /* flow */ struct Flow_ *flow; - uint8_t flowflags; + uint16_t flowflags; /* pkt vars */ PktVar *pktvar; diff --git a/src/detect.c b/src/detect.c index db1188f5cf..d8ee8fd237 100644 --- a/src/detect.c +++ b/src/detect.c @@ -340,6 +340,10 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh FlowSetIPOnlyFlag(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0); } + /* if we don't need any pattern matcher or other content inspection, then return*/ + if (p->flowflags & FLOW_PKT_NOPAYLOAD_INSPECTION) + return 1; + /* we assume we don't have an uri when we start inspection */ det_ctx->de_have_httpuri = 0; @@ -513,6 +517,11 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh * \retval 0 ok */ int Detect(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) { + + /*No need to perform any detection on this packet, if the the given flag is set.*/ + if (p->flowflags & FLOW_PKT_NOPACKET_INSPECTION) + return 0; + DetectEngineThreadCtx *det_ctx = (DetectEngineThreadCtx *)data; if (det_ctx == NULL) { printf("ERROR: Detect has no thread ctx\n"); diff --git a/src/flow-private.h b/src/flow-private.h index dc49dc43fa..af2fbba3c7 100644 --- a/src/flow-private.h +++ b/src/flow-private.h @@ -7,15 +7,20 @@ #include "flow-queue.h" /* per flow flags */ -#define FLOW_TO_SRC_SEEN 0x01 -#define FLOW_TO_DST_SEEN 0x02 +#define FLOW_TO_SRC_SEEN 0x0001 +#define FLOW_TO_DST_SEEN 0x0002 -#define FLOW_NEW_LIST 0x04 -#define FLOW_EST_LIST 0x08 -#define FLOW_CLOSED_LIST 0x10 +#define FLOW_NEW_LIST 0x0004 +#define FLOW_EST_LIST 0x0008 +#define FLOW_CLOSED_LIST 0x0010 -#define FLOW_TOSERVER_IPONLY_SET 0x20 -#define FLOW_TOCLIENT_IPONLY_SET 0x40 +#define FLOW_TOSERVER_IPONLY_SET 0x0020 +#define FLOW_TOCLIENT_IPONLY_SET 0x0040 + +#define FLOW_NOPACKET_INSPECTION 0x0080 +#define FLOW_NOPAYLOAD_INSPECTION 0x0100 +#define FLOW_NOCLIENT_REASSEMBLY 0x0200 +#define FLOW_NOSERVER_REASSEMBLY 0x0400 /* global flow flags */ #define FLOW_EMERGENCY 0x01 diff --git a/src/flow.c b/src/flow.c index 8b20a90a3f..bde8f67cdf 100644 --- a/src/flow.c +++ b/src/flow.c @@ -341,6 +341,16 @@ void FlowHandlePacket (ThreadVars *tv, Packet *p) if (f->flags & FLOW_TOSERVER_IPONLY_SET) p->flowflags |= FLOW_PKT_TOSERVER_IPONLY_SET; + /*set the detection bypass flags*/ + if (f->flags & FLOW_NOPACKET_INSPECTION) + p->flowflags |= FLOW_PKT_NOPACKET_INSPECTION; + if (f->flags & FLOW_NOPAYLOAD_INSPECTION) + p->flowflags |= FLOW_PKT_NOPAYLOAD_INSPECTION; + if (f->flags & FLOW_NOCLIENT_REASSEMBLY) + p->flowflags |= FLOW_PKT_NOCLIENT_REASSEMBLY; + if (f->flags & FLOW_NOSERVER_REASSEMBLY) + p->flowflags |= FLOW_PKT_NOSERVER_REASSEMBLY; + /* set the flow in the packet */ p->flow = f; @@ -740,6 +750,62 @@ int FlowSetProtoEmergencyTimeout(uint8_t proto, uint32_t emerg_new_timeout, uint return 1; } +/** \brief Set the No stream reassembly flag for 'direction'. This function + * handles the locking too. + * \param f Flow to set the flag in + * \param direction direction to set the flag in + */ +void FlowLockSetNoStreamReassemblyFlag(Flow *f, char direction) { + mutex_lock(&f->m); + direction ? (f->flags |= FLOW_NOSERVER_REASSEMBLY) : (f->flags |= FLOW_NOCLIENT_REASSEMBLY); + mutex_unlock(&f->m); +} + +/** \brief Set the No stream reassembly flag for 'direction' without any lock. + * + * \param f Flow to set the flag in + * \param direction direction to set the flag in + */ +void FlowSetNoStreamReassemblyFlag(Flow *f, char direction) { + direction ? (f->flags |= FLOW_NOSERVER_REASSEMBLY) : (f->flags |= FLOW_NOCLIENT_REASSEMBLY); +} + +/** \brief Set the No Packet Inspection Flag after locking the flow. + * + * \param f Flow to set the flag in + */ +void FlowLockSetNoPacketInspectionFlag(Flow *f) { + mutex_lock(&f->m); + f->flags |= FLOW_NOPACKET_INSPECTION; + mutex_unlock(&f->m); +} + +/** \brief Set the No Packet Inspection Flag without locking the flow. + * + * \param f Flow to set the flag in + */ +void FlowSetNoPacketInspectionFlag(Flow *f) { + f->flags |= FLOW_NOPACKET_INSPECTION; +} + +/** \brief Set the No payload inspection Flag after locking the flow. + * + * \param f Flow to set the flag in + */ +void FlowLockSetNoPayloadInspectionFlag(Flow *f) { + mutex_lock(&f->m); + f->flags |= FLOW_NOPAYLOAD_INSPECTION; + mutex_unlock(&f->m); +} + +/** \brief Set the No payload inspection Flag without locking the flow. + * + * \param f Flow to set the flag in + */ +void FlowSetNoPayloadInspectionFlag(Flow *f) { + f->flags |= FLOW_NOPAYLOAD_INSPECTION; +} + #ifdef UNITTESTS #include "stream-tcp-private.h" diff --git a/src/flow.h b/src/flow.h index f88336916a..2017d0b09d 100644 --- a/src/flow.h +++ b/src/flow.h @@ -10,14 +10,18 @@ #define FLOW_VERBOSE FALSE /* pkt flow flags */ -#define FLOW_PKT_TOSERVER 0x01 -#define FLOW_PKT_TOCLIENT 0x02 -#define FLOW_PKT_ESTABLISHED 0x04 -#define FLOW_PKT_STATELESS 0x08 -#define FLOW_PKT_TOSERVER_IPONLY_SET 0x10 -#define FLOW_PKT_TOCLIENT_IPONLY_SET 0x20 -#define FLOW_PKT_NOSTREAM 0x40 -#define FLOW_PKT_STREAMONLY 0x80 +#define FLOW_PKT_TOSERVER 0x0001 +#define FLOW_PKT_TOCLIENT 0x0002 +#define FLOW_PKT_ESTABLISHED 0x0004 +#define FLOW_PKT_STATELESS 0x0008 +#define FLOW_PKT_TOSERVER_IPONLY_SET 0x0010 +#define FLOW_PKT_TOCLIENT_IPONLY_SET 0x0020 +#define FLOW_PKT_NOSTREAM 0x0040 +#define FLOW_PKT_STREAMONLY 0x0080 +#define FLOW_PKT_NOPACKET_INSPECTION 0x0100 +#define FLOW_PKT_NOPAYLOAD_INSPECTION 0x0200 +#define FLOW_PKT_NOCLIENT_REASSEMBLY 0x0400 +#define FLOW_PKT_NOSERVER_REASSEMBLY 0x0800 /* global flow config */ typedef struct FlowCnf_ @@ -54,7 +58,7 @@ typedef struct Flow_ uint8_t proto; uint8_t recursion_level; - uint8_t flags; + uint16_t flags; /* ts of flow init and last update */ struct timeval startts; diff --git a/src/stream-tcp-private.h b/src/stream-tcp-private.h index 0bfd39e279..e83fce11b3 100644 --- a/src/stream-tcp-private.h +++ b/src/stream-tcp-private.h @@ -47,11 +47,13 @@ enum TCP_CLOSED, }; -#define STREAMTCP_FLAG_MIDSTREAM 0x01 /*Flag for mid stream session*/ -#define STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED 0x02 /*Flag for mid stream established session*/ -#define STREAMTCP_FLAG_TIMESTAMP 0x04 /*Flag for TCP Timestamp option*/ -#define STREAMTCP_FLAG_SERVER_WSCALE 0x08 /**< Server supports wscale (even though it can be 0) */ +#define STREAMTCP_FLAG_MIDSTREAM 0x01 /**< Flag for mid stream session*/ +#define STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED 0x02 /**< Flag for mid stream established session*/ +#define STREAMTCP_FLAG_TIMESTAMP 0x04 /**< Flag for TCP Timestamp option*/ +#define STREAMTCP_FLAG_SERVER_WSCALE 0x08 /**< Server supports wscale (even though it can be 0) */ #define STREAMTCP_FLAG_ZERO_TIMESTAMP 0x10 /**< Flag to indicate the zero value of timestamp*/ +#define STREAMTCP_FLAG_NO_REASSEMBLY 0x20 /**< Flag to avoid stream reassembly / application layer + inspection for the client stream.*/ #define PAWS_24DAYS 2073600 /* 24 days in seconds */ diff --git a/src/stream-tcp.c b/src/stream-tcp.c index b26c470ac5..8bbd0af301 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -316,6 +316,8 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread * SCLogDebug("ssn %p: ssn->client.isn %" PRIu32 ", ssn->client.next_seq %" PRIu32 ", ssn->client.last_ack %"PRIu32"", ssn, ssn->client.isn, ssn->client.next_seq, ssn->client.last_ack); + if ( p->flowflags & FLOW_PKT_NOCLIENT_REASSEMBLY) + ssn->client.flags |= STREAMTCP_FLAG_NO_REASSEMBLY; break; } case TH_SYN|TH_ACK: @@ -377,6 +379,9 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread * ssn->client.last_ts = 0; } + if (p->flowflags & FLOW_PKT_NOSERVER_REASSEMBLY) + ssn->server.flags |= STREAMTCP_FLAG_NO_REASSEMBLY; + break; /* Handle SYN/ACK and 3WHS shake missed together as it is almost similar. */ case TH_ACK: @@ -441,7 +446,14 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread * ssn->client.last_ts = 0; } - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + if ( p->flowflags & FLOW_PKT_NOCLIENT_REASSEMBLY) + ssn->client.flags |= STREAMTCP_FLAG_NO_REASSEMBLY; + if (p->flowflags & FLOW_PKT_NOSERVER_REASSEMBLY) + ssn->server.flags |= STREAMTCP_FLAG_NO_REASSEMBLY; + + /*If no stream reassembly/application layer protocol inspection, then simple return*/ + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); break; case TH_RST: case TH_RST|TH_ACK: @@ -535,6 +547,9 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p, StreamTcpThrea SCLogDebug("ssn %p: ssn->client.next_win %" PRIu32 "", ssn, ssn->client.next_win); SCLogDebug("ssn %p: ssn->server.isn %" PRIu32 ", ssn->server.next_seq %" PRIu32 ", ssn->server.last_ack %" PRIu32 " (ssn->client.last_ack %" PRIu32 ")", ssn, ssn->server.isn, ssn->server.next_seq, ssn->server.last_ack, ssn->client.last_ack); + if (p->flowflags & FLOW_PKT_NOSERVER_REASSEMBLY) + ssn->server.flags |= STREAMTCP_FLAG_NO_REASSEMBLY; + break; case TH_RST: case TH_RST|TH_ACK: @@ -613,6 +628,9 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p, StreamTcpThrea ssn->server.next_win = ssn->server.last_ack + ssn->server.window; SCLogDebug("ssn %p: ssn->server.next_win %" PRIu32 ", ssn->server.last_ack %"PRIu32"", ssn, ssn->server.next_win, ssn->server.last_ack); + if ( p->flowflags & FLOW_PKT_NOCLIENT_REASSEMBLY) + ssn->client.flags |= STREAMTCP_FLAG_NO_REASSEMBLY; + break; case TH_RST: case TH_RST|TH_ACK: @@ -696,7 +714,9 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT SCLogDebug("ssn %p: seq %"PRIu32", updated ssn->server.next_win %" PRIu32 " (win %"PRIu32")", ssn, TCP_GET_SEQ(p), ssn->server.next_win, ssn->server.window); } - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + /*If no stream reassembly/application layer protocol inspection, then simple return*/ + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); } else { SCLogDebug("ssn %p: server => SEQ out of window, packet SEQ %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), ssn->client.last_ack %" PRIu32 ", ssn->client.next_win %" PRIu32 "(%"PRIu32") (ssn->client.ra_base_seq %"PRIu32")", ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) + p->payload_len, ssn->client.last_ack, ssn->client.next_win, TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win, ssn->client.ra_base_seq); } @@ -741,7 +761,9 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT SCLogDebug("ssn %p: seq %"PRIu32", keeping ssn->client.next_win %" PRIu32 " the same (win %"PRIu32")", ssn, TCP_GET_SEQ(p), ssn->client.next_win, ssn->client.window); } - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + /*If no stream reassembly/application layer protocol inspection, then simple return*/ + if (ssn->server.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); } else { SCLogDebug("ssn %p: client => SEQ out of window, packet SEQ %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), ssn->server.last_ack %" PRIu32 ", ssn->server.next_win %" PRIu32 "(%"PRIu32") (ssn->server.ra_base_seq %"PRIu32")", ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) + p->payload_len, ssn->server.last_ack, ssn->server.next_win, TCP_GET_SEQ(p) + p->payload_len - ssn->server.next_win, ssn->server.ra_base_seq); } @@ -782,7 +804,8 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->client.next_seq, ssn->server.last_ack); } else { @@ -798,7 +821,8 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + if (ssn->server.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); } @@ -844,7 +868,8 @@ static int StreamTcpHandleFin(StreamTcpThread *stt, TcpSession *ssn, Packet *p) if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->client.next_seq, ssn->server.last_ack); @@ -868,7 +893,8 @@ static int StreamTcpHandleFin(StreamTcpThread *stt, TcpSession *ssn, Packet *p) if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + if (ssn->server.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); @@ -910,7 +936,8 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, StreamTcpThre if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->client.next_seq, ssn->server.last_ack); } else { /* implied to client */ @@ -923,7 +950,8 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, StreamTcpThre if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + if (ssn->server.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); } @@ -955,7 +983,8 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, StreamTcpThre if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->client.next_seq, ssn->server.last_ack); } else { /* implied to client */ @@ -976,7 +1005,8 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, StreamTcpThre if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + if (ssn->server.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); } @@ -1037,7 +1067,8 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, StreamTcpThre if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->client.next_seq, ssn->server.last_ack); } else { /* implied to client */ @@ -1057,7 +1088,8 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, StreamTcpThre if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + if (ssn->server.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); } @@ -1095,7 +1127,8 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, StreamTcpThre if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->client.next_seq, ssn->server.last_ack); @@ -1116,7 +1149,8 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, StreamTcpThre if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + if (ssn->server.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); } @@ -1169,7 +1203,8 @@ static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p, StreamTcpThrea if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->client.next_seq, ssn->server.last_ack); } else { /* implied to client */ @@ -1189,7 +1224,8 @@ static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p, StreamTcpThrea if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + if (ssn->server.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("StreamTcpPacketStateClosing (%p): =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); } @@ -1240,7 +1276,8 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p, StreamTcpThr if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + if (ssn->server.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); } @@ -1292,7 +1329,8 @@ static int StreamTcpPakcetStateLastAck(ThreadVars *tv, Packet *p, StreamTcpThrea if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->client.next_seq, ssn->server.last_ack); } @@ -1344,7 +1382,8 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p, StreamTcpThre if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + if (ssn->client.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->client.next_seq, ssn->server.last_ack); } else { @@ -1364,7 +1403,8 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p, StreamTcpThre if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + if (ssn->server.flags & STREAMTCP_FLAG_NO_REASSEMBLY) + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); }