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);
- f->alstate = NULL;
+ // Does not free the structures for the parser
+ // keeps f->alstate for new state creation
f->alparser = NULL;
f->alproto = ALPROTO_UNKNOWN;
f->alproto_ts = ALPROTO_UNKNOWN;
SetEOFFlags(pstate, flags);
alstate = f->alstate;
- if (alstate == NULL) {
+ if (alstate == NULL || FlowChangeProto(f)) {
f->alstate = alstate = p->StateAlloc(alstate, f->alproto_orig);
if (alstate == NULL)
goto error;
/***** 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);
/* 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);
+ FlowUnsetChangeProtoFlag(f);
+ AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
+ if (rd != 0) {
SCLogDebug("proto detect failure");
+ f->alstate = NULL;
goto failure;
}
SCLogDebug("protocol change, old %s, new %s",