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 <hlandau@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19198)
This commit is contained in:
Matt Caswell 2022-08-31 21:03:22 +01:00
parent 320145d5b3
commit 02719d5c4c
4 changed files with 30 additions and 22 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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