suricata
stream-tcp-cache.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2022 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 "suricata.h"
26#include "stream-tcp-private.h"
27#include "stream-tcp-cache.h"
28#include "util-debug.h"
29
30typedef struct TcpPoolCache {
31 bool cache_enabled; /**< cache should only be enabled for worker threads */
36
42
43static thread_local TcpPoolCache tcp_pool_cache;
44extern PoolThread *ssn_pool;
46
47/** \brief enable segment cache. Should only be done for worker threads */
49{
50 tcp_pool_cache.cache_enabled = true;
51}
52
54{
55 SCEnter();
56#ifdef UNITTESTS
57 if (RunmodeIsUnittests()) {
60 }
61#endif
62
63 /* cache can have segs from any pool id */
64 if (tcp_pool_cache.cache_enabled && tcp_pool_cache.segs_cache_idx < 64) {
65 tcp_pool_cache.segs_cache[tcp_pool_cache.segs_cache_idx++] = seg;
66 } else {
67 /* segs_returns should only have a single pool id. If ours is different,
68 * flush it. */
69 bool flush = false;
70 if (tcp_pool_cache.segs_returns_idx &&
71 tcp_pool_cache.segs_returns[0]->pool_id != seg->pool_id) {
72 flush = true;
73 }
74 if (tcp_pool_cache.segs_returns_idx == 64) {
75 flush = true;
76 }
77
78 if (flush) {
79 PoolThreadId pool_id = tcp_pool_cache.segs_returns[0]->pool_id;
81 for (uint32_t i = 0; i < tcp_pool_cache.segs_returns_idx; i++) {
82 TcpSegment *ret_seg = tcp_pool_cache.segs_returns[i];
84 }
86 tcp_pool_cache.segs_returns_idx = 0;
87 }
88
89 tcp_pool_cache.segs_returns[tcp_pool_cache.segs_returns_idx++] = seg;
90 }
91}
92
94{
95 SCEnter();
96#ifdef UNITTESTS
97 if (RunmodeIsUnittests()) {
100 }
101#endif
102
103 /* cache can have ssns from any pool id */
104 if (tcp_pool_cache.cache_enabled && tcp_pool_cache.ssns_cache_idx < 64) {
105 tcp_pool_cache.ssns_cache[tcp_pool_cache.ssns_cache_idx++] = ssn;
106 } else {
107 /* ssns_returns should only have a single pool id. If ours is different,
108 * flush it. */
109 bool flush = false;
110 if (tcp_pool_cache.ssns_returns_idx &&
111 tcp_pool_cache.ssns_returns[0]->pool_id != ssn->pool_id) {
112 flush = true;
113 }
114 if (tcp_pool_cache.ssns_returns_idx == 64) {
115 flush = true;
116 }
117
118 if (flush) {
119 PoolThreadId pool_id = tcp_pool_cache.ssns_returns[0]->pool_id;
121 for (uint32_t i = 0; i < tcp_pool_cache.ssns_returns_idx; i++) {
122 TcpSession *ret_ssn = tcp_pool_cache.ssns_returns[i];
124 }
126 tcp_pool_cache.ssns_returns_idx = 0;
127 }
128
129 tcp_pool_cache.ssns_returns[tcp_pool_cache.ssns_returns_idx++] = ssn;
130 }
131 SCReturn;
132}
133
135{
136 SCEnter();
137
138 /* segments */
139 SCLogDebug("tcp_pool_cache.segs_cache_idx %u", tcp_pool_cache.segs_cache_idx);
140 for (uint32_t i = 0; i < tcp_pool_cache.segs_cache_idx; i++) {
142 }
143 tcp_pool_cache.segs_cache_idx = 0;
144
145 SCLogDebug("tcp_pool_cache.segs_returns_idx %u", tcp_pool_cache.segs_returns_idx);
146 if (tcp_pool_cache.segs_returns_idx) {
147 PoolThreadId pool_id = tcp_pool_cache.segs_returns[0]->pool_id;
149 for (uint32_t i = 0; i < tcp_pool_cache.segs_returns_idx; i++) {
150 TcpSegment *ret_seg = tcp_pool_cache.segs_returns[i];
152 }
154 tcp_pool_cache.segs_returns_idx = 0;
155 }
156
157 /* sessions */
158 SCLogDebug("tcp_pool_cache.ssns_cache_idx %u", tcp_pool_cache.ssns_cache_idx);
159 for (uint32_t i = 0; i < tcp_pool_cache.ssns_cache_idx; i++) {
160 PoolThreadReturn(ssn_pool, tcp_pool_cache.ssns_cache[i]);
161 }
162 tcp_pool_cache.ssns_cache_idx = 0;
163
164 SCLogDebug("tcp_pool_cache.ssns_returns_idx %u", tcp_pool_cache.ssns_returns_idx);
165 if (tcp_pool_cache.ssns_returns_idx) {
166 PoolThreadId pool_id = tcp_pool_cache.ssns_returns[0]->pool_id;
168 for (uint32_t i = 0; i < tcp_pool_cache.ssns_returns_idx; i++) {
169 TcpSession *ret_ssn = tcp_pool_cache.ssns_returns[i];
171 }
173 tcp_pool_cache.ssns_returns_idx = 0;
174 }
175
176 SCReturn;
177}
178
180{
181 if (tcp_pool_cache.segs_cache_idx) {
182 TcpSegment *seg = tcp_pool_cache.segs_cache[tcp_pool_cache.segs_cache_idx - 1];
183 tcp_pool_cache.segs_cache_idx--;
184 memset(&seg->sbseg, 0, sizeof(seg->sbseg));
185 return seg;
186 }
187 return NULL;
188}
189
191{
192 if (tcp_pool_cache.ssns_cache_idx) {
193 TcpSession *ssn = tcp_pool_cache.ssns_cache[tcp_pool_cache.ssns_cache_idx - 1];
194 tcp_pool_cache.ssns_cache_idx--;
195 return ssn;
196 }
197 return NULL;
198}
void PoolThreadUnlock(PoolThread *pt, PoolThreadId id)
void PoolThreadReturn(PoolThread *pt, void *data)
return data to thread pool
void PoolThreadReturnRaw(PoolThread *pt, PoolThreadId id, void *data)
void PoolThreadLock(PoolThread *pt, PoolThreadId id)
TcpSession * StreamTcpThreadCacheGetSession(void)
void StreamTcpThreadCacheCleanup(void)
void StreamTcpThreadCacheEnable(void)
enable segment cache. Should only be done for worker threads
TcpSegment * StreamTcpThreadCacheGetSegment(void)
void StreamTcpThreadCacheReturnSession(TcpSession *ssn)
PoolThread * ssn_pool
Definition stream-tcp.c:213
PoolThread * segment_thread_pool
void StreamTcpThreadCacheReturnSegment(TcpSegment *seg)
PoolThreadId pool_id
uint32_t segs_returns_idx
TcpSegment * segs_cache[64]
TcpSegment * segs_returns[64]
TcpSession * ssns_returns[64]
uint32_t segs_cache_idx
uint32_t ssns_returns_idx
uint32_t ssns_cache_idx
TcpSession * ssns_cache[64]
StreamingBufferSegment sbseg
PoolThreadId pool_id
PoolThreadId pool_id
int RunmodeIsUnittests(void)
Definition suricata.c:270
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturn
Definition util-debug.h:279
uint16_t PoolThreadId