From: Victor Julien Date: Fri, 11 Apr 2014 10:20:04 +0000 (+0200) Subject: protocol detection: handle very unbalanced case X-Git-Tag: suricata-2.0.1rc1~31 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1bd189a07633aa92eb524c68c2873bfcef4e233e;p=thirdparty%2Fsuricata.git protocol detection: handle very unbalanced case Some traffic is very unbalanced. For example a 4 bytes request followed by 12mb of response data. If the 4 bytes don't lead to the protocol being detected, then app layer processing won't start, but it will not give up either. It will just wait for more data. This leads to piling up data on the opposite side. Observed: TS: 4 bytes. PP failed (bit set), PM has not given up (bit not set). This makes sense as max_depth is not yet reached. TC: 12mb. PP and PM failed (bits set). As ts-PM never gives up, we never consider proto detect complete, so all segments in either direction are still kept in the session. This patch adds a cutoff for this case: - IF for TS we have PP bit set, PM not set, AND - we have TC both bits set, AND - proto is unknown, AND - TC data is 100k already, THEN - give up on protocol detection. The same for the opposite direction. --- diff --git a/src/app-layer.c b/src/app-layer.c index 8f2c0fe4c4..18b4de551d 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -403,6 +403,32 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, APPLAYER_PROTO_DETECTION_SKIPPED); + /* little data in ts direction, pp done, pm not done (max + * depth not reached), ts direction done, lots of data in + * tc direction. */ + } else if (size_tc > 100000 && + FLOW_IS_PP_DONE(f, STREAM_TOSERVER) && !(FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && + FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT)) + { + FlowSetSessionNoApplayerInspectionFlag(f); + StreamTcpSetStreamFlagAppProtoDetectionCompleted(&ssn->server); + StreamTcpSetStreamFlagAppProtoDetectionCompleted(&ssn->client); + ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; + AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, + APPLAYER_PROTO_DETECTION_SKIPPED); + /* little data in tc direction, pp done, pm not done (max + * depth not reached), tc direction done, lots of data in + * ts direction. */ + } else if (size_ts > 100000 && + FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) && !(FLOW_IS_PM_DONE(f, STREAM_TOCLIENT)) && + FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) + { + FlowSetSessionNoApplayerInspectionFlag(f); + StreamTcpSetStreamFlagAppProtoDetectionCompleted(&ssn->server); + StreamTcpSetStreamFlagAppProtoDetectionCompleted(&ssn->client); + ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; + AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, + APPLAYER_PROTO_DETECTION_SKIPPED); } } }