void AppLayerProtoDetectReset(Flow *f)
{
- FlowUnsetChangeProtoFlag(f);
FLOW_RESET_PM_DONE(f, STREAM_TOSERVER);
FLOW_RESET_PM_DONE(f, STREAM_TOCLIENT);
FLOW_RESET_PP_DONE(f, STREAM_TOSERVER);
f->probing_parser_toserver_alproto_masks = 0;
f->probing_parser_toclient_alproto_masks = 0;
- AppLayerParserStateCleanup(f, f->alstate, f->alparser);
+ // Does not free the structures for the parser
f->alstate = NULL;
f->alparser = NULL;
f->alproto = ALPROTO_UNKNOWN;
/***** Cleanup *****/
-void AppLayerParserStateCleanup(const Flow *f, void *alstate,
- AppLayerParserState *pstate)
+void AppLayerParserStateProtoCleanup(
+ uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
{
SCEnter();
- AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[f->protomap][f->alproto];
+ AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[protomap][alproto];
if (ctx->StateFree != NULL && alstate != NULL)
ctx->StateFree(alstate);
SCReturn;
}
+void AppLayerParserStateCleanup(const Flow *f, void *alstate,
+ AppLayerParserState *pstate)
+{
+ AppLayerParserStateProtoCleanup(f->protomap, f->alproto, alstate, pstate);
+}
+
static void ValidateParserProtoDump(AppProto alproto, uint8_t ipproto)
{
uint8_t map = FlowGetProtoMapping(ipproto);
/***** Cleanup *****/
+void AppLayerParserStateProtoCleanup(
+ uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate);
void AppLayerParserStateCleanup(const Flow *f, void *alstate, AppLayerParserState *pstate);
void AppLayerParserRegisterProtocolParsers(void);
} else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
f->alproto_orig = f->alproto;
SCLogDebug("protocol change, old %s", AppProtoToString(f->alproto_orig));
+ void *alstate_orig = f->alstate;
+ AppLayerParserState *alparser = f->alparser;
+ // we delay AppLayerParserStateCleanup because we may need previous parser state
AppLayerProtoDetectReset(f);
+ StreamTcpResetStreamFlagAppProtoDetectionCompleted(&ssn->client);
+ StreamTcpResetStreamFlagAppProtoDetectionCompleted(&ssn->server);
/* rerun protocol detection */
- if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream,
- data, data_len, flags) != 0) {
+ int rd = TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags);
+ if (f->alproto == ALPROTO_UNKNOWN) {
+ // not enough data, revert AppLayerProtoDetectReset to rerun detection
+ f->alparser = alparser;
+ f->alstate = alstate_orig;
+ f->alproto = f->alproto_orig;
+ f->alproto_tc = f->alproto_orig;
+ f->alproto_ts = f->alproto_orig;
+ } else {
+ FlowUnsetChangeProtoFlag(f);
+ AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
+ }
+ if (rd != 0) {
SCLogDebug("proto detect failure");
goto failure;
}