From: Matt Caswell Date: Wed, 31 Aug 2022 20:03:22 +0000 (+0100) Subject: Make sure we call get_max_records() in the record layer code X-Git-Tag: openssl-3.2.0-alpha1~2025 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=02719d5c4c1e64350b4dddb17e703864809e130a;p=thirdparty%2Fopenssl.git Make sure we call get_max_records() in the record layer code We use the returned data to decide how to split the data we want to write into records. Reviewed-by: Hugo Landau Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/19198) --- diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h index 850c7ae8fa6..7c094b3a161 100644 --- a/ssl/record/methods/recmethod_local.h +++ b/ssl/record/methods/recmethod_local.h @@ -294,7 +294,8 @@ int tls_processed_read_pending(OSSL_RECORD_LAYER *rl); size_t tls_app_data_pending(OSSL_RECORD_LAYER *rl); int tls_write_pending(OSSL_RECORD_LAYER *rl); size_t tls_get_max_record_len(OSSL_RECORD_LAYER *rl); -size_t tls_get_max_records(OSSL_RECORD_LAYER *rl); +size_t tls_get_max_records(OSSL_RECORD_LAYER *rl, int type, size_t buflen, + size_t maxfrag, size_t *preffrag); int tls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates, size_t numtempl); int tls_retry_write_records(OSSL_RECORD_LAYER *rl); diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c index 5fb5f4ebbcd..32e26008006 100644 --- a/ssl/record/methods/tls_common.c +++ b/ssl/record/methods/tls_common.c @@ -1408,9 +1408,10 @@ size_t tls_get_max_record_len(OSSL_RECORD_LAYER *rl) return 0; } -size_t tls_get_max_records(OSSL_RECORD_LAYER *rl) +size_t tls_get_max_records(OSSL_RECORD_LAYER *rl, int type, size_t buflen, + size_t maxfrag, size_t *preffrag) { - return 0; + return 1; } int tls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates, diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 0c70995312a..9f81a9f0466 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -448,19 +448,17 @@ int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, size_t len, * processing then we also only use 1 pipeline, or if we're not using * explicit IVs */ - maxpipes = s->max_pipelines; - if (maxpipes > SSL_MAX_PIPELINES) { - /* - * We should have prevented this when we set max_pipelines so we - * shouldn't get here - */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return -1; - } - /* If no explicit maxpipes configuration - default to 1 */ - /* TODO(RECLAYER): Should we ask the record layer how many pipes it supports? */ - if (maxpipes <= 0) - maxpipes = 1; + + maxpipes = s->rlayer.wrlmethod->get_max_records(s->rlayer.wrl, type, n, + max_send_fragment, + &split_send_fragment); + 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 @@ -504,7 +502,7 @@ int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, size_t len, if (numpipes > maxpipes) numpipes = maxpipes; - if (n / numpipes >= max_send_fragment) { + if (n / numpipes >= split_send_fragment) { /* * We have enough data to completely fill all available * pipelines @@ -512,11 +510,11 @@ int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, size_t len, for (j = 0; j < numpipes; j++) { tmpls[j].type = type; tmpls[j].version = recversion; - tmpls[j].buf = &(buf[tot]) + (j * max_send_fragment); - tmpls[j].buflen = max_send_fragment; + 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 * max_send_fragment; + s->rlayer.wpend_tot = numpipes * split_send_fragment; } else { /* We can partially fill all available pipelines */ tmppipelen = n / numpipes; diff --git a/ssl/record/recordmethod.h b/ssl/record/recordmethod.h index 887a834eb9b..dad086ea817 100644 --- a/ssl/record/recordmethod.h +++ b/ssl/record/recordmethod.h @@ -178,9 +178,17 @@ struct ossl_record_method_st { * Find out the maximum number of records that the record layer is prepared * to process in a single call to write_records. It is the caller's * responsibility to ensure that no call to write_records exceeds this - * number of records. + * number of records. |type| is the type of the records that the caller + * wants to write, and |buflen| is the total amount of data that it wants + * to send. |maxfrag| is the maximum allowed fragment size based on user + * configuration, or TLS parameter negotiation. |*preffrag| contains on + * entry the default fragment size that will actually be used based on user + * configuration. This will always be less than or equal to |maxfrag|. On + * exit the record layer may update this to an alternative fragment size to + * be used. This must always be less than or equal to |maxfrag|. */ - size_t (*get_max_records)(OSSL_RECORD_LAYER *rl); + size_t (*get_max_records)(OSSL_RECORD_LAYER *rl, int type, size_t buflen, + size_t maxfrag, size_t *preffrag); /* * Write |numtempl| records from the array of record templates pointed to