diff --git a/include/haproxy/quic_tx-t.h b/include/haproxy/quic_tx-t.h index 1fba01660..cf2d98c58 100644 --- a/include/haproxy/quic_tx-t.h +++ b/include/haproxy/quic_tx-t.h @@ -5,6 +5,17 @@ #define QUIC_DGRAM_HEADLEN (sizeof(uint16_t) + sizeof(void *)) #define QUIC_MAX_CC_BUFSIZE (2 * (QUIC_MIN_CC_PKTSIZE + QUIC_DGRAM_HEADLEN)) +/* Sendmsg input buffer cannot be bigger than 65535 bytes. This comes from UDP + * header which uses a 2-bytes length field. QUIC datagrams are limited to 1252 + * bytes for now so this does not cause any issue for serialized emission. + * + * However when using GSO large buffer can be transferred. By default, no more + * than 64 datagrams can be emitted via a single GSO call (man 7 udp). This is + * still too much with 1252 bytes datagram. Use a 52 datagrams max value, which + * ensures sendmsg input will be limited to 65104 bytes. + */ +#define QUIC_MAX_GSO_DGRAMS 52 + #include #include diff --git a/src/quic_tx.c b/src/quic_tx.c index bc85f0d8b..14cf2bb43 100644 --- a/src/quic_tx.c +++ b/src/quic_tx.c @@ -570,6 +570,7 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf, int total = 0; struct quic_enc_level *qel, *tmp_qel; 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; TRACE_ENTER(QUIC_EV_CONN_IO_CB, qc); @@ -763,7 +764,8 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf, !(HA_ATOMIC_LOAD(&qc->li->flags) & LI_F_UDP_GSO_NOTSUPP) && dglen == qc->path->mtu && (char *)end < b_wrap(buf) && - gso_dgram_cnt < 64) { + ++gso_dgram_cnt < QUIC_MAX_GSO_DGRAMS) { + /* A datagram covering the full MTU has been * built, use GSO to built next entry. Do not * reserve extra space for datagram header. @@ -771,11 +773,6 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf, prv_pkt = cur_pkt; dglen = 0; - /* man 7 udp UDP_SEGMENT - * The segment size must be chosen such that at - * most 64 datagrams are sent in a single call - */ - ++gso_dgram_cnt; } else { /* Finalize current datagram if not all frames sent. */