From 9f95ab74415237ce672e93f86625d054ea41638d Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 8 Jun 2010 10:10:58 +0200 Subject: [PATCH] Make sure a stream that has a failing app layer inspection module no longer stops reassembly, but only app layer inspection. This way we can continue to inspect the reassembled stream. --- src/app-layer-parser.c | 25 ++++------ src/app-layer.c | 94 +++++++++++++++++++------------------ src/stream-tcp-private.h | 6 +++ src/stream-tcp-reassemble.h | 2 + src/stream-tcp.c | 10 +++- 5 files changed, 75 insertions(+), 62 deletions(-) diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index 676d07e47d..6611706f4a 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -794,8 +794,7 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input, SCLogDebug("No App Layer Data"); /* Nothing is there to clean up, so just return from here after setting * up the no reassembly flags */ - StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOCLIENT ? 1 : 0); - StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOSERVER ? 1 : 0); + StreamTcpSetSessionNoApplayerInspectionFlag(ssn); SCReturnInt(-1); } @@ -870,10 +869,9 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input, /* Set the no reassembly flag for both the stream in this TcpSession */ if (parser_state->flags & APP_LAYER_PARSER_NO_REASSEMBLY) { - StreamTcpSetSessionNoReassemblyFlag(ssn, - flags & STREAM_TOCLIENT ? 1 : 0); - StreamTcpSetSessionNoReassemblyFlag(ssn, - flags & STREAM_TOSERVER ? 1 : 0); + StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOCLIENT ? 1 : 0); + StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOSERVER ? 1 : 0); + StreamTcpSetSessionNoApplayerInspectionFlag(ssn); } } @@ -893,8 +891,7 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input, error: if (ssn != NULL) { /* Set the no reassembly flag for both the stream in this TcpSession */ - StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOCLIENT ? 1 : 0); - StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOSERVER ? 1 : 0); + StreamTcpSetSessionNoApplayerInspectionFlag(ssn); if (f->src.family == AF_INET) { char src[16]; @@ -1302,7 +1299,7 @@ static void TestProtocolStateFree(void *s) */ static int AppLayerParserTest01 (void) { - int result = 1; + int result = 0; Flow f; uint8_t testbuf[] = { 0x11 }; uint32_t testlen = sizeof(testbuf); @@ -1344,19 +1341,17 @@ static int AppLayerParserTest01 (void) int r = AppLayerParse(&f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF, testbuf, testlen); if (r != -1) { - printf("returned %" PRId32 ", expected -1: \n", r); - result = 0; + printf("returned %" PRId32 ", expected -1: ", r); goto end; } - if (!(ssn.flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY) || - !(ssn.flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) + if (!(ssn.flags & STREAMTCP_FLAG_NO_APPLAYER_INSPECTION)) { - printf("flags should be set, but they are not !\n"); - result = 0; + printf("flag should have been set, but is not: "); goto end; } + result = 1; end: StreamL7DataPtrFree(&ssn); StreamTcpFreeConfig(TRUE); diff --git a/src/app-layer.c b/src/app-layer.c index b0ae0b03ef..e5e2b71d0c 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -124,59 +124,61 @@ int AppLayerHandleMsg(AlpProtoDetectThreadCtx *dp_ctx, StreamMsg *smsg) if (ssn != NULL) { alproto = ssn->alproto; - /* if we don't know the proto yet and we have received a stream - * initializer message, we run proto detection. - * We receive 2 stream init msgs (one for each direction) but we - * only run the proto detection once. */ - if (alproto == ALPROTO_UNKNOWN && smsg->flags & STREAM_START) { - SCLogDebug("Stream initializer (len %" PRIu32 " (%" PRIu32 "))", + if (!(ssn->flags & STREAMTCP_FLAG_NO_APPLAYER_INSPECTION)) { + /* if we don't know the proto yet and we have received a stream + * initializer message, we run proto detection. + * We receive 2 stream init msgs (one for each direction) but we + * only run the proto detection once. */ + if (alproto == ALPROTO_UNKNOWN && smsg->flags & STREAM_START) { + SCLogDebug("Stream initializer (len %" PRIu32 " (%" PRIu32 "))", smsg->data.data_len, MSG_DATA_SIZE); - //printf("=> Init Stream Data -- start\n"); - //PrintRawDataFp(stdout, smsg->init.data, smsg->init.data_len); - //printf("=> Init Stream Data -- end\n"); + //printf("=> Init Stream Data -- start\n"); + //PrintRawDataFp(stdout, smsg->init.data, smsg->init.data_len); + //printf("=> Init Stream Data -- end\n"); - alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx, - smsg->data.data, smsg->data.data_len, smsg->flags); - if (alproto != ALPROTO_UNKNOWN) { - /* store the proto and setup the L7 data array */ - StreamL7DataPtrInit(ssn); - ssn->alproto = alproto; - ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; + alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx, + smsg->data.data, smsg->data.data_len, smsg->flags); + if (alproto != ALPROTO_UNKNOWN) { + /* store the proto and setup the L7 data array */ + StreamL7DataPtrInit(ssn); + ssn->alproto = alproto; + ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; - r = AppLayerParse(smsg->flow, alproto, smsg->flags, - smsg->data.data, smsg->data.data_len); - } else { - if (smsg->flags & STREAM_TOSERVER) { - if (smsg->data.data_len >= alp_proto_ctx.toserver.max_len) { - ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; - SCLogDebug("ALPROTO_UNKNOWN flow %p", smsg->flow); - StreamTcpSetSessionNoReassemblyFlag(ssn, 0); - } - } else if (smsg->flags & STREAM_TOCLIENT) { - if (smsg->data.data_len >= alp_proto_ctx.toclient.max_len) { - ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; - SCLogDebug("ALPROTO_UNKNOWN flow %p", smsg->flow); - StreamTcpSetSessionNoReassemblyFlag(ssn, 1); + r = AppLayerParse(smsg->flow, alproto, smsg->flags, + smsg->data.data, smsg->data.data_len); + } else { + if (smsg->flags & STREAM_TOSERVER) { + if (smsg->data.data_len >= alp_proto_ctx.toserver.max_len) { + ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; + SCLogDebug("ALPROTO_UNKNOWN flow %p", smsg->flow); + StreamTcpSetSessionNoReassemblyFlag(ssn, 0); + } + } else if (smsg->flags & STREAM_TOCLIENT) { + if (smsg->data.data_len >= alp_proto_ctx.toclient.max_len) { + ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; + SCLogDebug("ALPROTO_UNKNOWN flow %p", smsg->flow); + StreamTcpSetSessionNoReassemblyFlag(ssn, 1); + } } } - } - } else { - SCLogDebug("stream data (len %" PRIu32 " (%" PRIu32 ")), alproto " - "%"PRIu16" (flow %p)", smsg->data.data_len, MSG_DATA_SIZE, - alproto, smsg->flow); - - //printf("=> Stream Data -- start\n"); - //PrintRawDataFp(stdout, smsg->data.data, smsg->data.data_len); - //printf("=> Stream Data -- end\n"); - - /* if we don't have a data object here we are not getting it - * a start msg should have gotten us one */ - if (alproto != ALPROTO_UNKNOWN) { - r = AppLayerParse(smsg->flow, alproto, smsg->flags, - smsg->data.data, smsg->data.data_len); } else { - SCLogDebug(" smsg not start, but no l7 data? Weird"); + SCLogDebug("stream data (len %" PRIu32 " (%" PRIu32 ")), alproto " + "%"PRIu16" (flow %p)", smsg->data.data_len, MSG_DATA_SIZE, + alproto, smsg->flow); + + //printf("=> Stream Data -- start\n"); + //PrintRawDataFp(stdout, smsg->data.data, smsg->data.data_len); + //printf("=> Stream Data -- end\n"); + + /* if we don't have a data object here we are not getting it + * a start msg should have gotten us one */ + if (alproto != ALPROTO_UNKNOWN) { + r = AppLayerParse(smsg->flow, alproto, smsg->flags, + smsg->data.data, smsg->data.data_len); + } else { + SCLogDebug(" smsg not start, but no l7 data? Weird"); + } } } diff --git a/src/stream-tcp-private.h b/src/stream-tcp-private.h index 6625d8af25..33784887f9 100644 --- a/src/stream-tcp-private.h +++ b/src/stream-tcp-private.h @@ -125,6 +125,12 @@ enum reassembly / app layer inspection for the client stream.*/ +#define STREAMTCP_FLAG_NO_APPLAYER_INSPECTION 0x2000 /**< don't send any more + data to the app layer + parser, but still + reassemble for raw + reassembled data + inspection */ #define SEGMENTTCP_FLAG_PROCESSED 0x01 /**< Flag to indicate that the current diff --git a/src/stream-tcp-reassemble.h b/src/stream-tcp-reassemble.h index 62caf3f296..6f6812c352 100644 --- a/src/stream-tcp-reassemble.h +++ b/src/stream-tcp-reassemble.h @@ -69,7 +69,9 @@ void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t); void StreamL7DataPtrInit(TcpSession *); void StreamL7DataPtrFree(TcpSession *); +void StreamTcpSetSessionNoApplayerInspectionFlag(TcpSession *); void StreamTcpSetSessionNoReassemblyFlag (TcpSession *, char ); + void StreamTcpSetOSPolicy(TcpStream *, Packet *); void StreamTcpReassemblePause (TcpSession *, char ); void StreamTcpReassembleUnPause (TcpSession *, char ); diff --git a/src/stream-tcp.c b/src/stream-tcp.c index e0e1d390df..708a0764f7 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -2926,13 +2926,21 @@ static int ValidTimestamp (TcpSession *ssn, Packet *p) * \param ssn TCP Session to set the flag in * \param direction direction to set the flag in: 0 toserver, 1 toclient */ - void StreamTcpSetSessionNoReassemblyFlag (TcpSession *ssn, char direction) { direction ? (ssn->flags |= STREAMTCP_FLAG_NOSERVER_REASSEMBLY) : (ssn->flags |= STREAMTCP_FLAG_NOCLIENT_REASSEMBLY); } +/** \brief Set the No applayer inspection flag for the TCP session. + * + * \param ssn TCP Session to set the flag in + */ +void StreamTcpSetSessionNoApplayerInspectionFlag (TcpSession *ssn) +{ + ssn->flags |= STREAMTCP_FLAG_NO_APPLAYER_INSPECTION; +} + #ifdef UNITTESTS /**