/src/suricata7/src/host-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 "host.h" |
26 | | |
27 | | #include "detect-engine-tag.h" |
28 | | #include "detect-engine-threshold.h" |
29 | | |
30 | | #include "host-bit.h" |
31 | | #include "host-timeout.h" |
32 | | |
33 | | #include "reputation.h" |
34 | | |
35 | | uint32_t HostGetSpareCount(void) |
36 | 0 | { |
37 | 0 | return HostSpareQueueGetSize(); |
38 | 0 | } |
39 | | |
40 | | uint32_t HostGetActiveCount(void) |
41 | 0 | { |
42 | 0 | return SC_ATOMIC_GET(host_counter); |
43 | 0 | } |
44 | | |
45 | | /** \internal |
46 | | * \brief See if we can really discard this host. Check use_cnt reference. |
47 | | * |
48 | | * \param h host |
49 | | * \param ts timestamp |
50 | | * |
51 | | * \retval 0 not timed out just yet |
52 | | * \retval 1 fully timed out, lets kill it |
53 | | */ |
54 | | static int HostHostTimedOut(Host *h, SCTime_t ts) |
55 | 0 | { |
56 | 0 | int busy = 0; |
57 | | |
58 | | /** never prune a host that is used by a packet |
59 | | * we are currently processing in one of the threads */ |
60 | 0 | if (SC_ATOMIC_GET(h->use_cnt) > 0) { |
61 | 0 | return 0; |
62 | 0 | } |
63 | | |
64 | 0 | busy |= (h->iprep && SRepHostTimedOut(h) == 0); |
65 | 0 | busy |= (TagHostHasTag(h) && TagTimeoutCheck(h, ts) == 0); |
66 | 0 | busy |= (ThresholdHostHasThreshold(h) && ThresholdHostTimeoutCheck(h, ts) == 0); |
67 | 0 | busy |= (HostHasHostBits(h) && HostBitsTimedoutCheck(h, ts) == 0); |
68 | 0 | SCLogDebug("host %p %s", h, busy ? "still active" : "timed out"); |
69 | 0 | return !busy; |
70 | 0 | } |
71 | | |
72 | | /** |
73 | | * \internal |
74 | | * |
75 | | * \brief check all hosts in a hash row for timing out |
76 | | * |
77 | | * \param hb host hash row *LOCKED* |
78 | | * \param h last host in the hash row |
79 | | * \param ts timestamp |
80 | | * |
81 | | * \retval cnt timed out hosts |
82 | | */ |
83 | | static uint32_t HostHashRowTimeout(HostHashRow *hb, Host *h, SCTime_t ts) |
84 | 0 | { |
85 | 0 | uint32_t cnt = 0; |
86 | |
|
87 | 0 | do { |
88 | 0 | if (SCMutexTrylock(&h->m) != 0) { |
89 | 0 | h = h->hprev; |
90 | 0 | continue; |
91 | 0 | } |
92 | | |
93 | 0 | Host *next_host = h->hprev; |
94 | | |
95 | | /* check if the host is fully timed out and |
96 | | * ready to be discarded. */ |
97 | 0 | if (HostHostTimedOut(h, ts) == 1) { |
98 | | /* remove from the hash */ |
99 | 0 | if (h->hprev != NULL) |
100 | 0 | h->hprev->hnext = h->hnext; |
101 | 0 | if (h->hnext != NULL) |
102 | 0 | h->hnext->hprev = h->hprev; |
103 | 0 | if (hb->head == h) |
104 | 0 | hb->head = h->hnext; |
105 | 0 | if (hb->tail == h) |
106 | 0 | hb->tail = h->hprev; |
107 | |
|
108 | 0 | h->hnext = NULL; |
109 | 0 | h->hprev = NULL; |
110 | |
|
111 | 0 | HostClearMemory (h); |
112 | | |
113 | | /* no one is referring to this host, use_cnt 0, removed from hash |
114 | | * so we can unlock it and move it back to the spare queue. */ |
115 | 0 | SCMutexUnlock(&h->m); |
116 | | |
117 | | /* move to spare list */ |
118 | 0 | HostMoveToSpare(h); |
119 | |
|
120 | 0 | cnt++; |
121 | 0 | } else { |
122 | 0 | SCMutexUnlock(&h->m); |
123 | 0 | } |
124 | |
|
125 | 0 | h = next_host; |
126 | 0 | } while (h != NULL); |
127 | |
|
128 | 0 | return cnt; |
129 | 0 | } |
130 | | |
131 | | /** |
132 | | * \brief time out hosts from the hash |
133 | | * |
134 | | * \param ts timestamp |
135 | | * |
136 | | * \retval cnt number of timed out host |
137 | | */ |
138 | | uint32_t HostTimeoutHash(SCTime_t ts) |
139 | 0 | { |
140 | 0 | uint32_t idx = 0; |
141 | 0 | uint32_t cnt = 0; |
142 | |
|
143 | 0 | for (idx = 0; idx < host_config.hash_size; idx++) { |
144 | 0 | HostHashRow *hb = &host_hash[idx]; |
145 | |
|
146 | 0 | if (HRLOCK_TRYLOCK(hb) != 0) |
147 | 0 | continue; |
148 | | |
149 | | /* host hash bucket is now locked */ |
150 | | |
151 | 0 | if (hb->tail == NULL) { |
152 | 0 | HRLOCK_UNLOCK(hb); |
153 | 0 | continue; |
154 | 0 | } |
155 | | |
156 | | /* we have a host, or more than one */ |
157 | 0 | cnt += HostHashRowTimeout(hb, hb->tail, ts); |
158 | 0 | HRLOCK_UNLOCK(hb); |
159 | 0 | } |
160 | |
|
161 | 0 | return cnt; |
162 | 0 | } |
163 | | |