QUIC APL: Implement optimised FIN API
Reviewed-by: Neil Horman <nhorman@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/23343)
This commit is contained in:
parent
2695f7b19b
commit
113be15a5e
@ -1,4 +1,4 @@
|
||||
# Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
@ -1638,6 +1638,7 @@ SSL_R_UNSUPPORTED_ELLIPTIC_CURVE:315:unsupported elliptic curve
|
||||
SSL_R_UNSUPPORTED_PROTOCOL:258:unsupported protocol
|
||||
SSL_R_UNSUPPORTED_SSL_VERSION:259:unsupported ssl version
|
||||
SSL_R_UNSUPPORTED_STATUS_TYPE:329:unsupported status type
|
||||
SSL_R_UNSUPPORTED_WRITE_FLAG:412:unsupported write flag
|
||||
SSL_R_USE_SRTP_NOT_NEGOTIATED:369:use srtp not negotiated
|
||||
SSL_R_VERSION_TOO_HIGH:166:version too high
|
||||
SSL_R_VERSION_TOO_LOW:396:version too low
|
||||
|
@ -28,6 +28,8 @@ __owur int ossl_quic_accept(SSL *s);
|
||||
__owur int ossl_quic_connect(SSL *s);
|
||||
__owur int ossl_quic_read(SSL *s, void *buf, size_t len, size_t *readbytes);
|
||||
__owur int ossl_quic_peek(SSL *s, void *buf, size_t len, size_t *readbytes);
|
||||
__owur int ossl_quic_write_flags(SSL *s, const void *buf, size_t len,
|
||||
uint64_t flags, size_t *written);
|
||||
__owur int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written);
|
||||
__owur long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg);
|
||||
__owur long ossl_quic_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -350,6 +350,7 @@
|
||||
# define SSL_R_UNSUPPORTED_PROTOCOL 258
|
||||
# define SSL_R_UNSUPPORTED_SSL_VERSION 259
|
||||
# define SSL_R_UNSUPPORTED_STATUS_TYPE 329
|
||||
# define SSL_R_UNSUPPORTED_WRITE_FLAG 412
|
||||
# define SSL_R_USE_SRTP_NOT_NEGOTIATED 369
|
||||
# define SSL_R_VERSION_TOO_HIGH 166
|
||||
# define SSL_R_VERSION_TOO_LOW 396
|
||||
|
@ -174,7 +174,7 @@ static int ssl_write(BIO *b, const char *buf, size_t size, size_t *written)
|
||||
|
||||
BIO_clear_retry_flags(b);
|
||||
|
||||
ret = ssl_write_internal(ssl, buf, size, written);
|
||||
ret = ssl_write_internal(ssl, buf, size, 0, written);
|
||||
|
||||
switch (SSL_get_error(ssl, ret)) {
|
||||
case SSL_ERROR_NONE:
|
||||
|
@ -2166,7 +2166,9 @@ int ossl_quic_want(const SSL *s)
|
||||
*
|
||||
*/
|
||||
QUIC_NEEDS_LOCK
|
||||
static void quic_post_write(QUIC_XSO *xso, int did_append, int do_tick)
|
||||
static void quic_post_write(QUIC_XSO *xso, int did_append,
|
||||
int did_append_all, uint64_t flags,
|
||||
int do_tick)
|
||||
{
|
||||
/*
|
||||
* We have appended at least one byte to the stream.
|
||||
@ -2176,6 +2178,9 @@ static void quic_post_write(QUIC_XSO *xso, int did_append, int do_tick)
|
||||
ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(xso->conn->ch),
|
||||
xso->stream);
|
||||
|
||||
if (did_append_all && (flags & SSL_WRITE_FLAG_CONCLUDE) != 0)
|
||||
ossl_quic_sstream_fin(xso->stream->sstream);
|
||||
|
||||
/*
|
||||
* Try and send.
|
||||
*
|
||||
@ -2192,6 +2197,7 @@ struct quic_write_again_args {
|
||||
size_t len;
|
||||
size_t total_written;
|
||||
int err;
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -2267,7 +2273,8 @@ static int quic_write_again(void *arg)
|
||||
if (!xso_sstream_append(args->xso, args->buf, args->len, &actual_written))
|
||||
return -2;
|
||||
|
||||
quic_post_write(args->xso, actual_written > 0, 0);
|
||||
quic_post_write(args->xso, actual_written > 0,
|
||||
args->len == actual_written, args->flags, 0);
|
||||
|
||||
args->buf += actual_written;
|
||||
args->len -= actual_written;
|
||||
@ -2283,7 +2290,7 @@ static int quic_write_again(void *arg)
|
||||
|
||||
QUIC_NEEDS_LOCK
|
||||
static int quic_write_blocking(QCTX *ctx, const void *buf, size_t len,
|
||||
size_t *written)
|
||||
uint64_t flags, size_t *written)
|
||||
{
|
||||
int res;
|
||||
QUIC_XSO *xso = ctx->xso;
|
||||
@ -2297,7 +2304,7 @@ static int quic_write_blocking(QCTX *ctx, const void *buf, size_t len,
|
||||
return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);
|
||||
}
|
||||
|
||||
quic_post_write(xso, actual_written > 0, 1);
|
||||
quic_post_write(xso, actual_written > 0, actual_written == len, flags, 1);
|
||||
|
||||
if (actual_written == len) {
|
||||
/* Managed to append everything on the first try. */
|
||||
@ -2315,6 +2322,7 @@ static int quic_write_blocking(QCTX *ctx, const void *buf, size_t len,
|
||||
args.len = len - actual_written;
|
||||
args.total_written = 0;
|
||||
args.err = ERR_R_INTERNAL_ERROR;
|
||||
args.flags = flags;
|
||||
|
||||
res = block_until_pred(xso->conn, quic_write_again, &args, 0);
|
||||
if (res <= 0) {
|
||||
@ -2353,7 +2361,8 @@ static void aon_write_finish(QUIC_XSO *xso)
|
||||
|
||||
QUIC_NEEDS_LOCK
|
||||
static int quic_write_nonblocking_aon(QCTX *ctx, const void *buf,
|
||||
size_t len, size_t *written)
|
||||
size_t len, uint64_t flags,
|
||||
size_t *written)
|
||||
{
|
||||
QUIC_XSO *xso = ctx->xso;
|
||||
const void *actual_buf;
|
||||
@ -2390,7 +2399,8 @@ static int quic_write_nonblocking_aon(QCTX *ctx, const void *buf,
|
||||
return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);
|
||||
}
|
||||
|
||||
quic_post_write(xso, actual_written > 0, 1);
|
||||
quic_post_write(xso, actual_written > 0, actual_written == actual_len,
|
||||
flags, 1);
|
||||
|
||||
if (actual_written == actual_len) {
|
||||
/* We have sent everything. */
|
||||
@ -2440,7 +2450,7 @@ static int quic_write_nonblocking_aon(QCTX *ctx, const void *buf,
|
||||
|
||||
QUIC_NEEDS_LOCK
|
||||
static int quic_write_nonblocking_epw(QCTX *ctx, const void *buf, size_t len,
|
||||
size_t *written)
|
||||
uint64_t flags, size_t *written)
|
||||
{
|
||||
QUIC_XSO *xso = ctx->xso;
|
||||
|
||||
@ -2451,7 +2461,7 @@ static int quic_write_nonblocking_epw(QCTX *ctx, const void *buf, size_t len,
|
||||
return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL);
|
||||
}
|
||||
|
||||
quic_post_write(xso, *written > 0, 1);
|
||||
quic_post_write(xso, *written > 0, *written == len, flags, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2498,7 +2508,8 @@ static int quic_validate_for_write(QUIC_XSO *xso, int *err)
|
||||
}
|
||||
|
||||
QUIC_TAKES_LOCK
|
||||
int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written)
|
||||
int ossl_quic_write_flags(SSL *s, const void *buf, size_t len,
|
||||
uint64_t flags, size_t *written)
|
||||
{
|
||||
int ret;
|
||||
QCTX ctx;
|
||||
@ -2511,6 +2522,11 @@ int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written)
|
||||
|
||||
partial_write = ((ctx.xso->ssl_mode & SSL_MODE_ENABLE_PARTIAL_WRITE) != 0);
|
||||
|
||||
if ((flags & ~SSL_WRITE_FLAG_CONCLUDE) != 0) {
|
||||
ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_UNSUPPORTED_WRITE_FLAG, NULL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!quic_mutation_allowed(ctx.qc, /*req_active=*/0)) {
|
||||
ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
|
||||
goto out;
|
||||
@ -2532,22 +2548,31 @@ int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written)
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
if ((flags & SSL_WRITE_FLAG_CONCLUDE) != 0)
|
||||
quic_post_write(ctx.xso, 0, 1, flags, 1);
|
||||
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xso_blocking_mode(ctx.xso))
|
||||
ret = quic_write_blocking(&ctx, buf, len, written);
|
||||
ret = quic_write_blocking(&ctx, buf, len, flags, written);
|
||||
else if (partial_write)
|
||||
ret = quic_write_nonblocking_epw(&ctx, buf, len, written);
|
||||
ret = quic_write_nonblocking_epw(&ctx, buf, len, flags, written);
|
||||
else
|
||||
ret = quic_write_nonblocking_aon(&ctx, buf, len, written);
|
||||
ret = quic_write_nonblocking_aon(&ctx, buf, len, flags, written);
|
||||
|
||||
out:
|
||||
quic_unlock(ctx.qc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
QUIC_TAKES_LOCK
|
||||
int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written)
|
||||
{
|
||||
return ossl_quic_write_flags(s, buf, len, 0, written);
|
||||
}
|
||||
|
||||
/*
|
||||
* SSL_read
|
||||
* --------
|
||||
@ -2876,7 +2901,7 @@ int ossl_quic_conn_stream_conclude(SSL *s)
|
||||
}
|
||||
|
||||
ossl_quic_sstream_fin(qs->sstream);
|
||||
quic_post_write(ctx.xso, 1, 1);
|
||||
quic_post_write(ctx.xso, 1, 0, 0, 1);
|
||||
quic_unlock(ctx.qc);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -572,6 +572,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
|
||||
"unsupported ssl version"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_STATUS_TYPE),
|
||||
"unsupported status type"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_WRITE_FLAG),
|
||||
"unsupported write flag"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_USE_SRTP_NOT_NEGOTIATED),
|
||||
"use srtp not negotiated"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_VERSION_TOO_HIGH), "version too high"},
|
||||
|
@ -2512,13 +2512,14 @@ int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *readbytes)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written)
|
||||
int ssl_write_internal(SSL *s, const void *buf, size_t num,
|
||||
uint64_t flags, size_t *written)
|
||||
{
|
||||
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
|
||||
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
if (IS_QUIC(s))
|
||||
return s->method->ssl_write(s, buf, num, written);
|
||||
return ossl_quic_write_flags(s, buf, num, flags, written);
|
||||
#endif
|
||||
|
||||
if (sc == NULL)
|
||||
@ -2535,6 +2536,11 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags != 0) {
|
||||
ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_WRITE_FLAG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sc->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY
|
||||
|| sc->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY
|
||||
|| sc->early_data_state == SSL_EARLY_DATA_READ_RETRY) {
|
||||
@ -2640,7 +2646,7 @@ int SSL_write(SSL *s, const void *buf, int num)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ssl_write_internal(s, buf, (size_t)num, &written);
|
||||
ret = ssl_write_internal(s, buf, (size_t)num, 0, &written);
|
||||
|
||||
/*
|
||||
* The cast is safe here because ret should be <= INT_MAX because num is
|
||||
@ -2654,7 +2660,13 @@ int SSL_write(SSL *s, const void *buf, int num)
|
||||
|
||||
int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written)
|
||||
{
|
||||
int ret = ssl_write_internal(s, buf, num, written);
|
||||
return SSL_write_ex2(s, buf, num, 0, written);
|
||||
}
|
||||
|
||||
int SSL_write_ex2(SSL *s, const void *buf, size_t num, uint64_t flags,
|
||||
size_t *written)
|
||||
{
|
||||
int ret = ssl_write_internal(s, buf, num, flags, written);
|
||||
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
|
@ -2463,7 +2463,8 @@ void ossl_ssl_connection_free(SSL *ssl);
|
||||
__owur int ossl_ssl_connection_reset(SSL *ssl);
|
||||
|
||||
__owur int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes);
|
||||
__owur int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written);
|
||||
__owur int ssl_write_internal(SSL *s, const void *buf, size_t num,
|
||||
uint64_t flags, size_t *written);
|
||||
int ssl_clear_bad_session(SSL_CONNECTION *s);
|
||||
__owur CERT *ssl_cert_new(size_t ssl_pkey_num);
|
||||
__owur CERT *ssl_cert_dup(CERT *cert);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
Loading…
x
Reference in New Issue
Block a user