const uint16_t tv_id = GetTvId(tv);
const bool emerg = (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) != 0;
const uint32_t fb_nextts = !emerg ? SC_ATOMIC_GET(fb->next_ts) : 0;
+ const bool timeout_check = (fb_nextts <= (uint32_t)SCTIME_SECS(p->ts));
/* ok, we have a flow in the bucket. Let's find out if it is our flow */
Flow *prev_f = NULL; /* previous flow */
f = fb->head;
do {
Flow *next_f = NULL;
- FLOWLOCK_WRLOCK(f);
- const bool timedout = (fb_nextts <= (uint32_t)SCTIME_SECS(p->ts) &&
- FlowIsTimedOut(tv_id, f, p->ts, emerg));
- if (timedout) {
- next_f = f->next;
- MoveToWorkQueue(tv, fls, fb, f, prev_f);
- FLOWLOCK_UNLOCK(f);
- goto flow_removed;
- } else if (FlowCompare(f, p) != 0) {
- /* found a matching flow that is not timed out */
- if (unlikely(TcpSessionPacketSsnReuse(p, f, f->protoctx))) {
- Flow *new_f = TcpReuseReplace(tv, fls, fb, f, hash, p);
- if (prev_f == NULL) /* if we have no prev it means new_f is now our prev */
- prev_f = new_f;
- MoveToWorkQueue(tv, fls, fb, f, prev_f); /* evict old flow */
- FLOWLOCK_UNLOCK(f); /* unlock old replaced flow */
-
- if (new_f == NULL) {
- FBLOCK_UNLOCK(fb);
- return NULL;
+ const bool our_flow = FlowCompare(f, p) != 0;
+ if (our_flow || timeout_check) {
+ FLOWLOCK_WRLOCK(f);
+ const bool timedout = (timeout_check && FlowIsTimedOut(tv_id, f, p->ts, emerg));
+ if (timedout) {
+ next_f = f->next;
+ MoveToWorkQueue(tv, fls, fb, f, prev_f);
+ FLOWLOCK_UNLOCK(f);
+ goto flow_removed;
+ } else if (our_flow) {
+ /* found a matching flow that is not timed out */
+ if (unlikely(TcpSessionPacketSsnReuse(p, f, f->protoctx))) {
+ Flow *new_f = TcpReuseReplace(tv, fls, fb, f, hash, p);
+ if (prev_f == NULL) /* if we have no prev it means new_f is now our prev */
+ prev_f = new_f;
+ MoveToWorkQueue(tv, fls, fb, f, prev_f); /* evict old flow */
+ FLOWLOCK_UNLOCK(f); /* unlock old replaced flow */
+
+ if (new_f == NULL) {
+ FBLOCK_UNLOCK(fb);
+ return NULL;
+ }
+ f = new_f;
}
- f = new_f;
+ FlowReference(dest, f);
+ FBLOCK_UNLOCK(fb);
+ return f; /* return w/o releasing flow lock */
+ } else {
+ FLOWLOCK_UNLOCK(f);
}
- FlowReference(dest, f);
- FBLOCK_UNLOCK(fb);
- return f; /* return w/o releasing flow lock */
- } else {
- FLOWLOCK_UNLOCK(f);
}
/* unless we removed 'f', prev_f needs to point to
* current 'f' when adding a new flow below. */