suricata
ippair-timeout.c
Go to the documentation of this file.
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"
29 
30 uint32_t IPPairGetSpareCount(void)
31 {
32  return IPPairSpareQueueGetSize();
33 }
34 
35 uint32_t IPPairGetActiveCount(void)
36 {
37  return SC_ATOMIC_GET(ippair_counter);
38 }
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, struct timeval *ts)
50 {
51  int vars = 0;
52  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  if (SC_ATOMIC_GET(h->use_cnt) > 0) {
57  return 0;
58  }
59 
60  if (IPPairHasBits(h) && IPPairBitsTimedoutCheck(h, ts) == 0) {
61  vars = 1;
62  }
63 
65  thresholds = 1;
66  }
67 
68  if (vars || thresholds) {
69  return 0;
70  }
71 
72  SCLogDebug("ippair %p timed out", h);
73  return 1;
74 }
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, struct timeval *ts)
88 {
89  uint32_t cnt = 0;
90 
91  do {
92  if (SCMutexTrylock(&h->m) != 0) {
93  h = h->hprev;
94  continue;
95  }
96 
97  IPPair *next_ippair = h->hprev;
98 
99  /* check if the ippair is fully timed out and
100  * ready to be discarded. */
101  if (IPPairTimedOut(h, ts) == 1) {
102  /* remove from the hash */
103  if (h->hprev != NULL)
104  h->hprev->hnext = h->hnext;
105  if (h->hnext != NULL)
106  h->hnext->hprev = h->hprev;
107  if (hb->head == h)
108  hb->head = h->hnext;
109  if (hb->tail == h)
110  hb->tail = h->hprev;
111 
112  h->hnext = NULL;
113  h->hprev = NULL;
114 
115  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  SCMutexUnlock(&h->m);
120 
121  /* move to spare list */
123 
124  cnt++;
125  } else {
126  SCMutexUnlock(&h->m);
127  }
128 
129  h = next_ippair;
130  } while (h != NULL);
131 
132  return cnt;
133 }
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(struct timeval *ts)
143 {
144  uint32_t idx = 0;
145  uint32_t cnt = 0;
146 
147  for (idx = 0; idx < ippair_config.hash_size; idx++) {
148  IPPairHashRow *hb = &ippair_hash[idx];
149 
150  if (HRLOCK_TRYLOCK(hb) != 0)
151  continue;
152 
153  /* ippair hash bucket is now locked */
154 
155  if (hb->tail == NULL) {
156  HRLOCK_UNLOCK(hb);
157  continue;
158  }
159 
160  /* we have a ippair, or more than one */
161  cnt += IPPairHashRowTimeout(hb, hb->tail, ts);
162  HRLOCK_UNLOCK(hb);
163  }
164 
165  return cnt;
166 }
int ThresholdIPPairHasThreshold(IPPair *pair)
#define HRLOCK_UNLOCK(fb)
Definition: host.h:53
void IPPairMoveToSpare(IPPair *h)
Definition: ippair.c:96
uint32_t IPPairGetActiveCount(void)
#define SCLogDebug(...)
Definition: util-debug.h:335
#define SCMutexTrylock(mut)
void IPPairClearMemory(IPPair *h)
Definition: ippair.c:152
int IPPairHasBits(IPPair *ippair)
Definition: ippair-bit.c:59
#define HRLOCK_TRYLOCK(fb)
Definition: host.h:52
struct IPPair_ * hnext
Definition: ippair.h:72
int IPPairBitsTimedoutCheck(IPPair *h, struct timeval *ts)
Definition: ippair-bit.c:68
int ThresholdIPPairTimeoutCheck(IPPair *pair, struct timeval *tv)
IPPairConfig ippair_config
Definition: ippair.h:128
SCMutex m
Definition: ippair.h:60
uint32_t IPPairSpareQueueGetSize(void)
Definition: ippair.c:91
#define SCMutexUnlock(mut)
uint32_t hash_size
Definition: ippair.h:95
uint32_t IPPairTimeoutHash(struct timeval *ts)
time out ippairs from the hash
Definition: ippair.h:58
uint64_t ts
uint32_t IPPairGetSpareCount(void)
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:193
struct IPPair_ * hprev
Definition: ippair.h:73
IPPairHashRow * ippair_hash
Definition: ippair.h:87