QUIC APL: Introduce addressed v. non-addressed mode handling

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21715)
This commit is contained in:
Hugo Landau 2023-08-09 17:46:33 +01:00
parent c20b78d599
commit 62665fc243
2 changed files with 83 additions and 7 deletions

View File

@ -816,7 +816,7 @@ uint64_t ossl_quic_get_options(const SSL *ssl)
*/
static int csm_analyse_init_peer_addr(BIO *net_wbio, BIO_ADDR *peer)
{
if (BIO_dgram_get_peer(net_wbio, peer) <= 0)
if (BIO_dgram_detect_peer_addr(net_wbio, peer) <= 0)
return 0;
return 1;
@ -1518,12 +1518,6 @@ static int quic_do_handshake(QCTX *ctx)
if (!quic_mutation_allowed(qc, /*req_active=*/0))
return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
if (BIO_ADDR_family(&qc->init_peer_addr) == AF_UNSPEC) {
/* Peer address must have been set. */
QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_REMOTE_PEER_ADDRESS_NOT_SET, NULL);
return -1; /* Non-protocol error */
}
if (qc->as_server != qc->as_server_state) {
QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_PASSED_INVALID_ARGUMENT, NULL);
return -1; /* Non-protocol error */
@ -1535,6 +1529,82 @@ static int quic_do_handshake(QCTX *ctx)
return -1; /* Non-protocol error */
}
/*
* We need to determine our addressing mode. There are basically two
* ways we can use L4 addresses:
*
* - Addressed mode, in which our BIO_sendmmsg calls have destination
* addresses attached to them which we expect the underlying network BIO
* to handle;
*
* - Unaddressed mode, in which the BIO provided to us on the
* network side neither provides us with L4 addresses nor is capable of
* honouring ones we provide. We don't know where the QUIC traffic we
* send ends up exactly and trust the application to know what it is
* doing.
*
* Addressed mode is preferred because it enables support for connection
* migration, multipath, etc. in the future. Addressed mode is automatically
* enabled if we are using e.g. BIO_s_datagram, with or without
* BIO_s_connect.
*
* If we are passed a BIO_s_dgram_pair (or some custom BIO) we may have to
* use unaddressed mode unless that BIO supports capability flags indicating
* it can provide and honour L4 addresses.
*
* Our strategy for determining address mode is simple: we probe the
* underlying network BIOs for their capabilities. If the network BIOs
* support what we need, we use addressed mode. Otherwise, we use
* unaddressed mode.
*
* If addressed mode is chosen, we require an initial peer address to be
* set. If this is not set, we fail. If unaddressed mode is used, we do not
* require this, as such an address is superfluous, though it can be set if
* desired.
*/
if (!qc->started && !qc->addressing_probe_done) {
long rcaps = BIO_dgram_get_effective_caps(qc->net_rbio);
long wcaps = BIO_dgram_get_effective_caps(qc->net_wbio);
int can_use_addressed =
(wcaps & BIO_DGRAM_CAP_HANDLES_DST_ADDR) != 0
&& (rcaps & BIO_DGRAM_CAP_PROVIDES_SRC_ADDR) != 0;
qc->addressed_mode = can_use_addressed;
qc->addressing_probe_done = 1;
}
if (!qc->started && qc->addressed_mode
&& BIO_ADDR_family(&qc->init_peer_addr) == AF_UNSPEC) {
/*
* We are trying to connect and are using addressed mode, which means we
* need an initial peer address; if we do not have a peer address yet,
* we should try to autodetect one.
*
* We do this as late as possible because some BIOs (e.g. BIO_s_connect)
* may not be able to provide us with a peer address until they have
* finished their own processing. They may not be able to perform this
* processing until an application has figured configuring that BIO
* (e.g. with setter calls), which might happen after SSL_set_bio is
* called.
*/
if (!csm_analyse_init_peer_addr(qc->net_wbio, &qc->init_peer_addr))
/* best effort */
BIO_ADDR_clear(&qc->init_peer_addr);
else
ossl_quic_channel_set_peer_addr(qc->ch, &qc->init_peer_addr);
}
if (!qc->started
&& qc->addressed_mode
&& BIO_ADDR_family(&qc->init_peer_addr) == AF_UNSPEC) {
/*
* If we still don't have a peer address in addressed mode, we can't do
* anything.
*/
QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_REMOTE_PEER_ADDRESS_NOT_SET, NULL);
return -1; /* Non-protocol error */
}
/*
* Start connection process. Note we may come here multiple times in
* non-blocking mode, which is fine.

View File

@ -195,6 +195,12 @@ struct quic_conn_st {
*/
unsigned int shutting_down : 1;
/* Have we probed the BIOs for addressing support? */
unsigned int addressing_probe_done : 1;
/* Are we using addressed mode (BIO_sendmmsg with non-NULL peer)? */
unsigned int addressed_mode : 1;
/* Default stream type. Defaults to SSL_DEFAULT_STREAM_MODE_AUTO_BIDI. */
uint32_t default_stream_mode;