Small flow updates.

remotes/origin/master-1.0.x
Victor Julien 16 years ago
parent 2e3d7fcb9d
commit b4f0e82463

@ -39,14 +39,13 @@ Flow *FlowAlloc(void)
return f;
}
/** free the memory of a flow */
void FlowFree(Flow *f)
{
mutex_lock(&flow_memuse_mutex);
flow_memuse -= sizeof(Flow);
mutex_unlock(&flow_memuse_mutex);
GenericVarFree(f->flowvar);
free(f);
}

@ -3,6 +3,9 @@
#ifndef __FLOW_UTIL_H__
#define __FLOW_UTIL_H__
/** FlowProto specific timeouts and free/state functions */
FlowProto flow_proto[FLOW_PROTO_MAX];
#define COPY_TIMESTAMP(src,dst) ((dst)->tv_sec = (src)->tv_sec, (dst)->tv_usec = (src)->tv_usec)
/* only clear the parts that won't be overwritten

@ -34,18 +34,16 @@
#define FLOW_DEFAULT_PREALLOC 10000
/*Protocols specific timeouts and free function*/
Protocols protocols[4];
void FlowRegisterTests (void);
void FlowInitProtocols();
void FlowInitFlowProto();
static int FlowUpdateSpareFlows(void);
int FlowSetProtoTimeout(uint8_t , uint32_t ,uint32_t ,uint32_t);
int FlowSetProtoEmergencyTimeout(uint8_t , uint32_t ,uint32_t ,uint32_t);
static int FlowGetProtoMapping(uint8_t );
static int FlowClearMemory(Flow *,uint8_t );
static int FlowGetProtoMapping(uint8_t);
int FlowSetProtoFreeFunc(uint8_t, void (*Free)(void *));
int FlowSetFlowStateFunc (uint8_t , int (*GetProtoState)(void *));
/** \brief Update the flows position in the queue's
* \param f Flow to requeue.
*
@ -118,44 +116,44 @@ static int FlowPrune (FlowQueue *q, struct timeval *ts)
proto_map = FlowGetProtoMapping(f->proto);
if (flow_flags & FLOW_EMERGENCY) {
if (protocols[proto_map].GetProtoState != NULL) {
switch(protocols[proto_map].GetProtoState(f->stream)) {
if (flow_proto[proto_map].GetProtoState != NULL) {
switch(flow_proto[proto_map].GetProtoState(f->stream)) {
case FLOW_STATE_NEW:
timeout = protocols[proto_map].emerg_new_timeout;
timeout = flow_proto[proto_map].emerg_new_timeout;
break;
case FLOW_STATE_ESTABLISHED:
timeout = protocols[proto_map].emerg_est_timeout;
timeout = flow_proto[proto_map].emerg_est_timeout;
break;
case FLOW_STATE_CLOSED:
timeout = protocols[proto_map].emerg_closed_timeout;
timeout = flow_proto[proto_map].emerg_closed_timeout;
break;
}
} else {
if (f->flags & FLOW_EST_LIST)
timeout = protocols[proto_map].emerg_est_timeout;
timeout = flow_proto[proto_map].emerg_est_timeout;
else
timeout = protocols[proto_map].emerg_new_timeout;
timeout = flow_proto[proto_map].emerg_new_timeout;
}
} else {
if (protocols[proto_map].GetProtoState != NULL) {
switch(protocols[proto_map].GetProtoState(f->stream)) {
if (flow_proto[proto_map].GetProtoState != NULL) {
switch(flow_proto[proto_map].GetProtoState(f->stream)) {
case FLOW_STATE_NEW:
timeout = protocols[proto_map].new_timeout;
timeout = flow_proto[proto_map].new_timeout;
break;
case FLOW_STATE_ESTABLISHED:
timeout = protocols[proto_map].est_timeout;
timeout = flow_proto[proto_map].est_timeout;
break;
case FLOW_STATE_CLOSED:
timeout = protocols[proto_map].closed_timeout;
timeout = flow_proto[proto_map].closed_timeout;
break;
}
} else {
if (f->flags & FLOW_EST_LIST)
timeout = protocols[proto_map].est_timeout;
timeout = flow_proto[proto_map].est_timeout;
else
timeout = protocols[proto_map].new_timeout;
timeout = flow_proto[proto_map].new_timeout;
}
}
@ -390,7 +388,7 @@ void FlowInitConfig (char quiet)
flow_config.memuse, flow_config.memcap);
}
FlowInitProtocols();
FlowInitFlowProto();
}
@ -427,9 +425,13 @@ void FlowShutdown(void) {
FlowFree(f);
}
while((f = FlowDequeue(&flow_new_q))) {
uint8_t proto_map = FlowGetProtoMapping(f->proto);
FlowClearMemory(f, proto_map);
FlowFree(f);
}
while((f = FlowDequeue(&flow_est_q))) {
uint8_t proto_map = FlowGetProtoMapping(f->proto);
FlowClearMemory(f, proto_map);
FlowFree(f);
}
@ -545,46 +547,66 @@ void FlowManagerThreadSpawn()
/**
* \brief Function to set the default timeout, free function and flow state
* function for all supported protocols.
* function for all supported flow_proto.
*/
void FlowInitProtocols(void) {
void FlowInitFlowProto(void) {
/*Default*/
protocols[FLOW_PROTO_DEFAULT].new_timeout = FLOW_DEFAULT_NEW_TIMEOUT;
protocols[FLOW_PROTO_DEFAULT].est_timeout = FLOW_DEFAULT_EST_TIMEOUT;
protocols[FLOW_PROTO_DEFAULT].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT;
protocols[FLOW_PROTO_DEFAULT].emerg_new_timeout = FLOW_DEFAULT_EMERG_NEW_TIMEOUT;
protocols[FLOW_PROTO_DEFAULT].emerg_est_timeout = FLOW_DEFAULT_EMERG_EST_TIMEOUT;
protocols[FLOW_PROTO_DEFAULT].emerg_closed_timeout = FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT;
protocols[FLOW_PROTO_DEFAULT].Freefunc = NULL;
protocols[FLOW_PROTO_DEFAULT].GetProtoState = NULL;
flow_proto[FLOW_PROTO_DEFAULT].new_timeout = FLOW_DEFAULT_NEW_TIMEOUT;
flow_proto[FLOW_PROTO_DEFAULT].est_timeout = FLOW_DEFAULT_EST_TIMEOUT;
flow_proto[FLOW_PROTO_DEFAULT].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT;
flow_proto[FLOW_PROTO_DEFAULT].emerg_new_timeout = FLOW_DEFAULT_EMERG_NEW_TIMEOUT;
flow_proto[FLOW_PROTO_DEFAULT].emerg_est_timeout = FLOW_DEFAULT_EMERG_EST_TIMEOUT;
flow_proto[FLOW_PROTO_DEFAULT].emerg_closed_timeout = FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT;
flow_proto[FLOW_PROTO_DEFAULT].Freefunc = NULL;
flow_proto[FLOW_PROTO_DEFAULT].GetProtoState = NULL;
/*TCP*/
protocols[FLOW_PROTO_TCP].new_timeout = FLOW_IPPROTO_TCP_NEW_TIMEOUT;
protocols[FLOW_PROTO_TCP].est_timeout = FLOW_IPPROTO_TCP_EST_TIMEOUT;
protocols[FLOW_PROTO_TCP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT;
protocols[FLOW_PROTO_TCP].emerg_new_timeout = FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT;
protocols[FLOW_PROTO_TCP].emerg_est_timeout = FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT;
protocols[FLOW_PROTO_TCP].emerg_closed_timeout = FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT;
protocols[FLOW_PROTO_TCP].Freefunc = NULL;
protocols[FLOW_PROTO_TCP].GetProtoState = NULL;
flow_proto[FLOW_PROTO_TCP].new_timeout = FLOW_IPPROTO_TCP_NEW_TIMEOUT;
flow_proto[FLOW_PROTO_TCP].est_timeout = FLOW_IPPROTO_TCP_EST_TIMEOUT;
flow_proto[FLOW_PROTO_TCP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT;
flow_proto[FLOW_PROTO_TCP].emerg_new_timeout = FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT;
flow_proto[FLOW_PROTO_TCP].emerg_est_timeout = FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT;
flow_proto[FLOW_PROTO_TCP].emerg_closed_timeout = FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT;
flow_proto[FLOW_PROTO_TCP].Freefunc = NULL;
flow_proto[FLOW_PROTO_TCP].GetProtoState = NULL;
/*UDP*/
protocols[FLOW_PROTO_UDP].new_timeout = FLOW_IPPROTO_UDP_NEW_TIMEOUT;
protocols[FLOW_PROTO_UDP].est_timeout = FLOW_IPPROTO_UDP_EST_TIMEOUT;
protocols[FLOW_PROTO_UDP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT;
protocols[FLOW_PROTO_UDP].emerg_new_timeout = FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT;
protocols[FLOW_PROTO_UDP].emerg_est_timeout = FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT;
protocols[FLOW_PROTO_UDP].emerg_closed_timeout = FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT;
protocols[FLOW_PROTO_UDP].Freefunc = NULL;
protocols[FLOW_PROTO_UDP].GetProtoState = NULL;
flow_proto[FLOW_PROTO_UDP].new_timeout = FLOW_IPPROTO_UDP_NEW_TIMEOUT;
flow_proto[FLOW_PROTO_UDP].est_timeout = FLOW_IPPROTO_UDP_EST_TIMEOUT;
flow_proto[FLOW_PROTO_UDP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT;
flow_proto[FLOW_PROTO_UDP].emerg_new_timeout = FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT;
flow_proto[FLOW_PROTO_UDP].emerg_est_timeout = FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT;
flow_proto[FLOW_PROTO_UDP].emerg_closed_timeout = FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT;
flow_proto[FLOW_PROTO_UDP].Freefunc = NULL;
flow_proto[FLOW_PROTO_UDP].GetProtoState = NULL;
/*ICMP*/
protocols[FLOW_PROTO_ICMP].new_timeout = FLOW_IPPROTO_ICMP_NEW_TIMEOUT;
protocols[FLOW_PROTO_ICMP].est_timeout = FLOW_IPPROTO_ICMP_EST_TIMEOUT;
protocols[FLOW_PROTO_ICMP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT;
protocols[FLOW_PROTO_ICMP].emerg_new_timeout = FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT;
protocols[FLOW_PROTO_ICMP].emerg_est_timeout = FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT;
protocols[FLOW_PROTO_ICMP].emerg_closed_timeout = FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT;
protocols[FLOW_PROTO_ICMP].Freefunc = NULL;
protocols[FLOW_PROTO_ICMP].GetProtoState = 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;
flow_proto[FLOW_PROTO_ICMP].GetProtoState = NULL;
}
/**
* \brief Function to map the protocol to the defined FLOW_PROTO_* enumeration.
*
* \param proto protocol which is needed to be mapped
*/
static int FlowGetProtoMapping(uint8_t proto) {
switch (proto) {
case IPPROTO_TCP:
return FLOW_PROTO_TCP;
case IPPROTO_UDP:
return FLOW_PROTO_UDP;
case IPPROTO_ICMP:
return FLOW_PROTO_ICMP;
default:
return FLOW_PROTO_DEFAULT;
}
}
/**
@ -596,11 +618,14 @@ void FlowInitProtocols(void) {
*/
static int FlowClearMemory(Flow* f, uint8_t proto_map) {
/*This check should be removed later*/
if (protocols[proto_map].Freefunc != NULL)
protocols[proto_map].Freefunc(f->stream);
/* call the protocol specific free function if we have one */
if (flow_proto[proto_map].Freefunc != NULL) {
flow_proto[proto_map].Freefunc(f->stream);
}
f->stream = NULL;
memset(f, 0, sizeof(Flow));
//memset(f, 0, sizeof(Flow));
CLEAR_FLOW(f);
return 1;
}
@ -617,7 +642,7 @@ int FlowSetProtoFreeFunc (uint8_t proto, void (*Free)(void *)) {
uint8_t proto_map;
proto_map = FlowGetProtoMapping(proto);
protocols[proto_map].Freefunc = Free;
flow_proto[proto_map].Freefunc = Free;
return 1;
}
@ -633,7 +658,7 @@ int FlowSetFlowStateFunc (uint8_t proto, int (*GetProtoState)(void *)) {
uint8_t proto_map;
proto_map = FlowGetProtoMapping(proto);
protocols[proto_map].GetProtoState = GetProtoState;
flow_proto[proto_map].GetProtoState = GetProtoState;
return 1;
}
@ -651,9 +676,9 @@ int FlowSetProtoTimeout(uint8_t proto, uint32_t new_timeout, uint32_t est_timeou
uint8_t proto_map;
proto_map = FlowGetProtoMapping(proto);
protocols[proto_map].new_timeout = new_timeout;
protocols[proto_map].est_timeout = est_timeout;
protocols[proto_map].closed_timeout = closed_timeout;
flow_proto[proto_map].new_timeout = new_timeout;
flow_proto[proto_map].est_timeout = est_timeout;
flow_proto[proto_map].closed_timeout = closed_timeout;
return 1;
}
@ -673,33 +698,13 @@ int FlowSetProtoEmergencyTimeout(uint8_t proto, uint32_t emerg_new_timeout, uint
uint8_t proto_map;
proto_map = FlowGetProtoMapping(proto);
protocols[proto_map].emerg_new_timeout = emerg_new_timeout;
protocols[proto_map].emerg_est_timeout = emerg_est_timeout;
protocols[proto_map].emerg_closed_timeout = emerg_closed_timeout;
flow_proto[proto_map].emerg_new_timeout = emerg_new_timeout;
flow_proto[proto_map].emerg_est_timeout = emerg_est_timeout;
flow_proto[proto_map].emerg_closed_timeout = emerg_closed_timeout;
return 1;
}
/**
* \brief Function to map the protocol to the defined FLOW_PROTO_* enumeration.
*
* \param proto protocol which is needed to be mapped
*/
static int FlowGetProtoMapping(uint8_t proto) {
switch (proto) {
case IPPROTO_TCP:
return FLOW_PROTO_TCP;
case IPPROTO_UDP:
return FLOW_PROTO_UDP;
case IPPROTO_ICMP:
return FLOW_PROTO_ICMP;
default:
return FLOW_PROTO_DEFAULT;
}
}
/**
* \test Test the setting of the per protocol timeouts.
*
@ -712,29 +717,29 @@ static int FlowTest01 (void) {
proto_map = FlowGetProtoMapping(IPPROTO_TCP);
if ((protocols[proto_map].new_timeout != FLOW_IPPROTO_TCP_NEW_TIMEOUT) && (protocols[proto_map].est_timeout != FLOW_IPPROTO_TCP_EST_TIMEOUT)
&& (protocols[proto_map].emerg_new_timeout != FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT) && (protocols[proto_map].emerg_est_timeout != FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT)){
if ((flow_proto[proto_map].new_timeout != FLOW_IPPROTO_TCP_NEW_TIMEOUT) && (flow_proto[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)){
printf ("failed in setting TCP flow timeout");
return 0;
}
proto_map = FlowGetProtoMapping(IPPROTO_UDP);
if ((protocols[proto_map].new_timeout != FLOW_IPPROTO_UDP_NEW_TIMEOUT) && (protocols[proto_map].est_timeout != FLOW_IPPROTO_UDP_EST_TIMEOUT)
&& (protocols[proto_map].emerg_new_timeout != FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT) && (protocols[proto_map].emerg_est_timeout != FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT)){
if ((flow_proto[proto_map].new_timeout != FLOW_IPPROTO_UDP_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_IPPROTO_UDP_EST_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)){
printf ("failed in setting UDP flow timeout");
return 0;
}
proto_map = FlowGetProtoMapping(IPPROTO_ICMP);
if ((protocols[proto_map].new_timeout != FLOW_IPPROTO_ICMP_NEW_TIMEOUT) && (protocols[proto_map].est_timeout != FLOW_IPPROTO_ICMP_EST_TIMEOUT)
&& (protocols[proto_map].emerg_new_timeout != FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT) && (protocols[proto_map].emerg_est_timeout != FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT)){
if ((flow_proto[proto_map].new_timeout != FLOW_IPPROTO_ICMP_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_IPPROTO_ICMP_EST_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)){
printf ("failed in setting ICMP flow timeout");
return 0;
}
proto_map = FlowGetProtoMapping(IPPROTO_DCCP);
if ((protocols[proto_map].new_timeout != FLOW_DEFAULT_NEW_TIMEOUT) && (protocols[proto_map].est_timeout != FLOW_DEFAULT_EST_TIMEOUT)
&& (protocols[proto_map].emerg_new_timeout != FLOW_DEFAULT_EMERG_NEW_TIMEOUT) && (protocols[proto_map].emerg_est_timeout != FLOW_DEFAULT_EMERG_EST_TIMEOUT)){
if ((flow_proto[proto_map].new_timeout != FLOW_DEFAULT_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_DEFAULT_EST_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)){
printf ("failed in setting default flow timeout");
return 0;
}
@ -760,19 +765,19 @@ static int FlowTest02 (void) {
FlowSetProtoFreeFunc(IPPROTO_UDP, test);
FlowSetProtoFreeFunc(IPPROTO_ICMP, test);
if (protocols[FLOW_PROTO_DEFAULT].Freefunc != test) {
if (flow_proto[FLOW_PROTO_DEFAULT].Freefunc != test) {
printf("Failed in setting default free function\n");
return 0;
}
if (protocols[FLOW_PROTO_TCP].Freefunc != test) {
if (flow_proto[FLOW_PROTO_TCP].Freefunc != test) {
printf("Failed in setting TCP free function\n");
return 0;
}
if (protocols[FLOW_PROTO_UDP].Freefunc != test) {
if (flow_proto[FLOW_PROTO_UDP].Freefunc != test) {
printf("Failed in setting UDP free function\n");
return 0;
}
if (protocols[FLOW_PROTO_ICMP].Freefunc != test) {
if (flow_proto[FLOW_PROTO_ICMP].Freefunc != test) {
printf("Failed in setting ICMP free function\n");
return 0;
}
@ -980,4 +985,4 @@ void FlowRegisterTests (void) {
UtRegisterTest("FlowTest04 -- Timeout a flow having TcpSession with segments", FlowTest04, 1);
UtRegisterTest("FlowTest05 -- Timeout a flow in emergency having fresh TcpSession", FlowTest05, 1);
UtRegisterTest("FlowTest06 -- Timeout a flow in emergency having TcpSession with segments", FlowTest06, 1);
}
}

@ -89,6 +89,9 @@ enum {
FLOW_PROTO_TCP,
FLOW_PROTO_UDP,
FLOW_PROTO_ICMP,
/* should be last */
FLOW_PROTO_MAX,
};
enum {
@ -97,7 +100,7 @@ enum {
FLOW_STATE_CLOSED,
};
typedef struct Protocols_ {
typedef struct FlowProto_ {
uint32_t new_timeout;
uint32_t est_timeout;
uint32_t closed_timeout;
@ -106,7 +109,7 @@ typedef struct Protocols_ {
uint32_t emerg_closed_timeout;
void (*Freefunc)(void *);
int (*GetProtoState)(void *);
}Protocols;
} FlowProto;
void FlowHandlePacket (ThreadVars *, Packet *);
void FlowInitConfig (char);

@ -1602,6 +1602,8 @@ static int ValidReset(TcpSession *ssn, Packet *p) {
int StreamTcpGetFlowState(void *s) {
TcpSession *ssn = (TcpSession *)s;
if (ssn == NULL)
return FLOW_STATE_CLOSED;
switch(ssn->state) {
case 0:

Loading…
Cancel
Save