1 /****************************************************************************
2 * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 * Copyright (C) 2008-2013 Sourcefire, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License Version 2 as
7 * published by the Free Software Foundation. You may not use, modify or
8 * distribute this program under any other version of the GNU General
9 * Public License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 ****************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "stdlib.h"
27 #include "stdio.h"
28 #include "string.h"
29 #include "util.h"
30 #include "sfActionQueue.h"
31 #include "mempool.h"
32 #include "active.h"
33 #include "pkt_tracer.h"
34
sfActionQueueInit(int queueLength)35 tSfActionQueueId sfActionQueueInit(
36 int queueLength
37 )
38 {
39 tSfActionQueue *queue = SnortAlloc(sizeof(tSfActionQueue));
40 if (queue)
41 {
42 if (mempool_init(&queue->mempool,
43 queueLength, sizeof(tSfActionNode)) != 0)
44 {
45 FatalError("%s(%d) Could not initialize action queue memory pool.\n",
46 __FILE__, __LINE__);
47 }
48 }
49
50 return queue;
51 }
52
sfActionQueueAdd(tSfActionQueueId actionQ,void (* callback)(void *),void * data)53 int sfActionQueueAdd(
54 tSfActionQueueId actionQ,
55 void (*callback)(void *),
56 void *data
57 )
58 {
59 MemBucket *bucket = mempool_alloc(&actionQ->mempool);
60
61 if (bucket != NULL)
62 {
63 tSfActionNode *node = bucket->data;
64 node->callback = callback;
65 node->data = data;
66
67 //Using used_list in mempool for tracking allocated MemBucket
68 return 0;
69 }
70
71 return -1;
72 }
73
sfActionQueueExecAll(tSfActionQueueId actionQ)74 void sfActionQueueExecAll(
75 tSfActionQueueId actionQ
76 )
77 {
78 //drain
79 while (mempool_numUsedBuckets(&actionQ->mempool))
80 {
81 sfActionQueueExec(actionQ);
82 }
83 if (Active_PacketWasDropped() || Active_PacketWouldBeDropped())
84 {
85 if (pkt_trace_enabled)
86 addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE,
87 "Snort: processed decoder alerts or actions queue, %s\n", getPktTraceActMsg()));
88 else addPktTraceData(VERDICT_REASON_SNORT, 0);
89 }
90 }
91
sfActionQueueExec(tSfActionQueueId actionQ)92 void sfActionQueueExec(
93 tSfActionQueueId actionQ
94 )
95 {
96
97 MemBucket *firstUsedBucket = mempool_oldestUsedBucket(&actionQ->mempool);
98
99 if (firstUsedBucket)
100 {
101 tSfActionNode *node = (tSfActionNode *)firstUsedBucket->data;
102 (node->callback)(node->data);
103 mempool_free(&actionQ->mempool, firstUsedBucket);
104 }
105 }
106
107 /**Destroys action queue. All memory allocated by the actionQueue module is
108 * freed. Since the queued actions are not executed, any memory freed in the action
109 * will be lost. User should do a execAll if there is a potential memory leak
110 * or the actions must be completed.
111 */
sfActionQueueDestroy(tSfActionQueueId actionQ)112 void sfActionQueueDestroy(
113 tSfActionQueueId actionQ
114 )
115 {
116 mempool_destroy(&actionQ->mempool);
117 free(actionQ);
118 }
119
120
121