]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: quic: fix CRYPTO payload size calcul for encoding
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 11 Feb 2025 13:35:52 +0000 (14:35 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 12 Feb 2025 10:51:09 +0000 (11:51 +0100)
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

index 82b3f5fa044376d6d2d8d0560b4fa4ef7c60b40b..e17e66c6621183232993ec6c816e8f4cad0801d4 100644 (file)
@@ -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 <len_sz> which match our need.
-        * As we must put <ilen> bytes in our buffer, the minimum value for
-        * <len_sz> is the number of bytes required to encode <ilen>.
-        */
-       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 - len_sz - ilen, &dlen_sz);
-               if (!ret)
-                       return 0;
-
-               /* Check that <*len_sz> matches <ret> value */
-               if (len_sz + ilen + dlen_sz + ret <= quic_max_int(len_sz))
-                       return ret < dlen ? ret : dlen;
-       }
+       ret = max_available_room(sz - ilen, &dlen_sz);
+       if (!ret)
+               return 0;
 
-       return 0;
+       return ret < dlen ? ret : dlen;
 }
 
 /* Return the length in bytes of <pn> packet number depending on