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