mirror of https://github.com/openssl/openssl
QUIC: Add handling of SSL_get_shutdown()
Return SSL_SENT_SHUTDOWN and SSL_RECEIVED_SHUTDOWN with semantics similar to TLS connections. Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/22408)
This commit is contained in:
parent
8e520d2714
commit
7757f5ef73
|
@ -2,7 +2,8 @@
|
|||
|
||||
=head1 NAME
|
||||
|
||||
SSL_CTX_set_quiet_shutdown, SSL_CTX_get_quiet_shutdown, SSL_set_quiet_shutdown, SSL_get_quiet_shutdown - manipulate shutdown behaviour
|
||||
SSL_CTX_set_quiet_shutdown, SSL_CTX_get_quiet_shutdown, SSL_set_quiet_shutdown,
|
||||
SSL_get_quiet_shutdown - manipulate shutdown behaviour
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
@ -54,7 +55,7 @@ The default is normal shutdown behaviour as described by the TLS standard.
|
|||
SSL_CTX_set_quiet_shutdown() and SSL_set_quiet_shutdown() do not return
|
||||
diagnostic information.
|
||||
|
||||
SSL_CTX_get_quiet_shutdown() and SSL_get_quiet_shutdown return the current
|
||||
SSL_CTX_get_quiet_shutdown() and SSL_get_quiet_shutdown() return the current
|
||||
setting.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
|
|
@ -57,13 +57,21 @@ If a close_notify was received, SSL_RECEIVED_SHUTDOWN will be set,
|
|||
for setting SSL_SENT_SHUTDOWN the application must however still call
|
||||
L<SSL_shutdown(3)> or SSL_set_shutdown() itself.
|
||||
|
||||
These functions are not supported for QUIC SSL objects.
|
||||
SSL_set_shutdown() is not supported for QUIC SSL objects.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
SSL_set_shutdown() does not return diagnostic information.
|
||||
|
||||
SSL_get_shutdown() returns the current setting.
|
||||
SSL_get_shutdown() returns the current shutdown state as set or based
|
||||
on the actual connection state.
|
||||
|
||||
SSL_get_shutdown() returns 0 if called on a QUIC stream SSL object. If it
|
||||
is called on a QUIC connection SSL object, it returns a value with
|
||||
SSL_SENT_SHUTDOWN set if CONNECTION_CLOSE has been sent to the peer and
|
||||
it returns a value with SSL_RECEIVED_SHUTDOWN set if CONNECTION_CLOSE
|
||||
has been received from the peer or the QUIC connection is fully terminated
|
||||
for other reasons.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
|
|
@ -320,6 +320,7 @@ QUIC_STREAM *ossl_quic_channel_get_stream_by_id(QUIC_CHANNEL *ch,
|
|||
int ossl_quic_channel_is_term_any(const QUIC_CHANNEL *ch);
|
||||
const QUIC_TERMINATE_CAUSE *
|
||||
ossl_quic_channel_get_terminate_cause(const QUIC_CHANNEL *ch);
|
||||
int ossl_quic_channel_is_closing(const QUIC_CHANNEL *ch);
|
||||
int ossl_quic_channel_is_terminated(const QUIC_CHANNEL *ch);
|
||||
int ossl_quic_channel_is_active(const QUIC_CHANNEL *ch);
|
||||
int ossl_quic_channel_is_handshake_complete(const QUIC_CHANNEL *ch);
|
||||
|
|
|
@ -125,6 +125,7 @@ void ossl_quic_conn_force_assist_thread_wake(SSL *s);
|
|||
QUIC_CHANNEL *ossl_quic_conn_get_channel(SSL *s);
|
||||
|
||||
int ossl_quic_has_pending(const SSL *s);
|
||||
int ossl_quic_get_shutdown(const SSL *s);
|
||||
|
||||
# endif
|
||||
|
||||
|
|
|
@ -635,7 +635,7 @@ int ossl_quic_channel_is_active(const QUIC_CHANNEL *ch)
|
|||
return ch != NULL && ch->state == QUIC_CHANNEL_STATE_ACTIVE;
|
||||
}
|
||||
|
||||
static int ossl_quic_channel_is_closing(const QUIC_CHANNEL *ch)
|
||||
int ossl_quic_channel_is_closing(const QUIC_CHANNEL *ch)
|
||||
{
|
||||
return ch->state == QUIC_CHANNEL_STATE_TERMINATING_CLOSING;
|
||||
}
|
||||
|
|
|
@ -3571,6 +3571,27 @@ const SSL_CIPHER *ossl_quic_get_cipher(unsigned int u)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* SSL_get_shutdown()
|
||||
* ------------------
|
||||
*/
|
||||
int ossl_quic_get_shutdown(const SSL *s)
|
||||
{
|
||||
QCTX ctx;
|
||||
int shut = 0;
|
||||
|
||||
if (!expect_quic_conn_only(s, &ctx))
|
||||
return 0;
|
||||
|
||||
if (ossl_quic_channel_is_term_any(ctx.qc->ch)) {
|
||||
shut |= SSL_SENT_SHUTDOWN;
|
||||
if (!ossl_quic_channel_is_closing(ctx.qc->ch))
|
||||
shut |= SSL_RECEIVED_SHUTDOWN;
|
||||
}
|
||||
|
||||
return shut;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal Testing APIs
|
||||
* =====================
|
||||
|
|
|
@ -5142,7 +5142,7 @@ void SSL_set_quiet_shutdown(SSL *s, int mode)
|
|||
{
|
||||
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
|
||||
|
||||
/* TODO(QUIC): Currently not supported for QUIC. */
|
||||
/* Not supported with QUIC */
|
||||
if (sc == NULL)
|
||||
return;
|
||||
|
||||
|
@ -5153,7 +5153,7 @@ int SSL_get_quiet_shutdown(const SSL *s)
|
|||
{
|
||||
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);
|
||||
|
||||
/* TODO(QUIC): Currently not supported for QUIC. */
|
||||
/* Not supported with QUIC */
|
||||
if (sc == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -5164,7 +5164,7 @@ void SSL_set_shutdown(SSL *s, int mode)
|
|||
{
|
||||
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
|
||||
|
||||
/* TODO(QUIC): Do we want this for QUIC? */
|
||||
/* Not supported with QUIC */
|
||||
if (sc == NULL)
|
||||
return;
|
||||
|
||||
|
@ -5175,7 +5175,12 @@ int SSL_get_shutdown(const SSL *s)
|
|||
{
|
||||
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);
|
||||
|
||||
/* TODO(QUIC): Do we want this for QUIC? */
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
/* QUIC: Just indicate whether the connection was shutdown cleanly. */
|
||||
if (IS_QUIC(s))
|
||||
return ossl_quic_get_shutdown(s);
|
||||
#endif
|
||||
|
||||
if (sc == NULL)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -1335,6 +1335,52 @@ static int test_alpn(int idx)
|
|||
return testresult;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test SSL_get_shutdown() behavior.
|
||||
*/
|
||||
static int test_get_shutdown(void)
|
||||
{
|
||||
SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method());
|
||||
SSL *clientquic = NULL;
|
||||
QUIC_TSERVER *qtserv = NULL;
|
||||
int testresult = 0;
|
||||
|
||||
if (!TEST_ptr(cctx)
|
||||
|| !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert,
|
||||
privkey,
|
||||
QTEST_FLAG_FAKE_TIME,
|
||||
&qtserv, &clientquic,
|
||||
NULL, NULL))
|
||||
|| !TEST_true(qtest_create_quic_connection(qtserv, clientquic)))
|
||||
goto err;
|
||||
|
||||
if (!TEST_int_eq(SSL_get_shutdown(clientquic), 0))
|
||||
goto err;
|
||||
|
||||
if (!TEST_int_eq(SSL_shutdown(clientquic), 0))
|
||||
goto err;
|
||||
|
||||
if (!TEST_int_eq(SSL_get_shutdown(clientquic), SSL_SENT_SHUTDOWN))
|
||||
goto err;
|
||||
|
||||
do {
|
||||
ossl_quic_tserver_tick(qtserv);
|
||||
qtest_add_time(100);
|
||||
} while (SSL_shutdown(clientquic) == 0);
|
||||
|
||||
if (!TEST_int_eq(SSL_get_shutdown(clientquic),
|
||||
SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN))
|
||||
goto err;
|
||||
|
||||
testresult = 1;
|
||||
err:
|
||||
ossl_quic_tserver_free(qtserv);
|
||||
SSL_free(clientquic);
|
||||
SSL_CTX_free(cctx);
|
||||
|
||||
return testresult;
|
||||
}
|
||||
|
||||
#define MAX_LOOPS 2000
|
||||
|
||||
/*
|
||||
|
@ -1586,6 +1632,7 @@ int setup_tests(void)
|
|||
ADD_ALL_TESTS(test_client_auth, 2);
|
||||
ADD_ALL_TESTS(test_alpn, 2);
|
||||
ADD_ALL_TESTS(test_noisy_dgram, 2);
|
||||
ADD_TEST(test_get_shutdown);
|
||||
|
||||
return 1;
|
||||
err:
|
||||
|
|
Loading…
Reference in New Issue