From: Frantisek Tobias Date: Mon, 6 Oct 2025 08:59:56 +0000 (+0200) Subject: daemon/quic: add version negotiation for initial packet X-Git-Tag: v6.2.0~2^2~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4dc487a43a080e7528cea8201e59bafcced13626;p=thirdparty%2Fknot-resolver.git daemon/quic: add version negotiation for initial packet --- diff --git a/daemon/quic_common.c b/daemon/quic_common.c index a9af89ef8..869943850 100644 --- a/daemon/quic_common.c +++ b/daemon/quic_common.c @@ -4,6 +4,7 @@ #include "quic_common.h" #include "libdnssec/random.h" #include "session2.h" +#include 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; +} diff --git a/daemon/quic_common.h b/daemon/quic_common.h index 49b795bdd..db25b8866 100644 --- a/daemon/quic_common.h +++ b/daemon/quic_common.h @@ -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); diff --git a/daemon/quic_conn.c b/daemon/quic_conn.c index 258df9a6b..32b29435f 100644 --- a/daemon/quic_conn.c +++ b/daemon/quic_conn.c @@ -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: diff --git a/daemon/quic_demux.c b/daemon/quic_demux.c index 166081b5c..a13229e2e 100644 --- a/daemon/quic_demux.c +++ b/daemon/quic_demux.c @@ -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);