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.

remotes/origin/master-1.0.x
Victor Julien 15 years ago
parent 81f2499834
commit 9f95ab7441

@ -794,8 +794,7 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input,
SCLogDebug("No App Layer Data"); SCLogDebug("No App Layer Data");
/* Nothing is there to clean up, so just return from here after setting /* Nothing is there to clean up, so just return from here after setting
* up the no reassembly flags */ * up the no reassembly flags */
StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOCLIENT ? 1 : 0); StreamTcpSetSessionNoApplayerInspectionFlag(ssn);
StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOSERVER ? 1 : 0);
SCReturnInt(-1); 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 */ /* Set the no reassembly flag for both the stream in this TcpSession */
if (parser_state->flags & APP_LAYER_PARSER_NO_REASSEMBLY) { if (parser_state->flags & APP_LAYER_PARSER_NO_REASSEMBLY) {
StreamTcpSetSessionNoReassemblyFlag(ssn, StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOCLIENT ? 1 : 0);
flags & STREAM_TOCLIENT ? 1 : 0); StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOSERVER ? 1 : 0);
StreamTcpSetSessionNoReassemblyFlag(ssn, StreamTcpSetSessionNoApplayerInspectionFlag(ssn);
flags & STREAM_TOSERVER ? 1 : 0);
} }
} }
@ -893,8 +891,7 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input,
error: error:
if (ssn != NULL) { if (ssn != NULL) {
/* Set the no reassembly flag for both the stream in this TcpSession */ /* Set the no reassembly flag for both the stream in this TcpSession */
StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOCLIENT ? 1 : 0); StreamTcpSetSessionNoApplayerInspectionFlag(ssn);
StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOSERVER ? 1 : 0);
if (f->src.family == AF_INET) { if (f->src.family == AF_INET) {
char src[16]; char src[16];
@ -1302,7 +1299,7 @@ static void TestProtocolStateFree(void *s)
*/ */
static int AppLayerParserTest01 (void) static int AppLayerParserTest01 (void)
{ {
int result = 1; int result = 0;
Flow f; Flow f;
uint8_t testbuf[] = { 0x11 }; uint8_t testbuf[] = { 0x11 };
uint32_t testlen = sizeof(testbuf); uint32_t testlen = sizeof(testbuf);
@ -1344,19 +1341,17 @@ static int AppLayerParserTest01 (void)
int r = AppLayerParse(&f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF, testbuf, int r = AppLayerParse(&f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF, testbuf,
testlen); testlen);
if (r != -1) { if (r != -1) {
printf("returned %" PRId32 ", expected -1: \n", r); printf("returned %" PRId32 ", expected -1: ", r);
result = 0;
goto end; goto end;
} }
if (!(ssn.flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY) || if (!(ssn.flags & STREAMTCP_FLAG_NO_APPLAYER_INSPECTION))
!(ssn.flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY))
{ {
printf("flags should be set, but they are not !\n"); printf("flag should have been set, but is not: ");
result = 0;
goto end; goto end;
} }
result = 1;
end: end:
StreamL7DataPtrFree(&ssn); StreamL7DataPtrFree(&ssn);
StreamTcpFreeConfig(TRUE); StreamTcpFreeConfig(TRUE);

@ -124,59 +124,61 @@ int AppLayerHandleMsg(AlpProtoDetectThreadCtx *dp_ctx, StreamMsg *smsg)
if (ssn != NULL) { if (ssn != NULL) {
alproto = ssn->alproto; alproto = ssn->alproto;
/* if we don't know the proto yet and we have received a stream if (!(ssn->flags & STREAMTCP_FLAG_NO_APPLAYER_INSPECTION)) {
* initializer message, we run proto detection. /* if we don't know the proto yet and we have received a stream
* We receive 2 stream init msgs (one for each direction) but we * initializer message, we run proto detection.
* only run the proto detection once. */ * We receive 2 stream init msgs (one for each direction) but we
if (alproto == ALPROTO_UNKNOWN && smsg->flags & STREAM_START) { * only run the proto detection once. */
SCLogDebug("Stream initializer (len %" PRIu32 " (%" PRIu32 "))", if (alproto == ALPROTO_UNKNOWN && smsg->flags & STREAM_START) {
SCLogDebug("Stream initializer (len %" PRIu32 " (%" PRIu32 "))",
smsg->data.data_len, MSG_DATA_SIZE); smsg->data.data_len, MSG_DATA_SIZE);
//printf("=> Init Stream Data -- start\n"); //printf("=> Init Stream Data -- start\n");
//PrintRawDataFp(stdout, smsg->init.data, smsg->init.data_len); //PrintRawDataFp(stdout, smsg->init.data, smsg->init.data_len);
//printf("=> Init Stream Data -- end\n"); //printf("=> Init Stream Data -- end\n");
alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx, alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx,
smsg->data.data, smsg->data.data_len, smsg->flags); smsg->data.data, smsg->data.data_len, smsg->flags);
if (alproto != ALPROTO_UNKNOWN) { if (alproto != ALPROTO_UNKNOWN) {
/* store the proto and setup the L7 data array */ /* store the proto and setup the L7 data array */
StreamL7DataPtrInit(ssn); StreamL7DataPtrInit(ssn);
ssn->alproto = alproto; ssn->alproto = alproto;
ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED;
r = AppLayerParse(smsg->flow, alproto, smsg->flags, r = AppLayerParse(smsg->flow, alproto, smsg->flags,
smsg->data.data, smsg->data.data_len); smsg->data.data, smsg->data.data_len);
} else { } else {
if (smsg->flags & STREAM_TOSERVER) { if (smsg->flags & STREAM_TOSERVER) {
if (smsg->data.data_len >= alp_proto_ctx.toserver.max_len) { if (smsg->data.data_len >= alp_proto_ctx.toserver.max_len) {
ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED;
SCLogDebug("ALPROTO_UNKNOWN flow %p", smsg->flow); SCLogDebug("ALPROTO_UNKNOWN flow %p", smsg->flow);
StreamTcpSetSessionNoReassemblyFlag(ssn, 0); StreamTcpSetSessionNoReassemblyFlag(ssn, 0);
} }
} else if (smsg->flags & STREAM_TOCLIENT) { } else if (smsg->flags & STREAM_TOCLIENT) {
if (smsg->data.data_len >= alp_proto_ctx.toclient.max_len) { if (smsg->data.data_len >= alp_proto_ctx.toclient.max_len) {
ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED;
SCLogDebug("ALPROTO_UNKNOWN flow %p", smsg->flow); SCLogDebug("ALPROTO_UNKNOWN flow %p", smsg->flow);
StreamTcpSetSessionNoReassemblyFlag(ssn, 1); 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 { } 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");
}
} }
} }

@ -125,6 +125,12 @@ enum
reassembly / app layer reassembly / app layer
inspection for the inspection for the
client stream.*/ 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 #define SEGMENTTCP_FLAG_PROCESSED 0x01 /**< Flag to indicate
that the current that the current

@ -69,7 +69,9 @@ void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t);
void StreamL7DataPtrInit(TcpSession *); void StreamL7DataPtrInit(TcpSession *);
void StreamL7DataPtrFree(TcpSession *); void StreamL7DataPtrFree(TcpSession *);
void StreamTcpSetSessionNoApplayerInspectionFlag(TcpSession *);
void StreamTcpSetSessionNoReassemblyFlag (TcpSession *, char ); void StreamTcpSetSessionNoReassemblyFlag (TcpSession *, char );
void StreamTcpSetOSPolicy(TcpStream *, Packet *); void StreamTcpSetOSPolicy(TcpStream *, Packet *);
void StreamTcpReassemblePause (TcpSession *, char ); void StreamTcpReassemblePause (TcpSession *, char );
void StreamTcpReassembleUnPause (TcpSession *, char ); void StreamTcpReassembleUnPause (TcpSession *, char );

@ -2926,13 +2926,21 @@ static int ValidTimestamp (TcpSession *ssn, Packet *p)
* \param ssn TCP Session to set the flag in * \param ssn TCP Session to set the flag in
* \param direction direction to set the flag in: 0 toserver, 1 toclient * \param direction direction to set the flag in: 0 toserver, 1 toclient
*/ */
void StreamTcpSetSessionNoReassemblyFlag (TcpSession *ssn, char direction) void StreamTcpSetSessionNoReassemblyFlag (TcpSession *ssn, char direction)
{ {
direction ? (ssn->flags |= STREAMTCP_FLAG_NOSERVER_REASSEMBLY) : direction ? (ssn->flags |= STREAMTCP_FLAG_NOSERVER_REASSEMBLY) :
(ssn->flags |= STREAMTCP_FLAG_NOCLIENT_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 #ifdef UNITTESTS
/** /**

Loading…
Cancel
Save