flow: simplify timeout logic

Instead of a single big FlowProto array containing timeouts separately
for normal and emergency cases, plus the 'Free' pointer for the
protoctx, split up these arrays.

An array made of FlowProtoTimeout for just the normal timeouts and an
mirror of that for emergency timeouts are used through a pointer that
will be set at init and by swapped by the emergency logic. It's swapped
back when the emergency is over.

The free funcs are moved to their own array.

This simplifies the timeout lookup code and shrinks the data that is
commonly used.
pull/2266/head
Victor Julien 9 years ago
parent 96427cf371
commit aee1f0bb99

@ -367,6 +367,8 @@ static Flow *FlowGetNew(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p)
if (!(SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)) { if (!(SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)) {
SC_ATOMIC_OR(flow_flags, FLOW_EMERGENCY); SC_ATOMIC_OR(flow_flags, FLOW_EMERGENCY);
FlowTimeoutsEmergency();
/* under high load, waking up the flow mgr each time leads /* under high load, waking up the flow mgr each time leads
* to high cpu usage. Flows are not timed out much faster if * to high cpu usage. Flows are not timed out much faster if
* we check a 1000 times a second. */ * we check a 1000 times a second. */

@ -82,6 +82,20 @@ SC_ATOMIC_DECLARE(uint32_t, flowrec_cnt);
SC_ATOMIC_EXTERN(unsigned int, flow_flags); SC_ATOMIC_EXTERN(unsigned int, flow_flags);
typedef FlowProtoTimeout *FlowProtoTimeoutPtr;
SC_ATOMIC_DECLARE(FlowProtoTimeoutPtr, flow_timeouts);
void FlowTimeoutsInit(void)
{
SC_ATOMIC_SET(flow_timeouts, flow_timeouts_normal);
}
void FlowTimeoutsEmergency(void)
{
SC_ATOMIC_SET(flow_timeouts, flow_timeouts_emerg);
}
/* 1 seconds */ /* 1 seconds */
#define FLOW_NORMAL_MODE_UPDATE_DELAY_SEC 1 #define FLOW_NORMAL_MODE_UPDATE_DELAY_SEC 1
#define FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC 0 #define FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC 0
@ -164,42 +178,25 @@ void FlowDisableFlowManagerThread(void)
* *
* \param f flow * \param f flow
* \param state flow state * \param state flow state
* \param emergency bool indicating emergency mode 1 yes, 0 no
* *
* \retval timeout timeout in seconds * \retval timeout timeout in seconds
*/ */
static inline uint32_t FlowGetFlowTimeout(const Flow *f, int state, int emergency) static inline uint32_t FlowGetFlowTimeout(const Flow *f, int state)
{ {
uint32_t timeout; uint32_t timeout;
FlowProtoTimeoutPtr flow_timeouts = SC_ATOMIC_GET(flow_timeouts);
if (emergency) {
switch(state) { switch(state) {
default: default:
case FLOW_STATE_NEW: case FLOW_STATE_NEW:
timeout = flow_proto[f->protomap].emerg_new_timeout; timeout = flow_timeouts[f->protomap].new_timeout;
break; break;
case FLOW_STATE_ESTABLISHED: case FLOW_STATE_ESTABLISHED:
timeout = flow_proto[f->protomap].emerg_est_timeout; timeout = flow_timeouts[f->protomap].est_timeout;
break; break;
case FLOW_STATE_CLOSED: case FLOW_STATE_CLOSED:
timeout = flow_proto[f->protomap].emerg_closed_timeout; timeout = flow_timeouts[f->protomap].closed_timeout;
break; break;
} }
} else { /* implies no emergency */
switch(state) {
default:
case FLOW_STATE_NEW:
timeout = flow_proto[f->protomap].new_timeout;
break;
case FLOW_STATE_ESTABLISHED:
timeout = flow_proto[f->protomap].est_timeout;
break;
case FLOW_STATE_CLOSED:
timeout = flow_proto[f->protomap].closed_timeout;
break;
}
}
return timeout; return timeout;
} }
@ -208,16 +205,15 @@ static inline uint32_t FlowGetFlowTimeout(const Flow *f, int state, int emergenc
* *
* \param f flow * \param f flow
* \param ts timestamp * \param ts timestamp
* \param emergency bool indicating emergency mode
* *
* \retval 0 not timed out * \retval 0 not timed out
* \retval 1 timed out * \retval 1 timed out
*/ */
static int FlowManagerFlowTimeout(const Flow *f, int state, struct timeval *ts, int emergency) static int FlowManagerFlowTimeout(const Flow *f, int state, struct timeval *ts)
{ {
/* set the timeout value according to the flow operating mode, /* set the timeout value according to the flow operating mode,
* flow's state and protocol.*/ * flow's state and protocol.*/
uint32_t timeout = FlowGetFlowTimeout(f, state, emergency); uint32_t timeout = FlowGetFlowTimeout(f, state);
/* do the timeout check */ /* do the timeout check */
if ((int32_t)(f->lastts.tv_sec + timeout) >= ts->tv_sec) { if ((int32_t)(f->lastts.tv_sec + timeout) >= ts->tv_sec) {
@ -233,7 +229,6 @@ static int FlowManagerFlowTimeout(const Flow *f, int state, struct timeval *ts,
* *
* \param f flow * \param f flow
* \param ts timestamp * \param ts timestamp
* \param emergency bool indicating emergency mode
* *
* \retval 0 not timed out just yet * \retval 0 not timed out just yet
* \retval 1 fully timed out, lets kill it * \retval 1 fully timed out, lets kill it
@ -286,7 +281,7 @@ static uint32_t FlowManagerHashRowTimeout(Flow *f, struct timeval *ts,
int state = SC_ATOMIC_GET(f->flow_state); int state = SC_ATOMIC_GET(f->flow_state);
/* timeout logic goes here */ /* timeout logic goes here */
if (FlowManagerFlowTimeout(f, state, ts, emergency) == 0) { if (FlowManagerFlowTimeout(f, state, ts) == 0) {
f = f->hprev; f = f->hprev;
continue; continue;
} }
@ -653,6 +648,8 @@ static TmEcode FlowManager(ThreadVars *th_v, void *thread_data)
if (len * 100 / flow_config.prealloc > flow_config.emergency_recovery) { if (len * 100 / flow_config.prealloc > flow_config.emergency_recovery) {
SC_ATOMIC_AND(flow_flags, ~FLOW_EMERGENCY); SC_ATOMIC_AND(flow_flags, ~FLOW_EMERGENCY);
FlowTimeoutsReset();
emerg = FALSE; emerg = FALSE;
prev_emerg = FALSE; prev_emerg = FALSE;
@ -997,6 +994,7 @@ void TmModuleFlowManagerRegister (void)
SCLogDebug("%s registered", tmm_modules[TMM_FLOWMANAGER].name); SCLogDebug("%s registered", tmm_modules[TMM_FLOWMANAGER].name);
SC_ATOMIC_INIT(flowmgr_cnt); SC_ATOMIC_INIT(flowmgr_cnt);
SC_ATOMIC_INIT(flow_timeouts);
} }
void TmModuleFlowRecyclerRegister (void) void TmModuleFlowRecyclerRegister (void)
@ -1049,7 +1047,7 @@ static int FlowMgrTest01 (void)
f.proto = IPPROTO_TCP; f.proto = IPPROTO_TCP;
int state = SC_ATOMIC_GET(f.flow_state); int state = SC_ATOMIC_GET(f.flow_state);
if (FlowManagerFlowTimeout(&f, state, &ts, 0) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) { if (FlowManagerFlowTimeout(&f, state, &ts) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) {
FBLOCK_DESTROY(&fb); FBLOCK_DESTROY(&fb);
FLOW_DESTROY(&f); FLOW_DESTROY(&f);
FlowQueueDestroy(&flow_spare_q); FlowQueueDestroy(&flow_spare_q);
@ -1108,7 +1106,7 @@ static int FlowMgrTest02 (void)
f.proto = IPPROTO_TCP; f.proto = IPPROTO_TCP;
int state = SC_ATOMIC_GET(f.flow_state); int state = SC_ATOMIC_GET(f.flow_state);
if (FlowManagerFlowTimeout(&f, state, &ts, 0) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) { if (FlowManagerFlowTimeout(&f, state, &ts) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) {
FBLOCK_DESTROY(&fb); FBLOCK_DESTROY(&fb);
FLOW_DESTROY(&f); FLOW_DESTROY(&f);
FlowQueueDestroy(&flow_spare_q); FlowQueueDestroy(&flow_spare_q);
@ -1155,7 +1153,7 @@ static int FlowMgrTest03 (void)
f.flags |= FLOW_EMERGENCY; f.flags |= FLOW_EMERGENCY;
int state = SC_ATOMIC_GET(f.flow_state); int state = SC_ATOMIC_GET(f.flow_state);
if (FlowManagerFlowTimeout(&f, state, &ts, 0) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) { if (FlowManagerFlowTimeout(&f, state, &ts) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) {
FBLOCK_DESTROY(&fb); FBLOCK_DESTROY(&fb);
FLOW_DESTROY(&f); FLOW_DESTROY(&f);
FlowQueueDestroy(&flow_spare_q); FlowQueueDestroy(&flow_spare_q);
@ -1215,7 +1213,7 @@ static int FlowMgrTest04 (void)
f.flags |= FLOW_EMERGENCY; f.flags |= FLOW_EMERGENCY;
int state = SC_ATOMIC_GET(f.flow_state); int state = SC_ATOMIC_GET(f.flow_state);
if (FlowManagerFlowTimeout(&f, state, &ts, 0) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) { if (FlowManagerFlowTimeout(&f, state, &ts) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) {
FBLOCK_DESTROY(&fb); FBLOCK_DESTROY(&fb);
FLOW_DESTROY(&f); FLOW_DESTROY(&f);
FlowQueueDestroy(&flow_spare_q); FlowQueueDestroy(&flow_spare_q);

@ -24,6 +24,10 @@
#ifndef __FLOW_MANAGER_H__ #ifndef __FLOW_MANAGER_H__
#define __FLOW_MANAGER_H__ #define __FLOW_MANAGER_H__
#define FlowTimeoutsReset() FlowTimeoutsInit()
void FlowTimeoutsInit(void);
void FlowTimeoutsEmergency(void);
/** flow manager scheduling condition */ /** flow manager scheduling condition */
SCCtrlCondT flow_manager_ctrl_cond; SCCtrlCondT flow_manager_ctrl_cond;
SCCtrlMutex flow_manager_ctrl_mutex; SCCtrlMutex flow_manager_ctrl_mutex;

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2012 Open Information Security Foundation /* Copyright (C) 2007-2016 Open Information Security Foundation
* *
* You can copy, redistribute or modify this Program under the terms of * You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free * the GNU General Public License version 2 as published by the Free
@ -73,7 +73,10 @@ enum {
*/ */
/** FlowProto specific timeouts and free/state functions */ /** FlowProto specific timeouts and free/state functions */
FlowProto flow_proto[FLOW_PROTO_MAX];
FlowProtoTimeout flow_timeouts_normal[FLOW_PROTO_MAX];
FlowProtoTimeout flow_timeouts_emerg[FLOW_PROTO_MAX];
FlowProtoFreeFunc flow_freefuncs[FLOW_PROTO_MAX];
/** spare/unused/prealloced flows live here */ /** spare/unused/prealloced flows live here */
FlowQueue flow_spare_q; FlowQueue flow_spare_q;

@ -481,51 +481,41 @@ void FlowShutdown(void)
void FlowInitFlowProto(void) void FlowInitFlowProto(void)
{ {
/*Default*/ FlowTimeoutsInit();
flow_proto[FLOW_PROTO_DEFAULT].new_timeout = FLOW_DEFAULT_NEW_TIMEOUT;
flow_proto[FLOW_PROTO_DEFAULT].est_timeout = FLOW_DEFAULT_EST_TIMEOUT; #define SET_DEFAULTS(p, n, e, c, ne, ee, ce) \
flow_proto[FLOW_PROTO_DEFAULT].closed_timeout = flow_timeouts_normal[(p)].new_timeout = (n); \
FLOW_DEFAULT_CLOSED_TIMEOUT; flow_timeouts_normal[(p)].est_timeout = (e); \
flow_proto[FLOW_PROTO_DEFAULT].emerg_new_timeout = flow_timeouts_normal[(p)].closed_timeout = (c); \
FLOW_DEFAULT_EMERG_NEW_TIMEOUT; flow_timeouts_emerg[(p)].new_timeout = (ne); \
flow_proto[FLOW_PROTO_DEFAULT].emerg_est_timeout = flow_timeouts_emerg[(p)].est_timeout = (ee); \
FLOW_DEFAULT_EMERG_EST_TIMEOUT; flow_timeouts_emerg[(p)].closed_timeout = (ce);
flow_proto[FLOW_PROTO_DEFAULT].emerg_closed_timeout =
FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT; SET_DEFAULTS(FLOW_PROTO_DEFAULT,
flow_proto[FLOW_PROTO_DEFAULT].Freefunc = NULL; FLOW_DEFAULT_NEW_TIMEOUT, FLOW_DEFAULT_EST_TIMEOUT,
/*TCP*/ FLOW_DEFAULT_CLOSED_TIMEOUT,
flow_proto[FLOW_PROTO_TCP].new_timeout = FLOW_IPPROTO_TCP_NEW_TIMEOUT; FLOW_DEFAULT_EMERG_NEW_TIMEOUT, FLOW_DEFAULT_EMERG_EST_TIMEOUT,
flow_proto[FLOW_PROTO_TCP].est_timeout = FLOW_IPPROTO_TCP_EST_TIMEOUT; FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT);
flow_proto[FLOW_PROTO_TCP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT; SET_DEFAULTS(FLOW_PROTO_TCP,
flow_proto[FLOW_PROTO_TCP].emerg_new_timeout = FLOW_IPPROTO_TCP_NEW_TIMEOUT, FLOW_IPPROTO_TCP_EST_TIMEOUT,
FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT; FLOW_DEFAULT_CLOSED_TIMEOUT,
flow_proto[FLOW_PROTO_TCP].emerg_est_timeout = FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT, FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT,
FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT; FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT);
flow_proto[FLOW_PROTO_TCP].emerg_closed_timeout = SET_DEFAULTS(FLOW_PROTO_UDP,
FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT; FLOW_IPPROTO_UDP_NEW_TIMEOUT, FLOW_IPPROTO_UDP_EST_TIMEOUT,
flow_proto[FLOW_PROTO_TCP].Freefunc = NULL; FLOW_DEFAULT_CLOSED_TIMEOUT,
/*UDP*/ FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT, FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT,
flow_proto[FLOW_PROTO_UDP].new_timeout = FLOW_IPPROTO_UDP_NEW_TIMEOUT; FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT);
flow_proto[FLOW_PROTO_UDP].est_timeout = FLOW_IPPROTO_UDP_EST_TIMEOUT; SET_DEFAULTS(FLOW_PROTO_ICMP,
flow_proto[FLOW_PROTO_UDP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT; FLOW_IPPROTO_ICMP_NEW_TIMEOUT, FLOW_IPPROTO_ICMP_EST_TIMEOUT,
flow_proto[FLOW_PROTO_UDP].emerg_new_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT,
FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT; FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT, FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT,
flow_proto[FLOW_PROTO_UDP].emerg_est_timeout = FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT);
FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT;
flow_proto[FLOW_PROTO_UDP].emerg_closed_timeout = flow_freefuncs[FLOW_PROTO_DEFAULT].Freefunc = NULL;
FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT; flow_freefuncs[FLOW_PROTO_TCP].Freefunc = NULL;
flow_proto[FLOW_PROTO_UDP].Freefunc = NULL; flow_freefuncs[FLOW_PROTO_UDP].Freefunc = NULL;
/*ICMP*/ flow_freefuncs[FLOW_PROTO_ICMP].Freefunc = NULL;
flow_proto[FLOW_PROTO_ICMP].new_timeout = FLOW_IPPROTO_ICMP_NEW_TIMEOUT;
flow_proto[FLOW_PROTO_ICMP].est_timeout = FLOW_IPPROTO_ICMP_EST_TIMEOUT;
flow_proto[FLOW_PROTO_ICMP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT;
flow_proto[FLOW_PROTO_ICMP].emerg_new_timeout =
FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT;
flow_proto[FLOW_PROTO_ICMP].emerg_est_timeout =
FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT;
flow_proto[FLOW_PROTO_ICMP].emerg_closed_timeout =
FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT;
flow_proto[FLOW_PROTO_ICMP].Freefunc = NULL;
/* Let's see if we have custom timeouts defined from config */ /* Let's see if we have custom timeouts defined from config */
const char *new = NULL; const char *new = NULL;
@ -555,39 +545,39 @@ void FlowInitFlowProto(void)
if (new != NULL && if (new != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) { ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
flow_proto[FLOW_PROTO_DEFAULT].new_timeout = configval; flow_timeouts_normal[FLOW_PROTO_DEFAULT].new_timeout = configval;
} }
if (established != NULL && if (established != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(established), ByteExtractStringUint32(&configval, 10, strlen(established),
established) > 0) { established) > 0) {
flow_proto[FLOW_PROTO_DEFAULT].est_timeout = configval; flow_timeouts_normal[FLOW_PROTO_DEFAULT].est_timeout = configval;
} }
if (closed != NULL && if (closed != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(closed), ByteExtractStringUint32(&configval, 10, strlen(closed),
closed) > 0) { closed) > 0) {
flow_proto[FLOW_PROTO_DEFAULT].closed_timeout = configval; flow_timeouts_normal[FLOW_PROTO_DEFAULT].closed_timeout = configval;
} }
if (emergency_new != NULL && if (emergency_new != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(emergency_new), ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
emergency_new) > 0) { emergency_new) > 0) {
flow_proto[FLOW_PROTO_DEFAULT].emerg_new_timeout = configval; flow_timeouts_emerg[FLOW_PROTO_DEFAULT].new_timeout = configval;
} }
if (emergency_established != NULL && if (emergency_established != NULL &&
ByteExtractStringUint32(&configval, 10, ByteExtractStringUint32(&configval, 10,
strlen(emergency_established), strlen(emergency_established),
emergency_established) > 0) { emergency_established) > 0) {
flow_proto[FLOW_PROTO_DEFAULT].emerg_est_timeout= configval; flow_timeouts_emerg[FLOW_PROTO_DEFAULT].est_timeout= configval;
} }
if (emergency_closed != NULL && if (emergency_closed != NULL &&
ByteExtractStringUint32(&configval, 10, ByteExtractStringUint32(&configval, 10,
strlen(emergency_closed), strlen(emergency_closed),
emergency_closed) > 0) { emergency_closed) > 0) {
flow_proto[FLOW_PROTO_DEFAULT].emerg_closed_timeout = configval; flow_timeouts_emerg[FLOW_PROTO_DEFAULT].closed_timeout = configval;
} }
} }
@ -606,39 +596,39 @@ void FlowInitFlowProto(void)
if (new != NULL && if (new != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) { ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
flow_proto[FLOW_PROTO_TCP].new_timeout = configval; flow_timeouts_normal[FLOW_PROTO_TCP].new_timeout = configval;
} }
if (established != NULL && if (established != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(established), ByteExtractStringUint32(&configval, 10, strlen(established),
established) > 0) { established) > 0) {
flow_proto[FLOW_PROTO_TCP].est_timeout = configval; flow_timeouts_normal[FLOW_PROTO_TCP].est_timeout = configval;
} }
if (closed != NULL && if (closed != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(closed), ByteExtractStringUint32(&configval, 10, strlen(closed),
closed) > 0) { closed) > 0) {
flow_proto[FLOW_PROTO_TCP].closed_timeout = configval; flow_timeouts_normal[FLOW_PROTO_TCP].closed_timeout = configval;
} }
if (emergency_new != NULL && if (emergency_new != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(emergency_new), ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
emergency_new) > 0) { emergency_new) > 0) {
flow_proto[FLOW_PROTO_TCP].emerg_new_timeout = configval; flow_timeouts_emerg[FLOW_PROTO_TCP].new_timeout = configval;
} }
if (emergency_established != NULL && if (emergency_established != NULL &&
ByteExtractStringUint32(&configval, 10, ByteExtractStringUint32(&configval, 10,
strlen(emergency_established), strlen(emergency_established),
emergency_established) > 0) { emergency_established) > 0) {
flow_proto[FLOW_PROTO_TCP].emerg_est_timeout = configval; flow_timeouts_emerg[FLOW_PROTO_TCP].est_timeout = configval;
} }
if (emergency_closed != NULL && if (emergency_closed != NULL &&
ByteExtractStringUint32(&configval, 10, ByteExtractStringUint32(&configval, 10,
strlen(emergency_closed), strlen(emergency_closed),
emergency_closed) > 0) { emergency_closed) > 0) {
flow_proto[FLOW_PROTO_TCP].emerg_closed_timeout = configval; flow_timeouts_emerg[FLOW_PROTO_TCP].closed_timeout = configval;
} }
} }
@ -653,26 +643,26 @@ void FlowInitFlowProto(void)
if (new != NULL && if (new != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) { ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
flow_proto[FLOW_PROTO_UDP].new_timeout = configval; flow_timeouts_normal[FLOW_PROTO_UDP].new_timeout = configval;
} }
if (established != NULL && if (established != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(established), ByteExtractStringUint32(&configval, 10, strlen(established),
established) > 0) { established) > 0) {
flow_proto[FLOW_PROTO_UDP].est_timeout = configval; flow_timeouts_normal[FLOW_PROTO_UDP].est_timeout = configval;
} }
if (emergency_new != NULL && if (emergency_new != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(emergency_new), ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
emergency_new) > 0) { emergency_new) > 0) {
flow_proto[FLOW_PROTO_UDP].emerg_new_timeout = configval; flow_timeouts_emerg[FLOW_PROTO_UDP].new_timeout = configval;
} }
if (emergency_established != NULL && if (emergency_established != NULL &&
ByteExtractStringUint32(&configval, 10, ByteExtractStringUint32(&configval, 10,
strlen(emergency_established), strlen(emergency_established),
emergency_established) > 0) { emergency_established) > 0) {
flow_proto[FLOW_PROTO_UDP].emerg_est_timeout = configval; flow_timeouts_emerg[FLOW_PROTO_UDP].est_timeout = configval;
} }
} }
@ -688,26 +678,26 @@ void FlowInitFlowProto(void)
if (new != NULL && if (new != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) { ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
flow_proto[FLOW_PROTO_ICMP].new_timeout = configval; flow_timeouts_normal[FLOW_PROTO_ICMP].new_timeout = configval;
} }
if (established != NULL && if (established != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(established), ByteExtractStringUint32(&configval, 10, strlen(established),
established) > 0) { established) > 0) {
flow_proto[FLOW_PROTO_ICMP].est_timeout = configval; flow_timeouts_normal[FLOW_PROTO_ICMP].est_timeout = configval;
} }
if (emergency_new != NULL && if (emergency_new != NULL &&
ByteExtractStringUint32(&configval, 10, strlen(emergency_new), ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
emergency_new) > 0) { emergency_new) > 0) {
flow_proto[FLOW_PROTO_ICMP].emerg_new_timeout = configval; flow_timeouts_emerg[FLOW_PROTO_ICMP].new_timeout = configval;
} }
if (emergency_established != NULL && if (emergency_established != NULL &&
ByteExtractStringUint32(&configval, 10, ByteExtractStringUint32(&configval, 10,
strlen(emergency_established), strlen(emergency_established),
emergency_established) > 0) { emergency_established) > 0) {
flow_proto[FLOW_PROTO_ICMP].emerg_est_timeout = configval; flow_timeouts_emerg[FLOW_PROTO_ICMP].est_timeout = configval;
} }
} }
} }
@ -728,8 +718,8 @@ int FlowClearMemory(Flow* f, uint8_t proto_map)
SCEnter(); SCEnter();
/* call the protocol specific free function if we have one */ /* call the protocol specific free function if we have one */
if (flow_proto[proto_map].Freefunc != NULL) { if (flow_freefuncs[proto_map].Freefunc != NULL) {
flow_proto[proto_map].Freefunc(f->protoctx); flow_freefuncs[proto_map].Freefunc(f->protoctx);
} }
FlowFreeStorage(f); FlowFreeStorage(f);
@ -752,7 +742,7 @@ int FlowSetProtoFreeFunc (uint8_t proto, void (*Free)(void *))
uint8_t proto_map; uint8_t proto_map;
proto_map = FlowGetProtoMapping(proto); proto_map = FlowGetProtoMapping(proto);
flow_proto[proto_map].Freefunc = Free; flow_freefuncs[proto_map].Freefunc = Free;
return 1; return 1;
} }
@ -814,40 +804,35 @@ static int FlowTest01 (void)
FlowInitFlowProto(); FlowInitFlowProto();
proto_map = FlowGetProtoMapping(IPPROTO_TCP); proto_map = FlowGetProtoMapping(IPPROTO_TCP);
FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_TCP_NEW_TIMEOUT);
if ((flow_proto[proto_map].new_timeout != FLOW_IPPROTO_TCP_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_IPPROTO_TCP_EST_TIMEOUT) FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_TCP_EST_TIMEOUT);
&& (flow_proto[proto_map].emerg_new_timeout != FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT) && (flow_proto[proto_map].emerg_est_timeout != FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT)){ FAIL_IF(flow_timeouts_emerg[proto_map].new_timeout != FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT);
printf ("failed in setting TCP flow timeout"); FAIL_IF(flow_timeouts_emerg[proto_map].est_timeout != FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT);
return 0;
}
proto_map = FlowGetProtoMapping(IPPROTO_UDP); proto_map = FlowGetProtoMapping(IPPROTO_UDP);
if ((flow_proto[proto_map].new_timeout != FLOW_IPPROTO_UDP_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_IPPROTO_UDP_EST_TIMEOUT) FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_UDP_NEW_TIMEOUT);
&& (flow_proto[proto_map].emerg_new_timeout != FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT) && (flow_proto[proto_map].emerg_est_timeout != FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT)){ FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_UDP_EST_TIMEOUT);
printf ("failed in setting UDP flow timeout"); FAIL_IF(flow_timeouts_emerg[proto_map].new_timeout != FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT);
return 0; FAIL_IF(flow_timeouts_emerg[proto_map].est_timeout != FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT);
}
proto_map = FlowGetProtoMapping(IPPROTO_ICMP); proto_map = FlowGetProtoMapping(IPPROTO_ICMP);
if ((flow_proto[proto_map].new_timeout != FLOW_IPPROTO_ICMP_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_IPPROTO_ICMP_EST_TIMEOUT) FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_ICMP_NEW_TIMEOUT);
&& (flow_proto[proto_map].emerg_new_timeout != FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT) && (flow_proto[proto_map].emerg_est_timeout != FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT)){ FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_ICMP_EST_TIMEOUT);
printf ("failed in setting ICMP flow timeout"); FAIL_IF(flow_timeouts_emerg[proto_map].new_timeout != FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT);
return 0; FAIL_IF(flow_timeouts_emerg[proto_map].est_timeout != FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT);
}
proto_map = FlowGetProtoMapping(IPPROTO_DCCP); proto_map = FlowGetProtoMapping(IPPROTO_DCCP);
if ((flow_proto[proto_map].new_timeout != FLOW_DEFAULT_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_DEFAULT_EST_TIMEOUT) FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_DEFAULT_NEW_TIMEOUT);
&& (flow_proto[proto_map].emerg_new_timeout != FLOW_DEFAULT_EMERG_NEW_TIMEOUT) && (flow_proto[proto_map].emerg_est_timeout != FLOW_DEFAULT_EMERG_EST_TIMEOUT)){ FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_DEFAULT_EST_TIMEOUT);
printf ("failed in setting default flow timeout"); FAIL_IF(flow_timeouts_emerg[proto_map].new_timeout != FLOW_DEFAULT_EMERG_NEW_TIMEOUT);
return 0; FAIL_IF(flow_timeouts_emerg[proto_map].est_timeout != FLOW_DEFAULT_EMERG_EST_TIMEOUT);
}
return 1; PASS;
} }
/*Test function for the unit test FlowTest02*/ /*Test function for the unit test FlowTest02*/
void test(void *f) {} static void test(void *f) {}
/** /**
* \test Test the setting of the per protocol free function to free the * \test Test the setting of the per protocol free function to free the
@ -863,23 +848,12 @@ static int FlowTest02 (void)
FlowSetProtoFreeFunc(IPPROTO_UDP, test); FlowSetProtoFreeFunc(IPPROTO_UDP, test);
FlowSetProtoFreeFunc(IPPROTO_ICMP, test); FlowSetProtoFreeFunc(IPPROTO_ICMP, test);
if (flow_proto[FLOW_PROTO_DEFAULT].Freefunc != test) { FAIL_IF(flow_freefuncs[FLOW_PROTO_DEFAULT].Freefunc != test);
printf("Failed in setting default free function\n"); FAIL_IF(flow_freefuncs[FLOW_PROTO_TCP].Freefunc != test);
return 0; FAIL_IF(flow_freefuncs[FLOW_PROTO_UDP].Freefunc != test);
} FAIL_IF(flow_freefuncs[FLOW_PROTO_ICMP].Freefunc != test);
if (flow_proto[FLOW_PROTO_TCP].Freefunc != test) {
printf("Failed in setting TCP free function\n"); PASS;
return 0;
}
if (flow_proto[FLOW_PROTO_UDP].Freefunc != test) {
printf("Failed in setting UDP free function\n");
return 0;
}
if (flow_proto[FLOW_PROTO_ICMP].Freefunc != test) {
printf("Failed in setting ICMP free function\n");
return 0;
}
return 1;
} }
/** /**

@ -427,15 +427,15 @@ enum {
FLOW_STATE_CLOSED, FLOW_STATE_CLOSED,
}; };
typedef struct FlowProto_ { typedef struct FlowProtoTimeout_ {
uint32_t new_timeout; uint32_t new_timeout;
uint32_t est_timeout; uint32_t est_timeout;
uint32_t closed_timeout; uint32_t closed_timeout;
uint32_t emerg_new_timeout; } FlowProtoTimeout;
uint32_t emerg_est_timeout;
uint32_t emerg_closed_timeout; typedef struct FlowProtoFreeFunc_ {
void (*Freefunc)(void *); void (*Freefunc)(void *);
} FlowProto; } FlowProtoFreeFunc;
/** \brief prepare packet for a life with flow /** \brief prepare packet for a life with flow
* Set PKT_WANTS_FLOW flag to incidate workers should do a flow lookup * Set PKT_WANTS_FLOW flag to incidate workers should do a flow lookup

Loading…
Cancel
Save