From: Frédéric Lécaille Date: Mon, 20 Jun 2022 15:51:24 +0000 (+0200) Subject: BUG/MINOR: quic: Acknowledgement must be forced during handshake X-Git-Tag: v2.7-dev1~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=57bddbcbbb92c5bcbd675bf15d382b0a924d07c7;p=thirdparty%2Fhaproxy.git BUG/MINOR: quic: Acknowledgement must be forced during handshake All packets received during hanshakes must be acknowledged asap. This was not the case for Handshake packets received. At this time, this had no impact because the client has often only one Handshake packet to send and last handshake to be sent on our side always embeds an HANDSHAKE_DONE frame which leads the client to consider it has no more handshake packet to send. Add to qc_may_build_pkt() to force an ACK frame to be sent. Set this parameter to 1 when sending packets from Initial or Handshake packet number spaces, 0 when sending only Application level packet. Must be backported to 2.6. --- diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 20160e1613..7c31434605 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -2681,11 +2681,12 @@ static inline void qc_set_dg(struct cbuf *cbuf, * with as ack-eliciting frame list to send, 0 if not. * must equal to 1 if an immediate close was asked, 0 if not. * must equalt to 1 if a probing packet is required, 0 if not. + * may be set to 1 if you want to force an ack. */ static int qc_may_build_pkt(struct quic_conn *qc, struct list *frms, - struct quic_enc_level *qel, int cc, int probe) + struct quic_enc_level *qel, int cc, int probe, int force_ack) { - unsigned int must_ack = + unsigned int must_ack = force_ack || qel->pktns->rx.nb_aepkts_since_last_ack >= QUIC_MAX_RX_AEPKTS_SINCE_LAST_ACK; /* Do not build any more packet if the TX secrets are not available or @@ -2747,7 +2748,7 @@ static int qc_prep_app_pkts(struct quic_conn *qc, struct qring *qr, if (!cc) probe = qel->pktns->tx.pto_probe; - if (!qc_may_build_pkt(qc, frms, qel, cc, probe)) + if (!qc_may_build_pkt(qc, frms, qel, cc, probe, 0)) break; /* Leave room for the datagram header */ @@ -2849,6 +2850,9 @@ static int qc_prep_pkts(struct quic_conn *qc, struct qring *qr, enum quic_pkt_type pkt_type; struct quic_tls_ctx *tls_ctx; const struct quic_version *ver; + int force_ack = (qel->pktns->flags & QUIC_FL_PKTNS_ACK_REQUIRED) && + (qel == &qc->els[QUIC_TLS_ENC_LEVEL_INITIAL] || + qel == &qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE]); TRACE_POINT(QUIC_EV_CONN_PHPKTS, qc, qel); probe = 0; @@ -2857,7 +2861,7 @@ static int qc_prep_pkts(struct quic_conn *qc, struct qring *qr, if (!cc) probe = qel->pktns->tx.pto_probe; - if (!qc_may_build_pkt(qc, frms, qel, cc, probe)) { + if (!qc_may_build_pkt(qc, frms, qel, cc, probe, force_ack)) { if (prv_pkt) qc_set_dg(cbuf, dglen, first_pkt); /* Let's select the next encryption level */