Improve flow hash debugging functions. Make sure ICMP errors don't create flows. Handle ICMP DEST UNREACH errors in the flow they are sending the error about.

remotes/origin/master-1.0.x
Victor Julien 16 years ago
parent 2dc5405d3a
commit 548a3b2c93

@ -71,8 +71,9 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len )
case IPPROTO_TCP:
if (len >= IPV4_HEADER_LEN + TCP_HEADER_LEN ) {
p->icmpv4vars.emb_tcph = (TCPHdr*)(partial_packet + IPV4_HEADER_LEN);
p->icmpv4vars.emb_sport = p->icmpv4vars.emb_tcph->th_sport;
p->icmpv4vars.emb_dport = p->icmpv4vars.emb_tcph->th_dport;
p->icmpv4vars.emb_sport = ntohs(p->icmpv4vars.emb_tcph->th_sport);
p->icmpv4vars.emb_dport = ntohs(p->icmpv4vars.emb_tcph->th_dport);
p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP;
SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP header sport: "
"%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport,
@ -88,8 +89,9 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len )
case IPPROTO_UDP:
if (len >= IPV4_HEADER_LEN + UDP_HEADER_LEN ) {
p->icmpv4vars.emb_udph = (UDPHdr*)(partial_packet + IPV4_HEADER_LEN);
p->icmpv4vars.emb_sport = p->icmpv4vars.emb_udph->uh_sport;
p->icmpv4vars.emb_dport = p->icmpv4vars.emb_udph->uh_dport;
p->icmpv4vars.emb_sport = ntohs(p->icmpv4vars.emb_udph->uh_sport);
p->icmpv4vars.emb_dport = ntohs(p->icmpv4vars.emb_udph->uh_dport);
p->icmpv4vars.emb_ip4_proto = IPPROTO_UDP;
SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->UDP header sport: "
"%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport,
@ -106,6 +108,7 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len )
p->icmpv4vars.emb_icmpv4h = (ICMPV4Hdr*)(partial_packet + IPV4_HEADER_LEN);
p->icmpv4vars.emb_sport = 0;
p->icmpv4vars.emb_dport = 0;
p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP;
SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header");
@ -160,16 +163,20 @@ void DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
break;
case ICMP_DEST_UNREACH:
if (p->icmpv4h->code>NR_ICMP_UNREACH) {
if (p->icmpv4h->code > NR_ICMP_UNREACH) {
DECODER_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
} else {
// parse IP header plus 64 bytes
if (len >= ICMPV4_HEADER_PKT_OFFSET)
DecodePartialIPV4( p, (uint8_t*) (pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET );
/* parse IP header plus 64 bytes */
if (len >= ICMPV4_HEADER_PKT_OFFSET) {
DecodePartialIPV4( p, (uint8_t *)(pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET );
/* ICMP ICMP_DEST_UNREACH influence TCP/UDP flows */
if (ICMPV4_DEST_UNREACH_IS_VALID(p)) {
FlowHandlePacket(tv, p);
}
}
}
/* ICMP ICMP_DEST_UNREACH influence TCP/UDP flows */
FlowHandlePacket(tv, p);
break;

@ -196,6 +196,7 @@ typedef struct ICMPV4Vars_
struct in_addr emb_ip4_src;
struct in_addr emb_ip4_dst;
uint8_t emb_ip4_hlen;
uint8_t emb_ip4_proto;
/** TCP/UDP ports */
uint16_t emb_sport;
@ -207,7 +208,7 @@ typedef struct ICMPV4Vars_
/** macro for icmpv4 "type" access */
#define ICMPV4_GET_TYPE(p) (p)->icmpv4h->type
/** macro for icmpv4 "code" access */
#define ICMPV4_GET_CODE(p) (p)->icmpv4h->code
#define ICMPV4_GET_CODE(p) (p)->icmpv4h->code
/** macro for icmpv4 "csum" access */
#define ICMPV4_GET_CSUM(p) (p)->icmpv4h->csum
@ -228,7 +229,7 @@ typedef struct ICMPV4Vars_
#define ICMPV4_GET_MTU(p) (p)->icmpv4h->icmpv4b.icmpv4e.mtu
/** macro for icmpv4 embedded "protocol" access */
#define ICMPV4_GET_EMB_PROTO(p) (p)->icmpv4vars.emb_ip6_proto_next
#define ICMPV4_GET_EMB_PROTO(p) (p)->icmpv4vars.emb_ip4_proto
/** macro for icmpv4 embedded "ipv4h" header access */
#define ICMPV4_GET_EMB_IPV4(p) (p)->icmpv4vars.emb_ipv4h
/** macro for icmpv4 embedded "tcph" header access */
@ -238,6 +239,32 @@ typedef struct ICMPV4Vars_
/** macro for icmpv4 embedded "icmpv4h" header access */
#define ICMPV4_GET_EMB_ICMPV4H(p) (p)->icmpv4vars.emb_icmpv4h
/** macro for checking if a ICMP DEST UNREACH packet is valid for use
* in other parts of the engine, such as the flow engine.
*
* \warning use only _after_ the decoder has processed the packet
*/
#define ICMPV4_DEST_UNREACH_IS_VALID(p) (((p)->icmpv4h != NULL) && \
(ICMPV4_GET_TYPE((p)) == ICMP_DEST_UNREACH) && \
(ICMPV4_GET_EMB_IPV4((p)) != NULL) && \
((ICMPV4_GET_EMB_TCP((p)) != NULL) || \
(ICMPV4_GET_EMB_UDP((p)) != NULL)))
/**
* marco for checking if a ICMP packet is an error message or an
* query message.
*
* \todo This check is used in the flow engine and needs to be as
* cheap as possible. Consider setting a bitflag at the decoder
* stage so we can to a bit check instead of the more expensive
* check below.
*/
#define ICMPV4_IS_ERROR_MSG(p) (ICMPV4_GET_TYPE((p)) == ICMP_DEST_UNREACH || \
ICMPV4_GET_TYPE((p)) == ICMP_SOURCE_QUENCH || \
ICMPV4_GET_TYPE((p)) == ICMP_REDIRECT || \
ICMPV4_GET_TYPE((p)) == ICMP_TIME_EXCEEDED || \
ICMPV4_GET_TYPE((p)) == ICMP_PARAMETERPROB)
typedef struct ICMPV4Cache_ {
/* checksum computed over the icmpv4 packet */
int32_t comp_csum;

@ -92,6 +92,11 @@ typedef struct IPV4Hdr_
#define IPV4_GET_RAW_IPSRC(ip4h) ((ip4h)->ip_src)
#define IPV4_GET_RAW_IPDST(ip4h) ((ip4h)->ip_dst)
/** return the raw (directly from the header) src ip as uint32_t */
#define IPV4_GET_RAW_IPSRC_U32(ip4h) (uint32_t)((ip4h)->ip_src.s_addr)
/** return the raw (directly from the header) dst ip as uint32_t */
#define IPV4_GET_RAW_IPDST_U32(ip4h) (uint32_t)((ip4h)->ip_dst.s_addr)
/* we need to change them as well as get them */
#define IPV4_SET_RAW_VER(ip4h, value) ((ip4h)->ip_verhl = (((ip4h)->ip_verhl & 0x0f) | (value << 4)))
#define IPV4_SET_RAW_HLEN(ip4h, value) ((ip4h)->ip_verhl = (((ip4h)->ip_verhl & 0xf0) | (value & 0x0f)))

@ -34,10 +34,9 @@
#include "flow-util.h"
#include "flow-private.h"
#include "util-time.h"
#include "util-debug.h"
//#define FLOW_DEBUG_STATS
#ifdef FLOW_DEBUG_STATS
#define FLOW_DEBUG_STATS_PROTO_ALL 0
#define FLOW_DEBUG_STATS_PROTO_TCP 1
@ -47,6 +46,7 @@
static uint64_t flow_hash_count[5] = { 0, 0, 0, 0, 0 }; /* how often are we looking for a hash */
static uint64_t flow_hash_loop_count[5] = { 0, 0, 0, 0, 0 }; /* how often do we loop through a hash bucket */
static FILE *flow_hash_count_fp = NULL;
static SCSpinlock flow_hash_count_lock;
#define FlowHashCountUpdate do { \
@ -54,15 +54,18 @@ static SCSpinlock flow_hash_count_lock;
flow_hash_count[FLOW_DEBUG_STATS_PROTO_ALL]++; \
flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ALL] += _flow_hash_counter; \
if (f != NULL) { \
if (f->proto == IPPROTO_TCP) { \
if (p->proto == IPPROTO_TCP) { \
flow_hash_count[FLOW_DEBUG_STATS_PROTO_TCP]++; \
flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_TCP] += _flow_hash_counter; \
} else if (f->proto == IPPROTO_UDP) {\
} else if (p->proto == IPPROTO_UDP) {\
flow_hash_count[FLOW_DEBUG_STATS_PROTO_UDP]++; \
flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_UDP] += _flow_hash_counter; \
} else if (f->proto == IPPROTO_ICMP) {\
} else if (p->proto == IPPROTO_ICMP) {\
flow_hash_count[FLOW_DEBUG_STATS_PROTO_ICMP]++; \
flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ICMP] += _flow_hash_counter; \
} else {\
flow_hash_count[FLOW_DEBUG_STATS_PROTO_OTHER]++; \
flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_OTHER] += _flow_hash_counter; \
} \
} \
SCSpinUnlock(&flow_hash_count_lock); \
@ -71,40 +74,58 @@ static SCSpinlock flow_hash_count_lock;
#define FlowHashCountInit uint64_t _flow_hash_counter = 0
#define FlowHashCountIncr _flow_hash_counter++;
#else
#define FlowHashCountUpdate
#define FlowHashCountInit
#define FlowHashCountIncr
#endif /* FLOW_DEBUG_STATS */
void FlowHashDebugInit(void) {
#ifdef FLOW_DEBUG_STATS
SCSpinInit(&flow_hash_count_lock, 0);
#endif
flow_hash_count_fp = fopen("flow-debug.log", "w+");
}
void FlowHashDebugDeinit(void) {
void FlowHashDebugPrint(uint32_t ts) {
#ifdef FLOW_DEBUG_STATS
SCSpinDestroy(&flow_hash_count_lock);
SCLogInfo("TCP %"PRIu64" %"PRIu64, flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_TCP], flow_hash_count[FLOW_DEBUG_STATS_PROTO_TCP]);
if (flow_hash_count_fp == NULL)
return;
float avg_all = 0, avg_tcp = 0, avg_udp = 0, avg_icmp = 0, avg_other = 0;
SCSpinLock(&flow_hash_count_lock);
if (flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ALL] != 0)
avg_all = (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ALL]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_ALL]));
if (flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_TCP] != 0)
avg_tcp = (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_TCP]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_TCP]));
if (flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_UDP] != 0)
avg_udp = (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_UDP]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_UDP]));
if (flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ICMP] != 0)
avg_icmp= (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ICMP]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_ICMP]));
if (flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_OTHER] != 0)
avg_other= (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_OTHER]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_OTHER]));
fprintf(flow_hash_count_fp, "%"PRIu32": all %02.3f, tcp %02.3f, udp %02.3f, icmp %02.3f, other %02.3f\n", ts, avg_all, avg_tcp, avg_udp, avg_icmp, avg_other);
fflush(flow_hash_count_fp);
memset(&flow_hash_count, 0, sizeof(flow_hash_count));
memset(&flow_hash_loop_count, 0, sizeof(flow_hash_loop_count));
SCSpinUnlock(&flow_hash_count_lock);
#endif
}
void FlowHashDebugPrint(void) {
void FlowHashDebugDeinit(void) {
#ifdef FLOW_DEBUG_STATS
float avg_all, avg_tcp, avg_udp, avg_icmp;
SCSpinLock(&flow_hash_count_lock);
avg_all = (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ALL]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_ALL]));
avg_tcp = (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_TCP]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_TCP]));
avg_udp = (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_UDP]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_UDP]));
avg_icmp= (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ICMP]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_ICMP]));
SCSpinUnlock(&flow_hash_count_lock);
SCLogInfo("Avg flowbucket walk: all %02.3f, tcp %02.3f, udp %02.3f, icmp %02.3f", avg_all, avg_tcp, avg_udp, avg_icmp);
struct timeval ts;
memset(&ts, 0, sizeof(ts));
TimeGet(&ts);
FlowHashDebugPrint((uint32_t)ts.tv_sec);
if (flow_hash_count_fp != NULL)
fclose(flow_hash_count_fp);
SCSpinDestroy(&flow_hash_count_lock);
#endif
}
#else
#define FlowHashCountUpdate
#define FlowHashCountInit
#define FlowHashCountIncr
#endif /* FLOW_DEBUG_STATS */
/* calculate the hash key for this packet
*
* we're using:
@ -115,16 +136,49 @@ void FlowHashDebugPrint(void) {
* destination address
* recursion level -- for tunnels, make sure different tunnel layers can
* never get mixed up.
*
* For ICMP we only consider UNREACHABLE errors atm.
*/
uint32_t FlowGetKey(Packet *p) {
FlowKey *k = (FlowKey *)p;
uint32_t key;
if (p->ip4h != NULL)
key = (flow_config.hash_rand + k->proto + k->sp + k->dp + \
k->src.addr_data32[0] + k->dst.addr_data32[0] + \
k->recursion_level) % flow_config.hash_size;
else if (p->ip6h != NULL)
if (p->ip4h != NULL) {
if (p->tcph != NULL || p->udph != NULL) {
key = (flow_config.hash_rand + k->proto + k->sp + k->dp + \
k->src.addr_data32[0] + k->dst.addr_data32[0] + \
k->recursion_level) % flow_config.hash_size;
/*
SCLogDebug("TCP/UCP key %"PRIu32, key);
SCLogDebug("proto %u, sp %u, dp %u, src %u, dst %u, reclvl %u",
k->proto, k->sp, k->dp, k->src.addr_data32[0], k->dst.addr_data32[0],
k->recursion_level);
*/
} else if (ICMPV4_DEST_UNREACH_IS_VALID(p)) {
// SCLogDebug("valid ICMPv4 DEST UNREACH error packet");
key = (flow_config.hash_rand + ICMPV4_GET_EMB_PROTO(p) +
p->icmpv4vars.emb_sport + \
p->icmpv4vars.emb_dport + \
IPV4_GET_RAW_IPSRC_U32(ICMPV4_GET_EMB_IPV4(p)) + \
IPV4_GET_RAW_IPDST_U32(ICMPV4_GET_EMB_IPV4(p)) + \
k->recursion_level) % flow_config.hash_size;
/*
SCLogDebug("ICMP DEST UNREACH key %"PRIu32, key);
SCLogDebug("proto %u, sp %u, dp %u, src %u, dst %u, reclvl %u",
ICMPV4_GET_EMB_PROTO(p), p->icmpv4vars.emb_sport,
p->icmpv4vars.emb_dport, IPV4_GET_RAW_IPSRC_U32(ICMPV4_GET_EMB_IPV4(p)),
IPV4_GET_RAW_IPDST_U32(ICMPV4_GET_EMB_IPV4(p)), k->recursion_level);
*/
} else {
key = (flow_config.hash_rand + k->proto + \
k->src.addr_data32[0] + k->dst.addr_data32[0] + \
k->recursion_level) % flow_config.hash_size;
}
} else if (p->ip6h != NULL)
key = (flow_config.hash_rand + k->proto + k->sp + k->dp + \
k->src.addr_data32[0] + k->src.addr_data32[1] + \
k->src.addr_data32[2] + k->src.addr_data32[3] + \
@ -149,6 +203,79 @@ uint32_t FlowGetKey(Packet *p) {
(f1)->proto == (f2)->proto && \
(f1)->recursion_level == (f2)->recursion_level)
/**
* \brief See if a ICMP packet belongs to a flow by comparing the embedded
* packet in the ICMP error packet to the flow.
*
* \param f flow
* \param p ICMP packet
*
* \retval 1 match
* \retval 0 no match
*/
static inline int FlowCompareICMPv4(Flow *f, Packet *p) {
if (ICMPV4_DEST_UNREACH_IS_VALID(p)) {
/* first check the direction of the flow, in other words, the client ->
* server direction as it's most likely the ICMP error will be a
* response to the clients traffic */
if ((f->src.addr_data32[0] == IPV4_GET_RAW_IPSRC_U32( ICMPV4_GET_EMB_IPV4(p) )) &&
(f->dst.addr_data32[0] == IPV4_GET_RAW_IPDST_U32( ICMPV4_GET_EMB_IPV4(p) )) &&
f->sp == p->icmpv4vars.emb_sport &&
f->dp == p->icmpv4vars.emb_dport &&
f->proto == ICMPV4_GET_EMB_PROTO(p) &&
f->recursion_level == p->recursion_level)
{
return 1;
/* check the less likely case where the ICMP error was a response to
* a packet from the server. */
} else if ((f->dst.addr_data32[0] == IPV4_GET_RAW_IPSRC_U32( ICMPV4_GET_EMB_IPV4(p) )) &&
(f->src.addr_data32[0] == IPV4_GET_RAW_IPDST_U32( ICMPV4_GET_EMB_IPV4(p) )) &&
f->dp == p->icmpv4vars.emb_sport &&
f->sp == p->icmpv4vars.emb_dport &&
f->proto == ICMPV4_GET_EMB_PROTO(p) &&
f->recursion_level == p->recursion_level)
{
return 1;
}
/* no match, fall through */
} else {
/* just treat ICMP as a normal proto for now */
return CMP_FLOW(f, p);
}
return 0;
}
static inline int FlowCompare(Flow *f, Packet *p) {
if (p->proto == IPPROTO_ICMP) {
return FlowCompareICMPv4(f, p);
} else {
return CMP_FLOW(f, p);
}
}
/**
* \brief Check if we should create a flow based on a packet
*
* We use this check to filter out flow creation based on:
* - ICMP error messages
*
* \param p packet
* \retval 1 true
* \retval 0 false
*/
static inline int FlowCreateCheck(Packet *p) {
if (PKT_IS_ICMPV4(p)) {
if (ICMPV4_IS_ERROR_MSG(p)) {
return 0;
}
}
return 1;
}
/* FlowGetFlowFromHash
*
* Hash retrieval function for flows. Looks up the hash bucket containing the
@ -178,6 +305,12 @@ Flow *FlowGetFlowFromHash (Packet *p)
/* see if the bucket already has a flow */
if (fb->f == NULL) {
if (FlowCreateCheck(p) == 0) {
SCSpinUnlock(&fb->s);
FlowHashCountUpdate;
return NULL;
}
/* no, so get a new one */
f = fb->f = FlowDequeue(&flow_spare_q);
if (f == NULL) {
@ -212,7 +345,7 @@ Flow *FlowGetFlowFromHash (Packet *p)
SCMutexLock(&f->m);
/* see if this is the flow we are looking for */
if (CMP_FLOW(f, p) == 0) {
if (FlowCompare(f, p) == 0) {
Flow *pf = NULL; /* previous flow */
SCMutexUnlock(&f->m);
@ -223,6 +356,12 @@ Flow *FlowGetFlowFromHash (Packet *p)
f = f->hnext;
if (f == NULL) {
if (FlowCreateCheck(p) == 0) {
SCSpinUnlock(&fb->s);
FlowHashCountUpdate;
return NULL;
}
/* get us a new one and put it and the list tail */
f = pf->hnext = FlowDequeue(&flow_spare_q);
if (f == NULL) {
@ -254,7 +393,7 @@ Flow *FlowGetFlowFromHash (Packet *p)
SCMutexLock(&f->m);
if (CMP_FLOW(f, p) != 0) {
if (FlowCompare(f, p) != 0) {
/* we found our flow, lets put it on top of the
* hash list -- this rewards active flows */
if (f->hnext) f->hnext->hprev = f->hprev;

@ -38,9 +38,18 @@ typedef struct FlowBucket_ {
Flow *FlowGetFlowFromHash(Packet *);
/** enable to print stats on hash lookups in flow-debug.log */
//#define FLOW_DEBUG_STATS
#ifdef FLOW_DEBUG_STATS
void FlowHashDebugInit(void);
void FlowHashDebugDeinit(void);
void FlowHashDebugPrint(void);
void FlowHashDebugPrint(uint32_t);
#else
#define FlowHashDebugInit(...)
#define FlowHashDebugPrint(...)
#define FlowHashDebugDeinit(...)
#endif
#endif /* __FLOW_HASH_H__ */

@ -382,6 +382,24 @@ static inline int FlowGetPacketDirection(Flow *f, Packet *p) {
return TOSERVER;
}
/**
* \brief Check to update "seen" flags
*
* \param p packet
*
* \retval 1 true
* \retval 0 false
*/
static inline int FlowUpdateSeenFlag(Packet *p) {
if (PKT_IS_ICMPV4(p)) {
if (ICMPV4_IS_ERROR_MSG(p)) {
return 0;
}
}
return 1;
}
/** \brief Entry point for packet flow handling
*
* This is called for every packet.
@ -405,11 +423,15 @@ void FlowHandlePacket (ThreadVars *tv, Packet *p)
/* update flags and counters */
if (FlowGetPacketDirection(f,p) == TOSERVER) {
f->flags |= FLOW_TO_DST_SEEN;
if (FlowUpdateSeenFlag(p)) {
f->flags |= FLOW_TO_DST_SEEN;
}
f->todstpktcnt++;
p->flowflags |= FLOW_PKT_TOSERVER;
} else {
f->flags |= FLOW_TO_SRC_SEEN;
if (FlowUpdateSeenFlag(p)) {
f->flags |= FLOW_TO_SRC_SEEN;
}
f->tosrcpktcnt++;
p->flowflags |= FLOW_PKT_TOCLIENT;
}
@ -659,6 +681,7 @@ void *FlowManagerThread(void *td)
uint32_t established_cnt = 0, new_cnt = 0, closing_cnt = 0, nowcnt;
uint32_t sleeping = 0;
uint8_t emerg = FALSE;
uint32_t last_sec = 0;
memset(&ts, 0, sizeof(ts));
@ -679,22 +702,21 @@ void *FlowManagerThread(void *td)
if (sleeping >= 100 || flow_flags & FLOW_EMERGENCY)
{
FlowHashDebugPrint();
/*uint32_t timeout_new = flow_config.timeout_new;
uint32_t timeout_est = flow_config.timeout_est;
printf("The Timeout values are %" PRIu32" and %"
PRIu32"\n", timeout_est, timeout_new);*/
if (flow_flags & FLOW_EMERGENCY) {
emerg = TRUE;
SCLogDebug("Flow emergency mode entered...");
}
/* Get the time */
last_sec = (uint32_t)ts.tv_sec;
memset(&ts, 0, sizeof(ts));
TimeGet(&ts);
SCLogDebug("ts %" PRIdMAX "", (intmax_t)ts.tv_sec);
if (((uint32_t)ts.tv_sec - last_sec) > 60) {
FlowHashDebugPrint((uint32_t)ts.tv_sec);
}
/* see if we still have enough spare flows */
FlowUpdateSpareFlows();

Loading…
Cancel
Save