]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
QUIC: Base client/server identity on SSL method, not SSL_set_connect/accept_state
authorHugo Landau <hlandau@openssl.org>
Tue, 18 Apr 2023 18:30:54 +0000 (19:30 +0100)
committerHugo Landau <hlandau@openssl.org>
Fri, 12 May 2023 13:47:10 +0000 (14:47 +0100)
In QUIC, we have an architectural need (in future, when we implement
0-RTT, etc.) to be able to create streams before we start connecting.
This requires we allocate a stream, including a stream ID, after
creating a QCSO but prior to connecting. However stream IDs are
dependent on whether the endpoint is in the client or server role,
therefore we must know whether we are going to be a client or server
before any pre-connection streams are created. Moreover, the originally
defined QUIC_client_method() and QUIC_server_method() functions heavily
implied the original plan was to have different SSL_METHODs for clients
and servers. Up until now we had been relying on
SSL_set_connect/accept_state() instead.

Solve these problems by basing client/server identity on whether
QUIC_server_method() is used (in future, when we support servers). This
ensures that once a QCSO is created its client/server identity are fixed
and cannot change, allowing pre-connection stream IDs, etc. to be
allocated.

Client/server uncertainty was the primary reason why QUIC_CHANNEL
creation was deferred until connection time up until now, so this
enables further refactoring to facilitate eager allocation of the
QUIC_CHANNEL at QCSO allocation time. This is important as allocating a
stream including its write buffers is hard without having the
QUIC_CHANNEL (which owns the QUIC_STREAM_MAP) in existence.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20765)

ssl/quic/quic_impl.c
ssl/quic/quic_local.h

index 106e4b30235f342af7cb24d8e086555c47dc8acb..52fce3ea4584c12bda9d447d7d11de2c53519e2f 100644 (file)
@@ -247,6 +247,9 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
     qc->is_thread_assisted
         = (ssl_base->method == OSSL_QUIC_client_thread_method());
 
+    qc->as_server       = 0; /* TODO(QUIC): server support */
+    qc->as_server_state = qc->as_server;
+
     /* Channel is not created yet. */
     qc->ssl_mode   = qc->ssl.ctx->mode;
     qc->last_error = SSL_ERROR_NONE;
@@ -803,7 +806,7 @@ void ossl_quic_set_connect_state(SSL *s)
     if (ctx.qc->started)
         return;
 
-    ctx.qc->as_server = 0;
+    ctx.qc->as_server_state = 0;
 }
 
 /* SSL_set_accept_state */
@@ -818,7 +821,7 @@ void ossl_quic_set_accept_state(SSL *s)
     if (ctx.qc->started)
         return;
 
-    ctx.qc->as_server = 1;
+    ctx.qc->as_server_state = 1;
 }
 
 /* SSL_do_handshake */
@@ -926,7 +929,7 @@ static int quic_do_handshake(QUIC_CONNECTION *qc)
         return -1; /* Non-protocol error */
     }
 
-    if (qc->as_server) {
+    if (qc->as_server != qc->as_server_state) {
         /* TODO(QUIC): Server mode not currently supported */
         QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_PASSED_INVALID_ARGUMENT, NULL);
         return -1; /* Non-protocol error */
index a1e84e6854e76e3202ad65f485be7d270e976def..903e681008f8b51eecfcbc6d3800b56a5ed44f62 100644 (file)
@@ -86,11 +86,17 @@ struct quic_conn_st {
     unsigned int                    can_poll_net_wbio       : 1;
 
     /*
-     * Has the application called SSL_set_accept_state? We do not support this
-     * but track it here so we can reject a subsequent handshake call.
+     * This is 1 if we were instantiated using a QUIC server method
+     * (for future use).
      */
     unsigned int                    as_server               : 1;
 
+    /*
+     * Has the application called SSL_set_accept_state? We require this to be
+     * congruent with the value of as_server.
+     */
+    unsigned int                    as_server_state         : 1;
+
     /* Are we using thread assisted mode? Never changes after init. */
     unsigned int                    is_thread_assisted      : 1;