From 04c65a309e90b5312280ff9d6c437e1925e94d77 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Mon, 4 Mar 2019 00:10:54 +0100 Subject: [PATCH] flow-hash: new function to get flow from flowkey --- src/flow-hash.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ src/flow-hash.h | 1 + 2 files changed, 67 insertions(+) diff --git a/src/flow-hash.c b/src/flow-hash.c index 8b109ad6d6..ea90a9455d 100644 --- a/src/flow-hash.c +++ b/src/flow-hash.c @@ -609,6 +609,72 @@ static inline int FlowCompareKey(Flow *f, FlowKey *key) return CMP_FLOW(f, key); } +Flow *FlowGetFromFlowKey(FlowKey *key, struct timespec *ttime, const uint32_t hash) +{ + Flow *f = NULL; + + f = FlowGetExistingFlowFromHash(key, hash); + if (f != NULL) { + return f; + } + + /* No existing flow so let's get one new */ + f = FlowDequeue(&flow_spare_q); + if (f == NULL) { + return NULL; + /* now see if we can alloc a new flow */ + f = FlowAlloc(); + if (f == NULL) { + SCLogError(SC_ERR_FLOW_INIT, "Can't get a spare flow at start"); + return NULL; + } + } + f->proto = key->proto; + f->vlan_id[0] = key->vlan_id[0]; + f->vlan_id[1] = key->vlan_id[1]; + f->src.addr_data32[0] = key->src.addr_data32[0]; + f->src.addr_data32[1] = key->src.addr_data32[1]; + f->src.addr_data32[2] = key->src.addr_data32[2]; + f->src.addr_data32[3] = key->src.addr_data32[3]; + f->dst.addr_data32[0] = key->dst.addr_data32[0]; + f->dst.addr_data32[1] = key->dst.addr_data32[1]; + f->dst.addr_data32[2] = key->dst.addr_data32[2]; + f->dst.addr_data32[3] = key->dst.addr_data32[3]; + f->sp = key->sp; + f->dp = key->dp; + f->recursion_level = 0; + f->flow_hash = hash; + if (key->src.family == AF_INET) { + f->flags |= FLOW_IPV4; + } + if (key->src.family == AF_INET6) { + f->flags |= FLOW_IPV6; + } + FlowUpdateState(f, FLOW_STATE_CAPTURE_BYPASSED); + + f->protomap = FlowGetProtoMapping(f->proto); + /* set timestamp to now */ + f->startts.tv_sec = ttime->tv_sec; + f->startts.tv_usec = ttime->tv_nsec * 1000; + f->lastts = f->startts; + + FlowBucket *fb = &flow_hash[hash % flow_config.hash_size]; + FBLOCK_LOCK(fb); + f->fb = fb; + if (fb->head == NULL) { + fb->head = f; + fb->tail = f; + } else { + f->hprev = fb->tail; + f->hprev->hnext = f; + fb->tail = f; + } + FLOWLOCK_WRLOCK(f); + FBLOCK_UNLOCK(fb); + + return f; +} + /** \brief Look for existing Flow using a FlowKey * * Hash retrieval function for flows. Looks up the hash bucket containing the diff --git a/src/flow-hash.h b/src/flow-hash.h index 38268a7729..d70c4d377a 100644 --- a/src/flow-hash.h +++ b/src/flow-hash.h @@ -76,6 +76,7 @@ typedef struct FlowBucket_ { Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *, Flow **); +Flow *FlowGetFromFlowKey(FlowKey *key, struct timespec *ttime, const uint32_t hash); Flow *FlowGetExistingFlowFromHash(FlowKey * key, uint32_t hash); void FlowDisableTcpReuseHandling(void);