From 7661587f012d373dbbee046e87d41f430e71aa88 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Sun, 15 Oct 2017 22:05:34 -0400 Subject: [mod_openssl] copy data for larger SSL packets copy small mem chunks into single large buffer before SSL_write() to reduce number times write() called underneath SSL_write() and potentially reduce number of packets generated if socket TCP_NODELAY --- src/mod_openssl.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mod_openssl.c b/src/mod_openssl.c index 550ddf8d..052a79b6 100644 --- a/src/mod_openssl.c +++ b/src/mod_openssl.c @@ -1101,14 +1101,14 @@ static int load_next_chunk (server *srv, chunkqueue *cq, off_t max_bytes, const char **data, size_t *data_len) { - chunk * const c = cq->first; + chunk *c = cq->first; /* local_send_buffer is a 64k sendbuffer (LOCAL_SEND_BUFSIZE) * * it has to stay at the same location all the time to satisfy the needs * of SSL_write to pass the SAME parameter in case of a _WANT_WRITE * - * buffer is allocated once, is NOT realloced + * buffer is allocated once, is NOT realloced (note: not thread-safe) * * (Note: above restriction no longer true since SSL_CTX_set_mode() is * called with SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) @@ -1118,18 +1118,41 @@ load_next_chunk (server *srv, chunkqueue *cq, off_t max_bytes, switch (c->type) { case MEM_CHUNK: - { + *data = NULL; + *data_len = 0; + do { size_t have; force_assert(c->offset >= 0 && c->offset <= (off_t)buffer_string_length(c->mem)); have = buffer_string_length(c->mem) - c->offset; + + /* copy small mem chunks into single large buffer before SSL_write() + * to reduce number times write() called underneath SSL_write() and + * potentially reduce number of packets generated if TCP_NODELAY */ + if (*data_len) { + size_t space = LOCAL_SEND_BUFSIZE - *data_len; + if (have > space) + have = space; + if (have > (size_t)max_bytes - *data_len) + have = (size_t)max_bytes - *data_len; + if (*data != local_send_buffer) { + memcpy(local_send_buffer, *data, *data_len); + *data = local_send_buffer; + } + memcpy(local_send_buffer+*data_len,c->mem->ptr+c->offset,have); + *data_len += have; + continue; + } + if ((off_t) have > max_bytes) have = max_bytes; *data = c->mem->ptr + c->offset; *data_len = have; - } + } while ((c = c->next) && c->type == MEM_CHUNK + && *data_len < LOCAL_SEND_BUFSIZE + && (off_t) *data_len < max_bytes); return 0; case FILE_CHUNK: @@ -1365,7 +1388,7 @@ connection_read_cq_ssl (server *srv, connection *con, /* FIXME: later */ } - /* fall thourgh */ + /* fall through */ default: while((ssl_err = ERR_get_error())) { switch (ERR_GET_REASON(ssl_err)) { -- cgit v1.2.1