]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
kdig: rebase kdig on ngtcp2-v0.6.0
authorJan Hák <jan.hak@nic.cz>
Tue, 21 Jun 2022 10:28:26 +0000 (12:28 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Wed, 22 Jun 2022 08:00:23 +0000 (10:00 +0200)
src/utils/common/quic.c
src/utils/common/quic.h

index c0b8478743cecc21f612c5eef756735dc14c0149..d11d1611d6b97b6e4ad4e661300772f8c8aa6ca4 100644 (file)
@@ -276,6 +276,9 @@ static const ngtcp2_callbacks quic_client_callbacks = {
        NULL, /* lost_datagram */
        ngtcp2_crypto_get_path_challenge_data_cb,
        NULL, /* stream_stop_sending */
+       ngtcp2_crypto_version_negotiation_cb,
+       NULL, /* recv_rx_key */
+       NULL  /* recv_tx_key */
 };
 
 static int hook_func(gnutls_session_t session, unsigned int htype,
@@ -291,117 +294,6 @@ static int hook_func(gnutls_session_t session, unsigned int htype,
        return GNUTLS_E_SUCCESS;
 }
 
-static int secret_func(gnutls_session_t session,
-        gnutls_record_encryption_level_t gtls_level, const void *rx_secret,
-        const void *tx_secret, size_t secretlen)
-{
-       quic_ctx_t *ctx = (quic_ctx_t *)gnutls_session_get_ptr(session);
-       ngtcp2_crypto_level level = quic_get_encryption_level(gtls_level);
-
-       if (rx_secret) {
-               int ret = ngtcp2_crypto_derive_and_install_rx_key(ctx->conn,
-                               NULL, NULL, NULL, level, rx_secret, secretlen);
-               if (ret != 0) {
-                       return -1;
-               }
-
-               if (level == NGTCP2_CRYPTO_LEVEL_APPLICATION) {
-                       quic_open_bidi_stream(ctx);
-               }
-       }
-
-       if (tx_secret &&
-           ngtcp2_crypto_derive_and_install_tx_key(ctx->conn, NULL, NULL,
-                       NULL, level, tx_secret, secretlen) != 0) {
-               return -1;
-       }
-
-       return GNUTLS_E_SUCCESS;
-}
-
-static int read_func(gnutls_session_t session,
-        gnutls_record_encryption_level_t gtls_level,
-        gnutls_handshake_description_t htype, const void *data, size_t datalen)
-{
-       if (htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC) {
-               return GNUTLS_E_SUCCESS;
-       }
-
-       quic_ctx_t *ctx = (quic_ctx_t *)gnutls_session_get_ptr(session);
-       if (ngtcp2_conn_submit_crypto_data(ctx->conn,
-               quic_get_encryption_level(gtls_level), (const uint8_t *)data,
-               datalen) != 0) {
-               return -1;
-       }
-
-       return GNUTLS_E_SUCCESS;
-}
-
-static int alert_read_func(gnutls_session_t session,
-        gnutls_record_encryption_level_t gtls_level,
-        gnutls_alert_level_t alert_level, gnutls_alert_description_t alert)
-{
-       (void)gtls_level;
-       (void)alert_level;
-
-       quic_ctx_t *ctx = (quic_ctx_t *)gnutls_session_get_ptr(session);
-       set_transport_error(ctx, NGTCP2_CRYPTO_ERROR | alert, NULL, 0);
-
-       return GNUTLS_E_SUCCESS;
-}
-
-static int tp_recv_func(gnutls_session_t session, const uint8_t *data,
-        size_t datalen)
-{
-       quic_ctx_t *ctx = (quic_ctx_t *)gnutls_session_get_ptr(session);
-       ngtcp2_transport_params params;
-
-       int ret = ngtcp2_decode_transport_params(&params,
-               NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS, data,
-               datalen);
-       if (ret != 0)   {
-               return -1;
-       }
-
-       ret = ngtcp2_conn_set_remote_transport_params(ctx->conn, &params);
-       if (ret != 0)   {
-               return -1;
-       }
-
-       return GNUTLS_E_SUCCESS;
-}
-
-static int tp_send_func(gnutls_session_t session, gnutls_buffer_t extdata)
-{
-       quic_ctx_t *ctx = (quic_ctx_t *)gnutls_session_get_ptr(session);
-       uint8_t buf[64];
-       ngtcp2_transport_params params;
-
-       ngtcp2_conn_get_local_transport_params(ctx->conn, &params);
-       ngtcp2_ssize nwrite = ngtcp2_encode_transport_params(buf, sizeof(buf),
-               NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO, &params);
-       if (nwrite < 0) {
-               return -1;
-       }
-
-       return gnutls_buffer_append_data(extdata, buf, (size_t)nwrite);
-}
-
-static int quic_setup_tls(tls_ctx_t *tls_ctx)
-{
-       gnutls_handshake_set_hook_function(tls_ctx->session,
-               GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST, hook_func);
-       gnutls_handshake_set_secret_function(tls_ctx->session, secret_func);
-       gnutls_handshake_set_read_function(tls_ctx->session, read_func);
-       gnutls_alert_set_read_function(tls_ctx->session, alert_read_func);
-       return gnutls_session_ext_register(tls_ctx->session,
-               "QUIC Transport Parameters",
-               NGTCP2_TLSEXT_QUIC_TRANSPORT_PARAMETERS_V1, GNUTLS_EXT_TLS,
-               tp_recv_func, tp_send_func, NULL, NULL, NULL,
-               GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_CLIENT_HELLO |
-               GNUTLS_EXT_FLAG_EE);
-}
-
 static int quic_send_data(quic_ctx_t *ctx, int sockfd, int family,
         ngtcp2_vec *datav, size_t datavlen)
 {
@@ -625,12 +517,21 @@ static int verify_certificate(gnutls_session_t session)
        return tls_certificate_verification(ctx->tls);
 }
 
+static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref)
+{
+       return ((quic_ctx_t *)conn_ref->user_data)->conn;
+}
+
 int quic_ctx_init(quic_ctx_t *ctx, tls_ctx_t *tls_ctx, const quic_params_t *params)
 {
        if (ctx == NULL || tls_ctx == NULL || params == NULL) {
                return KNOT_EINVAL;
        }
 
+       ctx->conn_ref = (ngtcp2_crypto_conn_ref) {
+               .get_conn = get_conn,
+               .user_data = ctx
+       };
        ctx->params = *params;
        ctx->tls = tls_ctx;
        ctx->state = OPENING;
@@ -709,7 +610,9 @@ int quic_ctx_connect(quic_ctx_t *ctx, int sockfd, struct addrinfo *dst_addr)
                return KNOT_NET_ECONNECT;
        }
 
-       ret = quic_setup_tls(ctx->tls);
+       gnutls_handshake_set_hook_function(ctx->tls->session,
+               GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST, hook_func);
+       ret = ngtcp2_crypto_gnutls_configure_client_session(ctx->tls->session);
        if (ret != KNOT_EOK) {
                tls_ctx_deinit(ctx->tls);
                return KNOT_NET_ECONNECT;
@@ -751,9 +654,11 @@ int quic_ctx_connect(quic_ctx_t *ctx, int sockfd, struct addrinfo *dst_addr)
                        tls_ctx_deinit(ctx->tls);
                        return ret;
                }
-
-               ngtcp2_conn_get_remote_transport_params(ctx->conn, &params);
-               timeout = quic_ceil_duration_to_ms(params.max_ack_delay);
+               const ngtcp2_transport_params *pp =
+                       ngtcp2_conn_get_remote_transport_params(ctx->conn);
+               if (pp != NULL) {
+                       timeout = quic_ceil_duration_to_ms(pp->max_ack_delay);
+               }
        }
 
        return KNOT_EOK;
@@ -766,7 +671,6 @@ int quic_send_dns_query(quic_ctx_t *ctx, int sockfd, struct addrinfo *srv,
                return KNOT_EINVAL;
        }
 
-       ngtcp2_transport_params params;
        uint16_t query_length = htons(buf_len);
        ngtcp2_vec datav[] = {
                {
@@ -792,6 +696,7 @@ int quic_send_dns_query(quic_ctx_t *ctx, int sockfd, struct addrinfo *srv,
                quic_send(ctx, sockfd, srv->ai_family);
        }
 
+       int timeout =  ctx->tls->wait * 1000;
        while (ctx->stream.out_ack == 0) {
                if (quic_timeout(ctx->idle_ts, ctx->tls->wait)) {
                        WARN("QUIC, failed to send\n");
@@ -809,8 +714,11 @@ int quic_send_dns_query(quic_ctx_t *ctx, int sockfd, struct addrinfo *srv,
                pdatav = NULL;
                datavlen = 0;
 
-               ngtcp2_conn_get_remote_transport_params(ctx->conn, &params);
-               int timeout = quic_ceil_duration_to_ms(params.max_ack_delay);
+               const ngtcp2_transport_params *pp =
+                       ngtcp2_conn_get_remote_transport_params(ctx->conn);
+               if (pp != NULL) {
+                       timeout = quic_ceil_duration_to_ms(pp->max_ack_delay);
+               }
                ret = poll(&pfd, 1, timeout);
                if (ret < 0) {
                        WARN("QUIC, failed to send\n");
@@ -823,6 +731,9 @@ int quic_send_dns_query(quic_ctx_t *ctx, int sockfd, struct addrinfo *srv,
                        WARN("QUIC, failed to send\n");
                        return ret;
                }
+               if (ctx->stream.in_parsed_size) {
+                       return KNOT_EOK;
+               }
        }
 
        return KNOT_EOK;
@@ -850,10 +761,13 @@ int quic_recv_dns_response(quic_ctx_t *ctx, uint8_t *buf, const size_t buf_len,
                .revents = 0,
        };
 
-       ngtcp2_transport_params params;
+       int timeout = ctx->tls->wait * 1000;
        while (!quic_timeout(ctx->idle_ts, ctx->tls->wait)) {
-               ngtcp2_conn_get_remote_transport_params(ctx->conn, &params);
-               int timeout = quic_ceil_duration_to_ms(params.max_ack_delay);
+               const ngtcp2_transport_params *pp =
+                       ngtcp2_conn_get_remote_transport_params(ctx->conn);
+               if (pp != NULL) {
+                       timeout = quic_ceil_duration_to_ms(pp->max_ack_delay);
+               }
                ret = poll(&pfd, 1, timeout);
                if (ret < 0) {
                        WARN("QUIC, failed to receive reply (%s)\n",
index 1d428cf090aa241604b1620db483f7f8cfb1c0bd..d835604e03a4f86b85ce41f3d4ba3267f51f9fcc 100644 (file)
@@ -31,6 +31,7 @@ void quic_params_clean(quic_params_t *params);
 #ifdef LIBNGTCP2
 
 #include <ngtcp2/ngtcp2.h>
+#include <ngtcp2/ngtcp2_crypto.h>
 
 #include "utils/common/tls.h"
 
@@ -70,6 +71,7 @@ typedef enum {
 } quic_doq_error_t;
 
 typedef struct {
+       ngtcp2_crypto_conn_ref conn_ref;
        // Parameters
        quic_params_t params;