Coverage Report

Created: 2025-11-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/ippair-timeout.c
Line
Count
Source
1
/* Copyright (C) 2007-2012 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17
18
/**
19
 * \file
20
 *
21
 * \author Victor Julien <victor@inliniac.net>
22
 */
23
24
#include "suricata-common.h"
25
#include "ippair.h"
26
#include "ippair-bit.h"
27
#include "ippair-timeout.h"
28
#include "detect-engine-threshold.h"
29
30
uint32_t IPPairGetSpareCount(void)
31
0
{
32
0
    return IPPairSpareQueueGetSize();
33
0
}
34
35
uint32_t IPPairGetActiveCount(void)
36
0
{
37
0
    return SC_ATOMIC_GET(ippair_counter);
38
0
}
39
40
/** \internal
41
 *  \brief See if we can really discard this ippair. Check use_cnt reference.
42
 *
43
 *  \param h ippair
44
 *  \param ts timestamp
45
 *
46
 *  \retval 0 not timed out just yet
47
 *  \retval 1 fully timed out, lets kill it
48
 */
49
static int IPPairTimedOut(IPPair *h, SCTime_t ts)
50
0
{
51
0
    int vars = 0;
52
0
    int thresholds = 0;
53
54
    /** never prune a ippair that is used by a packet
55
     *  we are currently processing in one of the threads */
56
0
    if (SC_ATOMIC_GET(h->use_cnt) > 0) {
57
0
        return 0;
58
0
    }
59
60
0
    if (IPPairHasBits(h) && IPPairBitsTimedoutCheck(h, ts) == 0) {
61
0
        vars = 1;
62
0
    }
63
64
0
    if (ThresholdIPPairHasThreshold(h) && ThresholdIPPairTimeoutCheck(h, ts) == 0) {
65
0
        thresholds = 1;
66
0
    }
67
68
0
    if (vars || thresholds) {
69
0
        return 0;
70
0
    }
71
72
0
    SCLogDebug("ippair %p timed out", h);
73
0
    return 1;
74
0
}
75
76
/**
77
 *  \internal
78
 *
79
 *  \brief check all ippairs in a hash row for timing out
80
 *
81
 *  \param hb ippair hash row *LOCKED*
82
 *  \param h last ippair in the hash row
83
 *  \param ts timestamp
84
 *
85
 *  \retval cnt timed out ippairs
86
 */
87
static uint32_t IPPairHashRowTimeout(IPPairHashRow *hb, IPPair *h, SCTime_t ts)
88
0
{
89
0
    uint32_t cnt = 0;
90
91
0
    do {
92
0
        if (SCMutexTrylock(&h->m) != 0) {
93
0
            h = h->hprev;
94
0
            continue;
95
0
        }
96
97
0
        IPPair *next_ippair = h->hprev;
98
99
        /* check if the ippair is fully timed out and
100
         * ready to be discarded. */
101
0
        if (IPPairTimedOut(h, ts) == 1) {
102
            /* remove from the hash */
103
0
            if (h->hprev != NULL)
104
0
                h->hprev->hnext = h->hnext;
105
0
            if (h->hnext != NULL)
106
0
                h->hnext->hprev = h->hprev;
107
0
            if (hb->head == h)
108
0
                hb->head = h->hnext;
109
0
            if (hb->tail == h)
110
0
                hb->tail = h->hprev;
111
112
0
            h->hnext = NULL;
113
0
            h->hprev = NULL;
114
115
0
            IPPairClearMemory (h);
116
117
            /* no one is referring to this ippair, use_cnt 0, removed from hash
118
             * so we can unlock it and move it back to the spare queue. */
119
0
            SCMutexUnlock(&h->m);
120
121
            /* move to spare list */
122
0
            IPPairMoveToSpare(h);
123
124
0
            cnt++;
125
0
        } else {
126
0
            SCMutexUnlock(&h->m);
127
0
        }
128
129
0
        h = next_ippair;
130
0
    } while (h != NULL);
131
132
0
    return cnt;
133
0
}
134
135
/**
136
 *  \brief time out ippairs from the hash
137
 *
138
 *  \param ts timestamp
139
 *
140
 *  \retval cnt number of timed out ippair
141
 */
142
uint32_t IPPairTimeoutHash(SCTime_t ts)
143
0
{
144
0
    uint32_t idx = 0;
145
0
    uint32_t cnt = 0;
146
147
0
    for (idx = 0; idx < ippair_config.hash_size; idx++) {
148
0
        IPPairHashRow *hb = &ippair_hash[idx];
149
150
0
        if (HRLOCK_TRYLOCK(hb) != 0)
151
0
            continue;
152
153
        /* ippair hash bucket is now locked */
154
155
0
        if (hb->tail == NULL) {
156
0
            HRLOCK_UNLOCK(hb);
157
0
            continue;
158
0
        }
159
160
        /* we have a ippair, or more than one */
161
0
        cnt += IPPairHashRowTimeout(hb, hb->tail, ts);
162
0
        HRLOCK_UNLOCK(hb);
163
0
    }
164
165
0
    return cnt;
166
0
}