From 22c05da3cd938810a102b7862f379417314cb0de Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Sun, 4 Aug 2013 01:31:32 +0530 Subject: [PATCH] Replace ssn appproto_detection_completed flag with individual stream ones. --- src/app-layer.c | 16 +++++++--- src/app-layer.h | 2 +- src/stream-tcp-private.h | 15 +++++----- src/stream-tcp-reassemble.c | 60 ++++++++++++++++++------------------- 4 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/app-layer.c b/src/app-layer.c index 5efe7ddf8e..d77b9b24d8 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -114,7 +114,9 @@ extern AlpProtoDetectCtx alp_proto_ctx; * \retval -1 error */ int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *dp_ctx, Flow *f, - TcpSession *ssn, uint8_t *data, uint32_t data_len, uint8_t flags) + TcpSession *ssn, TcpStream *stream, + uint8_t *data, uint32_t data_len, + uint8_t flags) { SCEnter(); @@ -138,7 +140,9 @@ int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *dp_ctx, Flow *f, * We receive 2 stream init msgs (one for each direction) but we * only run the proto detection once. */ if (f->alproto == ALPROTO_UNKNOWN && (flags & STREAM_GAP)) { - ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; + //stream->flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED; + ssn->client.flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED; + ssn->server.flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED; SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f); StreamTcpSetSessionNoReassemblyFlag(ssn, 0); } else if (f->alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) { @@ -159,7 +163,9 @@ int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *dp_ctx, Flow *f, PACKET_PROFILING_APP_PD_END(dp_ctx); if (f->alproto != ALPROTO_UNKNOWN) { - ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; + //stream->flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED; + ssn->client.flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED; + ssn->server.flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED; PACKET_PROFILING_APP_START(dp_ctx, f->alproto); r = AppLayerParse(dp_ctx->alproto_local_storage[f->alproto], f, f->alproto, flags, data, data_len); @@ -168,7 +174,9 @@ int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *dp_ctx, Flow *f, if ((FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && (FLOW_IS_PM_DONE(f, STREAM_TOCLIENT)) && (FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) && (FLOW_IS_PP_DONE(f, STREAM_TOCLIENT))) { FlowSetSessionNoApplayerInspectionFlag(f); - ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; + //stream->flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED; + ssn->client.flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED; + ssn->server.flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED; } } } else { diff --git a/src/app-layer.h b/src/app-layer.h index 66c9f989ae..4465ce8256 100644 --- a/src/app-layer.h +++ b/src/app-layer.h @@ -38,7 +38,7 @@ uint16_t AppLayerGetProtoFromPacket(Packet *); void *AppLayerGetProtoStateFromPacket(Packet *); void *AppLayerGetProtoStateFromFlow(Flow *); -int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *, Flow *, TcpSession *, uint8_t *, uint32_t, uint8_t); +int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *, Flow *, TcpSession *, TcpStream *, uint8_t *, uint32_t, uint8_t); int AppLayerHandleTCPMsg(AlpProtoDetectThreadCtx *, StreamMsg *); //int AppLayerHandleMsg(AlpProtoDetectThreadCtx *, StreamMsg *); int AppLayerHandleUdp(AlpProtoDetectThreadCtx *, Flow *, Packet *p); diff --git a/src/stream-tcp-private.h b/src/stream-tcp-private.h index 992c16544d..5296ec3dd8 100644 --- a/src/stream-tcp-private.h +++ b/src/stream-tcp-private.h @@ -127,24 +127,21 @@ enum /** Flag to indicate we're dealing with 4WHS: SYN, SYN, SYN/ACK, ACK * (http://www.breakingpointsystems.com/community/blog/tcp-portals-the-three-way-handshake-is-a-lie) */ #define STREAMTCP_FLAG_4WHS 0x0080 -/** Flag to indicate the app layer has detected the app layer protocol on - * the current TCP session */ -#define STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED 0x0100 /** Flag to indicate that this session is possible trying to evade the detection * (http://www.packetstan.com/2010/06/recently-ive-been-on-campaign-to-make.html) */ -#define STREAMTCP_FLAG_DETECTION_EVASION_ATTEMPT 0x0200 +#define STREAMTCP_FLAG_DETECTION_EVASION_ATTEMPT 0x0100 /** Flag to indicate the client (SYN pkt) permits SACK */ -#define STREAMTCP_FLAG_CLIENT_SACKOK 0x0400 +#define STREAMTCP_FLAG_CLIENT_SACKOK 0x0200 /** Flag to indicate both sides of the session permit SACK (SYN + SYN/ACK) */ -#define STREAMTCP_FLAG_SACKOK 0x0800 +#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 0x1000 +#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 * event. */ -#define STREAMTCP_FLAG_3WHS_CONFIRMED 0x2000 +#define STREAMTCP_FLAG_3WHS_CONFIRMED 0x1000 /* * Per STREAM flags @@ -165,6 +162,8 @@ enum #define STREAMTCP_STREAM_FLAG_TIMESTAMP 0x20 /** Flag to indicate the zero value of timestamp */ #define STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP 0x40 +/** App proto detection completed */ +#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED 0x80 /* * Per SEGMENT flags diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 359c5a0056..f3dc9e3e38 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -1677,7 +1677,7 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre #define STREAM_SET_FLAGS(ssn, stream, p, flag) { \ flag = 0; \ - if (!(ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) {\ + if (!(stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) {\ flag |= STREAM_START; \ } \ if (stream->flags & STREAMTCP_STREAM_FLAG_CLOSE_INITIATED) { \ @@ -1695,7 +1695,7 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre #define STREAM_SET_INLINE_FLAGS(ssn, stream, p, flag) { \ flag = 0; \ - if (!(ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) {\ + if (!(stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) {\ flag |= STREAM_START; \ } \ if (stream->flags & STREAMTCP_STREAM_FLAG_CLOSE_INITIATED) { \ @@ -1856,7 +1856,7 @@ static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv, SCLogDebug("sending empty eof message"); /* send EOF to app layer */ STREAM_SET_INLINE_FLAGS(ssn, stream, p, flags); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, NULL, 0, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); @@ -1905,7 +1905,7 @@ static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv, /* if app layer protocol has been detected, then remove all the segments * which has been previously processed and reassembled */ - } else if ((ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED) && + } else if ((stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) && (seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) && StreamTcpAppLayerSegmentProcessed(stream, seg)) { SCLogDebug("segment(%p) of length %"PRIu16" has been processed," @@ -1935,7 +1935,7 @@ static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv, STREAM_SET_INLINE_FLAGS(ssn, stream, p, flags); /* process what we have so far */ - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, data, data_len, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); @@ -1964,7 +1964,7 @@ static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv, /* send gap signal */ STREAM_SET_INLINE_FLAGS(ssn, stream, p, flags); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, NULL, 0, flags|STREAM_GAP); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); data_len = 0; @@ -2036,7 +2036,7 @@ static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv, /* process what we have so far */ STREAM_SET_INLINE_FLAGS(ssn, stream, p, flags); BUG_ON(data_len > sizeof(data)); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, data, data_len, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); data_sent += data_len; @@ -2090,7 +2090,7 @@ static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv, /* process what we have so far */ STREAM_SET_INLINE_FLAGS(ssn, stream, p, flags); BUG_ON(data_len > sizeof(data)); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, data, data_len, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); data_sent += data_len; @@ -2126,7 +2126,7 @@ static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv, /* process what we have so far */ STREAM_SET_INLINE_FLAGS(ssn, stream, p, flags); BUG_ON(data_len > sizeof(data)); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, data, data_len, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); data_sent += data_len; @@ -2136,13 +2136,13 @@ static int StreamTcpReassembleInlineAppLayer (ThreadVars *tv, SCLogDebug("sending empty eof message"); /* send EOF to app layer */ STREAM_SET_INLINE_FLAGS(ssn, stream, p, flags); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, NULL, 0, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); } /* store ra_base_seq in the stream */ - if ((ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) { + if ((stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) { stream->ra_app_base_seq = ra_base_seq; } @@ -2241,7 +2241,7 @@ static int StreamTcpReassembleInlineRaw (TcpReassemblyThreadCtx *ra_ctx, * which has been previously processed and reassembled * * If the stream is in GAP state the app layer flag won't be set */ - if ((ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED) && + if ((stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) && (seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) && StreamTcpAppLayerSegmentProcessed(stream, seg)) { @@ -2541,7 +2541,7 @@ void StreamTcpPruneSession(Flow *f, uint8_t flags) { seg = next_seg; continue; - } else if ((ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED) && + } else if ((stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) && (seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) && (seg->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED)) { @@ -2595,7 +2595,7 @@ static int StreamTcpReassembleAppLayer (ThreadVars *tv, SCLogDebug("sending empty eof message"); /* send EOF to app layer */ STREAM_SET_FLAGS(ssn, stream, p, flags); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, NULL, 0, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); @@ -2671,7 +2671,7 @@ static int StreamTcpReassembleAppLayer (ThreadVars *tv, /* if app layer protocol has been detected, then remove all the segments which has been previously processed and reassembled */ - if ((ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED) && + if ((stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) && (seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) && (seg->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED)) { @@ -2699,7 +2699,7 @@ static int StreamTcpReassembleAppLayer (ThreadVars *tv, STREAM_SET_FLAGS(ssn, stream, p, flags); /* process what we have so far */ - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, data, data_len, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); data_len = 0; @@ -2726,7 +2726,7 @@ static int StreamTcpReassembleAppLayer (ThreadVars *tv, /* send gap signal */ STREAM_SET_FLAGS(ssn, stream, p, flags); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, NULL, 0, flags|STREAM_GAP); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); data_len = 0; @@ -2823,14 +2823,14 @@ static int StreamTcpReassembleAppLayer (ThreadVars *tv, /* process what we have so far */ STREAM_SET_FLAGS(ssn, stream, p, flags); BUG_ON(data_len > sizeof(data)); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, data, data_len, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); data_len = 0; /* if after the first data chunk we have no alproto yet, * there is no point in continueing here. */ - if (!(ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) { + if (!(stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) { SCLogDebug("no alproto after first data chunk"); break; } @@ -2883,14 +2883,14 @@ static int StreamTcpReassembleAppLayer (ThreadVars *tv, /* process what we have so far */ STREAM_SET_FLAGS(ssn, stream, p, flags); BUG_ON(data_len > sizeof(data)); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, data, data_len, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); data_len = 0; /* if after the first data chunk we have no alproto yet, * there is no point in continueing here. */ - if (!(ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) { + if (!(stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) { SCLogDebug("no alproto after first data chunk"); break; } @@ -2930,13 +2930,13 @@ static int StreamTcpReassembleAppLayer (ThreadVars *tv, /* process what we have so far */ STREAM_SET_FLAGS(ssn, stream, p, flags); BUG_ON(data_len > sizeof(data)); - AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, + AppLayerHandleTCPData(&ra_ctx->dp_ctx, p->flow, ssn, stream, data, data_len, flags); PACKET_PROFILING_APP_STORE(&ra_ctx->dp_ctx, p); } /* store ra_base_seq in the stream */ - if ((ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) { + if ((stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) { stream->ra_app_base_seq = ra_base_seq; } SCLogDebug("stream->ra_app_base_seq %u", stream->ra_app_base_seq); @@ -2974,7 +2974,7 @@ static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx, #if 0 if (ssn->state <= TCP_ESTABLISHED && - !(ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) { + !(stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) { SCLogDebug("only starting raw reassembly after app layer protocol " "detection has completed."); SCReturnInt(0); @@ -3030,7 +3030,7 @@ static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx, * which has been previously processed and reassembled * * If the stream is in GAP state the app layer flag won't be set */ - if ((ssn->flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED) && + if ((stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) && (seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) && ((seg->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED) || (stream->flags & STREAMTCP_STREAM_FLAG_GAP))) @@ -6300,7 +6300,7 @@ static int StreamTcpReassembleTest39 (void) { /* Check if we have stream smsgs in queue */ if (ra_ctx->stream_q->len == 0 && - !(ssn.flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) { + !(ssn.client.flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) { printf("there should be a stream smsgs in the queue, as we have detected" " the app layer protocol and one smsg from toserver side has " "been sent (10): "); @@ -6325,8 +6325,8 @@ static int StreamTcpReassembleTest39 (void) { SCLogDebug("final check"); - if (!(ssn.flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) { - printf("STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED flag should have been set (13): "); + if (!(ssn.client.flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) { + printf("STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED flag should have been set (13): "); goto end; } @@ -6909,7 +6909,7 @@ static int StreamTcpReassembleTest43 (void) { goto end; } #endif - if (!(ssn.flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) { + if (!(ssn.client.flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) { printf("app layer detected flag isn't set, it should be (8): "); goto end; } @@ -6965,7 +6965,7 @@ static int StreamTcpReassembleTest43 (void) { #endif /* the flag should be set, as the smsg scanned size has crossed the max. signature size for app proto detection */ - if (! (ssn.flags & STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED)) { + if (! (ssn.client.flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) { printf("app layer detected flag is not set, it should be (14): "); goto end; }