]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/quic: add version negotiation for initial packet
authorFrantisek Tobias <frantisek.tobias@nic.cz>
Mon, 6 Oct 2025 08:59:56 +0000 (10:59 +0200)
committerFrantisek Tobias <frantisek.tobias@nic.cz>
Wed, 7 Jan 2026 13:39:14 +0000 (14:39 +0100)
daemon/quic_common.c
daemon/quic_common.h
daemon/quic_conn.c
daemon/quic_demux.c

index a9af89ef8391b27029d05178113d2e538d6fe61c..8699438502f1e92f024b88f3e54133c0356d4370 100644 (file)
@@ -4,6 +4,7 @@
 #include "quic_common.h"
 #include "libdnssec/random.h"
 #include "session2.h"
+#include <ngtcp2/ngtcp2.h>
 
 uint64_t quic_timestamp(void)
 {
@@ -47,3 +48,19 @@ void quic_event_close_connection(struct pl_quic_conn_sess_data *conn,
        session2_event(session, PROTOLAYER_EVENT_DISCONNECT, conn);
 }
 
+ssize_t send_version_negotiation(struct wire_buf *dest, ngtcp2_version_cid dec_cids,
+               ngtcp2_cid dcid, ngtcp2_cid scid)
+{
+       uint8_t rnd = 0;
+       dnssec_random_buffer(&rnd, sizeof(rnd));
+       uint32_t supported_quic[1] = { NGTCP2_PROTO_VER_V1 };
+       int ret = ngtcp2_pkt_write_version_negotiation(
+               wire_buf_free_space(dest),
+               wire_buf_free_space_length(dest),
+               rnd, dec_cids.scid, dec_cids.scidlen,
+               dec_cids.dcid, dec_cids.dcidlen, supported_quic,
+               sizeof(supported_quic) / sizeof(*supported_quic)
+       );
+
+       return ret;
+}
index 49b795bddcf09f5a40e433080610559ae2bb1e8e..db25b8866e5a0e4a37217b92ffc3b210765dbabd 100644 (file)
@@ -82,3 +82,5 @@ bool kr_quic_conn_timeout(struct pl_quic_conn_sess_data *conn, uint64_t *now);
 void init_random_cid(ngtcp2_cid *cid, size_t len);
 void quic_event_close_connection(struct pl_quic_conn_sess_data *conn,
                struct session2 *session);
+ssize_t send_version_negotiation(struct wire_buf *dest, ngtcp2_version_cid dec_cids,
+               ngtcp2_cid dcid, ngtcp2_cid scid);
index 258df9a6baba8bed87d9ffb0343b5d62dd4e9576..32b29435f2108dcb0582b6fb18daaf5c72111eaa 100644 (file)
@@ -564,9 +564,6 @@ static int send_special(struct pl_quic_conn_sess_data *conn,
 
        uint64_t now = quic_timestamp();
 
-       uint8_t rnd = 0;
-       dnssec_random_buffer(&rnd, sizeof(rnd));
-       uint32_t supported_quic[1] = { NGTCP2_PROTO_VER_V1 };
        ngtcp2_cid new_dcid;
        uint8_t retry_token[NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN];
        uint8_t stateless_reset_token[NGTCP2_STATELESS_RESET_TOKENLEN];
@@ -579,13 +576,10 @@ static int send_special(struct pl_quic_conn_sess_data *conn,
        int ret = 0;
        switch (action) {
        case QUIC_SEND_VERSION_NEGOTIATION:
-               ret = ngtcp2_pkt_write_version_negotiation(
-                       wire_buf_free_space(ctx->payload.wire_buf),
-                       wire_buf_free_space_length(ctx->payload.wire_buf),
-                       rnd, conn->dec_cids.scid, conn->dec_cids.scidlen,
-                       conn->dec_cids.dcid, conn->dec_cids.dcidlen, supported_quic,
-                       sizeof(supported_quic) / sizeof(*supported_quic)
-               );
+               ret = send_version_negotiation(ctx->payload.wire_buf,
+                               conn->dec_cids,
+                               conn->dcid,
+                               conn->scid);
                break;
 
        case QUIC_SEND_RETRY:
index 166081b5c09c6b6e62d476e0ab0f9e8f358af815..a13229e2e4ee6d120c9cef81588989e6ab91698d 100644 (file)
@@ -202,7 +202,16 @@ static enum protolayer_iter_cb_result pl_quic_demux_unwrap(void *sess_data,
        ngtcp2_cid_init(&scid, dec_cids.scid, dec_cids.scidlen);
 
        if (ret == NGTCP2_ERR_VERSION_NEGOTIATION) {
-               /* version negotiation packet should be sent */
+               wire_buf_reset(ctx->payload.wire_buf);
+               send_version_negotiation(ctx->payload.wire_buf,
+                               dec_cids, dcid, scid);
+               if (ret >= 0) {
+                       session2_wrap(demux->h.session, ctx->payload, ctx->comm,
+                                       ctx->req, ctx->finished_cb,
+                                       ctx->finished_cb_baton);
+               }
+
+               return protolayer_break(ctx, kr_ok());
        }
 
        qconn = kr_quic_table_lookup(&dcid, demux->conn_table);