Coverage Report

Created: 2026-03-31 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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