]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Allocate QUIC datagrams from sock I/O handler
authorFrédéric Lécaille <flecaille@haproxy.com>
Wed, 26 Jan 2022 15:07:16 +0000 (16:07 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 27 Jan 2022 15:37:55 +0000 (16:37 +0100)
Add quic_dgram new structure to store information about datagrams received
by the sock I/O handler (quic_sock_fd_iocb) and its associated pool.
Implement quic_get_dgram_dcid() to retrieve the datagram DCID which must
be the same for all the packets in the datagram.
Modify quic_lstnr_dgram_read() called by the sock I/O handler to allocate
a quic_dgram each time a correct datagram is found and add it to the sock I/O
handler rxbuf dgram list.

include/haproxy/xprt_quic-t.h
include/haproxy/xprt_quic.h
src/quic_sock.c
src/xprt_quic.c

index 6e22fe1b36230c34b5fcb902b28c8067f0d6ddcc..5cfd3daa37e2a2db1ca2304f8d9e40343ee7cba6 100644 (file)
@@ -420,6 +420,14 @@ struct quic_pktns {
        unsigned int flags;
 };
 
+/* QUIC datagram */
+struct quic_dgram {
+       unsigned char *buf;
+       size_t len;
+       struct sockaddr_storage saddr;
+       struct list list;
+};
+
 /* The QUIC packet numbers are 62-bits integers */
 #define QUIC_MAX_PACKET_NUM      ((1ULL << 62) - 1)
 
index a24df7480e95454d61e48d582bc5622d3c5de0d7..4bda6a74d6bf49b527113159117f08a10c39bb16 100644 (file)
@@ -1184,8 +1184,8 @@ void chunk_frm_appendf(struct buffer *buf, const struct quic_frame *frm);
 
 void quic_set_tls_alert(struct quic_conn *qc, int alert);
 int quic_set_app_ops(struct quic_conn *qc, const unsigned char *alpn, size_t alpn_len);
-ssize_t quic_lstnr_dgram_read(unsigned char *buf, size_t len, void *owner,
-                              struct sockaddr_storage *saddr);
+int quic_lstnr_dgram_read(unsigned char *buf, size_t len, void *owner,
+                          struct sockaddr_storage *saddr, struct list *dgrams);
 
 #endif /* USE_QUIC */
 #endif /* _HAPROXY_XPRT_QUIC_H */
index ef94acb1591fe376956ee3adf66a59ad94b3e413..ef03908c6e3421dbb476badb088ba1f89b2314d3 100644 (file)
@@ -212,7 +212,8 @@ void quic_sock_fd_iocb(int fd)
        } while (0);
 
        b_add(buf, ret);
-       quic_lstnr_dgram_read((unsigned char *)b_head(buf), ret, l, &saddr);
+       quic_lstnr_dgram_read((unsigned char *)b_head(buf), ret,
+                             l, &saddr, &rxbuf->dgrams);
        b_del(buf, ret);
  out:
        MT_LIST_APPEND(&l->rx.rxbuf_list, &rxbuf->mt_list);
index 0a0e6f3337322d7217ae46d7c02b298dd343de28..cc3985e914a4abc9e407e1f33e7115d69abbb333 100644 (file)
@@ -160,6 +160,7 @@ DECLARE_STATIC_POOL(pool_head_quic_conn_ctx,
 DECLARE_STATIC_POOL(pool_head_quic_conn, "quic_conn", sizeof(struct quic_conn));
 DECLARE_POOL(pool_head_quic_connection_id,
              "quic_connnection_id_pool", sizeof(struct quic_connection_id));
+DECLARE_POOL(pool_head_quic_dgram, "quic_dgram", sizeof(struct quic_dgram));
 DECLARE_POOL(pool_head_quic_rx_packet, "quic_rx_packet_pool", sizeof(struct quic_rx_packet));
 DECLARE_POOL(pool_head_quic_tx_packet, "quic_tx_packet_pool", sizeof(struct quic_tx_packet));
 DECLARE_STATIC_POOL(pool_head_quic_rx_crypto_frm, "quic_rx_crypto_frm_pool", sizeof(struct quic_rx_crypto_frm));
@@ -5401,10 +5402,62 @@ static ssize_t quic_dgram_read(unsigned char *buf, size_t len, void *owner,
        return -1;
 }
 
-ssize_t quic_lstnr_dgram_read(unsigned char *buf, size_t len, void *owner,
-                              struct sockaddr_storage *saddr)
+/* Retreive the DCID from a QUIC datagram or packet with <buf> as first octet.
+ * Returns 1 if succeeded, 0 if not.
+ */
+static int quic_get_dgram_dcid(unsigned char *buf, const unsigned char *end,
+                               unsigned char **dcid, size_t *dcid_len)
+{
+       int long_header;
+       size_t minlen, skip;
+
+       if (!(*buf & QUIC_PACKET_FIXED_BIT))
+               goto err;
+
+       long_header = *buf & QUIC_PACKET_LONG_HEADER_BIT;
+       minlen = long_header ?
+               QUIC_LONG_PACKET_MINLEN : QUIC_SHORT_PACKET_MINLEN + QUIC_HAP_CID_LEN;
+       skip = long_header ? QUIC_LONG_PACKET_DCID_OFF : QUIC_SHORT_PACKET_DCID_OFF;
+       if (end - buf <= minlen || !(*buf & QUIC_PACKET_FIXED_BIT))
+               goto err;
+
+       buf += skip;
+       *dcid_len = long_header ? *buf++ : QUIC_HAP_CID_LEN;
+       if (*dcid_len > QUIC_CID_MAXLEN || end - buf <= *dcid_len)
+               goto err;
+
+       *dcid = buf;
+
+       return 1;
+
+ err:
+       TRACE_PROTO("wrong datagram", QUIC_EV_CONN_LPKT);
+       return 0;
+}
+
+int quic_lstnr_dgram_read(unsigned char *buf, size_t len, void *owner,
+                          struct sockaddr_storage *saddr, struct list *dgrams)
 {
+       struct quic_dgram *dgram;
+       unsigned char *dcid;
+       size_t dcid_len;
+
+       if (!len || !quic_get_dgram_dcid(buf, buf + len, &dcid, &dcid_len))
+               goto out;
+
+       dgram = pool_alloc(pool_head_quic_dgram);
+       if (!dgram)
+               goto out;
+
+       dgram->buf = buf;
+       dgram->len = len;
+       dgram->saddr = *saddr;
+       LIST_APPEND(dgrams, &dgram->list);
+
        return quic_dgram_read(buf, len, owner, saddr, qc_lstnr_pkt_rcv);
+
+ out:
+       return 0;
 }
 
 /* Function to automatically activate QUIC traces on stdout.