app-layer: support changing flow alproto

Support changing the application level protocol for a flow. This is
needed by STARTTLS and HTTP CONNECT to switch from the original
alproto to tls.

This commit allows a flag to be set 'FLOW_CHANGE_PROTO', which
triggers a new protocol detection on the next packet for a flow.
pull/2693/head
Mats Klepsland 9 years ago committed by Victor Julien
parent 9b1f74409b
commit b8d13f354b

@ -1614,6 +1614,24 @@ void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_n
SCReturn;
}
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);
FLOW_RESET_PP_DONE(f, STREAM_TOCLIENT);
f->probing_parser_toserver_alproto_masks = 0;
f->probing_parser_toclient_alproto_masks = 0;
AppLayerParserStateCleanup(f->proto, f->alproto, f->alstate, f->alparser);
f->alstate = NULL;
f->alparser = NULL;
f->alproto = ALPROTO_UNKNOWN;
f->alproto_ts = ALPROTO_UNKNOWN;
f->alproto_tc = ALPROTO_UNKNOWN;
}
int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto,
const char *alproto)
{

@ -106,6 +106,11 @@ int AppLayerProtoDetectPMRegisterPatternCI(uint8_t ipproto, AppProto alproto,
*/
int AppLayerProtoDetectSetup(void);
/**
* \brief Reset proto detect for flow
*/
void AppLayerProtoDetectReset(Flow *);
/**
* \brief Cleans up the app layer protocol detection phase.
*/

@ -562,6 +562,14 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
data, data_len, flags) != 0) {
goto failure;
}
} else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
f->alproto_orig = f->alproto;
AppLayerProtoDetectReset(f);
/* rerun protocol detection */
if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream,
data, data_len, flags) != 0) {
goto failure;
}
} else {
SCLogDebug("stream data (len %" PRIu32 " alproto "
"%"PRIu16" (flow %p)", data_len, f->alproto, f);

@ -181,6 +181,38 @@ int FlowHasAlerts(const Flow *f)
return 0;
}
/** \brief Set flag to indicate to change proto for the flow
*
* \param f flow
*/
void FlowSetChangeProtoFlag(Flow *f)
{
f->flags |= FLOW_CHANGE_PROTO;
}
/** \brief Unset flag to indicate to change proto for the flow
*
* \param f flow
*/
void FlowUnsetChangeProtoFlag(Flow *f)
{
f->flags &= ~FLOW_CHANGE_PROTO;
}
/** \brief Check if change proto flag is set for flow
* \param f flow
* \retval 1 change proto flag is set
* \retval 0 change proto flag is not set
*/
int FlowChangeProto(Flow *f)
{
if (f->flags & FLOW_CHANGE_PROTO) {
return 1;
}
return 0;
}
/**
* \brief determine the direction of the packet compared to the flow
* \retval 0 to_server

@ -93,6 +93,8 @@ typedef struct AppLayerParserState_ AppLayerParserState;
#define FLOW_PROTO_DETECT_TS_DONE BIT_U32(20)
#define FLOW_PROTO_DETECT_TC_DONE BIT_U32(21)
/** Indicate that alproto detection for flow should be done again */
#define FLOW_CHANGE_PROTO BIT_U32(22)
/* File flags */
@ -384,6 +386,10 @@ typedef struct Flow_
AppProto alproto_ts;
AppProto alproto_tc;
/** original application level protocol. Used to indicate the previous
protocol when changing to another protocol , e.g. with STARTTLS. */
AppProto alproto_orig;
/** detection engine ctx version used to inspect this flow. Set at initial
* inspection. If it doesn't match the currently in use de_ctx, the
* stored sgh ptrs are reset. */
@ -455,6 +461,9 @@ void FlowShutdown(void);
void FlowSetIPOnlyFlag(Flow *, int);
void FlowSetHasAlertsFlag(Flow *);
int FlowHasAlerts(const Flow *);
void FlowSetChangeProtoFlag(Flow *);
void FlowUnsetChangeProtoFlag(Flow *);
int FlowChangeProto(Flow *);
void FlowRegisterTests (void);
int FlowSetProtoTimeout(uint8_t ,uint32_t ,uint32_t ,uint32_t);

Loading…
Cancel
Save