]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
QUIC APL: Rework QCTX to support listener calls
authorHugo Landau <hlandau@openssl.org>
Thu, 11 Jan 2024 10:21:37 +0000 (10:21 +0000)
committerViktor Dukhovni <openssl-users@dukhovni.org>
Wed, 11 Sep 2024 07:32:29 +0000 (17:32 +1000)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23334)

crypto/err/openssl.txt
include/openssl/sslerr.h
ssl/quic/quic_impl.c
ssl/quic/quic_local.h
ssl/quic/quic_obj.c
ssl/quic/quic_obj_local.h
ssl/ssl_err.c

index 9b24e77a017096e31e499dd7fbf54ea380f9ca26..94a94347e65f0e17fe6606dd6bd9ec2d533b1f96 100644 (file)
@@ -1468,6 +1468,7 @@ SSL_R_LENGTH_TOO_LONG:404:length too long
 SSL_R_LENGTH_TOO_SHORT:160:length too short
 SSL_R_LIBRARY_BUG:274:library bug
 SSL_R_LIBRARY_HAS_NO_CIPHERS:161:library has no ciphers
+SSL_R_LISTENER_USE_ONLY:412:listener use only
 SSL_R_MAXIMUM_ENCRYPTED_PKTS_REACHED:395:maximum encrypted pkts reached
 SSL_R_MISSING_DSA_SIGNING_CERT:165:missing dsa signing cert
 SSL_R_MISSING_ECDSA_SIGNING_CERT:381:missing ecdsa signing cert
index d6ae547876b45dc264698e1897eab86b63fffc03..f29299ee3117482a852176153efccea4de8c4f0b 100644 (file)
 # define SSL_R_LENGTH_TOO_SHORT                           160
 # define SSL_R_LIBRARY_BUG                                274
 # define SSL_R_LIBRARY_HAS_NO_CIPHERS                     161
+# define SSL_R_LISTENER_USE_ONLY                          412
 # define SSL_R_MAXIMUM_ENCRYPTED_PKTS_REACHED             395
 # define SSL_R_MISSING_DSA_SIGNING_CERT                   165
 # define SSL_R_MISSING_ECDSA_SIGNING_CERT                 381
index 3f305e8bf71750ae3a4b083f8cfe943720b19256..338667511796cdd15f9df2e732f3b0e72062ee3d 100644 (file)
@@ -28,8 +28,8 @@ static int create_channel(QUIC_CONNECTION *qc, SSL_CTX *ctx);
 static QUIC_XSO *create_xso_from_stream(QUIC_CONNECTION *qc, QUIC_STREAM *qs);
 static int qc_try_create_default_xso_for_write(QCTX *ctx);
 static int qc_wait_for_default_xso_for_read(QCTX *ctx, int peek);
-static void quic_lock(QUIC_CONNECTION *qc);
-static void quic_unlock(QUIC_CONNECTION *qc);
+static void qctx_lock(QCTX *qctx);
+static void qctx_unlock(QCTX *qctx);
 static void quic_lock_for_io(QCTX *ctx);
 static int quic_do_handshake(QCTX *ctx);
 static void qc_update_reject_policy(QUIC_CONNECTION *qc);
@@ -102,6 +102,7 @@ static OSSL_TIME get_time_cb(void *arg)
  *   - whether a QSSO was passed (xso == NULL must not be used to determine this
  *     because it may be non-NULL when a QCSO is passed if that QCSO has a
  *     default stream);
+ *   - a pointer to a QUIC_LISTENER object, if one is relevant;
  *   - whether we are in "I/O context", meaning that non-normal errors can
  *     be reported via SSL_get_error() as well as via ERR. Functions such as
  *     SSL_read(), SSL_write() and SSL_do_handshake() are "I/O context"
@@ -111,9 +112,11 @@ static OSSL_TIME get_time_cb(void *arg)
  *     of SSL_get_error.
  */
 struct qctx_st {
+    QUIC_OBJ        *obj;
+    QUIC_LISTENER   *ql;
     QUIC_CONNECTION *qc;
     QUIC_XSO        *xso;
-    int             is_stream, in_io;
+    int             is_stream, is_listener, in_io;
 };
 
 QUIC_NEEDS_LOCK
@@ -192,21 +195,26 @@ static int quic_raise_non_normal_error(QCTX *ctx,
                                 (msg))
 
 /*
- * Given a QCSO or QSSO, initialises a QCTX, determining the contextually
- * applicable QUIC_CONNECTION pointer and, if applicable, QUIC_XSO pointer.
+ * Given a QCSO, QSSO or QLSO, initialises a QCTX, determining the contextually
+ * applicable QUIC_LISTENER, QUIC_CONNECTION, QUIC_XSO and QUIC_CONNECTION
+ * pointers.
  *
  * After this returns 1, all fields of the passed QCTX are initialised.
  * Returns 0 on failure. This function is intended to be used to provide API
  * semantics and as such, it invokes QUIC_RAISE_NON_NORMAL_ERROR() on failure.
  */
-static int expect_quic(const SSL *s, QCTX *ctx)
+static int expect_quic_any(const SSL *s, QCTX *ctx)
 {
+    QUIC_LISTENER *ql;
     QUIC_CONNECTION *qc;
     QUIC_XSO *xso;
 
-    ctx->qc         = NULL;
-    ctx->xso        = NULL;
-    ctx->is_stream  = 0;
+    ctx->obj            = NULL;
+    ctx->ql             = NULL;
+    ctx->qc             = NULL;
+    ctx->xso            = NULL;
+    ctx->is_stream      = 0;
+    ctx->is_listener    = 0;
 
     if (s == NULL)
         return QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_PASSED_NULL_PARAMETER, NULL);
@@ -214,6 +222,8 @@ static int expect_quic(const SSL *s, QCTX *ctx)
     switch (s->type) {
     case SSL_TYPE_QUIC_CONNECTION:
         qc              = (QUIC_CONNECTION *)s;
+        ctx->obj        = &qc->obj;
+        ctx->ql         = qc->listener;
         ctx->qc         = qc;
         ctx->xso        = qc->default_xso;
         ctx->is_stream  = 0;
@@ -222,17 +232,57 @@ static int expect_quic(const SSL *s, QCTX *ctx)
 
     case SSL_TYPE_QUIC_XSO:
         xso             = (QUIC_XSO *)s;
+        ctx->obj        = &xso->obj;
+        ctx->ql         = xso->conn->listener;
         ctx->qc         = xso->conn;
         ctx->xso        = xso;
         ctx->is_stream  = 1;
         ctx->in_io      = 0;
         return 1;
 
+    case SSL_TYPE_QUIC_LISTENER:
+        ql                  = (QUIC_LISTENER *)s;
+        ctx->obj            = &ql->obj;
+        ctx->ql             = ql;
+        ctx->is_listener    = 1;
+        ctx->in_io          = 0;
+        return 1;
+
     default:
         return QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
     }
 }
 
+/*
+ * Given a QCSO or QSSO, initialises a QCTX, determining the contextually
+ * applicable QUIC_CONNECTION pointer and, if applicable, QUIC_XSO pointer.
+ *
+ * After this returns 1, all fields of the passed QCTX are initialised.
+ * Returns 0 on failure. This function is intended to be used to provide API
+ * semantics and as such, it invokes QUIC_RAISE_NON_NORMAL_ERROR() on failure.
+ */
+static int expect_quic(const SSL *s, QCTX *ctx)
+{
+    if (!expect_quic_any(s, ctx))
+        return 0;
+
+    if (ctx->obj->ssl.type == SSL_TYPE_QUIC_LISTENER)
+        return QUIC_RAISE_NON_NORMAL_ERROR(NULL, SSL_R_CONN_USE_ONLY, NULL);
+
+    return 1;
+}
+
+static int expect_quic_listener(const SSL *s, QCTX *ctx)
+{
+    if (!expect_quic_any(s, ctx))
+        return 0;
+
+    if (ctx->obj->ssl.type != SSL_TYPE_QUIC_LISTENER)
+        return QUIC_RAISE_NON_NORMAL_ERROR(NULL, SSL_R_LISTENER_USE_ONLY, NULL);
+
+    return 1;
+}
+
 /*
  * Like expect_quic(), but requires a QUIC_XSO be contextually available. In
  * other words, requires that the passed QSO be a QSSO or a QCSO with a default
@@ -253,7 +303,7 @@ static int ossl_unused expect_quic_with_stream_lock(const SSL *s, int remote_ini
     if (in_io)
         quic_lock_for_io(ctx);
     else
-        quic_lock(ctx->qc);
+        qctx_lock(ctx);
 
     if (ctx->xso == NULL && remote_init >= 0) {
         if (!quic_mutation_allowed(ctx->qc, /*req_active=*/0)) {
@@ -285,7 +335,7 @@ static int ossl_unused expect_quic_with_stream_lock(const SSL *s, int remote_ini
     return 1; /* coverity[missing_unlock]: lock held */
 
 err:
-    quic_unlock(ctx->qc);
+    qctx_unlock(ctx);
     return 0;
 }
 
@@ -305,21 +355,32 @@ static int ossl_unused expect_quic_conn_only(const SSL *s, QCTX *ctx)
 }
 
 /*
- * Ensures that the channel mutex is held for a method which touches channel
+ * Ensures that the domain mutex is held for a method which touches channel
  * state.
  *
- * Precondition: Channel mutex is not held (unchecked)
+ * Precondition: Domain mutex is not held (unchecked)
  */
-static void quic_lock(QUIC_CONNECTION *qc)
+static void qctx_lock(QCTX *ctx)
+{
+#if defined(OPENSSL_THREADS)
+    assert(ctx->obj != NULL);
+    ossl_crypto_mutex_lock(ossl_quic_obj_get0_mutex(ctx->obj));
+#endif
+}
+
+/* Precondition: Channel mutex is held (unchecked) */
+QUIC_NEEDS_LOCK
+static void qctx_unlock(QCTX *ctx)
 {
 #if defined(OPENSSL_THREADS)
-    ossl_crypto_mutex_lock(qc->mutex);
+    assert(ctx->obj != NULL);
+    ossl_crypto_mutex_unlock(ossl_quic_obj_get0_mutex(ctx->obj));
 #endif
 }
 
 static void quic_lock_for_io(QCTX *ctx)
 {
-    quic_lock(ctx->qc);
+    qctx_lock(ctx);
     ctx->in_io = 1;
 
     /*
@@ -331,15 +392,6 @@ static void quic_lock_for_io(QCTX *ctx)
     quic_set_last_error(ctx, SSL_ERROR_NONE);
 }
 
-/* Precondition: Channel mutex is held (unchecked) */
-QUIC_NEEDS_LOCK
-static void quic_unlock(QUIC_CONNECTION *qc)
-{
-#if defined(OPENSSL_THREADS)
-    ossl_crypto_mutex_unlock(qc->mutex);
-#endif
-}
-
 /*
  * This predicate is the criterion which should determine API call rejection for
  * *most* mutating API calls, particularly stream-related operations for send
@@ -487,7 +539,8 @@ static void qc_cleanup(QUIC_CONNECTION *qc, int have_lock)
     qc->tls = NULL;
 
     if (have_lock)
-        quic_unlock(qc); /* tsan doesn't like freeing locked mutexes */
+        /* tsan doesn't like freeing locked mutexes */
+        ossl_crypto_mutex_unlock(qc->mutex);
 
 #if defined(OPENSSL_THREADS)
     ossl_crypto_mutex_free(&qc->mutex);
@@ -505,7 +558,7 @@ void ossl_quic_free(SSL *s)
     if (!expect_quic(s, &ctx))
         return;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     if (ctx.is_stream) {
         /*
@@ -537,7 +590,7 @@ void ossl_quic_free(SSL *s)
                                           ctx.xso->stream);
 
         is_default = (ctx.xso == ctx.qc->default_xso);
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
 
         /*
          * Unref the connection in most cases; the XSO has a ref to the QC and
@@ -560,9 +613,9 @@ void ossl_quic_free(SSL *s)
     if (ctx.qc->default_xso != NULL) {
         QUIC_XSO *xso = ctx.qc->default_xso;
 
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         SSL_free(&xso->obj.ssl);
-        quic_lock(ctx.qc);
+        qctx_lock(&ctx);
         ctx.qc->default_xso = NULL;
     }
 
@@ -629,12 +682,12 @@ int ossl_quic_conn_set_override_now_cb(SSL *s,
     if (!expect_quic(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     ctx.qc->override_now_cb     = now_cb;
     ctx.qc->override_now_cb_arg = now_cb_arg;
 
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return 1;
 }
 
@@ -752,7 +805,7 @@ static uint64_t quic_mask_or_options(SSL *ssl, uint64_t mask_value, uint64_t or_
     if (!expect_quic(ssl, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     if (!ctx.is_stream) {
         /*
@@ -781,7 +834,7 @@ static uint64_t quic_mask_or_options(SSL *ssl, uint64_t mask_value, uint64_t or_
 
     ret = ctx.is_stream ? ctx.xso->ssl_options : ctx.qc->default_ssl_options;
 
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -985,7 +1038,7 @@ int ossl_quic_conn_set_blocking_mode(SSL *s, int blocking)
     if (!expect_quic(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     /* Sanity check - can we support the request given the current network BIO? */
     if (blocking) {
@@ -1022,7 +1075,7 @@ int ossl_quic_conn_set_blocking_mode(SSL *s, int blocking)
     ret = 1;
 out:
     qc_update_blocking_mode(ctx.qc);
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -1081,10 +1134,10 @@ int ossl_quic_handle_events(SSL *s)
     if (!expect_quic(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
     if (ctx.qc->started)
         ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0);
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return 1;
 }
 
@@ -1104,7 +1157,7 @@ int ossl_quic_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite)
     if (!expect_quic(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     if (ctx.qc->started)
         deadline
@@ -1120,13 +1173,13 @@ int ossl_quic_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite)
         tv->tv_sec  = 1000000;
         tv->tv_usec = 0;
 
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return 1;
     }
 
     *tv = ossl_time_to_timeval(ossl_time_subtract(deadline, get_time(ctx.qc)));
     *is_infinite = 0;
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return 1;
 }
 
@@ -1170,9 +1223,9 @@ int ossl_quic_get_net_read_desired(SSL *s)
     if (!expect_quic(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
     ret = ossl_quic_reactor_net_read_desired(ossl_quic_channel_get_reactor(ctx.qc->ch));
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -1186,9 +1239,9 @@ int ossl_quic_get_net_write_desired(SSL *s)
     if (!expect_quic(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
     ret = ossl_quic_reactor_net_write_desired(ossl_quic_channel_get_reactor(ctx.qc->ch));
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -1272,10 +1325,10 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags,
         return -1;
     }
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     if (ossl_quic_channel_is_terminated(ctx.qc->ch)) {
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return 1;
     }
 
@@ -1296,7 +1349,7 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags,
         }
 
         if (!qc_shutdown_flush_finished(ctx.qc)) {
-            quic_unlock(ctx.qc);
+            qctx_unlock(&ctx);
             return 0; /* ongoing */
         }
     }
@@ -1338,7 +1391,7 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags,
     SSL_set_shutdown(ctx.qc->tls, SSL_SENT_SHUTDOWN);
 
     if (ossl_quic_channel_is_terminated(ctx.qc->ch)) {
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return 1;
     }
 
@@ -1356,7 +1409,7 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags,
 
     ret = ossl_quic_channel_is_terminated(ctx.qc->ch);
 err:
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -1774,7 +1827,7 @@ int ossl_quic_do_handshake(SSL *s)
     quic_lock_for_io(&ctx);
 
     ret = quic_do_handshake(&ctx);
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -2024,7 +2077,7 @@ static SSL *quic_conn_stream_new(QCTX *ctx, uint64_t flags, int need_lock)
     int advance = ((flags & SSL_STREAM_FLAG_ADVANCE) != 0);
 
     if (need_lock)
-        quic_lock(qc);
+        qctx_lock(ctx);
 
     if (!quic_mutation_allowed(qc, /*req_active=*/0)) {
         QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
@@ -2070,7 +2123,7 @@ static SSL *quic_conn_stream_new(QCTX *ctx, uint64_t flags, int need_lock)
 
     qc_touch_default_xso(qc); /* inhibits default XSO */
     if (need_lock)
-        quic_unlock(qc);
+        qctx_unlock(ctx);
 
     return &xso->obj.ssl;
 
@@ -2078,7 +2131,7 @@ err:
     OPENSSL_free(xso);
     ossl_quic_stream_map_release(ossl_quic_channel_get_qsm(qc->ch), qs);
     if (need_lock)
-        quic_unlock(qc);
+        qctx_unlock(ctx);
 
     return NULL;
 
@@ -2124,10 +2177,10 @@ int ossl_quic_get_error(const SSL *s, int i)
     if (!expect_quic(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
     net_error = ossl_quic_channel_net_error(ctx.qc->ch);
     last_error = ctx.is_stream ? ctx.xso->last_error : ctx.qc->last_error;
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
 
     if (net_error)
         return SSL_ERROR_SYSCALL;
@@ -2171,11 +2224,11 @@ int ossl_quic_want(const SSL *s)
     if (!expect_quic(s, &ctx))
         return SSL_NOTHING;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     w = error_to_want(ctx.is_stream ? ctx.xso->last_error : ctx.qc->last_error);
 
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return w;
 }
 
@@ -2608,7 +2661,7 @@ int ossl_quic_write_flags(SSL *s, const void *buf, size_t len,
         ret = quic_write_nonblocking_aon(&ctx, buf, len, flags, written);
 
 out:
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -2853,7 +2906,7 @@ static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek
     }
 
 out:
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -2881,7 +2934,7 @@ static size_t ossl_quic_pending_int(const SSL *s, int check_channel)
     if (!expect_quic(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     if (!ctx.qc->started)
         goto out;
@@ -2911,7 +2964,7 @@ static size_t ossl_quic_pending_int(const SSL *s, int check_channel)
                                               /*include_fin=*/0);
 
 out:
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return avail;
 }
 
@@ -2943,23 +2996,23 @@ int ossl_quic_conn_stream_conclude(SSL *s)
     qs = ctx.xso->stream;
 
     if (!quic_mutation_allowed(ctx.qc, /*req_active=*/1)) {
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
     }
 
     if (!quic_validate_for_write(ctx.xso, &err)) {
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL);
     }
 
     if (ossl_quic_sstream_get_final_size(qs->sstream, NULL)) {
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return 1;
     }
 
     ossl_quic_sstream_fin(qs->sstream);
     quic_post_write(ctx.xso, 1, 0, 0, qctx_should_autotick(&ctx));
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return 1;
 }
 
@@ -2980,12 +3033,12 @@ int SSL_inject_net_dgram(SSL *s, const unsigned char *buf,
     if (!expect_quic(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     demux = ossl_quic_channel_get0_demux(ctx.qc->ch);
     ret = ossl_quic_demux_inject(demux, buf, buf_len, peer, local);
 
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -3066,7 +3119,7 @@ uint64_t ossl_quic_get_stream_id(SSL *s)
         return UINT64_MAX;
 
     id = ctx.xso->stream->id;
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
 
     return id;
 }
@@ -3085,7 +3138,7 @@ int ossl_quic_is_stream_local(SSL *s)
         return -1;
 
     is_local = ossl_quic_stream_is_local_init(ctx.xso->stream);
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
 
     return is_local;
 }
@@ -3102,10 +3155,10 @@ int ossl_quic_set_default_stream_mode(SSL *s, uint32_t mode)
     if (!expect_quic_conn_only(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     if (ctx.qc->default_xso_created) {
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,
                                        "too late to change default stream mode");
     }
@@ -3117,12 +3170,12 @@ int ossl_quic_set_default_stream_mode(SSL *s, uint32_t mode)
         ctx.qc->default_stream_mode = mode;
         break;
     default:
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT,
                                        "bad default stream type");
     }
 
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return 1;
 }
 
@@ -3139,13 +3192,13 @@ SSL *ossl_quic_detach_stream(SSL *s)
     if (!expect_quic_conn_only(s, &ctx))
         return NULL;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     /* Calling this function inhibits default XSO autocreation. */
     /* QC ref to any default XSO is transferred to us and to caller. */
     qc_set_default_xso_keep_ref(ctx.qc, NULL, /*touch=*/1, &xso);
 
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
 
     return xso != NULL ? &xso->obj.ssl : NULL;
 }
@@ -3170,10 +3223,10 @@ int ossl_quic_attach_stream(SSL *conn, SSL *stream)
 
     xso = (QUIC_XSO *)stream;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     if (ctx.qc->default_xso != NULL) {
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,
                                        "connection already has a default stream");
     }
@@ -3183,13 +3236,13 @@ int ossl_quic_attach_stream(SSL *conn, SSL *stream)
      * more than one ref.
      */
     if (!CRYPTO_GET_REF(&xso->obj.ssl.references, &nref)) {
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR,
                                        "ref");
     }
 
     if (nref != 1) {
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT,
                                        "stream being attached must have "
                                        "only 1 reference");
@@ -3199,7 +3252,7 @@ int ossl_quic_attach_stream(SSL *conn, SSL *stream)
     /* Calling this function inhibits default XSO autocreation. */
     qc_set_default_xso(ctx.qc, xso, /*touch=*/1);
 
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return 1;
 }
 
@@ -3244,7 +3297,7 @@ int ossl_quic_set_incoming_stream_policy(SSL *s, int policy,
     if (!expect_quic_conn_only(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     switch (policy) {
     case SSL_INCOMING_STREAM_POLICY_AUTO:
@@ -3261,7 +3314,7 @@ int ossl_quic_set_incoming_stream_policy(SSL *s, int policy,
     }
 
     qc_update_reject_policy(ctx.qc);
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -3594,7 +3647,7 @@ SSL *ossl_quic_accept_stream(SSL *s, uint64_t flags)
     if (!expect_quic_conn_only(s, &ctx))
         return NULL;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     if (qc_get_effective_incoming_stream_policy(ctx.qc)
         == SSL_INCOMING_STREAM_POLICY_REJECT) {
@@ -3640,7 +3693,7 @@ SSL *ossl_quic_accept_stream(SSL *s, uint64_t flags)
     qc_touch_default_xso(ctx.qc); /* inhibits default XSO */
 
 out:
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return new_s;
 }
 
@@ -3657,11 +3710,11 @@ size_t ossl_quic_get_accept_stream_queue_len(SSL *s)
     if (!expect_quic_conn_only(s, &ctx))
         return 0;
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     v = ossl_quic_stream_map_get_total_accept_queue_len(ossl_quic_channel_get_qsm(ctx.qc->ch));
 
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return v;
 }
 
@@ -3696,7 +3749,7 @@ int ossl_quic_stream_reset(SSL *ssl,
         ctx.xso->requested_reset = 1;
 
 err:
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ok;
 }
 
@@ -3773,7 +3826,7 @@ static int quic_get_stream_state(SSL *ssl, int is_write)
         return SSL_STREAM_STATE_NONE;
 
     quic_classify_stream(ctx.qc, ctx.xso->stream, is_write, &state, NULL);
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return state;
 }
 
@@ -3807,7 +3860,7 @@ static int quic_get_stream_error_code(SSL *ssl, int is_write,
     quic_classify_stream(ctx.qc, ctx.xso->stream, /*is_write=*/0,
                          &state, app_error_code);
 
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     switch (state) {
         case SSL_STREAM_STATE_FINISHED:
              return 0;
@@ -3868,7 +3921,7 @@ int ossl_quic_set_write_buffer_size(SSL *ssl, size_t size)
     ret = 1;
 
 out:
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return ret;
 }
 
@@ -3927,16 +3980,16 @@ int ossl_quic_key_update(SSL *ssl, int update_type)
         return 0;
     }
 
-    quic_lock(ctx.qc);
+    qctx_lock(&ctx);
 
     /* Attempt to perform a TXKU. */
     if (!ossl_quic_channel_trigger_txku(ctx.qc->ch)) {
         QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_TOO_MANY_KEY_UPDATES, NULL);
-        quic_unlock(ctx.qc);
+        qctx_unlock(&ctx);
         return 0;
     }
 
-    quic_unlock(ctx.qc);
+    qctx_unlock(&ctx);
     return 1;
 }
 
index 1bf34f35dc0c871000e12589a872e0691a801da5..2c3bd73f1455852f5e2711dda28c6be109e63793 100644 (file)
@@ -136,6 +136,9 @@ struct quic_conn_st {
 
     SSL                             *tls;
 
+    /* The QLSO this connection belongs to, if any. */
+    QUIC_LISTENER                   *listener;
+
     /* The QUIC engine representing the QUIC event domain. */
     QUIC_ENGINE                     *engine;
 
index 2981fd4fe86da6b00b07c1b86617c684eb8dfa41..5404aa09dcfab6e23882c56fc9035b10a91cb7e6 100644 (file)
@@ -37,11 +37,11 @@ int ossl_quic_obj_init(QUIC_OBJ *obj,
     obj->parent_obj         = parent_obj;
     obj->is_event_leader    = is_event_leader;
     obj->is_port_leader     = is_port_leader;
+    obj->engine             = engine;
+    obj->port               = port;
     if (!obj_update_cache(obj))
         goto err;
 
-    obj->engine             = engine;
-    obj->port               = port;
     obj->init_done          = 1;
     return 1;
 
index c58532431cc14ab8b3819ef92ac88a622608a3a8..2b31f4b426bd6621023242e2f61005863ea5ad73 100644 (file)
@@ -165,6 +165,7 @@ static ossl_inline ossl_unused QUIC_ENGINE *
 ossl_quic_obj_get0_engine(const QUIC_OBJ *obj)
 {
     assert(obj->init_done);
+    assert(obj->engine != NULL);
     return obj->engine;
 }
 
index 3ef6afd03e6520103daec7ffa8d32cc804f89954..cf6b42436af038c7be79485ba33a3561fee44926 100644 (file)
@@ -250,6 +250,7 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LIBRARY_BUG), "library bug"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LIBRARY_HAS_NO_CIPHERS),
     "library has no ciphers"},
+    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LISTENER_USE_ONLY), "listener use only"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MAXIMUM_ENCRYPTED_PKTS_REACHED),
     "maximum encrypted pkts reached"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_DSA_SIGNING_CERT),