]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic-be: get rid of ->li quic_conn member
authorFrederic Lecaille <flecaille@haproxy.com>
Fri, 6 Jun 2025 13:20:00 +0000 (15:20 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 11 Jun 2025 16:37:34 +0000 (18:37 +0200)
Replace ->li quic_conn pointer to struct listener member by  ->target which is
an object type enum and adapt the code.
Use __objt_(listener|server)() where the object type is known. Typically
this is were the code which is specific to one connection type (frontend/backend).
Remove <server> parameter passed to qc_new_conn(). It is redundant with the
<target> parameter.
GSO is not supported at this time for QUIC backend. qc_prep_pkts() is modified
to prevent it from building more than an MTU. This has as consequence to prevent
qc_send_ppkts() to use GSO.
ssl_clienthello.c code is run only by listeners. This is why __objt_listener()
is used in place of ->li.

14 files changed:
include/haproxy/quic_conn-t.h
include/haproxy/quic_conn.h
include/haproxy/quic_sock.h
src/cli.c
src/quic_cli.c
src/quic_conn.c
src/quic_rx.c
src/quic_sock.c
src/quic_ssl.c
src/quic_tx.c
src/ssl_clienthello.c
src/ssl_ocsp.c
src/ssl_sock.c
src/xprt_quic.c

index a8ffd9e7a5e24f1e28c988800c0973b98342243a..6720f2f9aee875433f5b4de7f0e60c7b70b59b65 100644 (file)
@@ -319,7 +319,7 @@ struct qcc_app_ops;
          * with a connection                                                   \
          */                                                                    \
         struct eb_root *cids;                                                  \
-        struct listener *li; /* only valid for frontend connections */         \
+        enum obj_type *target;                                                 \
         /* Idle timer task */                                                  \
         struct task *idle_timer_task;                                          \
         unsigned int idle_expire;                                              \
index 409ebf2c3701023fbc065038890e97667099bd29..9bc073df384121a3a751cfe990ed4a16a7844787 100644 (file)
@@ -69,7 +69,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
                               struct quic_connection_id *conn_id,
                               struct sockaddr_storage *local_addr,
                               struct sockaddr_storage *peer_addr,
-                              int server, int token, void *owner,
+                              int token, void *owner,
                               struct connection *conn);
 int quic_build_post_handshake_frames(struct quic_conn *qc);
 const struct quic_version *qc_supported_version(uint32_t version);
@@ -164,13 +164,6 @@ static inline void quic_free_ncbuf(struct ncbuf *ncbuf)
        *ncbuf = NCBUF_NULL;
 }
 
-/* Return the address of the connection owner object type. */
-static inline enum obj_type *qc_owner_obj_type(struct quic_conn *qc)
-{
-       return qc_is_listener(qc) ? &qc->li->obj_type :
-               &objt_server(qc->conn->target)->obj_type;
-}
-
 /* Return the address of the QUIC counters attached to the proxy of
  * the owner of the connection whose object type address is <o> for
  * listener and servers, or NULL for others object type.
index 66f24c58e137b1133b75858cbf0d97bbdb602512..d8b45ec323f3897de87010fb94f0eec51554de74 100644 (file)
@@ -33,6 +33,7 @@
 #include <haproxy/connection-t.h>
 #include <haproxy/fd-t.h>
 #include <haproxy/listener-t.h>
+#include <haproxy/obj_type.h>
 #include <haproxy/quic_conn-t.h>
 #include <haproxy/quic_sock-t.h>
 
@@ -78,7 +79,8 @@ static inline char qc_test_fd(struct quic_conn *qc)
  */
 static inline int qc_fd(struct quic_conn *qc)
 {
-       return qc_test_fd(qc) ? qc->fd : qc->li->rx.fd;
+       /* TODO: check this: For backends, qc->fd is always initialized */
+       return qc_test_fd(qc) ? qc->fd : __objt_listener(qc->target)->rx.fd;
 }
 
 /* Try to increment <l> handshake current counter. If listener limit is
index 5ad88d48da4ff5e10fb90172be543d5513f65c85..49e8e3502d776a555bc48225a122c15064fae664 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -1423,7 +1423,8 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
 #if defined(USE_QUIC)
                else if (fdt.iocb == quic_conn_sock_fd_iocb) {
                        qc = fdtab[fd].owner;
-                       li = qc ? qc->li : NULL;
+                       li = qc ? objt_listener(qc->target) : NULL;
+                       sv = qc ? objt_server(qc->target) : NULL;
                        xprt_ctx   = qc ? qc->xprt_ctx : NULL;
                        conn = qc ? qc->conn : NULL;
                        xprt = conn ? conn->xprt : NULL; // in fact it's &ssl_quic
index e3a41e61e9bc3d5d832c738c026eb028663c36b1..d0300f847b873b7d02e4fa327b89f3ca866397c0 100644 (file)
@@ -4,7 +4,7 @@
 #include <haproxy/cli.h>
 #include <haproxy/list.h>
 #include <haproxy/mux_quic.h>
-#include <haproxy/quic_conn-t.h>
+#include <haproxy/quic_conn.h>
 #include <haproxy/quic_tp.h>
 #include <haproxy/quic_utils.h>
 #include <haproxy/tools.h>
@@ -181,9 +181,11 @@ static void dump_quic_oneline(struct show_quic_ctx *ctx, struct quic_conn *qc)
        char bufaddr[INET6_ADDRSTRLEN], bufport[6];
        int ret;
        unsigned char cid_len;
+       struct listener *l = objt_listener(qc->target);
 
        ret = chunk_appendf(&trash, "%p[%02u]/%-.12s ", qc, ctx->thr,
-                           qc->li->bind_conf->frontend->id);
+                           l ? l->bind_conf->frontend->id : __objt_server(qc->target)->id);
+
        chunk_appendf(&trash, "%*s", 36 - ret, " "); /* align output */
 
        /* State */
index dc4f1691f27c8bd610b27072ea23db02cd87c5c7..2cb9fde9f410c0d49125350a0f830b5f02aed55f 100644 (file)
@@ -749,7 +749,7 @@ static struct quic_conn_closed *qc_new_cc_conn(struct quic_conn *qc)
        cc_qc->dcid = qc->dcid;
        cc_qc->scid = qc->scid;
 
-       cc_qc->li = qc->li;
+       cc_qc->target = qc->target;
        cc_qc->cids = qc->cids;
 
        cc_qc->idle_timer_task = qc->idle_timer_task;
@@ -1067,27 +1067,18 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
                               struct quic_connection_id *conn_id,
                               struct sockaddr_storage *local_addr,
                               struct sockaddr_storage *peer_addr,
-                              int server, int token, void *owner,
+                              int token, void *target,
                               struct connection *conn)
 {
        struct quic_conn *qc = NULL;
-       struct listener *l = NULL;
-       struct server *srv = NULL;
-       struct proxy *prx = NULL;
+       struct listener *l = objt_listener(target);
+       struct server *srv = objt_server(target);
+       struct proxy *prx = l ? l->bind_conf->frontend : __objt_server(target)->proxy;
        struct quic_cc_algo *cc_algo = NULL;
        unsigned int next_actconn = 0, next_sslconn = 0, next_handshake = 0;
 
        TRACE_ENTER(QUIC_EV_CONN_INIT);
 
-       if (server) {
-               l = owner;
-               prx = l->bind_conf->frontend;
-       }
-       else {
-               srv = owner;
-               prx = srv->proxy;
-       }
-
        next_actconn = increment_actconn();
        if (!next_actconn) {
                _HA_ATOMIC_INC(&maxconn_reached);
@@ -1101,7 +1092,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
                goto err;
        }
 
-       if (server) {
+       if (l) {
                next_handshake = quic_increment_curr_handshake(l);
                if (!next_handshake) {
                        TRACE_STATE("max handshake reached", QUIC_EV_CONN_INIT);
@@ -1121,6 +1112,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
                goto err;
        }
 
+       qc->target = target;
        *qc->cids = EB_ROOT;
        /* Now that quic_conn instance is allocated, quic_conn_release() will
         * ensure global accounting is decremented.
@@ -1176,7 +1168,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
        qc->prx_counters = EXTRA_COUNTERS_GET(prx->extra_counters_fe, &quic_stats_module);
 
        /* QUIC Server (or listener). */
-       if (server) {
+       if (l) {
                cc_algo = l->bind_conf->quic_cc_algo;
 
                qc->flags = QUIC_FL_CONN_LISTENER;
@@ -1189,7 +1181,6 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
                /* Copy the packet SCID to reuse it as DCID for sending */
                qc->dcid = *scid;
                qc->tx.buf = BUF_NULL;
-               qc->li = l;
                conn_id->qc = qc;
        }
        /* QUIC Client (outgoing connection to servers) */
@@ -1218,7 +1209,6 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
                conn_id = conn_cid;
 
                qc->tx.buf = BUF_NULL;
-               qc->li = NULL;
                qc->next_cid_seq_num = 1;
                conn->handle.qc = qc;
        }
@@ -1228,7 +1218,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
        /* Listener only: if connection is instantiated due to an INITIAL packet with an
         * already checked token, consider the peer address as validated.
         */
-       if (server) {
+       if (l) {
                if (token_odcid->len) {
                        TRACE_STATE("validate peer address due to initial token",
                                                QUIC_EV_CONN_INIT, qc);
@@ -1301,7 +1291,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
        qc->max_ack_delay = 0;
        /* Only one path at this time (multipath not supported) */
        qc->path = &qc->paths[0];
-       quic_cc_path_init(qc->path, ipv4, server ? l->bind_conf->max_cwnd : 0,
+       quic_cc_path_init(qc->path, ipv4, l ? l->bind_conf->max_cwnd : 0,
                          cc_algo ? cc_algo : default_quic_cc_algo, qc);
 
        if (local_addr)
@@ -1310,7 +1300,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
                memset(&qc->local_addr, 0, sizeof(qc->local_addr));
        memcpy(&qc->peer_addr, peer_addr, sizeof qc->peer_addr);
 
-       if (server) {
+       if (l) {
                qc_lstnr_params_init(qc, &l->bind_conf->quic_params,
                                     conn_id->stateless_reset_token,
                                     qc->dcid.data, qc->dcid.len,
@@ -1344,7 +1334,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
            !quic_conn_init_idle_timer_task(qc, prx))
                goto err;
 
-       if (!qc_new_isecs(qc, &qc->iel->tls_ctx, qc->original_version, dcid->data, dcid->len, server))
+       if (!qc_new_isecs(qc, &qc->iel->tls_ctx, qc->original_version, dcid->data, dcid->len, !!l))
                goto err;
 
        /* Counters initialization */
@@ -1395,7 +1385,7 @@ int qc_handle_conn_migration(struct quic_conn *qc,
         * used during the handshake, unless the endpoint has acted on a
         * preferred_address transport parameter from the peer.
         */
-       if (qc->li->bind_conf->quic_params.disable_active_migration) {
+       if (__objt_listener(qc->target)->bind_conf->quic_params.disable_active_migration) {
                TRACE_ERROR("Active migration was disabled, datagram dropped", QUIC_EV_CONN_LPKT, qc);
                goto err;
        }
@@ -1525,8 +1515,8 @@ int quic_conn_release(struct quic_conn *qc)
         */
        if (MT_LIST_INLIST(&qc->accept_list)) {
                MT_LIST_DELETE(&qc->accept_list);
-               BUG_ON(qc->li->rx.quic_curr_accept == 0);
-               HA_ATOMIC_DEC(&qc->li->rx.quic_curr_accept);
+               BUG_ON(__objt_listener(qc->target)->rx.quic_curr_accept == 0);
+               HA_ATOMIC_DEC(&__objt_listener(qc->target)->rx.quic_curr_accept);
        }
 
        /* Substract last congestion window from global memory counter. */
@@ -1596,8 +1586,8 @@ int quic_conn_release(struct quic_conn *qc)
        /* Connection released before handshake completion. */
        if (unlikely(qc->state < QUIC_HS_ST_COMPLETE)) {
                if (qc_is_listener(qc)) {
-                       BUG_ON(qc->li->rx.quic_curr_handshake == 0);
-                       HA_ATOMIC_DEC(&qc->li->rx.quic_curr_handshake);
+                       BUG_ON(__objt_listener(qc->target)->rx.quic_curr_handshake == 0);
+                       HA_ATOMIC_DEC(&__objt_listener(qc->target)->rx.quic_curr_handshake);
                }
        }
 
@@ -2005,8 +1995,8 @@ void qc_bind_tid_commit(struct quic_conn *qc, struct listener *new_li)
        /* At this point no connection was accounted for yet on this
         * listener so it's OK to just swap the pointer.
         */
-       if (new_li && new_li != qc->li)
-               qc->li = new_li;
+       if (new_li && new_li != __objt_listener(qc->target))
+               qc->target = &new_li->obj_type;
 
        /* Rebind the connection FD. */
        if (qc_test_fd(qc)) {
index 3b6a678d66c17094750995d51dfa48dae8ca4683..b705d414d2c52275e5d478cd161d67bc05f3414e 100644 (file)
@@ -1819,7 +1819,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
                                goto err;
 
                        qc = qc_new_conn(pkt->version, ipv4, &pkt->dcid, &pkt->scid, &token_odcid,
-                                        conn_id, &dgram->daddr, &pkt->saddr, 1,
+                                        conn_id, &dgram->daddr, &pkt->saddr,
                                         !!pkt->token_len, l, NULL);
                        if (qc == NULL) {
                                pool_free(pool_head_quic_connection_id, conn_id);
index f3c6341ce3be4ceffcfbce99de58d436d0ca4278..490e5bfb00ef27fe8c30e1847476ce9cad9f569c 100644 (file)
@@ -87,13 +87,13 @@ int quic_sock_get_dst(struct connection *conn, struct sockaddr *addr, socklen_t
                memcpy(addr, &qc->peer_addr, len);
        } else {
                struct sockaddr_storage *from;
+               struct listener *l = objt_listener(qc->target);
 
                /* Return listener address if IP_PKTINFO or friends are not
                 * supported by the socket.
                 */
-               BUG_ON(!qc->li);
-               from = is_addr(&qc->local_addr) ? &qc->local_addr :
-                                                 &qc->li->rx.addr;
+               BUG_ON(!l);
+               from = is_addr(&qc->local_addr) ? &qc->local_addr : &l->rx.addr;
                if (len > sizeof(*from))
                        len = sizeof(*from);
                memcpy(addr, from, len);
@@ -819,6 +819,7 @@ int qc_rcv_buf(struct quic_conn *qc)
        struct buffer buf = BUF_NULL;
        unsigned char *dgram_buf;
        ssize_t ret = 0;
+       struct listener *l = objt_listener(qc->target);
 
        /* Do not call this if quic-conn FD is uninitialized. */
        BUG_ON(qc->fd < 0);
@@ -869,7 +870,7 @@ int qc_rcv_buf(struct quic_conn *qc)
                        continue;
                }
 
-               if (qc_is_listener(qc) && !qc_check_dcid(qc, new_dgram->dcid, new_dgram->dcid_len)) {
+               if (l && !qc_check_dcid(qc, new_dgram->dcid, new_dgram->dcid_len)) {
                        /* Datagram received by error on the connection FD, dispatch it
                         * to its associated quic-conn.
                         *
@@ -879,7 +880,6 @@ int qc_rcv_buf(struct quic_conn *qc)
                        struct quic_dgram *tmp_dgram;
                        unsigned char *rxbuf_tail;
                        size_t cspace;
-                       struct listener *l = qc->li;
 
                        TRACE_STATE("datagram for other connection on quic-conn socket, requeue it", QUIC_EV_CONN_RCV, qc);
 
@@ -928,7 +928,7 @@ int qc_rcv_buf(struct quic_conn *qc)
                        continue;
                }
 
-               quic_dgram_parse(new_dgram, qc, qc_owner_obj_type(qc));
+               quic_dgram_parse(new_dgram, qc, qc->target);
                /* A datagram must always be consumed after quic_parse_dgram(). */
                BUG_ON(new_dgram->buf);
        } while (ret > 0);
@@ -950,11 +950,13 @@ int qc_rcv_buf(struct quic_conn *qc)
  *
  * Return the socket FD or a negative error code. On error, socket is marked as
  * uninitialized.
+ * Note: This function must not be run for backends connection.
  */
 void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src,
                  const struct sockaddr_storage *dst)
 {
-       struct bind_conf *bc = qc->li->bind_conf;
+       struct listener *l = __objt_listener(qc->target);
+       struct bind_conf *bc = l->bind_conf;
        struct proxy *p = bc->frontend;
        int fd = -1;
        int ret;
@@ -1007,7 +1009,7 @@ void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src,
                        }
 
                        /* Fallback to listener socket for this receiver instance. */
-                       HA_ATOMIC_STORE(&qc->li->rx.quic_mode, QUIC_SOCK_MODE_LSTNR);
+                       HA_ATOMIC_STORE(&l->rx.quic_mode, QUIC_SOCK_MODE_LSTNR);
                }
                goto err;
        }
@@ -1061,13 +1063,14 @@ struct quic_accept_queue *quic_accept_queues;
 void quic_accept_push_qc(struct quic_conn *qc)
 {
        struct quic_accept_queue *queue = &quic_accept_queues[tid];
-       struct li_per_thread *lthr = &qc->li->per_thr[ti->ltid];
+       struct listener *l = __objt_listener(qc->target);
+       struct li_per_thread *lthr = &l->per_thr[ti->ltid];
 
        /* A connection must only be accepted once per instance. */
        BUG_ON(qc->flags & QUIC_FL_CONN_ACCEPT_REGISTERED);
 
        BUG_ON(MT_LIST_INLIST(&qc->accept_list));
-       HA_ATOMIC_INC(&qc->li->rx.quic_curr_accept);
+       HA_ATOMIC_INC(&l->rx.quic_curr_accept);
 
        qc->flags |= QUIC_FL_CONN_ACCEPT_REGISTERED;
        /* 1. insert the listener in the accept queue
index 7a1b5c9e2fd94b727c3f5368fb95c9bf044d7aeb..a600e6d69c06be4d912b2c4ebbecdc043c5c794b 100644 (file)
@@ -937,14 +937,16 @@ static int qc_ssl_provide_quic_data(struct ncbuf *ncbuf,
                 * provided by the stack. This happens after having received the peer
                 * handshake level CRYPTO data which are validated by the TLS stack.
                 */
-               if (qc->li->bind_conf->ssl_conf.early_data &&
-                   (!qc->ael || !qc->ael->tls_ctx.rx.secret)) {
-                       TRACE_PROTO("SSL handshake in progress",
-                                   QUIC_EV_CONN_IO_CB, qc, &state, &ssl_err);
-                       goto out;
-               }
-               else {
-                       TRACE_PROTO("SSL handshake OK", QUIC_EV_CONN_IO_CB, qc, &state);
+               if (qc_is_listener(qc)) {
+                       if (__objt_listener(qc->target)->bind_conf->ssl_conf.early_data &&
+                               (!qc->ael || !qc->ael->tls_ctx.rx.secret)) {
+                               TRACE_PROTO("SSL handshake in progress",
+                                           QUIC_EV_CONN_IO_CB, qc, &state, &ssl_err);
+                               goto out;
+                       }
+                       else {
+                               TRACE_PROTO("SSL handshake OK", QUIC_EV_CONN_IO_CB, qc, &state);
+                       }
                }
 #endif
 
@@ -957,6 +959,7 @@ static int qc_ssl_provide_quic_data(struct ncbuf *ncbuf,
 
                qc->flags |= QUIC_FL_CONN_NEED_POST_HANDSHAKE_FRMS;
                if (qc_is_listener(ctx->qc)) {
+                       struct listener *l = __objt_listener(qc->target);
                        /* I/O callback switch */
                        qc->wait_event.tasklet->process = quic_conn_app_io_cb;
                        qc->state = QUIC_HS_ST_CONFIRMED;
@@ -972,8 +975,8 @@ static int qc_ssl_provide_quic_data(struct ncbuf *ncbuf,
                                tasklet_wakeup(qc->wait_event.tasklet);
                        }
 
-                       BUG_ON(qc->li->rx.quic_curr_handshake == 0);
-                       HA_ATOMIC_DEC(&qc->li->rx.quic_curr_handshake);
+                       BUG_ON(l->rx.quic_curr_handshake == 0);
+                       HA_ATOMIC_DEC(&l->rx.quic_curr_handshake);
                }
                else {
                        qc->state = QUIC_HS_ST_COMPLETE;
@@ -1201,7 +1204,7 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc, struct connection *conn)
        ctx->qc = qc;
 
        if (qc_is_listener(qc)) {
-               struct bind_conf *bc = qc->li->bind_conf;
+               struct bind_conf *bc = __objt_listener(qc->target)->bind_conf;
 
                if (qc_ssl_sess_init(qc, bc->initial_ctx, &ctx->ssl, NULL, 1) == -1)
                        goto err;
index 919fb12825eb356dbec77a81145d37dc3a080f91..e36bb2fdfc2066b187a9c99df8cf6aa5351500ea 100644 (file)
@@ -288,8 +288,10 @@ static int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
        int ret = 0;
        struct quic_conn *qc;
        char skip_sendto = 0;
+       struct listener *l;
 
        qc = ctx->qc;
+       l = objt_listener(qc->target);
        TRACE_ENTER(QUIC_EV_CONN_SPPKTS, qc);
        while (b_contig_data(buf, 0)) {
                unsigned char *pos;
@@ -305,7 +307,11 @@ static int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
 
                /* If datagram bigger than MTU, several ones were encoded for GSO usage. */
                if (dglen > qc->path->mtu) {
-                       if (likely(!(HA_ATOMIC_LOAD(&qc->li->flags) & LI_F_UDP_GSO_NOTSUPP))) {
+                       /* TODO: note that at this time for connection to backends this
+                        * part is not run because no more than an MTU has been prepared for
+                        * such connections (dglen <= qc->path->mtu). So, here l is not NULL.
+                        */
+                       if (likely(!(HA_ATOMIC_LOAD(&l->flags) & LI_F_UDP_GSO_NOTSUPP))) {
                                TRACE_PROTO("send multiple datagrams with GSO", QUIC_EV_CONN_SPPKTS, qc);
                                gso = qc->path->mtu;
                        }
@@ -327,11 +333,15 @@ static int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
                        int ret = qc_snd_buf(qc, &tmpbuf, tmpbuf.data, 0, gso);
                        if (ret < 0) {
                                if (gso && ret == -EIO) {
+                                       /* TODO: note that at this time for connection to backends this
+                                        * part is not run because no more than an MTU has been
+                                        * prepared for such connections (l is not NULL).
+                                        */
                                        /* Disable permanently UDP GSO for this listener.
                                         * Retry standard emission.
                                         */
                                        TRACE_ERROR("mark listener UDP GSO as unsupported", QUIC_EV_CONN_SPPKTS, qc, first_pkt);
-                                       HA_ATOMIC_OR(&qc->li->flags, LI_F_UDP_GSO_NOTSUPP);
+                                       HA_ATOMIC_OR(&l->flags, LI_F_UDP_GSO_NOTSUPP);
                                        continue;
                                }
 
@@ -576,6 +586,7 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf,
        int dgram_cnt = 0;
        /* Restrict GSO emission to comply with sendmsg limitation. See QUIC_MAX_GSO_DGRAMS for more details. */
        uchar gso_dgram_cnt = 0;
+       struct listener *l = objt_listener(qc->target);
 
        TRACE_ENTER(QUIC_EV_CONN_IO_CB, qc);
        /* Currently qc_prep_pkts() does not handle buffer wrapping so the
@@ -765,11 +776,13 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf,
                                prv_pkt = cur_pkt;
                        }
                        else if (!(quic_tune.options & QUIC_TUNE_NO_UDP_GSO) &&
-                                !(HA_ATOMIC_LOAD(&qc->li->flags) & LI_F_UDP_GSO_NOTSUPP) &&
                                 dglen == qc->path->mtu &&
                                 (char *)end < b_wrap(buf) &&
-                                ++gso_dgram_cnt < QUIC_MAX_GSO_DGRAMS) {
-
+                                ++gso_dgram_cnt < QUIC_MAX_GSO_DGRAMS &&
+                                l && !(HA_ATOMIC_LOAD(&l->flags) & LI_F_UDP_GSO_NOTSUPP)) {
+                               /* TODO: note that for backends GSO is not used. No more than
+                                * an MTU is prepared.
+                                */
                                /* A datagram covering the full MTU has been
                                 * built, use GSO to built next entry. Do not
                                 * reserve extra space for datagram header.
index 19f1411549fcc1af456ab7c56a92c7aa18833509..ca0d6fb276958e2c2c8ad10be428261c19bf9751 100644 (file)
@@ -177,7 +177,7 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
                s = __objt_listener(conn->target)->bind_conf;
 #ifdef USE_QUIC
        else if (qc)
-               s = qc->li->bind_conf;
+               s = __objt_listener(qc->target)->bind_conf;
 #endif /* USE_QUIC */
 
        if (!s) {
index a6355e6f096f632e70381c8886bbe3dfae4a87fb..d8d85a76ca147613feb14c3e283c1c68642f438e 100644 (file)
@@ -127,7 +127,7 @@ int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
                struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
 
                /* null if not a listener */
-               li = qc->li;
+               li = objt_listener(qc->target);
        }
 #endif
 
index 663a14da42a0770bbb4ae403495e32935bf6c241..6c787d7b790432ad515edda95da304e78a962cec 100644 (file)
@@ -926,7 +926,7 @@ static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned
                ref  = __objt_listener(conn->target)->bind_conf->keys_ref;
 #ifdef USE_QUIC
        else if (qc)
-               ref =  qc->li->bind_conf->keys_ref;
+               ref =  __objt_listener(qc->target)->bind_conf->keys_ref;
 #endif
 
        if (!ref) {
@@ -1482,7 +1482,7 @@ int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
        else {
                qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
                BUG_ON(!qc); /* Must never happen */
-               bind_conf = qc->li->bind_conf;
+               bind_conf = __objt_listener(qc->target)->bind_conf;
                ctx = qc->xprt_ctx;
        }
 #endif
index 1575f36455e61c1865560d5cad22b283a4b35051..02da5efc3935dfb4e2115f3215945cd219139598 100644 (file)
@@ -123,7 +123,7 @@ static int qc_conn_init(struct connection *conn, void **xprt_ctx)
                int ipv4 = conn->dst->ss_family == AF_INET;
                struct server *srv = objt_server(conn->target);
                qc = qc_new_conn(quic_version_1, ipv4, NULL, NULL, NULL,
-                                NULL, NULL, &srv->addr, 0, 0, srv, conn);
+                                NULL, NULL, &srv->addr, 0, srv, conn);
        }
 
        if (!qc)