From ea9b9b50630facc65de81052453d5ae2f0907a8a Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Mon, 24 Apr 2017 15:00:20 +0200 Subject: [PATCH] stream-tcp: add option to accept invalid packets Suricata was inconditionaly dropping packets that are invalid with respect to the streaming engine. In some corner case like asymetric trafic capture, this was leading to dropping some legitimate trafic. The async-oneside option did help but this was not perfect in some real life case. So this patch introduces an option that allow the user to tell Suricata not to drop packet that are invalid with respect to streaming. --- src/stream-tcp.c | 22 +++++++++++++++++++++- src/stream-tcp.h | 4 +++- suricata.yaml.in | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/stream-tcp.c b/src/stream-tcp.c index fcde11e027..f061b9224d 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -301,6 +301,17 @@ static void StreamTcpSessionPoolCleanup(void *s) } } +/** + * \brief See if stream engine is dropping invalid packet in inline mode + * + * \retval 0 no + * \retval 1 yes + */ +int StreamTcpInlineDropInvalid(void) +{ + return (stream_inline && (stream_config.flags & STREAMTCP_INIT_FLAG_DROP_INVALID)); +} + /** \brief To initialize the stream global configuration data * * \param quiet It tells the mode of operation, if it is TRUE nothing will @@ -425,6 +436,15 @@ void StreamTcpInitConfig(char quiet) stream_config.bypass = 0; } + int drop_invalid = 0; + if ((ConfGetBool("stream.drop-invalid", &drop_invalid)) == 1) { + if (drop_invalid == 1) { + stream_config.flags |= STREAMTCP_INIT_FLAG_DROP_INVALID; + } + } else { + stream_config.flags |= STREAMTCP_INIT_FLAG_DROP_INVALID; + } + if (!quiet) { SCLogConfig("stream \"bypass\": %s", bypass ? "enabled" : "disabled"); } @@ -4663,7 +4683,7 @@ error: ReCalculateChecksum(p); } - if (StreamTcpInlineMode()) { + if (StreamTcpInlineDropInvalid()) { PACKET_DROP(p); } SCReturnInt(-1); diff --git a/src/stream-tcp.h b/src/stream-tcp.h index 74bfc5f486..52cb034cbb 100644 --- a/src/stream-tcp.h +++ b/src/stream-tcp.h @@ -33,7 +33,8 @@ #define STREAM_VERBOSE FALSE /* Flag to indicate that the checksum validation for the stream engine has been enabled */ -#define STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION 0x01 +#define STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION BIT_U8(0) +#define STREAMTCP_INIT_FLAG_DROP_INVALID BIT_U8(1) /*global flow data*/ typedef struct TcpStreamCnf_ { @@ -210,6 +211,7 @@ void StreamTcpSessionCleanup(TcpSession *ssn); void StreamTcpStreamCleanup(TcpStream *stream); /* check if bypass is enabled */ int StreamTcpBypassEnabled(void); +int StreamTcpInlineDropInvalid(void); int TcpSessionPacketSsnReuse(const Packet *p, const Flow *f, const void *tcp_ssn); diff --git a/suricata.yaml.in b/suricata.yaml.in index c7a4ea8be3..19e5401929 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -1182,6 +1182,7 @@ flow-timeouts: # midstream: false # don't allow midstream session pickups # async-oneside: false # don't enable async stream handling # inline: no # stream inline mode +# drop-invalid: yes # in inline mode, drop packets that are invalid with regards to streaming engine # max-synack-queued: 5 # Max different SYN/ACKs to queue # bypass: no # Bypass packets when stream.depth is reached #