From e6a223542ae87880b3e8261daffbe362730f9e55 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 11 Feb 2025 14:35:52 +0100 Subject: [PATCH] BUG/MINOR: quic: fix CRYPTO payload size calcul for encoding Function max_stream_data_size() is used to determine the payload length of a CRYPTO frame. It takes into account that the CRYPTO length field is a variable length integer. Implemented calcul was incorrect as it reserved too much space as a frame header. This error is mostly due because max_stream_data_size() reuses max_available_room() which also reserve space for a variable length integer. This results in CRYPTO frames shorter of 1 to 2 bytes than the maximum achievable value, which produces in the end datagram shorter than the MTU. Fix max_stream_data_size() implementation. It is now merely a wrapper on max_available_room(). This ensures that CRYPTO frame encoding is now properly optimized to use the MTU available. This should be backported up to 2.6. --- src/quic_tx.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/src/quic_tx.c b/src/quic_tx.c index 82b3f5fa0..e17e66c66 100644 --- a/src/quic_tx.c +++ b/src/quic_tx.c @@ -1369,30 +1369,13 @@ static inline size_t max_available_room(size_t sz, size_t *len_sz) */ static inline size_t max_stream_data_size(size_t sz, size_t ilen, size_t dlen) { - size_t ret, len_sz, dlen_sz; + size_t ret, dlen_sz; - /* - * The length of variable-length QUIC integers are powers of two. - * Look for the first 3length" field value which match our need. - * As we must put bytes in our buffer, the minimum value for - * is the number of bytes required to encode . - */ - for (len_sz = quic_int_getsize(ilen); - len_sz <= QUIC_VARINT_MAX_SIZE; - len_sz <<= 1) { - if (sz < len_sz + ilen) - return 0; + ret = max_available_room(sz - ilen, &dlen_sz); + if (!ret) + return 0; - ret = max_available_room(sz - len_sz - ilen, &dlen_sz); - if (!ret) - return 0; - - /* Check that <*len_sz> matches value */ - if (len_sz + ilen + dlen_sz + ret <= quic_max_int(len_sz)) - return ret < dlen ? ret : dlen; - } - - return 0; + return ret < dlen ? ret : dlen; } /* Return the length in bytes of packet number depending on