1 /* Copyright (C) 2007-2010 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 * \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
23 */
24
25 #ifndef __STREAM_TCP_H__
26 #define __STREAM_TCP_H__
27
28 #include "stream-tcp-private.h"
29
30 #include "stream.h"
31 #include "stream-tcp-reassemble.h"
32
33 #define STREAM_VERBOSE FALSE
34 /* Flag to indicate that the checksum validation for the stream engine
35 has been enabled */
36 #define STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION BIT_U8(0)
37 #define STREAMTCP_INIT_FLAG_DROP_INVALID BIT_U8(1)
38 #define STREAMTCP_INIT_FLAG_BYPASS BIT_U8(2)
39 #define STREAMTCP_INIT_FLAG_INLINE BIT_U8(3)
40
41 /*global flow data*/
42 typedef struct TcpStreamCnf_ {
43 /** stream tracking
44 *
45 * max stream mem usage
46 */
47 SC_ATOMIC_DECLARE(uint64_t, memcap);
48 SC_ATOMIC_DECLARE(uint64_t, reassembly_memcap); /**< max memory usage for stream reassembly */
49
50 uint16_t stream_init_flags; /**< new stream flags will be initialized to this */
51
52 /* coccinelle: TcpStreamCnf:flags:STREAMTCP_INIT_ */
53 uint8_t flags;
54 uint8_t max_synack_queued;
55
56 uint32_t prealloc_sessions; /**< ssns to prealloc per stream thread */
57 uint32_t prealloc_segments; /**< segments to prealloc per stream thread */
58 int midstream;
59 int async_oneside;
60 uint32_t reassembly_depth; /**< Depth until when we reassemble the stream */
61
62 uint16_t reassembly_toserver_chunk_size;
63 uint16_t reassembly_toclient_chunk_size;
64
65 bool streaming_log_api;
66
67 StreamingBufferConfig sbcnf;
68 } TcpStreamCnf;
69
70 typedef struct StreamTcpThread_ {
71 int ssn_pool_id;
72
73 /** queue for pseudo packet(s) that were created in the stream
74 * process and need further handling. Currently only used when
75 * receiving (valid) RST packets */
76 PacketQueueNoLock pseudo_queue;
77
78 uint16_t counter_tcp_sessions;
79 /** sessions not picked up because memcap was reached */
80 uint16_t counter_tcp_ssn_memcap;
81 /** pseudo packets processed */
82 uint16_t counter_tcp_pseudo;
83 /** pseudo packets failed to setup */
84 uint16_t counter_tcp_pseudo_failed;
85 /** packets rejected because their csum is invalid */
86 uint16_t counter_tcp_invalid_checksum;
87 /** TCP packets with no associated flow */
88 uint16_t counter_tcp_no_flow;
89 /** sessions reused */
90 uint16_t counter_tcp_reused_ssn;
91 /** syn pkts */
92 uint16_t counter_tcp_syn;
93 /** syn/ack pkts */
94 uint16_t counter_tcp_synack;
95 /** rst pkts */
96 uint16_t counter_tcp_rst;
97 /** midstream pickups */
98 uint16_t counter_tcp_midstream_pickups;
99 /** wrong thread */
100 uint16_t counter_tcp_wrong_thread;
101
102 /** tcp reassembly thread data */
103 TcpReassemblyThreadCtx *ra_ctx;
104 } StreamTcpThread;
105
106 extern TcpStreamCnf stream_config;
107 void StreamTcpInitConfig (char);
108 void StreamTcpFreeConfig(char);
109 void StreamTcpRegisterTests (void);
110
111 void StreamTcpSessionPktFree (Packet *);
112
113 void StreamTcpInitMemuse(void);
114 void StreamTcpIncrMemuse(uint64_t);
115 void StreamTcpDecrMemuse(uint64_t);
116 int StreamTcpSetMemcap(uint64_t);
117 uint64_t StreamTcpGetMemcap(void);
118 int StreamTcpCheckMemcap(uint64_t);
119 uint64_t StreamTcpMemuseCounter(void);
120 uint64_t StreamTcpReassembleMemuseGlobalCounter(void);
121
122 Packet *StreamTcpPseudoSetup(Packet *, uint8_t *, uint32_t);
123
124 int StreamTcpSegmentForEach(const Packet *p, uint8_t flag,
125 StreamSegmentCallback CallbackFunc,
126 void *data);
127 void StreamTcpReassembleConfigEnableOverlapCheck(void);
128 void TcpSessionSetReassemblyDepth(TcpSession *ssn, uint32_t size);
129
130 typedef int (*StreamReassembleRawFunc)(void *data, const uint8_t *input, const uint32_t input_len);
131
132 int StreamReassembleLog(TcpSession *ssn, TcpStream *stream,
133 StreamReassembleRawFunc Callback, void *cb_data,
134 uint64_t progress_in,
135 uint64_t *progress_out, bool eof);
136 int StreamReassembleRaw(TcpSession *ssn, const Packet *p,
137 StreamReassembleRawFunc Callback, void *cb_data,
138 uint64_t *progress_out, bool respect_inspect_depth);
139 void StreamReassembleRawUpdateProgress(TcpSession *ssn, Packet *p, uint64_t progress);
140
141 void StreamTcpDetectLogFlush(ThreadVars *tv, StreamTcpThread *stt, Flow *f, Packet *p, PacketQueueNoLock *pq);
142
143 const char *StreamTcpStateAsString(const enum TcpState);
144 const char *StreamTcpSsnStateAsString(const TcpSession *ssn);
145
146 /** ------- Inline functions: ------ */
147
148 /**
149 * \brief If we are on IPS mode, and got a drop action triggered from
150 * the IP only module, or from a reassembled msg and/or from an
151 * applayer detection, then drop the rest of the packets of the
152 * same stream and avoid inspecting it any further
153 * \param p pointer to the Packet to check
154 * \retval 1 if we must drop this stream
155 * \retval 0 if the stream still legal
156 */
StreamTcpCheckFlowDrops(Packet * p)157 static inline int StreamTcpCheckFlowDrops(Packet *p)
158 {
159 /* If we are on IPS mode, and got a drop action triggered from
160 * the IP only module, or from a reassembled msg and/or from an
161 * applayer detection, then drop the rest of the packets of the
162 * same stream and avoid inspecting it any further */
163 if (EngineModeIsIPS() && (p->flow->flags & FLOW_ACTION_DROP))
164 return 1;
165
166 return 0;
167 }
168
169 enum {
170 /* stream has no segments for forced reassembly, nor for detection */
171 STREAM_HAS_UNPROCESSED_SEGMENTS_NONE = 0,
172 /* stream has no segments for forced reassembly, but only segments that
173 * have been sent for detection, but are stuck in the detection queues */
174 STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION = 1,
175 };
176
177 TmEcode StreamTcp (ThreadVars *, Packet *, void *, PacketQueueNoLock *);
178 int StreamNeedsReassembly(const TcpSession *ssn, uint8_t direction);
179 TmEcode StreamTcpThreadInit(ThreadVars *, void *, void **);
180 TmEcode StreamTcpThreadDeinit(ThreadVars *tv, void *data);
181 void StreamTcpRegisterTests (void);
182
183 int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
184 PacketQueueNoLock *pq);
185 /* clear ssn and return to pool */
186 void StreamTcpSessionClear(void *ssnptr);
187 /* cleanup ssn, but don't free ssn */
188 void StreamTcpSessionCleanup(TcpSession *ssn);
189 /* cleanup stream, but don't free the stream */
190 void StreamTcpStreamCleanup(TcpStream *stream);
191 /* check if bypass is enabled */
192 int StreamTcpBypassEnabled(void);
193 int StreamTcpInlineDropInvalid(void);
194 int StreamTcpInlineMode(void);
195
196 int TcpSessionPacketSsnReuse(const Packet *p, const Flow *f, const void *tcp_ssn);
197
198 void StreamTcpUpdateAppLayerProgress(TcpSession *ssn, char direction,
199 const uint32_t progress);
200
201 #endif /* __STREAM_TCP_H__ */
202
203