Implement read pipeline support in libssl

Read pipelining is controlled in a slightly different way than with write
pipelining. While reading we are constrained by the number of records that
the peer (and the network) can provide to us in one go. The more records
we can get in one go the more opportunity we have to parallelise the
processing.

There are two parameters that affect this:
* The number of pipelines that we are willing to process in one go. This is
controlled by max_pipelines (as for write pipelining)
* The size of our read buffer. A subsequent commit will provide an API for
adjusting the size of the buffer.

Another requirement for this to work is that "read_ahead" must be set. The
read_ahead parameter will attempt to read as much data into our read buffer
as the network can provide. Without this set, data is read into the read
buffer on demand. Setting the max_pipelines parameter to a value greater
than 1 will automatically also turn read_ahead on.

Finally, the read pipelining as currently implemented will only parallelise
the processing of application data records. This would only make a
difference for renegotiation so is unlikely to have a significant impact.

Reviewed-by: Tim Hudson <tjh@openssl.org>
This commit is contained in:
Matt Caswell
2016-01-12 14:52:35 +00:00
parent 2f2c9caa72
commit 94777c9c86
6 changed files with 469 additions and 309 deletions

View File

@@ -672,6 +672,8 @@ SSL *SSL_new(SSL_CTX *ctx)
s->max_send_fragment = ctx->max_send_fragment;
s->split_send_fragment = ctx->split_send_fragment;
s->max_pipelines = ctx->max_pipelines;
if (s->max_pipelines > 1)
RECORD_LAYER_set_read_ahead(&s->rlayer, 1);
CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
s->ctx = ctx;
@@ -1694,6 +1696,8 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
if (larg < 1 || larg > SSL_MAX_PIPELINES)
return 0;
s->max_pipelines = larg;
if (larg > 1)
RECORD_LAYER_set_read_ahead(&s->rlayer, 1);
case SSL_CTRL_GET_RI_SUPPORT:
if (s->s3)
return s->s3->send_connection_binding;