suricata
flow-queue.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 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  * Flow queue handler functions
24  */
25 
26 #include "suricata-common.h"
27 #include "threads.h"
28 #include "flow-private.h"
29 #include "flow-queue.h"
30 #include "flow-util.h"
31 #include "util-error.h"
32 #include "util-debug.h"
33 #include "util-print.h"
34 
36 {
37  FlowQueue *q = (FlowQueue *)SCMalloc(sizeof(FlowQueue));
38  if (q == NULL) {
39  SCLogError(SC_ERR_FATAL, "Fatal error encountered in FlowQueueNew. Exiting...");
40  exit(EXIT_SUCCESS);
41  }
42  q = FlowQueueInit(q);
43  return q;
44 }
45 
47 {
48  if (q != NULL) {
49  memset(q, 0, sizeof(FlowQueue));
50  FQLOCK_INIT(q);
51  }
52  return q;
53 }
54 
55 /**
56  * \brief Destroy a flow queue
57  *
58  * \param q the flow queue to destroy
59  */
61 {
62  FQLOCK_DESTROY(q);
63 }
64 
66 {
67  if (fqc->top == NULL) {
68  fqc->top = fqc->bot = f;
69  fqc->len = 1;
70  } else {
71  fqc->bot->next = f;
72  fqc->bot = f;
73  fqc->len++;
74  }
75  f->next = NULL;
76 }
77 
79 {
80  f->next = fqc->top;
81  fqc->top = f;
82  if (f->next == NULL) {
83  fqc->bot = f;
84  }
85  fqc->len++;
86 }
87 
89 {
90  if (src->top == NULL)
91  return;
92 
93  if (dest->bot == NULL) {
94  dest->top = src->top;
95  dest->bot = src->bot;
96  dest->len = src->len;
97  } else {
98  dest->bot->next = src->top;
99  dest->bot = src->bot;
100  dest->len += src->len;
101  }
102  src->top = src->bot = NULL;
103  src->len = 0;
104 }
105 
106 static inline void FlowQueueAtomicSetNonEmpty(FlowQueue *fq)
107 {
108  if (SC_ATOMIC_GET(fq->non_empty) == false) {
109  SC_ATOMIC_SET(fq->non_empty, true);
110  }
111 }
112 static inline void FlowQueueAtomicSetEmpty(FlowQueue *fq)
113 {
114  if (SC_ATOMIC_GET(fq->non_empty) == true) {
115  SC_ATOMIC_SET(fq->non_empty, false);
116  }
117 }
118 
120 {
121  if (fqc->top == NULL)
122  return;
123 
124  FQLOCK_LOCK(fq);
125  if (fq->qbot == NULL) {
126  fq->qtop = fqc->top;
127  fq->qbot = fqc->bot;
128  fq->qlen = fqc->len;
129  } else {
130  fq->qbot->next = fqc->top;
131  fq->qbot = fqc->bot;
132  fq->qlen += fqc->len;
133  }
134  FlowQueueAtomicSetNonEmpty(fq);
135  FQLOCK_UNLOCK(fq);
136  fqc->top = fqc->bot = NULL;
137  fqc->len = 0;
138 }
139 
141 {
142  FQLOCK_LOCK(fq);
143  FlowQueuePrivate fqc = fq->priv;
144  fq->qtop = fq->qbot = NULL;
145  fq->qlen = 0;
146  FlowQueueAtomicSetEmpty(fq);
147  FQLOCK_UNLOCK(fq);
148  return fqc;
149 }
150 
152 {
153  Flow *f = fqc->top;
154  if (f == NULL) {
155  return NULL;
156  }
157 
158  fqc->top = f->next;
159  f->next = NULL;
160  fqc->len--;
161  if (fqc->top == NULL) {
162  fqc->bot = NULL;
163  }
164  return f;
165 }
166 
167 /**
168  * \brief add a flow to a queue
169  *
170  * \param q queue
171  * \param f flow
172  */
174 {
175 #ifdef DEBUG
176  BUG_ON(q == NULL || f == NULL);
177 #endif
178  FQLOCK_LOCK(q);
180  FlowQueueAtomicSetNonEmpty(q);
181  FQLOCK_UNLOCK(q);
182 }
183 
184 /**
185  * \brief remove a flow from the queue
186  *
187  * \param q queue
188  *
189  * \retval f flow or NULL if empty list.
190  */
192 {
193  FQLOCK_LOCK(q);
195  if (f == NULL)
196  FlowQueueAtomicSetEmpty(q);
197  FQLOCK_UNLOCK(q);
198  return f;
199 }
FlowQueue_::priv
FlowQueuePrivate priv
Definition: flow-queue.h:50
flow-util.h
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:387
threads.h
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:356
FlowQueueDestroy
void FlowQueueDestroy(FlowQueue *q)
Destroy a flow queue.
Definition: flow-queue.c:60
FlowQueuePrivatePrependFlow
void FlowQueuePrivatePrependFlow(FlowQueuePrivate *fqc, Flow *f)
Definition: flow-queue.c:78
FlowQueuePrivate_::len
uint32_t len
Definition: flow-queue.h:44
FlowEnqueue
void FlowEnqueue(FlowQueue *q, Flow *f)
add a flow to a queue
Definition: flow-queue.c:173
FQLOCK_INIT
#define FQLOCK_INIT(q)
Definition: flow-queue.h:71
FQLOCK_LOCK
#define FQLOCK_LOCK(q)
Definition: flow-queue.h:73
FlowQueuePrivate_::top
Flow * top
Definition: flow-queue.h:42
util-debug.h
util-error.h
FQLOCK_DESTROY
#define FQLOCK_DESTROY(q)
Definition: flow-queue.h:72
util-print.h
FlowQueueInit
FlowQueue * FlowQueueInit(FlowQueue *q)
Definition: flow-queue.c:46
FlowQueuePrivate_::bot
Flow * bot
Definition: flow-queue.h:43
FlowQueuePrivateGetFromTop
Flow * FlowQueuePrivateGetFromTop(FlowQueuePrivate *fqc)
Definition: flow-queue.c:151
FlowQueueAppendPrivate
void FlowQueueAppendPrivate(FlowQueue *fq, FlowQueuePrivate *fqc)
Definition: flow-queue.c:119
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:289
FlowQueuePrivateAppendPrivate
void FlowQueuePrivateAppendPrivate(FlowQueuePrivate *dest, FlowQueuePrivate *src)
Definition: flow-queue.c:88
flow-queue.h
Flow_::next
struct Flow_ * next
Definition: flow.h:407
FlowQueue_
Definition: flow-queue.h:49
FlowDequeue
Flow * FlowDequeue(FlowQueue *q)
remove a flow from the queue
Definition: flow-queue.c:191
FlowQueueExtractPrivate
FlowQueuePrivate FlowQueueExtractPrivate(FlowQueue *fq)
Definition: flow-queue.c:140
suricata-common.h
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:255
FlowQueuePrivate_
Definition: flow-queue.h:41
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
src
uint16_t src
Definition: app-layer-dnp3.h:5
FlowQueueNew
FlowQueue * FlowQueueNew()
Definition: flow-queue.c:35
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:376
FlowQueuePrivateAppendFlow
void FlowQueuePrivateAppendFlow(FlowQueuePrivate *fqc, Flow *f)
Definition: flow-queue.c:65
FQLOCK_UNLOCK
#define FQLOCK_UNLOCK(q)
Definition: flow-queue.h:75