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