From: Victor Julien Date: Thu, 22 Jan 2015 12:43:31 +0000 (+0100) Subject: tcp: add stream.reassembly.zero-copy-size option X-Git-Tag: suricata-2.1beta4~222 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9327b08ab16c10807b70a2fb200d5681ed6aea39;p=thirdparty%2Fsuricata.git tcp: add stream.reassembly.zero-copy-size option 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. --- diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index e3ee004875..cebdd53544 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -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, diff --git a/src/stream-tcp.h b/src/stream-tcp.h index b8a31855af..113e2e88a1 100644 --- a/src/stream-tcp.h +++ b/src/stream-tcp.h @@ -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; diff --git a/suricata.yaml.in b/suricata.yaml.in index 04cb3b2285..2bb208381e 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -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: #