From ae7aae81dc25271f30d4c26f0588f65ad8f44c09 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 17 Mar 2015 12:48:14 +0100 Subject: [PATCH] flow: get flow reference during lookup Update Flow lookup functions to get a flow reference during lookup. This reference is set under the FlowBucket lock. This paves the way to not getting a flow lock during lookups. --- src/flow-hash.c | 13 ++++++++++--- src/flow-hash.h | 2 +- src/flow.c | 5 +---- src/flow.h | 4 ++-- src/stream-tcp.c | 4 ++-- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/flow-hash.c b/src/flow-hash.c index f6d746630c..20f1d36c61 100644 --- a/src/flow-hash.c +++ b/src/flow-hash.c @@ -418,7 +418,7 @@ static Flow *FlowGetNew(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p) return f; } -Flow *FlowGetFlowFromHashByPacket(const Packet *p) +Flow *FlowGetFlowFromHashByPacket(const Packet *p, Flow **dest) { Flow *f = NULL; @@ -448,6 +448,7 @@ Flow *FlowGetFlowFromHashByPacket(const Packet *p) f->fb = fb; /* update the last seen timestamp of this flow */ COPY_TIMESTAMP(&p->ts,&f->lastts); + FlowReference(dest, f); } FBLOCK_UNLOCK(fb); @@ -463,7 +464,7 @@ Flow *FlowGetFlowFromHashByPacket(const Packet *p) * * \retval f flow or NULL if not found */ -Flow *FlowLookupFlowFromHash(const Packet *p) +Flow *FlowLookupFlowFromHash(const Packet *p, Flow **dest) { Flow *f = NULL; @@ -516,6 +517,7 @@ Flow *FlowLookupFlowFromHash(const Packet *p) FLOWLOCK_WRLOCK(f); /* update the last seen timestamp of this flow */ COPY_TIMESTAMP(&p->ts,&f->lastts); + FlowReference(dest, f); FBLOCK_UNLOCK(fb); return f; @@ -527,6 +529,7 @@ Flow *FlowLookupFlowFromHash(const Packet *p) FLOWLOCK_WRLOCK(f); /* update the last seen timestamp of this flow */ COPY_TIMESTAMP(&p->ts,&f->lastts); + FlowReference(dest, f); FBLOCK_UNLOCK(fb); return f; @@ -549,7 +552,7 @@ Flow *FlowLookupFlowFromHash(const Packet *p) * * \retval f *LOCKED* flow or NULL */ -Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p) +Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p, Flow **dest) { Flow *f = NULL; @@ -580,6 +583,7 @@ Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p /* update the last seen timestamp of this flow */ COPY_TIMESTAMP(&p->ts,&f->lastts); + FlowReference(dest, f); FBLOCK_UNLOCK(fb); return f; @@ -615,6 +619,7 @@ Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p /* update the last seen timestamp of this flow */ COPY_TIMESTAMP(&p->ts,&f->lastts); + FlowReference(dest, f); FBLOCK_UNLOCK(fb); return f; @@ -642,6 +647,7 @@ Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p FLOWLOCK_WRLOCK(f); /* update the last seen timestamp of this flow */ COPY_TIMESTAMP(&p->ts,&f->lastts); + FlowReference(dest, f); FBLOCK_UNLOCK(fb); return f; @@ -653,6 +659,7 @@ Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p FLOWLOCK_WRLOCK(f); /* update the last seen timestamp of this flow */ COPY_TIMESTAMP(&p->ts,&f->lastts); + FlowReference(dest, f); FBLOCK_UNLOCK(fb); return f; diff --git a/src/flow-hash.h b/src/flow-hash.h index 16d408521b..e570b05551 100644 --- a/src/flow-hash.h +++ b/src/flow-hash.h @@ -68,7 +68,7 @@ typedef struct FlowBucket_ { /* prototypes */ -Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *); +Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *, Flow **); void FlowDisableTcpReuseHandling(void); diff --git a/src/flow.c b/src/flow.c index a2e1a64cd4..9c3973e654 100644 --- a/src/flow.c +++ b/src/flow.c @@ -270,9 +270,6 @@ void FlowHandlePacketUpdate(Flow *f, Packet *p) { SCLogDebug("packet %"PRIu64" -- flow %p", p->pcap_cnt, f); - /* Point the Packet at the Flow */ - FlowReference(&p->flow, f); - /* update flags and counters */ if (FlowGetPacketDirection(f, p) == TOSERVER) { f->todstpktcnt++; @@ -329,7 +326,7 @@ void FlowHandlePacket(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p) /* Get this packet's flow from the hash. FlowHandlePacket() will setup * a new flow if nescesary. If we get NULL, we're out of flow memory. * The returned flow is locked. */ - Flow *f = FlowGetFlowFromHash(tv, dtv, p); + Flow *f = FlowGetFlowFromHash(tv, dtv, p, &p->flow); if (f == NULL) return; diff --git a/src/flow.h b/src/flow.h index 5953b55fcf..2085f32242 100644 --- a/src/flow.h +++ b/src/flow.h @@ -580,8 +580,8 @@ uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags); void FlowHandlePacketUpdateRemove(Flow *f, Packet *p); void FlowHandlePacketUpdate(Flow *f, Packet *p); -Flow *FlowGetFlowFromHashByPacket(const Packet *p); -Flow *FlowLookupFlowFromHash(const Packet *p); +Flow *FlowGetFlowFromHashByPacket(const Packet *p, Flow **dest); +Flow *FlowLookupFlowFromHash(const Packet *p, Flow **dest); #endif /* __FLOW_H__ */ diff --git a/src/stream-tcp.c b/src/stream-tcp.c index b83d45c336..22cb446c8f 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -4920,7 +4920,7 @@ static void TcpSessionReuseHandle(Packet *p) { * a different thread. */ /* Get a flow. It will be either a locked flow or NULL */ - Flow *new_f = FlowGetFlowFromHashByPacket(p); + Flow *new_f = FlowGetFlowFromHashByPacket(p, &p->flow); if (new_f == NULL) { FlowDeReference(&old_f); // < can't disappear while usecnt >0 return; @@ -4992,7 +4992,7 @@ static void TcpSessionReuseHandleApplyToPacket(Packet *p) FlowDeReference(&p->flow); // < can't disappear while usecnt >0 /* find the new flow that does belong to this packet */ - Flow *new_f = FlowLookupFlowFromHash(p); + Flow *new_f = FlowLookupFlowFromHash(p, &p->flow); if (new_f == NULL) { // TODO reset packet flag wrt flow: direction, HAS_FLOW etc p->flags &= ~PKT_HAS_FLOW;