]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
tcp: add stream.reassembly.zero-copy-size option
authorVictor Julien <victor@inliniac.net>
Thu, 22 Jan 2015 12:43:31 +0000 (13:43 +0100)
committerVictor Julien <victor@inliniac.net>
Wed, 4 Feb 2015 10:23:46 +0000 (11:23 +0100)
The option sets in bytes the value at which segment data is passed to
the app layer API directly. Data sizes equal to and higher than the
value set are passed on directly.

Default is 128.

src/stream-tcp-reassemble.c
src/stream-tcp.h
suricata.yaml.in

index e3ee0048753e009012932da28be276f96e14d13e..cebdd53544d5452d99dcbd36b1d7187223e3db23 100644 (file)
@@ -466,6 +466,19 @@ int StreamTcpReassemblyConfig(char quiet)
     if (!quiet)
         SCLogInfo("stream.reassembly \"chunk-prealloc\": %u", stream_chunk_prealloc);
     StreamMsgQueuesInit(stream_chunk_prealloc);
+
+    intmax_t zero_copy_size = 128;
+    if (ConfGetInt("stream.reassembly.zero-copy-size", &zero_copy_size) == 1) {
+        if (zero_copy_size < 0 || zero_copy_size > 0xffff) {
+            SCLogError(SC_ERR_INVALID_ARGUMENT, "stream.reassembly.zero-copy-size of "
+                    "%"PRIiMAX" is invalid: valid values are 0 to 65535", zero_copy_size);
+            return -1;
+        }
+    }
+    stream_config.zero_copy_size = (uint16_t)zero_copy_size;
+    if (!quiet)
+        SCLogInfo("stream.reassembly \"zero-copy-size\": %u", stream_config.zero_copy_size);
+
     return 0;
 }
 
@@ -2577,7 +2590,10 @@ static inline int DoReassemble(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
                  Packet *p)
 {
     /* fast path 1: segment is exactly what we need */
-    if (likely(rd->data_len == 0 && SEQ_EQ(seg->seq, rd->ra_base_seq+1) && SEQ_EQ(stream->last_ack, (seg->seq + seg->payload_len)))) {
+    if (likely(rd->data_len == 0 &&
+               SEQ_EQ(seg->seq, rd->ra_base_seq+1) &&
+               SEQ_EQ(stream->last_ack, (seg->seq + seg->payload_len))))
+    {
         /* process single segment directly */
         AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream,
                 seg->payload, seg->payload_len,
@@ -2596,7 +2612,11 @@ static inline int DoReassemble(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
         }
         return 1;
     /* fast path 2: segment acked completely, meets minimal size req for 0copy processing */
-    } else if (rd->data_len == 0 && SEQ_EQ(seg->seq, rd->ra_base_seq+1) && SEQ_GT(stream->last_ack, (seg->seq + seg->payload_len)) && seg->payload_len >= 128) {
+    } else if (rd->data_len == 0 &&
+               SEQ_EQ(seg->seq, rd->ra_base_seq+1) &&
+               SEQ_GT(stream->last_ack, (seg->seq + seg->payload_len)) &&
+               seg->payload_len >= stream_config.zero_copy_size)
+    {
         /* process single segment directly */
         AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream,
                 seg->payload, seg->payload_len,
index b8a31855afad574dc92e0b51314d2d34e36099a2..113e2e88a135396025123aa9cc694e2930030271 100644 (file)
@@ -51,6 +51,9 @@ typedef struct TcpStreamCnf_ {
     uint32_t ssn_init_flags; /**< new ssn flags will be initialized to this */
     uint8_t segment_init_flags; /**< new seg flags will be initialized to this */
 
+    uint16_t zero_copy_size;    /**< use zero copy for app layer above segments
+                                 *   of this size */
+
     uint32_t prealloc_sessions; /**< ssns to prealloc per stream thread */
     int midstream;
     int async_oneside;
index 04cb3b2285711aebb1aaad6cc1f705d303175c86..2bb208381eee12b8c3d774bda3ca995943b68b16 100644 (file)
@@ -785,6 +785,11 @@ flow-timeouts:
 #       - size: 4               # Size of the (data)segment for a pool
 #         prealloc: 256         # Number of segments to prealloc and keep
 #                               # in the pool.
+#     zero-copy-size: 128       # This option sets in bytes the value at
+#                               # which segment data is passed to the app
+#                               # layer API directly. Data sizes equal to
+#                               # and higher than the value set are passed
+#                               # on directly.
 #
 stream:
   memcap: 32mb
@@ -816,6 +821,7 @@ stream:
     #    prealloc: 1024
     #  - size: 65535
     #    prealloc: 128
+    #zero-copy-size: 128
 
 # Host table:
 #