diff options
author | Matt Caswell <matt@openssl.org> | 2022-09-09 15:53:40 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2022-09-23 14:54:49 +0100 |
commit | c6186792b98e93cf2d5d2a9fb85e4aeab31db890 (patch) | |
tree | 95a9254e0ac8a58037dd30ee338125681553de3c /ssl | |
parent | c6d5f343336532a7aba4368099b0631a457194a6 (diff) | |
download | openssl-c6186792b98e93cf2d5d2a9fb85e4aeab31db890.tar.gz |
Move the pipelining code into the record layer
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19198)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/record/methods/tls_common.c | 26 | ||||
-rw-r--r-- | ssl/record/rec_layer_s3.c | 74 |
2 files changed, 57 insertions, 43 deletions
diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c index 6e48bb3a7c..38bf142ba6 100644 --- a/ssl/record/methods/tls_common.c +++ b/ssl/record/methods/tls_common.c @@ -1450,6 +1450,9 @@ static int tls_is_multiblock_capable(OSSL_RECORD_LAYER *rl, int type, size_t tls_get_max_records(OSSL_RECORD_LAYER *rl, int type, size_t len, size_t maxfrag, size_t *preffrag) { + /* TODO(RECLAYER): Remove me */ + SSL_CONNECTION *s = rl->cbarg; + if (tls_is_multiblock_capable(rl, type, len, *preffrag)) { /* minimize address aliasing conflicts */ if ((*preffrag & 0xfff) == 0) @@ -1460,6 +1463,29 @@ size_t tls_get_max_records(OSSL_RECORD_LAYER *rl, int type, size_t len, return 4; } + + /* + * TODO(RECLYAER): There is no test for the pipelining code. We should add + * one. + */ + /* + * If we have a pipeline capable cipher, and we have been configured to use + * it, then return the preferred number of pipelines. + */ + if (rl->max_pipelines > 0 + && s->enc_write_ctx != NULL + && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx)) + & EVP_CIPH_FLAG_PIPELINE) != 0 + && RLAYER_USE_EXPLICIT_IV(rl)) { + size_t pipes; + + if (len == 0) + return 1; + pipes = ((len - 1) / *preffrag) + 1; + + return (pipes < rl->max_pipelines) ? pipes : rl->max_pipelines; + } + return 1; } diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 792b0716d8..0318b07a9f 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -292,35 +292,6 @@ int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, size_t len, max_send_fragment = ssl_get_max_send_fragment(s); split_send_fragment = ssl_get_split_send_fragment(s); - /* - * Ask the record layer how it would like to split the amount of data that - * we have, and how many of those records it would like in one go. - */ - maxpipes = s->rlayer.wrlmethod->get_max_records(s->rlayer.wrl, type, n, - max_send_fragment, - &split_send_fragment); - /* - * If max_pipelines is 0 then this means "undefined" and we default to - * whatever the record layer wants to do. Otherwise we use the smallest - * value from the number requested by the record layer, and max number - * configured by the user. - */ - if (s->max_pipelines > 0 && maxpipes > s->max_pipelines) - maxpipes = s->max_pipelines; - - if (maxpipes > SSL_MAX_PIPELINES) - maxpipes = SSL_MAX_PIPELINES; - - -#if 0 - /* TODO(RECLAYER): FIX ME */ - if (maxpipes == 0 - || s->enc_write_ctx == NULL - || (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx)) - & EVP_CIPH_FLAG_PIPELINE) == 0 - || !SSL_USE_EXPLICIT_IV(s)) - maxpipes = 1; -#endif if (max_send_fragment == 0 || split_send_fragment == 0 || split_send_fragment > max_send_fragment) { @@ -346,39 +317,56 @@ int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, size_t len, for (;;) { size_t tmppipelen, remain; - size_t numpipes, j, lensofar = 0; + size_t j, lensofar = 0; - if (n == 0) - numpipes = 1; - else - numpipes = ((n - 1) / split_send_fragment) + 1; - if (numpipes > maxpipes) - numpipes = maxpipes; + /* + * Ask the record layer how it would like to split the amount of data + * that we have, and how many of those records it would like in one go. + */ + maxpipes = s->rlayer.wrlmethod->get_max_records(s->rlayer.wrl, type, n, + max_send_fragment, + &split_send_fragment); + /* + * If max_pipelines is 0 then this means "undefined" and we default to + * whatever the record layer wants to do. Otherwise we use the smallest + * value from the number requested by the record layer, and max number + * configured by the user. + */ + if (s->max_pipelines > 0 && maxpipes > s->max_pipelines) + maxpipes = s->max_pipelines; + + if (maxpipes > SSL_MAX_PIPELINES) + maxpipes = SSL_MAX_PIPELINES; + + if (split_send_fragment > max_send_fragment) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return -1; + } - if (n / numpipes >= split_send_fragment) { + if (n / maxpipes >= split_send_fragment) { /* * We have enough data to completely fill all available * pipelines */ - for (j = 0; j < numpipes; j++) { + for (j = 0; j < maxpipes; j++) { tmpls[j].type = type; tmpls[j].version = recversion; tmpls[j].buf = &(buf[tot]) + (j * split_send_fragment); tmpls[j].buflen = split_send_fragment; } /* Remember how much data we are going to be sending */ - s->rlayer.wpend_tot = numpipes * split_send_fragment; + s->rlayer.wpend_tot = maxpipes * split_send_fragment; } else { /* We can partially fill all available pipelines */ - tmppipelen = n / numpipes; - remain = n % numpipes; + tmppipelen = n / maxpipes; + remain = n % maxpipes; /* * If there is a remainder we add an extra byte to the first few * pipelines */ if (remain > 0) tmppipelen++; - for (j = 0; j < numpipes; j++) { + for (j = 0; j < maxpipes; j++) { tmpls[j].type = type; tmpls[j].version = recversion; tmpls[j].buf = &(buf[tot]) + lensofar; @@ -392,7 +380,7 @@ int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, size_t len, } i = HANDLE_RLAYER_WRITE_RETURN(s, - s->rlayer.wrlmethod->write_records(s->rlayer.wrl, tmpls, numpipes)); + s->rlayer.wrlmethod->write_records(s->rlayer.wrl, tmpls, maxpipes)); if (i <= 0) { /* SSLfatal() already called if appropriate */ s->rlayer.wnum = tot; |