diff --git a/src/app-layer.c b/src/app-layer.c index 5a891d200f..e19e33365a 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -336,21 +336,25 @@ static int TCPProtoDetect(ThreadVars *tv, if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != *alproto) { AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS); - /* it indicates some data has already been sent to the parser */ + if (ssn->data_first_seen_dir == APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - f->alproto = *alproto = *alproto_otherdir; + /* if we already invoked the parser, we go with that proto */ + f->alproto = *alproto_otherdir; } else { + /* no data sent to parser yet, we can still choose + * we're trusting the server more. */ if (flags & STREAM_TOCLIENT) - f->alproto = *alproto_otherdir = *alproto; + f->alproto = *alproto; else - f->alproto = *alproto = *alproto_otherdir; + f->alproto = *alproto_otherdir; } + } else { + f->alproto = *alproto; } - f->alproto = *alproto; StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream); TcpSessionSetReassemblyDepth(ssn, - AppLayerParserGetStreamDepth(f->proto, *alproto)); + AppLayerParserGetStreamDepth(f->proto, f->alproto)); if (flags & STREAM_TOCLIENT) FlagPacketFlow(p, f, STREAM_TOCLIENT); else @@ -397,7 +401,7 @@ static int TCPProtoDetect(ThreadVars *tv, */ if (ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { uint8_t first_data_dir; - first_data_dir = AppLayerParserGetFirstDataDir(f->proto, *alproto); + first_data_dir = AppLayerParserGetFirstDataDir(f->proto, f->alproto); if (first_data_dir && !(first_data_dir & ssn->data_first_seen_dir)) { AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, @@ -415,9 +419,7 @@ static int TCPProtoDetect(ThreadVars *tv, * hasn't managed to send data from the other direction * to the app layer. */ if (first_data_dir && !(first_data_dir & flags)) { - BUG_ON(*alproto_otherdir != ALPROTO_UNKNOWN); FlowCleanupAppLayer(f); - f->alproto = *alproto = ALPROTO_UNKNOWN; StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream); FLOW_RESET_PP_DONE(f, flags); FLOW_RESET_PM_DONE(f, flags); @@ -429,10 +431,10 @@ static int TCPProtoDetect(ThreadVars *tv, ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; /* finally, invoke the parser */ - PACKET_PROFILING_APP_START(app_tctx, *alproto); - int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, *alproto, + PACKET_PROFILING_APP_START(app_tctx, f->alproto); + int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto, flags, data, data_len); - PACKET_PROFILING_APP_END(app_tctx, *alproto); + PACKET_PROFILING_APP_END(app_tctx, f->alproto); if (r < 0) goto failure; @@ -499,22 +501,26 @@ static int TCPProtoDetect(ThreadVars *tv, if (data_len > 0) ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - PACKET_PROFILING_APP_START(app_tctx, *alproto_otherdir); + PACKET_PROFILING_APP_START(app_tctx, f->alproto); int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, - *alproto_otherdir, flags, + f->alproto, flags, data, data_len); - PACKET_PROFILING_APP_END(app_tctx, *alproto_otherdir); + PACKET_PROFILING_APP_END(app_tctx, f->alproto); + AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION); StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream); TcpSessionSetReassemblyDepth(ssn, - AppLayerParserGetStreamDepth(f->proto, *alproto)); + AppLayerParserGetStreamDepth(f->proto, f->alproto)); + *alproto = ALPROTO_FAILED; if (flags & STREAM_TOCLIENT) FlagPacketFlow(p, f, STREAM_TOCLIENT); else FlagPacketFlow(p, f, STREAM_TOSERVER); + SCLogDebug("packet %u: pd done(us %u them %u), parser called (r==%d), APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION set", + (uint)p->pcap_cnt, *alproto, *alproto_otherdir, r); if (r < 0) goto failure; }