From: Amaury Denoyelle Date: Wed, 6 Aug 2025 14:19:38 +0000 (+0200) Subject: MINOR: quic: prefer qc_is_back() usage over qc->target X-Git-Tag: v3.3-dev7~62 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=731b52ded958fd814ec21d3f19053fab0eaee86e;p=thirdparty%2Fhaproxy.git MINOR: quic: prefer qc_is_back() usage over qc->target Previously quic_conn member was used to determine if quic_conn was used on the frontend (as server) or backend side (as client). A new helper function can now be used to directly check flag QUIC_FL_CONN_IS_BACK. This reduces the dependency between quic_conn and their relative listener/server instances. --- diff --git a/src/quic_conn.c b/src/quic_conn.c index 2917ad062..340b85a1a 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -151,7 +151,7 @@ static int quic_conn_init_idle_timer_task(struct quic_conn *qc, struct proxy *px /* Returns 1 if the peer has validated QUIC connection address, 0 if not. */ int quic_peer_validated_addr(struct quic_conn *qc) { - if (objt_server(qc->target)) + if (qc_is_back(qc)) return 1; if (qc->flags & QUIC_FL_CONN_PEER_VALIDATED_ADDR) @@ -478,7 +478,7 @@ int quic_build_post_handshake_frames(struct quic_conn *qc) qel = qc->ael; /* Only servers must send a HANDSHAKE_DONE frame. */ - if (objt_listener(qc->target)) { + if (!qc_is_back(qc)) { size_t new_token_frm_len; frm = qc_frm_alloc(QUIC_FT_HANDSHAKE_DONE); @@ -825,7 +825,7 @@ struct task *quic_conn_io_cb(struct task *t, void *context, unsigned int state) st = qc->state; - if (objt_listener(qc->target)) { + if (!qc_is_back(qc)) { if (st >= QUIC_HS_ST_COMPLETE && !quic_tls_pktns_is_dcd(qc, qc->hpktns)) discard_hpktns = 1; } @@ -841,13 +841,13 @@ struct task *quic_conn_io_cb(struct task *t, void *context, unsigned int state) qc_set_timer(qc); qc_el_rx_pkts_del(qc->hel); qc_release_pktns_frms(qc, qc->hel->pktns); - if (objt_server(qc->target)) { + if (qc_is_back(qc)) { /* I/O callback switch */ qc->wait_event.tasklet->process = quic_conn_app_io_cb; } } - if (objt_listener(qc->target) && st >= QUIC_HS_ST_COMPLETE) { + if (!qc_is_back(qc) && st >= QUIC_HS_ST_COMPLETE) { /* Note: if no token for address validation was received * for a 0RTT connection, some 0RTT packet could still be * waiting for HP removal AFTER the successful handshake completion. @@ -913,7 +913,7 @@ struct task *quic_conn_io_cb(struct task *t, void *context, unsigned int state) * discard Initial keys when it first sends a Handshake packet... */ - if (objt_server(qc->target) && !quic_tls_pktns_is_dcd(qc, qc->ipktns) && + if (qc_is_back(qc) && !quic_tls_pktns_is_dcd(qc, qc->ipktns) && qc->hpktns && qc->hpktns->tx.in_flight > 0) { /* Discard the Initial packet number space. */ TRACE_PROTO("discarding Initial pktns", QUIC_EV_CONN_PRSHPKT, qc); @@ -1029,7 +1029,7 @@ struct task *qc_process_timer(struct task *task, void *ctx, unsigned int state) } } } - else if (objt_server(qc->target) && qc->state <= QUIC_HS_ST_COMPLETE) { + else if (qc_is_back(qc) && qc->state <= QUIC_HS_ST_COMPLETE) { if (quic_tls_has_tx_sec(qc->hel)) qc->hel->pktns->tx.pto_probe = 1; if (quic_tls_has_tx_sec(qc->iel)) @@ -1608,7 +1608,7 @@ int quic_conn_release(struct quic_conn *qc) /* Connection released before handshake completion. */ if (unlikely(qc->state < QUIC_HS_ST_COMPLETE)) { - if (objt_listener(qc->target)) { + if (!qc_is_back(qc)) { BUG_ON(__objt_listener(qc->target)->rx.quic_curr_handshake == 0); HA_ATOMIC_DEC(&__objt_listener(qc->target)->rx.quic_curr_handshake); } diff --git a/src/quic_openssl_compat.c b/src/quic_openssl_compat.c index 57e679b3d..2e55c3ced 100644 --- a/src/quic_openssl_compat.c +++ b/src/quic_openssl_compat.c @@ -150,22 +150,22 @@ void quic_tls_compat_keylog_callback(const SSL *ssl, const char *line) if (sizeof(QUIC_OPENSSL_COMPAT_CLIENT_HANDSHAKE) - 1 == n && !strncmp(start, QUIC_OPENSSL_COMPAT_CLIENT_HANDSHAKE, n)) { level = ssl_encryption_handshake; - write = objt_listener(qc->target) ? 0 : 1; + write = !qc_is_back(qc) ? 0 : 1; } else if (sizeof(QUIC_OPENSSL_COMPAT_SERVER_HANDSHAKE) - 1 == n && !strncmp(start, QUIC_OPENSSL_COMPAT_SERVER_HANDSHAKE, n)) { level = ssl_encryption_handshake; - write = objt_listener(qc->target) ? 1 : 0; + write = !qc_is_back(qc) ? 1 : 0; } else if (sizeof(QUIC_OPENSSL_COMPAT_CLIENT_APPLICATION) - 1 == n && !strncmp(start, QUIC_OPENSSL_COMPAT_CLIENT_APPLICATION, n)) { level = ssl_encryption_application; - write = objt_listener(qc->target) ? 0 : 1; + write = !qc_is_back(qc) ? 0 : 1; } else if (sizeof(QUIC_OPENSSL_COMPAT_SERVER_APPLICATION) - 1 == n && !strncmp(start, QUIC_OPENSSL_COMPAT_SERVER_APPLICATION, n)) { level = ssl_encryption_application; - write = objt_listener(qc->target) ? 1 : 0; + write = !qc_is_back(qc) ? 1 : 0; } else goto leave; diff --git a/src/quic_retransmit.c b/src/quic_retransmit.c index 770512feb..ee4d662db 100644 --- a/src/quic_retransmit.c +++ b/src/quic_retransmit.c @@ -166,7 +166,7 @@ void qc_prep_fast_retrans(struct quic_conn *qc, /* When building a packet from another one, the field which may increase the * packet size is the packet number. And the maximum increase is 4 bytes. */ - if (!quic_peer_validated_addr(qc) && objt_listener(qc->target) && + if (!quic_peer_validated_addr(qc) && !qc_is_back(qc) && pkt->len + 4 > quic_may_send_bytes(qc)) { qc->flags |= QUIC_FL_CONN_ANTI_AMPLIFICATION_REACHED; TRACE_PROTO("anti-amplification limit would be reached", QUIC_EV_CONN_SPPKTS, qc, pkt); @@ -230,7 +230,7 @@ void qc_prep_hdshk_fast_retrans(struct quic_conn *qc, /* When building a packet from another one, the field which may increase the * packet size is the packet number. And the maximum increase is 4 bytes. */ - if (!quic_peer_validated_addr(qc) && objt_listener(qc->target)) { + if (!quic_peer_validated_addr(qc) && !qc_is_back(qc)) { size_t dglen = pkt->len + 4; size_t may_send; diff --git a/src/quic_rx.c b/src/quic_rx.c index ba501473d..9fe7b465f 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -920,7 +920,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, break; case QUIC_RX_RET_FRM_DUP: - if (objt_listener(qc->target) && qel == qc->iel && + if (!qc_is_back(qc) && qel == qc->iel && !(qc->flags & QUIC_FL_CONN_HANDSHAKE_SPEED_UP)) { fast_retrans = 1; } @@ -936,7 +936,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, break; case QUIC_FT_NEW_TOKEN: - if (objt_listener(qc->target)) { + if (!qc_is_back(qc)) { TRACE_ERROR("reject NEW_TOKEN frame emitted by client", QUIC_EV_CONN_PRSHPKT, qc); @@ -1096,7 +1096,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, } break; case QUIC_FT_HANDSHAKE_DONE: - if (objt_listener(qc->target)) { + if (!qc_is_back(qc)) { TRACE_ERROR("non accepted QUIC_FT_HANDSHAKE_DONE frame", QUIC_EV_CONN_PRSHPKT, qc); @@ -1186,7 +1186,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, * has successfully parse a Handshake packet. The Initial encryption must also * be discarded. */ - if (pkt->type == QUIC_PACKET_TYPE_HANDSHAKE && objt_listener(qc->target)) { + if (pkt->type == QUIC_PACKET_TYPE_HANDSHAKE && !qc_is_back(qc)) { if (qc->state >= QUIC_HS_ST_SERVER_INITIAL) { if (qc->ipktns && !quic_tls_pktns_is_dcd(qc, qc->ipktns)) { /* Discard the handshake packet number space. */ @@ -1225,7 +1225,7 @@ static inline void qc_handle_spin_bit(struct quic_conn *qc, struct quic_rx_packe pkt->pn <= largest_pn) return; - if (objt_listener(qc->target)) { + if (!qc_is_back(qc)) { if (pkt->flags & QUIC_FL_RX_PACKET_SPIN_BIT) qc->flags |= QUIC_FL_CONN_SPIN_BIT; else @@ -1248,7 +1248,7 @@ static void qc_rm_hp_pkts(struct quic_conn *qc, struct quic_enc_level *el) TRACE_ENTER(QUIC_EV_CONN_ELRMHP, qc); /* A server must not process incoming 1-RTT packets before the handshake is complete. */ - if (el == qc->ael && objt_listener(qc->target) && qc->state < QUIC_HS_ST_COMPLETE) { + if (el == qc->ael && !qc_is_back(qc) && qc->state < QUIC_HS_ST_COMPLETE) { TRACE_PROTO("RX hp not removed (handshake not completed)", QUIC_EV_CONN_ELRMHP, qc); goto out; diff --git a/src/quic_ssl.c b/src/quic_ssl.c index ca91fe342..f39df08d3 100644 --- a/src/quic_ssl.c +++ b/src/quic_ssl.c @@ -232,7 +232,7 @@ static int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t * listener and if a token was received. Note that a listener derives only RX * secrets for this level. */ - if (objt_listener(qc->target) && level == ssl_encryption_early_data) { + if (!qc_is_back(qc) && level == ssl_encryption_early_data) { if (qc->flags & QUIC_FL_CONN_NO_TOKEN_RCVD) { /* Leave a chance to the address validation to be completed by the * handshake without starting the mux: one does not want to process @@ -281,7 +281,7 @@ write: } /* Set the transport parameters in the TLS stack. */ - if (level == ssl_encryption_handshake && objt_listener(qc->target) && + if (level == ssl_encryption_handshake && !qc_is_back(qc) && !qc_ssl_set_quic_transport_params(qc->xprt_ctx->ssl, qc, ver, 1)) goto leave; @@ -292,7 +292,7 @@ write: struct quic_tls_kp *nxt_tx = &qc->ku.nxt_tx; #if !defined(USE_QUIC_OPENSSL_COMPAT) && !defined(HAVE_OPENSSL_QUIC) - if (objt_server(qc->target)) { + if (qc_is_back(qc)) { const unsigned char *tp; size_t tplen; @@ -580,7 +580,6 @@ static int ha_quic_ossl_got_transport_params(SSL *ssl, const unsigned char *para { int ret = 0; struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index); - struct listener *l = objt_listener(qc->target); TRACE_ENTER(QUIC_EV_TRANSP_PARAMS, qc); @@ -589,7 +588,7 @@ static int ha_quic_ossl_got_transport_params(SSL *ssl, const unsigned char *para QUIC_EV_TRANSP_PARAMS, qc); ret = 1; } - else if (!quic_transport_params_store(qc, !l, params, params + params_len)) { + else if (!quic_transport_params_store(qc, qc_is_back(qc), params, params + params_len)) { goto err; } @@ -956,7 +955,7 @@ 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 (objt_listener(qc->target)) { + if (!qc_is_back(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", @@ -970,7 +969,7 @@ static int qc_ssl_provide_quic_data(struct ncbuf *ncbuf, #endif /* Check the alpn could be negotiated */ - if (objt_listener(qc->target)) { + if (!qc_is_back(qc)) { if (!qc->app_ops) { TRACE_ERROR("No negotiated ALPN", QUIC_EV_CONN_IO_CB, qc, &state); quic_set_tls_alert(qc, SSL_AD_NO_APPLICATION_PROTOCOL); @@ -1000,7 +999,7 @@ static int qc_ssl_provide_quic_data(struct ncbuf *ncbuf, } qc->flags |= QUIC_FL_CONN_NEED_POST_HANDSHAKE_FRMS; - if (objt_listener(ctx->qc->target)) { + if (!qc_is_back(qc)) { struct listener *l = __objt_listener(qc->target); /* I/O callback switch */ qc->wait_event.tasklet->process = quic_conn_app_io_cb; @@ -1245,7 +1244,7 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc, struct connection *conn) ctx->sent_early_data = 0; ctx->qc = qc; - if (objt_listener(qc->target)) { + if (!qc_is_back(qc)) { struct bind_conf *bc = __objt_listener(qc->target)->bind_conf; if (qc_ssl_sess_init(qc, bc->initial_ctx, &ctx->ssl, NULL, 1) == -1) diff --git a/src/quic_tx.c b/src/quic_tx.c index d5f00168b..dc249d349 100644 --- a/src/quic_tx.c +++ b/src/quic_tx.c @@ -586,7 +586,6 @@ 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 @@ -650,7 +649,7 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf, * to stay under MTU limit. */ if (!dglen) { - if (!quic_peer_validated_addr(qc) && objt_listener(qc->target)) + if (!quic_peer_validated_addr(qc) && !qc_is_back(qc)) end = pos + QUIC_MIN(qc->path->mtu, quic_may_send_bytes(qc)); else end = pos + qc->path->mtu; @@ -672,7 +671,7 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf, * datagrams carrying ack-eliciting Initial packets to at least the * smallest allowed maximum datagram size of 1200 bytes. */ - if (qel == qc->iel && (!l || !LIST_ISEMPTY(frms) || probe)) { + if (qel == qc->iel && (qc_is_back(qc) || !LIST_ISEMPTY(frms) || probe)) { /* Ensure that no Initial packets are sent into too small datagrams */ if (end - pos < QUIC_INITIAL_PACKET_MINLEN) { TRACE_PROTO("No more enough room to build an Initial packet", @@ -704,8 +703,8 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf, cur_pkt = qc_build_pkt(&pos, end, qel, tls_ctx, frms, qc, ver, dglen, pkt_type, must_ack, padding && - ((!l && (!next_qel || LIST_ISEMPTY(next_qel->send_frms))) || - (l && !next_qel && (!probe || !LIST_ISEMPTY(frms)))), + ((qc_is_back(qc) && (!next_qel || LIST_ISEMPTY(next_qel->send_frms))) || + (!qc_is_back(qc) && !next_qel && (!probe || !LIST_ISEMPTY(frms)))), probe, cc, &err); if (!cur_pkt) { switch (err) {