]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: quic: implement Initial token parsing
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 11 Jan 2022 13:11:32 +0000 (14:11 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 12 Jan 2022 10:08:48 +0000 (11:08 +0100)
Implement the parsing of token from Initial packets. It is expected that
the token contains a CID which is the DCID from the Initial packet
received from the client without token which triggers a Retry packet.
This CID is then used for transport parameters.

Note that at the moment Retry packet emission is not implemented. This
will be achieved in a following commit.

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

index 06c43fe59b9c637e406a80c8af8275e775318b77..78ced5160cca4cff32faaf208b539c88d70249f9 100644 (file)
@@ -435,6 +435,7 @@ struct quic_rx_packet {
        /* Packet number length */
        uint32_t pnl;
        uint64_t token_len;
+       const unsigned char *token;
        /* Packet length */
        uint64_t len;
        /* Packet length before decryption */
index 558e7048ffedbdae3bfeeec685fa9686fd93f1c2..6cf0d4bb7a21e3eda23cb0317dfa429df2351fb7 100644 (file)
@@ -4046,6 +4046,25 @@ static struct quic_conn *retrieve_qc_conn_from_cid(struct quic_rx_packet *pkt,
        return qc;
 }
 
+/* Parse the Retry token from buffer <token> whose size is <token_len>. This
+ * will extract the parameters stored in the token : <odcid>.
+ *
+ * Returns 0 on success else non-zero.
+ */
+static int parse_retry_token(const unsigned char *token, uint64_t token_len,
+                             struct quic_cid *odcid)
+{
+       uint64_t odcid_len;
+
+       if (!quic_dec_int(&odcid_len, &token, token + token_len))
+               return 1;
+
+       memcpy(odcid->data, token, odcid_len);
+       odcid->len = odcid_len;
+
+       return 0;
+}
+
 static ssize_t qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
                                 struct quic_rx_packet *pkt,
                                 struct quic_dgram_ctx *dgram_ctx,
@@ -4127,6 +4146,10 @@ static ssize_t qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
                         * The token must be provided in a Retry packet or NEW_TOKEN frame.
                         */
                        pkt->token_len = token_len;
+                       if (pkt->token_len) {
+                               pkt->token = buf;
+                               buf += pkt->token_len;
+                       }
                }
                else if (pkt->type != QUIC_PACKET_TYPE_0RTT) {
                        if (pkt->dcid.len != QUIC_HAP_CID_LEN) {
@@ -4168,9 +4191,19 @@ static ssize_t qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
                        odcid = &qc->rx.params.original_destination_connection_id;
                        /* Copy the transport parameters. */
                        qc->rx.params = l->bind_conf->quic_params;
+
                        /* Copy original_destination_connection_id transport parameter. */
-                       memcpy(odcid->data, &pkt->dcid.data, pkt->dcid.len);
-                       odcid->len = pkt->dcid.len;
+                       if (pkt->token_len) {
+                               if (parse_retry_token(pkt->token, pkt->token_len, odcid)) {
+                                       TRACE_PROTO("Error during Initial token parsing", QUIC_EV_CONN_LPKT, qc);
+                                       goto err;
+                               }
+                       }
+                       else {
+                               memcpy(odcid->data, &pkt->dcid.data, pkt->dcid.len);
+                               odcid->len = pkt->dcid.len;
+                       }
+
                        /* Copy the initial source connection ID. */
                        quic_cid_cpy(&qc->rx.params.initial_source_connection_id, &qc->scid);
                        qc->enc_params_len =