/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 | } |