]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Avoid header collisions
authorFrédéric Lécaille <flecaille@haproxy.com>
Tue, 23 Mar 2021 13:46:56 +0000 (14:46 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 23 Sep 2021 13:27:25 +0000 (15:27 +0200)
Extract the QUIC varints encoding functions from xprt_quic.h to avoid
header collisions.

include/haproxy/quic_enc.h [new file with mode: 0644]
include/haproxy/xprt_quic.h

diff --git a/include/haproxy/quic_enc.h b/include/haproxy/quic_enc.h
new file mode 100644 (file)
index 0000000..3222a27
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * include/haproxy/quic_enc.h
+ * This file contains QUIC varint encoding function prototypes
+ *
+ * Copyright 2021 HAProxy Technologies, Frédéric Lécaille <flecaille@haproxy.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _HAPROXY_QUIC_ENC_H
+#define _HAPROXY_QUIC_ENC_H
+#ifdef USE_QUIC
+#ifndef USE_OPENSSL
+#error "Must define USE_OPENSSL"
+#endif
+
+#include <stdint.h>
+
+#include <haproxy/buf.h>
+#include <haproxy/chunk.h>
+
+/* The maximum size of a variable-length QUIC integer encoded with 1 byte */
+#define QUIC_VARINT_1_BYTE_MAX       ((1UL <<  6) - 1)
+/* The maximum size of a variable-length QUIC integer encoded with 2 bytes */
+#define QUIC_VARINT_2_BYTE_MAX       ((1UL <<  14) - 1)
+/* The maximum size of a variable-length QUIC integer encoded with 4 bytes */
+#define QUIC_VARINT_4_BYTE_MAX       ((1UL <<  30) - 1)
+/* The maximum size of a variable-length QUIC integer encoded with 8 bytes */
+#define QUIC_VARINT_8_BYTE_MAX       ((1ULL <<  62) - 1)
+
+/* The maximum size of a variable-length QUIC integer */
+#define QUIC_VARINT_MAX_SIZE       8
+
+/* The two most significant bits of byte #0 from a QUIC packet gives the 2
+ * logarithm of the length of a variable length encoded integer.
+ */
+#define QUIC_VARINT_BYTE_0_BITMASK 0x3f
+#define QUIC_VARINT_BYTE_0_SHIFT   6
+
+/* Returns enough log2 of first powers of two to encode QUIC variable length
+ * integers.
+ * Returns -1 if <val> if out of the range of lengths supported by QUIC.
+ */
+static inline int quic_log2(unsigned int val)
+{
+       switch (val) {
+       case 8:
+               return 3;
+       case 4:
+               return 2;
+       case 2:
+               return 1;
+       case 1:
+               return 0;
+       default:
+               return -1;
+       }
+}
+
+/* Returns the size in bytes required to encode a 64bits integer if
+ * not out of range (< (1 << 62)), or 0 if out of range.
+ */
+static inline size_t quic_int_getsize(uint64_t val)
+{
+       switch (val) {
+       case 0 ... QUIC_VARINT_1_BYTE_MAX:
+               return 1;
+       case QUIC_VARINT_1_BYTE_MAX + 1 ... QUIC_VARINT_2_BYTE_MAX:
+               return 2;
+       case QUIC_VARINT_2_BYTE_MAX + 1 ... QUIC_VARINT_4_BYTE_MAX:
+               return 4;
+       case QUIC_VARINT_4_BYTE_MAX + 1 ... QUIC_VARINT_8_BYTE_MAX:
+               return 8;
+       default:
+               return 0;
+       }
+}
+
+/* Decode a QUIC variable-length integer from <buf> buffer into <val>.
+ * Note that the result is a 64-bits integer but with the less significant
+ * 62 bits as relevant information. The most significant 2 remaining bits encode
+ * the length of the integer.
+ * Returns 1 if succeeded there was enough data in <buf>), 0 if not.
+ */
+static inline int quic_dec_int(uint64_t *val,
+                               const unsigned char **buf,
+                               const unsigned char *end)
+{
+       size_t len;
+
+       if (*buf >= end)
+               return 0;
+
+       len = 1 << (**buf >> QUIC_VARINT_BYTE_0_SHIFT);
+       if (*buf + len > end)
+               return 0;
+
+       *val = *(*buf)++ & QUIC_VARINT_BYTE_0_BITMASK;
+       while (--len)
+               *val = (*val << 8) | *(*buf)++;
+
+       return 1;
+}
+
+/* Decode a QUIC variable-length integer from <b> buffer into <val> supporting wrapping.
+ * Note that the result is a 64-bits integer but with the less significant
+ * 62 bits as relevant information. The most significant 2 bits encode
+ * the length of the integer.
+ * Note that this function update <b> buffer when a variable-length integer
+ * has successfully been parsed.
+ * Returns 1 and if succeeded (there was enough data in <buf>), 0 if not.
+ * If <retlen> is not null, increment <*retlen> by the number of bytes consumed to decode
+ * the varint.
+ */
+static inline size_t b_quic_dec_int(uint64_t *val, struct buffer *b, size_t *retlen)
+{
+       const unsigned char *pos = (const unsigned char *)b_head(b);
+       const unsigned char *end = (const unsigned char *)b_wrap(b);
+       size_t size = b_size(b);
+       size_t data = b_data(b);
+       size_t save_len, len;
+
+       if (!data)
+               return 0;
+
+       save_len = len = 1 << (*pos >> QUIC_VARINT_BYTE_0_SHIFT);
+       if (data < len)
+               return 0;
+
+       *val = *pos & QUIC_VARINT_BYTE_0_BITMASK;
+       if (++pos == end)
+               pos -= size;
+       while (--len) {
+               *val = (*val << 8) | *pos;
+               if (++pos == end)
+                       pos -= size;
+       }
+       if (retlen)
+               *retlen += save_len;
+       b_del(b, save_len);
+
+       return 1;
+}
+
+/* Encode a QUIC variable-length integer from <val> into <buf> buffer with <end> as first
+ * byte address after the end of this buffer.
+ * Returns 1 if succeeded (there was enough room in buf), 0 if not.
+ */
+static inline int quic_enc_int(unsigned char **buf, const unsigned char *end, uint64_t val)
+{
+       size_t len;
+       unsigned int shift;
+       unsigned char size_bits, *head;
+
+       len = quic_int_getsize(val);
+       if (!len || end - *buf < len)
+               return 0;
+
+       shift = (len - 1) * 8;
+       /* set the bits of byte#0 which gives the length of the encoded integer */
+       size_bits = quic_log2(len) << QUIC_VARINT_BYTE_0_SHIFT;
+       head = *buf;
+       while (len--) {
+               *(*buf)++ = val >> shift;
+               shift -= 8;
+       }
+       *head |= size_bits;
+
+       return 1;
+}
+
+/* Encode a QUIC variable-length integer <val> into <b> buffer.
+ * Returns 1 if succeeded (there was enough room in buf), 0 if not.
+ */
+static inline int b_quic_enc_int(struct buffer *b, uint64_t val)
+{
+       unsigned int shift;
+       unsigned char size_bits, *head, *pos, *wrap;
+       size_t save_len, len;
+       size_t data = b_data(b);
+       size_t size = b_size(b);
+
+       if (data == size)
+               return 0;
+
+       save_len = len = quic_int_getsize(val);
+       if (!len)
+               return 0;
+
+       shift = (len - 1) * 8;
+       /* set the bits of byte#0 which gives the length of the encoded integer */
+       size_bits = quic_log2(len) << QUIC_VARINT_BYTE_0_SHIFT;
+       pos = head = (unsigned char *)b_head(b);
+       wrap = (unsigned char *)b_wrap(b);
+       while (len--) {
+               *pos++ = val >> shift;
+               shift -= 8;
+               if (pos == wrap)
+                       pos -= size;
+               if (++data == size && len)
+                       return 0;
+       }
+       *head |= size_bits;
+       b_add(b, save_len);
+
+       return 1;
+}
+
+#endif /* USE_QUIC */
+#endif /* _HAPROXY_QUIC_ENC_H */
index 537a5175644829094f456a4d18a636009673afbd..ce01a647871e32596f754f3471f40ccdf15028c3 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <haproxy/listener.h>
 #include <haproxy/quic_cc.h>
+#include <haproxy/quic_enc.h>
 #include <haproxy/quic_frame.h>
 #include <haproxy/quic_loss.h>
 #include <haproxy/mux_quic.h>
@@ -235,46 +236,6 @@ static inline int quic_write_uint32(unsigned char **buf,
        return 1;
 }
 
-
-/* Returns enough log2 of first powers of two to encode QUIC variable length
- * integers.
- * Returns -1 if <val> if out of the range of lengths supported by QUIC.
- */
-static inline int quic_log2(unsigned int val)
-{
-       switch (val) {
-       case 8:
-               return 3;
-       case 4:
-               return 2;
-       case 2:
-               return 1;
-       case 1:
-               return 0;
-       default:
-               return -1;
-       }
-}
-
-/* Returns the size in bytes required to encode a 64bits integer if
- * not out of range (< (1 << 62)), or 0 if out of range.
- */
-static inline size_t quic_int_getsize(uint64_t val)
-{
-       switch (val) {
-       case 0 ... QUIC_VARINT_1_BYTE_MAX:
-               return 1;
-       case QUIC_VARINT_1_BYTE_MAX + 1 ... QUIC_VARINT_2_BYTE_MAX:
-               return 2;
-       case QUIC_VARINT_2_BYTE_MAX + 1 ... QUIC_VARINT_4_BYTE_MAX:
-               return 4;
-       case QUIC_VARINT_4_BYTE_MAX + 1 ... QUIC_VARINT_8_BYTE_MAX:
-               return 8;
-       default:
-               return 0;
-       }
-}
-
 /* Return the difference between the encoded length of <val> and the encoded
  * length of <val+1>.
  */
@@ -393,136 +354,6 @@ static inline size_t max_stream_data_size(size_t sz, size_t ilen, size_t dlen)
        return 0;
 }
 
-/* Decode a QUIC variable-length integer from <buf> buffer into <val>.
- * Note that the result is a 64-bits integer but with the less significant
- * 62 bits as relevant information. The most significant 2 remaining bits encode
- * the length of the integer.
- * Returns 1 if succeeded there was enough data in <buf>), 0 if not.
- */
-static inline int quic_dec_int(uint64_t *val,
-                               const unsigned char **buf,
-                               const unsigned char *end)
-{
-       size_t len;
-
-       if (*buf >= end)
-               return 0;
-
-       len = 1 << (**buf >> QUIC_VARINT_BYTE_0_SHIFT);
-       if (*buf + len > end)
-               return 0;
-
-       *val = *(*buf)++ & QUIC_VARINT_BYTE_0_BITMASK;
-       while (--len)
-               *val = (*val << 8) | *(*buf)++;
-
-       return 1;
-}
-
-/* Decode a QUIC variable-length integer from <b> buffer into <val> supporting wrapping.
- * Note that the result is a 64-bits integer but with the less significant
- * 62 bits as relevant information. The most significant 2 bits encode
- * the length of the integer.
- * Note that this function update <b> buffer when a variable-length integer
- * has successfully been parsed.
- * Returns 1 and if succeeded (there was enough data in <buf>), 0 if not.
- * If <retlen> is not null, increment <*retlen> by the number of bytes consumed to decode
- * the varint.
- */
-static inline size_t b_quic_dec_int(uint64_t *val, struct buffer *b, size_t *retlen)
-{
-       const unsigned char *pos = (const unsigned char *)b_head(b);
-       const unsigned char *end = (const unsigned char *)b_wrap(b);
-       size_t size = b_size(b);
-       size_t data = b_data(b);
-       size_t save_len, len;
-
-       if (!data)
-               return 0;
-
-       save_len = len = 1 << (*pos >> QUIC_VARINT_BYTE_0_SHIFT);
-       if (data < len)
-               return 0;
-
-       *val = *pos & QUIC_VARINT_BYTE_0_BITMASK;
-       if (++pos == end)
-               pos -= size;
-       while (--len) {
-               *val = (*val << 8) | *pos;
-               if (++pos == end)
-                       pos -= size;
-       }
-       if (retlen)
-               *retlen += save_len;
-       b_del(b, save_len);
-
-       return 1;
-}
-
-/* Encode a QUIC variable-length integer from <val> into <buf> buffer with <end> as first
- * byte address after the end of this buffer.
- * Returns 1 if succeeded (there was enough room in buf), 0 if not.
- */
-static inline int quic_enc_int(unsigned char **buf, const unsigned char *end, uint64_t val)
-{
-       size_t len;
-       unsigned int shift;
-       unsigned char size_bits, *head;
-
-       len = quic_int_getsize(val);
-       if (!len || end - *buf < len)
-               return 0;
-
-       shift = (len - 1) * 8;
-       /* set the bits of byte#0 which gives the length of the encoded integer */
-       size_bits = quic_log2(len) << QUIC_VARINT_BYTE_0_SHIFT;
-       head = *buf;
-       while (len--) {
-               *(*buf)++ = val >> shift;
-               shift -= 8;
-       }
-       *head |= size_bits;
-
-       return 1;
-}
-
-/* Encode a QUIC variable-length integer <val> into <b> buffer.
- * Returns 1 if succeeded (there was enough room in buf), 0 if not.
- */
-static inline int b_quic_enc_int(struct buffer *b, uint64_t val)
-{
-       unsigned int shift;
-       unsigned char size_bits, *head, *pos, *wrap;
-       size_t save_len, len;
-       size_t data = b_data(b);
-       size_t size = b_size(b);
-
-       if (data == size)
-               return 0;
-
-       save_len = len = quic_int_getsize(val);
-       if (!len)
-               return 0;
-
-       shift = (len - 1) * 8;
-       /* set the bits of byte#0 which gives the length of the encoded integer */
-       size_bits = quic_log2(len) << QUIC_VARINT_BYTE_0_SHIFT;
-       pos = head = (unsigned char *)b_head(b);
-       wrap = (unsigned char *)b_wrap(b);
-       while (len--) {
-               *pos++ = val >> shift;
-               shift -= 8;
-               if (pos == wrap)
-                       pos -= size;
-               if (++data == size && len)
-                       return 0;
-       }
-       *head |= size_bits;
-       b_add(b, save_len);
-
-       return 1;
-}
-
 /* Return the length in bytes of <pn> packet number depending on
  * <largest_acked_pn> the largest ackownledged packet number.
  */