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 
30 typedef struct TcpPoolCache {
31  bool cache_enabled; /**< cache should only be enabled for worker threads */
33  uint32_t segs_cache_idx;
34  uint32_t segs_returns_idx;
36 
38  uint32_t ssns_cache_idx;
39  uint32_t ssns_returns_idx;
42 
43 static thread_local TcpPoolCache tcp_pool_cache;
44 extern 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()) {
59  SCReturn;
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()) {
99  SCReturn;
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++) {
141  PoolThreadReturn(segment_thread_pool, tcp_pool_cache.segs_cache[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 }
segment_thread_pool
PoolThread * segment_thread_pool
Definition: stream-tcp-reassemble.c:80
TcpSegment::pool_id
PoolThreadId pool_id
Definition: stream-tcp-private.h:73
StreamTcpThreadCacheGetSession
TcpSession * StreamTcpThreadCacheGetSession(void)
Definition: stream-tcp-cache.c:190
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
PoolThreadReturnRaw
void PoolThreadReturnRaw(PoolThread *pt, PoolThreadId id, void *data)
Definition: util-pool-thread.c:214
StreamTcpThreadCacheReturnSession
void StreamTcpThreadCacheReturnSession(TcpSession *ssn)
Definition: stream-tcp-cache.c:93
TcpSegment::sbseg
StreamingBufferSegment sbseg
Definition: stream-tcp-private.h:77
pool_id
PoolThreadId pool_id
Definition: stream-tcp-private.h:0
StreamTcpThreadCacheGetSegment
TcpSegment * StreamTcpThreadCacheGetSegment(void)
Definition: stream-tcp-cache.c:179
util-debug.h
TcpPoolCache
Definition: stream-tcp-cache.c:30
TcpPoolCache::segs_cache
TcpSegment * segs_cache[64]
Definition: stream-tcp-cache.c:32
TcpSession_::pool_id
PoolThreadId pool_id
Definition: stream-tcp-private.h:284
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
SCReturn
#define SCReturn
Definition: util-debug.h:273
TcpSegment
Definition: stream-tcp-private.h:72
stream-tcp-private.h
PoolThreadReturn
void PoolThreadReturn(PoolThread *pt, void *data)
return data to thread pool
Definition: util-pool-thread.c:192
TcpPoolCache::ssns_cache_idx
uint32_t ssns_cache_idx
Definition: stream-tcp-cache.c:38
StreamTcpThreadCacheCleanup
void StreamTcpThreadCacheCleanup(void)
Definition: stream-tcp-cache.c:134
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:251
PoolThreadLock
void PoolThreadLock(PoolThread *pt, PoolThreadId id)
Definition: util-pool-thread.c:207
TcpPoolCache::ssns_returns_idx
uint32_t ssns_returns_idx
Definition: stream-tcp-cache.c:39
ssn_pool
PoolThread * ssn_pool
Definition: stream-tcp.c:213
TcpPoolCache::segs_cache_idx
uint32_t segs_cache_idx
Definition: stream-tcp-cache.c:33
suricata-common.h
StreamTcpThreadCacheReturnSegment
void StreamTcpThreadCacheReturnSegment(TcpSegment *seg)
Definition: stream-tcp-cache.c:53
TcpPoolCache::segs_returns
TcpSegment * segs_returns[64]
Definition: stream-tcp-cache.c:35
PoolThread_
Definition: util-pool-thread.h:53
stream-tcp-cache.h
StreamTcpThreadCacheEnable
void StreamTcpThreadCacheEnable(void)
enable segment cache. Should only be done for worker threads
Definition: stream-tcp-cache.c:48
PoolThreadId
uint16_t PoolThreadId
Definition: util-pool-thread.h:60
TcpPoolCache::ssns_returns
TcpSession * ssns_returns[64]
Definition: stream-tcp-cache.c:40
suricata.h
TcpSession_
Definition: stream-tcp-private.h:283
TcpPoolCache::segs_returns_idx
uint32_t segs_returns_idx
Definition: stream-tcp-cache.c:34
TcpPoolCache::cache_enabled
bool cache_enabled
Definition: stream-tcp-cache.c:31
TcpPoolCache
struct TcpPoolCache TcpPoolCache
PoolThreadUnlock
void PoolThreadUnlock(PoolThread *pt, PoolThreadId id)
Definition: util-pool-thread.c:221
TcpPoolCache::ssns_cache
TcpSession * ssns_cache[64]
Definition: stream-tcp-cache.c:37