]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
flow-hash: new function to get flow from flowkey
authorEric Leblond <eric@regit.org>
Sun, 3 Mar 2019 23:10:54 +0000 (00:10 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 18 Jun 2019 05:07:02 +0000 (07:07 +0200)
src/flow-hash.c
src/flow-hash.h

index 8b109ad6d61de8a4b067b2b6fe5a3f34571aec36..ea90a9455dc900cd1302077fe162b8e22a49a58e 100644 (file)
@@ -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
index 38268a7729e70e48c7148cc62e75c0d580ede75d..d70c4d377a615f2410b6382c88950513a804eb4a 100644 (file)
@@ -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);