suricata
defrag-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 "decode.h"
26 #include "defrag.h"
27 #include "defrag-hash.h"
28 #include "defrag-timeout.h"
29 
30 /** \internal
31  * \brief See if we can really discard this tracker. Check use_cnt reference.
32  *
33  * \param dt tracker
34  * \param ts timestamp
35  *
36  * \retval 0 not timed out just yet
37  * \retval 1 fully timed out, lets kill it
38  */
39 static int DefragTrackerTimedOut(DefragTracker *dt, SCTime_t ts)
40 {
41  /** never prune a trackers that is used by a packet
42  * we are currently processing in one of the threads */
43  if (SC_ATOMIC_GET(dt->use_cnt) > 0) {
44  return 0;
45  }
46 
47  /* retain if remove is not set and not timed out */
48  if (!dt->remove && SCTIME_CMP_GT(dt->timeout, ts))
49  return 0;
50 
51  return 1;
52 }
53 
54 /**
55  * \internal
56  *
57  * \brief check all trackers in a hash row for timing out
58  *
59  * \param hb tracker hash row *LOCKED*
60  * \param dt last tracker in the hash row
61  * \param ts timestamp
62  *
63  * \retval cnt timed out tracker
64  */
65 static uint32_t DefragTrackerHashRowTimeout(
67 {
68  uint32_t cnt = 0;
69 
70  do {
71  if (SCMutexTrylock(&dt->lock) != 0) {
72  dt = dt->hprev;
73  continue;
74  }
75 
76  DefragTracker *next_dt = dt->hprev;
77 
78  /* check if the tracker is fully timed out and
79  * ready to be discarded. */
80  if (DefragTrackerTimedOut(dt, ts) == 1) {
81  /* remove from the hash */
82  if (dt->hprev != NULL)
83  dt->hprev->hnext = dt->hnext;
84  if (dt->hnext != NULL)
85  dt->hnext->hprev = dt->hprev;
86  if (hb->head == dt)
87  hb->head = dt->hnext;
88  if (hb->tail == dt)
89  hb->tail = dt->hprev;
90 
91  dt->hnext = NULL;
92  dt->hprev = NULL;
93 
95 
96  /* no one is referring to this tracker, use_cnt 0, removed from hash
97  * so we can unlock it and move it back to the spare queue. */
98  SCMutexUnlock(&dt->lock);
99 
100  /* move to spare list */
102 
103  cnt++;
104  } else {
105  SCMutexUnlock(&dt->lock);
106  }
107 
108  dt = next_dt;
109  } while (dt != NULL);
110 
111  return cnt;
112 }
113 
114 /**
115  * \brief time out tracker from the hash
116  *
117  * \param ts timestamp
118  *
119  * \retval cnt number of timed out tracker
120  */
122 {
123  uint32_t idx = 0;
124  uint32_t cnt = 0;
125 
126  for (idx = 0; idx < defrag_config.hash_size; idx++) {
128 
129  if (DRLOCK_TRYLOCK(hb) != 0)
130  continue;
131 
132  /* defrag hash bucket is now locked */
133 
134  if (hb->tail == NULL) {
135  DRLOCK_UNLOCK(hb);
136  continue;
137  }
138 
139  /* we have a tracker, or more than one */
140  cnt += DefragTrackerHashRowTimeout(hb, hb->tail, ts);
141  DRLOCK_UNLOCK(hb);
142  }
143 
144  return cnt;
145 }
146 
ts
uint64_t ts
Definition: source-erf-file.c:55
DefragTracker_::hnext
struct DefragTracker_ * hnext
Definition: defrag.h:118
defragtracker_hash
DefragTrackerHashRow * defragtracker_hash
Definition: defrag-hash.c:29
DefragTrackerHashRow_
Definition: defrag-hash.h:59
DefragTrackerClearMemory
void DefragTrackerClearMemory(DefragTracker *dt)
Definition: defrag-hash.c:156
defrag-timeout.h
DefragTrackerMoveToSpare
void DefragTrackerMoveToSpare(DefragTracker *h)
Definition: defrag-hash.c:82
DefragTracker_::hprev
struct DefragTracker_ * hprev
Definition: defrag.h:119
DefragTracker_::lock
SCMutex lock
Definition: defrag.h:87
DefragConfig_::hash_size
uint32_t hash_size
Definition: defrag-hash.h:74
DefragTrackerHashRow_::head
DefragTracker * head
Definition: defrag-hash.h:61
DefragTracker_::remove
uint8_t remove
Definition: defrag.h:104
defrag_config
DefragConfig defrag_config
Definition: defrag-hash.c:30
decode.h
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
DefragTracker_
Definition: defrag.h:86
DefragTrackerHashRow_::tail
DefragTracker * tail
Definition: defrag-hash.h:62
DRLOCK_UNLOCK
#define DRLOCK_UNLOCK(fb)
Definition: defrag-hash.h:54
SCTime_t
Definition: util-time.h:40
defrag.h
suricata-common.h
DefragTimeoutHash
uint32_t DefragTimeoutHash(SCTime_t ts)
time out tracker from the hash
Definition: defrag-timeout.c:121
DefragTracker_::timeout
SCTime_t timeout
Definition: defrag.h:109
DRLOCK_TRYLOCK
#define DRLOCK_TRYLOCK(fb)
Definition: defrag-hash.h:53
SCTIME_CMP_GT
#define SCTIME_CMP_GT(a, b)
Definition: util-time.h:83
defrag-hash.h
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:376
SCMutexTrylock
#define SCMutexTrylock(mut)
Definition: threads-debug.h:118