mirror of
https://github.com/openssl/openssl.git
synced 2024-12-03 05:41:46 +08:00
QUIC APL/CHANNEL: Wire up connection closure reason
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21565)
This commit is contained in:
parent
d56b81ac9f
commit
40c8c756c8
@ -149,6 +149,21 @@ typedef struct quic_terminate_cause_st {
|
||||
*/
|
||||
uint64_t frame_type;
|
||||
|
||||
/*
|
||||
* Optional reason string. When calling ossl_quic_channel_local_close, if a
|
||||
* reason string pointer is passed, it is copied and stored inside
|
||||
* QUIC_CHANNEL for the remainder of the lifetime of the channel object.
|
||||
* Thus the string pointed to by this value, if non-NULL, is valid for the
|
||||
* lifetime of the QUIC_CHANNEL object.
|
||||
*/
|
||||
const char *reason;
|
||||
|
||||
/*
|
||||
* Length of reason in bytes. The reason is supposed to contain a UTF-8
|
||||
* string but may be arbitrary data if the reason came from the network.
|
||||
*/
|
||||
size_t reason_len;
|
||||
|
||||
/* Is this error code in the transport (0) or application (1) space? */
|
||||
unsigned int app : 1;
|
||||
|
||||
@ -196,7 +211,8 @@ int ossl_quic_channel_set_mutator(QUIC_CHANNEL *ch,
|
||||
int ossl_quic_channel_start(QUIC_CHANNEL *ch);
|
||||
|
||||
/* Start a locally initiated connection shutdown. */
|
||||
void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code);
|
||||
void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code,
|
||||
const char *app_reason);
|
||||
|
||||
/*
|
||||
* Called when the handshake is confirmed.
|
||||
|
@ -2339,10 +2339,10 @@ __owur int SSL_get_stream_read_error_code(SSL *ssl, uint64_t *app_error_code);
|
||||
__owur int SSL_get_stream_write_error_code(SSL *ssl, uint64_t *app_error_code);
|
||||
|
||||
typedef struct ssl_conn_close_info_st {
|
||||
uint64_t error_code;
|
||||
char *reason;
|
||||
size_t reason_len;
|
||||
int is_local, is_transport;
|
||||
uint64_t error_code;
|
||||
const char *reason;
|
||||
size_t reason_len;
|
||||
int is_local, is_transport;
|
||||
} SSL_CONN_CLOSE_INFO;
|
||||
|
||||
__owur int SSL_get_conn_close_info(SSL *ssl,
|
||||
|
@ -371,6 +371,7 @@ static void ch_cleanup(QUIC_CHANNEL *ch)
|
||||
ossl_qrx_free(ch->qrx);
|
||||
ossl_quic_demux_free(ch->demux);
|
||||
OPENSSL_free(ch->local_transport_params);
|
||||
OPENSSL_free((char *)ch->terminate_cause.reason);
|
||||
OSSL_ERR_STATE_free(ch->err_state);
|
||||
}
|
||||
|
||||
@ -2438,7 +2439,8 @@ int ossl_quic_channel_start(QUIC_CHANNEL *ch)
|
||||
}
|
||||
|
||||
/* Start a locally initiated connection shutdown. */
|
||||
void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code)
|
||||
void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code,
|
||||
const char *app_reason)
|
||||
{
|
||||
QUIC_TERMINATE_CAUSE tcause = {0};
|
||||
|
||||
@ -2447,6 +2449,8 @@ void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code)
|
||||
|
||||
tcause.app = 1;
|
||||
tcause.error_code = app_error_code;
|
||||
tcause.reason = app_reason;
|
||||
tcause.reason_len = app_reason != NULL ? strlen(app_reason) : 0;
|
||||
ch_start_terminating(ch, &tcause, 0);
|
||||
}
|
||||
|
||||
@ -2622,6 +2626,37 @@ int ossl_quic_channel_on_handshake_confirmed(QUIC_CHANNEL *ch)
|
||||
* closing state and send a packet containing a CONNECTION_CLOSE
|
||||
* frame in response to any UDP datagram that is received.
|
||||
*/
|
||||
static void copy_tcause(QUIC_TERMINATE_CAUSE *dst,
|
||||
const QUIC_TERMINATE_CAUSE *src)
|
||||
{
|
||||
dst->error_code = src->error_code;
|
||||
dst->frame_type = src->frame_type;
|
||||
dst->app = src->app;
|
||||
dst->remote = src->remote;
|
||||
|
||||
dst->reason = NULL;
|
||||
dst->reason_len = 0;
|
||||
|
||||
if (src->reason != NULL && src->reason_len > 0) {
|
||||
size_t l = src->reason_len;
|
||||
char *r;
|
||||
|
||||
if (l >= SIZE_MAX)
|
||||
--l;
|
||||
|
||||
/*
|
||||
* If this fails, dst->reason becomes NULL and we simply do not use a
|
||||
* reason. This ensures termination is infallible.
|
||||
*/
|
||||
dst->reason = r = OPENSSL_memdup(src->reason, l + 1);
|
||||
if (r == NULL)
|
||||
return;
|
||||
|
||||
r[l] = '\0';
|
||||
dst->reason_len = l;
|
||||
}
|
||||
}
|
||||
|
||||
static void ch_start_terminating(QUIC_CHANNEL *ch,
|
||||
const QUIC_TERMINATE_CAUSE *tcause,
|
||||
int force_immediate)
|
||||
@ -2629,12 +2664,12 @@ static void ch_start_terminating(QUIC_CHANNEL *ch,
|
||||
switch (ch->state) {
|
||||
default:
|
||||
case QUIC_CHANNEL_STATE_IDLE:
|
||||
ch->terminate_cause = *tcause;
|
||||
copy_tcause(&ch->terminate_cause, tcause);
|
||||
ch_on_terminating_timeout(ch);
|
||||
break;
|
||||
|
||||
case QUIC_CHANNEL_STATE_ACTIVE:
|
||||
ch->terminate_cause = *tcause;
|
||||
copy_tcause(&ch->terminate_cause, tcause);
|
||||
|
||||
if (!force_immediate) {
|
||||
ch->state = tcause->remote ? QUIC_CHANNEL_STATE_TERMINATING_DRAINING
|
||||
@ -2656,6 +2691,8 @@ static void ch_start_terminating(QUIC_CHANNEL *ch,
|
||||
f.error_code = ch->terminate_cause.error_code;
|
||||
f.frame_type = ch->terminate_cause.frame_type;
|
||||
f.is_app = ch->terminate_cause.app;
|
||||
f.reason = (char *)ch->terminate_cause.reason;
|
||||
f.reason_len = ch->terminate_cause.reason_len;
|
||||
ossl_quic_tx_packetiser_schedule_conn_close(ch->txp, &f);
|
||||
/*
|
||||
* RFC 9000 s. 10.2.2 Draining Connection State:
|
||||
@ -2714,7 +2751,8 @@ void ossl_quic_channel_on_remote_conn_close(QUIC_CHANNEL *ch,
|
||||
tcause.app = f->is_app;
|
||||
tcause.error_code = f->error_code;
|
||||
tcause.frame_type = f->frame_type;
|
||||
|
||||
tcause.reason = f->reason;
|
||||
tcause.reason_len = f->reason_len;
|
||||
ch_start_terminating(ch, &tcause, 0);
|
||||
}
|
||||
|
||||
@ -2967,6 +3005,7 @@ void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch,
|
||||
|
||||
tcause.error_code = error_code;
|
||||
tcause.frame_type = frame_type;
|
||||
tcause.reason = reason;
|
||||
|
||||
ch_start_terminating(ch, &tcause, 0);
|
||||
}
|
||||
|
@ -1200,7 +1200,8 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags,
|
||||
|
||||
/* Phase 2: Connection Closure */
|
||||
ossl_quic_channel_local_close(ctx.qc->ch,
|
||||
args != NULL ? args->quic_error_code : 0);
|
||||
args != NULL ? args->quic_error_code : 0,
|
||||
args != NULL ? args->quic_reason : NULL);
|
||||
|
||||
SSL_set_shutdown(ctx.qc->tls, SSL_SENT_SHUTDOWN);
|
||||
|
||||
@ -3043,8 +3044,8 @@ int ossl_quic_get_conn_close_info(SSL *ssl,
|
||||
return 0;
|
||||
|
||||
info->error_code = tc->error_code;
|
||||
info->reason = NULL; /* TODO(QUIC): Wire reason */
|
||||
info->reason_len = 0;
|
||||
info->reason = tc->reason;
|
||||
info->reason_len = tc->reason_len;
|
||||
info->is_local = !tc->remote;
|
||||
info->is_transport = !tc->app;
|
||||
return 1;
|
||||
|
@ -488,7 +488,7 @@ OSSL_TIME ossl_quic_tserver_get_deadline(QUIC_TSERVER *srv)
|
||||
|
||||
int ossl_quic_tserver_shutdown(QUIC_TSERVER *srv)
|
||||
{
|
||||
ossl_quic_channel_local_close(srv->ch, 0);
|
||||
ossl_quic_channel_local_close(srv->ch, 0, NULL);
|
||||
|
||||
/* TODO(QUIC): !SSL_SHUTDOWN_FLAG_NO_STREAM_FLUSH */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user