]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Parse long packet version from qc_parse_hd_form()
authorFrédéric Lécaille <flecaille@haproxy.com>
Wed, 8 Jun 2022 11:22:17 +0000 (13:22 +0200)
committerFrédéric Lécaille <flecaille@haproxy.com>
Thu, 16 Jun 2022 12:56:24 +0000 (14:56 +0200)
This is to prepare the support for QUIC v2 version. The packet type
depends on the version. So, we must parse early enough the version
before defining the type of each packet.

src/xprt_quic.c

index 145cf00a8638cd0ad28bb507fa10bd2ad7dd31b8..a899ec796c0376cab1cf932f8c961e7c3bf267d9 100644 (file)
@@ -4537,8 +4537,7 @@ static inline int quic_packet_read_long_header(unsigned char **buf, const unsign
 {
        unsigned char dcid_len, scid_len;
 
-       /* Version */
-       if (!quic_read_uint32(&pkt->version, (const unsigned char **)buf, end))
+       if (end == *buf)
                return 0;
 
        /* Destination Connection ID Length */
@@ -4662,21 +4661,51 @@ static inline int qc_try_rm_hp(struct quic_conn *qc,
        return 0;
 }
 
-/* Parse the header form from <byte0> first byte of <pkt> pacekt to set type.
+/* Parse the header form from <byte0> first byte of <pkt> packet to set its type.
  * Also set <*long_header> to 1 if this form is long, 0 if not.
  */
-static inline void qc_parse_hd_form(struct quic_rx_packet *pkt,
-                                    unsigned char byte0, int *long_header)
+static inline int qc_parse_hd_form(struct quic_rx_packet *pkt,
+                                   unsigned char **buf, const unsigned char *end,
+                                   int *long_header)
 {
+       const unsigned char byte0 = **buf;
+
+       (*buf)++;
        if (byte0 & QUIC_PACKET_LONG_HEADER_BIT) {
-               pkt->type =
+               unsigned char type =
                        (byte0 >> QUIC_PACKET_TYPE_SHIFT) & QUIC_PACKET_TYPE_BITMASK;
+
                *long_header = 1;
+               /* Version */
+               if (!quic_read_uint32(&pkt->version, (const unsigned char **)buf, end))
+                       return 0;
+
+               if (pkt->version != QUIC_PROTOCOL_VERSION_2_DRAFT) {
+                       pkt->type = type;
+               }
+               else {
+                       switch (type) {
+                       case 0:
+                               pkt->type = QUIC_PACKET_TYPE_RETRY;
+                               break;
+                       case 1:
+                               pkt->type = QUIC_PACKET_TYPE_INITIAL;
+                               break;
+                       case 2:
+                               pkt->type = QUIC_PACKET_TYPE_0RTT;
+                               break;
+                       case 3:
+                               pkt->type = QUIC_PACKET_TYPE_HANDSHAKE;
+                               break;
+                       }
+               }
        }
        else {
                pkt->type = QUIC_PACKET_TYPE_SHORT;
                *long_header = 0;
        }
+
+       return 1;
 }
 
 /*
@@ -5242,7 +5271,11 @@ static void qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
        }
 
        /* Header form */
-       qc_parse_hd_form(pkt, *buf++, &long_header);
+       if (!qc_parse_hd_form(pkt, &buf, end, &long_header)) {
+               TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
+               goto drop;
+       }
+
        if (long_header) {
                uint64_t len;
                struct quic_cid odcid;