mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
7.7 KiB
C
212 lines
7.7 KiB
C
/* Copyright (C) 2007-2024 Open Information Security Foundation
|
|
*
|
|
* You can copy, redistribute or modify this Program under the terms of
|
|
* the GNU General Public License version 2 as published by the Free
|
|
* Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* version 2 along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
*
|
|
* \author Victor Julien <victor@inliniac.net>
|
|
* \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
|
|
*/
|
|
|
|
#ifndef SURICATA_STREAM_TCP_H
|
|
#define SURICATA_STREAM_TCP_H
|
|
|
|
#include "stream-tcp-private.h"
|
|
|
|
#include "stream.h"
|
|
#include "stream-tcp-reassemble.h"
|
|
#include "suricata.h"
|
|
#include "util-exception-policy-types.h"
|
|
|
|
#define STREAM_VERBOSE false
|
|
/* Flag to indicate that the checksum validation for the stream engine
|
|
has been enabled */
|
|
#define STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION BIT_U8(0)
|
|
#define STREAMTCP_INIT_FLAG_DROP_INVALID BIT_U8(1)
|
|
#define STREAMTCP_INIT_FLAG_BYPASS BIT_U8(2)
|
|
#define STREAMTCP_INIT_FLAG_INLINE BIT_U8(3)
|
|
|
|
/*global flow data*/
|
|
typedef struct TcpStreamCnf_ {
|
|
/** stream tracking
|
|
*
|
|
* max stream mem usage
|
|
*/
|
|
SC_ATOMIC_DECLARE(uint64_t, memcap);
|
|
SC_ATOMIC_DECLARE(uint64_t, reassembly_memcap); /**< max memory usage for stream reassembly */
|
|
|
|
uint16_t stream_init_flags; /**< new stream flags will be initialized to this */
|
|
|
|
/* coccinelle: TcpStreamCnf:flags:STREAMTCP_INIT_ */
|
|
uint8_t flags;
|
|
uint8_t max_synack_queued;
|
|
|
|
uint32_t prealloc_sessions; /**< ssns to prealloc per stream thread */
|
|
uint32_t prealloc_segments; /**< segments to prealloc per stream thread */
|
|
bool midstream;
|
|
bool async_oneside;
|
|
bool streaming_log_api;
|
|
uint8_t max_syn_queued;
|
|
|
|
uint32_t reassembly_depth; /**< Depth until when we reassemble the stream */
|
|
|
|
uint16_t reassembly_toserver_chunk_size;
|
|
uint16_t reassembly_toclient_chunk_size;
|
|
|
|
enum ExceptionPolicy ssn_memcap_policy;
|
|
enum ExceptionPolicy reassembly_memcap_policy;
|
|
enum ExceptionPolicy midstream_policy;
|
|
|
|
/* default to "LINUX" timestamp behavior if true*/
|
|
bool liberal_timestamps;
|
|
|
|
StreamingBufferConfig sbcnf;
|
|
} TcpStreamCnf;
|
|
|
|
typedef struct StreamTcpThread_ {
|
|
int ssn_pool_id;
|
|
|
|
uint16_t counter_tcp_active_sessions;
|
|
uint16_t counter_tcp_sessions;
|
|
/** sessions not picked up because memcap was reached */
|
|
uint16_t counter_tcp_ssn_memcap;
|
|
uint16_t counter_tcp_ssn_from_cache;
|
|
uint16_t counter_tcp_ssn_from_pool;
|
|
/** exception policy */
|
|
ExceptionPolicyCounters counter_tcp_ssn_memcap_eps;
|
|
/** pseudo packets processed */
|
|
uint16_t counter_tcp_pseudo;
|
|
/** pseudo packets failed to setup */
|
|
uint16_t counter_tcp_pseudo_failed;
|
|
/** packets rejected because their csum is invalid */
|
|
uint16_t counter_tcp_invalid_checksum;
|
|
/** midstream pickups */
|
|
uint16_t counter_tcp_midstream_pickups;
|
|
/** exception policy stats */
|
|
ExceptionPolicyCounters counter_tcp_midstream_eps;
|
|
/** wrong thread */
|
|
uint16_t counter_tcp_wrong_thread;
|
|
/** ack for unseen data */
|
|
uint16_t counter_tcp_ack_unseen_data;
|
|
|
|
/** tcp reassembly thread data */
|
|
TcpReassemblyThreadCtx *ra_ctx;
|
|
} StreamTcpThread;
|
|
|
|
extern TcpStreamCnf stream_config;
|
|
void StreamTcpInitConfig(bool);
|
|
void StreamTcpFreeConfig(bool);
|
|
void StreamTcpRegisterTests (void);
|
|
|
|
void StreamTcpSessionPktFree (Packet *);
|
|
|
|
void StreamTcpInitMemuse(void);
|
|
void StreamTcpIncrMemuse(uint64_t);
|
|
void StreamTcpDecrMemuse(uint64_t);
|
|
int StreamTcpSetMemcap(uint64_t);
|
|
uint64_t StreamTcpGetMemcap(void);
|
|
int StreamTcpCheckMemcap(uint64_t);
|
|
uint64_t StreamTcpMemuseCounter(void);
|
|
uint64_t StreamTcpReassembleMemuseGlobalCounter(void);
|
|
|
|
int StreamTcpSegmentForEach(const Packet *p, uint8_t flag,
|
|
StreamSegmentCallback CallbackFunc,
|
|
void *data);
|
|
int StreamTcpSegmentForSession(
|
|
const Packet *p, uint8_t flag, StreamSegmentCallback CallbackFunc, void *data);
|
|
void StreamTcpReassembleConfigEnableOverlapCheck(void);
|
|
void TcpSessionSetReassemblyDepth(TcpSession *ssn, uint32_t size);
|
|
|
|
typedef int (*StreamReassembleRawFunc)(
|
|
void *data, const uint8_t *input, const uint32_t input_len, const uint64_t offset);
|
|
|
|
int StreamReassembleForFrame(TcpSession *ssn, TcpStream *stream, StreamReassembleRawFunc Callback,
|
|
void *cb_data, const uint64_t offset, const bool eof);
|
|
int StreamReassembleLog(const TcpSession *ssn, const TcpStream *stream,
|
|
StreamReassembleRawFunc Callback, void *cb_data, const uint64_t progress_in,
|
|
uint64_t *progress_out, const bool eof);
|
|
int StreamReassembleRaw(TcpSession *ssn, const Packet *p,
|
|
StreamReassembleRawFunc Callback, void *cb_data,
|
|
uint64_t *progress_out, bool respect_inspect_depth);
|
|
void StreamReassembleRawUpdateProgress(TcpSession *ssn, Packet *p, const uint64_t progress);
|
|
|
|
void StreamTcpDetectLogFlush(ThreadVars *tv, StreamTcpThread *stt, Flow *f, Packet *p, PacketQueueNoLock *pq);
|
|
|
|
const char *StreamTcpStateAsString(const enum TcpState);
|
|
const char *StreamTcpSsnStateAsString(const TcpSession *ssn);
|
|
|
|
/** ------- Inline functions: ------ */
|
|
|
|
/**
|
|
* \brief If we are on IPS mode, and got a drop action triggered from
|
|
* the IP only module, or from a reassembled msg and/or from an
|
|
* applayer detection, then drop the rest of the packets of the
|
|
* same stream and avoid inspecting it any further
|
|
* \param p pointer to the Packet to check
|
|
* \retval 1 if we must drop this stream
|
|
* \retval 0 if the stream still legal
|
|
*/
|
|
static inline int StreamTcpCheckFlowDrops(Packet *p)
|
|
{
|
|
/* If we are on IPS mode, and got a drop action triggered from
|
|
* the IP only module, or from a reassembled msg and/or from an
|
|
* applayer detection, then drop the rest of the packets of the
|
|
* same stream and avoid inspecting it any further */
|
|
if (EngineModeIsIPS() && (p->flow->flags & FLOW_ACTION_DROP))
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
enum {
|
|
/* stream has no segments for forced reassembly, nor for detection */
|
|
STREAM_HAS_UNPROCESSED_SEGMENTS_NONE = 0,
|
|
/* stream has no segments for forced reassembly, but only segments that
|
|
* have been sent for detection, but are stuck in the detection queues */
|
|
STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION = 1,
|
|
};
|
|
|
|
TmEcode StreamTcp (ThreadVars *, Packet *, void *, PacketQueueNoLock *);
|
|
uint8_t StreamNeedsReassembly(const TcpSession *ssn, uint8_t direction);
|
|
TmEcode StreamTcpThreadInit(ThreadVars *, void *, void **);
|
|
TmEcode StreamTcpThreadDeinit(ThreadVars *tv, void *data);
|
|
|
|
int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
|
|
PacketQueueNoLock *pq);
|
|
/* clear ssn and return to pool */
|
|
void StreamTcpSessionClear(void *ssnptr);
|
|
/* cleanup ssn, but don't free ssn */
|
|
void StreamTcpSessionCleanup(TcpSession *ssn);
|
|
/* cleanup stream, but don't free the stream */
|
|
void StreamTcpStreamCleanup(TcpStream *stream);
|
|
/* check if bypass is enabled */
|
|
int StreamTcpBypassEnabled(void);
|
|
bool StreamTcpInlineMode(void);
|
|
|
|
bool TcpSessionPacketSsnReuse(const Packet *p, const Flow *f, const void *tcp_ssn);
|
|
|
|
void StreamTcpUpdateAppLayerProgress(TcpSession *ssn, char direction,
|
|
const uint32_t progress);
|
|
|
|
uint64_t StreamTcpGetUsable(const TcpStream *stream, const bool eof);
|
|
uint64_t StreamDataRightEdge(const TcpStream *stream, const bool eof);
|
|
|
|
void StreamTcpThreadCacheEnable(void);
|
|
void StreamTcpThreadCacheCleanup(void);
|
|
|
|
#endif /* SURICATA_STREAM_TCP_H */
|