static Flow *FlowGetUsedFlow(ThreadVars *tv, DecodeThreadVars *dtv);
static int handle_tcp_reuse = 1;
-#ifdef FLOW_DEBUG_STATS
-#define FLOW_DEBUG_STATS_PROTO_ALL 0
-#define FLOW_DEBUG_STATS_PROTO_TCP 1
-#define FLOW_DEBUG_STATS_PROTO_UDP 2
-#define FLOW_DEBUG_STATS_PROTO_ICMP 3
-#define FLOW_DEBUG_STATS_PROTO_OTHER 4
-
-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 { \
- 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 (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 (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 (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); \
-} while(0);
-
-#define FlowHashCountInit uint64_t _flow_hash_counter = 0
-#define FlowHashCountIncr _flow_hash_counter++;
-
-void FlowHashDebugInit(void)
-{
-#ifdef FLOW_DEBUG_STATS
- SCSpinInit(&flow_hash_count_lock, 0);
-#endif
- flow_hash_count_fp = fopen("flow-debug.log", "w+");
- if (flow_hash_count_fp != NULL) {
- fprintf(flow_hash_count_fp, "ts,all,tcp,udp,icmp,other\n");
- }
-}
-
-void FlowHashDebugPrint(uint32_t ts)
-{
-#ifdef FLOW_DEBUG_STATS
- 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",%02.3f,%02.3f,%02.3f,%02.3f,%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 FlowHashDebugDeinit(void)
-{
-#ifdef FLOW_DEBUG_STATS
- 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 */
-
void FlowDisableTcpReuseHandling(void)
{
handle_tcp_reuse = 0;
/* see if this is the flow we are looking for */
if (FlowCompare(f, p) == 0) {
while (f) {
- FlowHashCountIncr;
-
f = f->hnext;
if (f == NULL) {
Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p)
{
Flow *f = NULL;
- FlowHashCountInit;
/* get the key to our bucket */
uint32_t hash = FlowGetHash(p);
SCLogDebug("fb %p fb->head %p", fb, fb->head);
- FlowHashCountIncr;
-
/* see if the bucket already has a flow */
if (fb->head == NULL) {
f = FlowGetNew(tv, dtv, p);
if (f == NULL) {
FBLOCK_UNLOCK(fb);
- FlowHashCountUpdate;
return NULL;
}
COPY_TIMESTAMP(&p->ts,&f->lastts);
FBLOCK_UNLOCK(fb);
- FlowHashCountUpdate;
return f;
}
Flow *pf = NULL; /* previous flow */
while (f) {
- FlowHashCountIncr;
-
pf = f;
f = f->hnext;
f = pf->hnext = FlowGetNew(tv, dtv, p);
if (f == NULL) {
FBLOCK_UNLOCK(fb);
- FlowHashCountUpdate;
return NULL;
}
fb->tail = f;
COPY_TIMESTAMP(&p->ts,&f->lastts);
FBLOCK_UNLOCK(fb);
- FlowHashCountUpdate;
return f;
}
COPY_TIMESTAMP(&p->ts,&f->lastts);
FBLOCK_UNLOCK(fb);
- FlowHashCountUpdate;
return f;
}
}
COPY_TIMESTAMP(&p->ts,&f->lastts);
FBLOCK_UNLOCK(fb);
- FlowHashCountUpdate;
return f;
}
uint32_t established_cnt = 0, new_cnt = 0, closing_cnt = 0;
int emerg = FALSE;
int prev_emerg = FALSE;
- uint32_t last_sec = 0;
struct timespec cond_time;
int flow_update_delay_sec = FLOW_NORMAL_MODE_UPDATE_DELAY_SEC;
int flow_update_delay_nsec = FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC;
*/
memset(&ts, 0, sizeof(ts));
- FlowHashDebugInit();
-
while (1)
{
if (TmThreadsCheckFlag(th_v, THV_PAUSE)) {
TimeGet(&ts);
SCLogDebug("ts %" PRIdMAX "", (intmax_t)ts.tv_sec);
- if (((uint32_t)ts.tv_sec - last_sec) > 600) {
- FlowHashDebugPrint((uint32_t)ts.tv_sec);
- last_sec = (uint32_t)ts.tv_sec;
- }
-
/* see if we still have enough spare flows */
if (ftd->instance == 1)
FlowUpdateSpareFlows();
StatsSyncCountersIfSignalled(th_v);
}
- FlowHashDebugDeinit();
-
SCLogInfo("%" PRIu32 " new flows, %" PRIu32 " established flows were "
"timed out, %"PRIu32" flows in closed state", new_cnt,
established_cnt, closing_cnt);