]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream-tcp: add option to accept invalid packets
authorEric Leblond <eric@regit.org>
Mon, 24 Apr 2017 13:00:20 +0000 (15:00 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 6 Jun 2017 14:26:31 +0000 (16:26 +0200)
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
src/stream-tcp.h
suricata.yaml.in

index fcde11e027b047f285511f1e2ffba3f857aac2b0..f061b9224dddc345c8b1aa7d83add2b8031f63f7 100644 (file)
@@ -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);
index 74bfc5f48653a11c8eb407890601a85383ece27e..52cb034cbb83c1cd42dae909fe143197c612b2ce 100644 (file)
@@ -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);
 
index c7a4ea8be3f9a7dbe20e5e9c702b1540c8a2c534..19e54019295c4e993d7b2e8cbfa78e8b8f377b91 100644 (file)
@@ -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
 #