]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
requestor: fix local certificate initialization
authorDaniel Salzman <daniel.salzman@nic.cz>
Tue, 4 Apr 2023 17:50:00 +0000 (19:50 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Tue, 23 May 2023 08:42:01 +0000 (10:42 +0200)
19 files changed:
src/knot/dnssec/ds_query.c
src/knot/dnssec/ds_query.h
src/knot/events/handlers/ds_check.c
src/knot/events/handlers/ds_push.c
src/knot/events/handlers/notify.c
src/knot/events/handlers/refresh.c
src/knot/events/handlers/update.c
src/knot/modules/dnsproxy/dnsproxy.c
src/knot/modules/onlinesign/onlinesign.c
src/knot/query/quic-requestor.c
src/knot/query/quic-requestor.h
src/knot/query/requestor.c
src/knot/query/requestor.h
src/knot/server/server.c
src/libknot/quic/quic.c
src/libknot/quic/quic.h
src/libknot/quic/quic_conn.c
src/utils/kxdpgun/main.c
tests/knot/test_requestor.c

index c71f3194173bdd8deb07bbef91aa69de034cf5c8..f768d1522d7686ef372908461f21fc83f5914aac 100644 (file)
@@ -24,6 +24,7 @@
 #include "knot/query/layer.h"
 #include "knot/query/query.h"
 #include "knot/query/requestor.h"
+#include "knot/server/server.h"
 
 static bool match_key_ds(knot_kasp_key_t *key, knot_rdata_t *ds)
 {
@@ -171,7 +172,8 @@ static const knot_layer_api_t ds_query_api = {
 };
 
 static int try_ds(conf_t *conf, const knot_dname_t *zone_name, const conf_remote_t *parent,
-                  knot_kasp_key_t *key, knot_kasp_key_t *not_key, size_t timeout, uint32_t *ds_ttl)
+                  knot_kasp_key_t *key, knot_kasp_key_t *not_key, server_t *server,
+                  size_t timeout, uint32_t *ds_ttl)
 {
        // TODO: Abstract interface to issue DNS queries. This is almost copy-pasted.
 
@@ -199,7 +201,7 @@ static int try_ds(conf_t *conf, const knot_dname_t *zone_name, const conf_remote
                return KNOT_ENOMEM;
        }
 
-       knot_request_t *req = knot_request_make(NULL, parent, pkt, 0);
+       knot_request_t *req = knot_request_make(NULL, parent, pkt, server->quic_creds, 0);
        if (req == NULL) {
                knot_request_free(req, NULL);
                knot_requestor_clear(&requestor);
@@ -239,7 +241,7 @@ static knot_kasp_key_t *get_not_key(kdnssec_ctx_t *kctx, knot_kasp_key_t *key)
 }
 
 static bool parents_have_ds(conf_t *conf, kdnssec_ctx_t *kctx, knot_kasp_key_t *key,
-                            size_t timeout, uint32_t *max_ds_ttl)
+                            server_t *server, size_t timeout, uint32_t *max_ds_ttl)
 {
        bool success = false;
        knot_dynarray_foreach(parent, knot_kasp_parent_t, i, kctx->policy->parents) {
@@ -247,7 +249,7 @@ static bool parents_have_ds(conf_t *conf, kdnssec_ctx_t *kctx, knot_kasp_key_t *
                for (size_t j = 0; j < i->addrs; j++) {
                        uint32_t ds_ttl = 0;
                        int ret = try_ds(conf, kctx->zone->dname, &i->addr[j], key,
-                                        get_not_key(kctx, key), timeout, &ds_ttl);
+                                        get_not_key(kctx, key), server, timeout, &ds_ttl);
                        if (ret == KNOT_EOK) {
                                *max_ds_ttl = MAX(*max_ds_ttl, ds_ttl);
                                success = true;
@@ -265,7 +267,8 @@ static bool parents_have_ds(conf_t *conf, kdnssec_ctx_t *kctx, knot_kasp_key_t *
        return success;
 }
 
-int knot_parent_ds_query(conf_t *conf, kdnssec_ctx_t *kctx, size_t timeout)
+int knot_parent_ds_query(conf_t *conf, kdnssec_ctx_t *kctx, struct server *server,
+                         size_t timeout)
 {
        uint32_t max_ds_ttl = 0;
 
@@ -275,7 +278,7 @@ int knot_parent_ds_query(conf_t *conf, kdnssec_ctx_t *kctx, size_t timeout)
                    knot_time_cmp(key->timing.ready, kctx->now) <= 0 &&
                    knot_time_cmp(key->timing.active, kctx->now) > 0) {
                        assert(key->is_ksk);
-                       if (parents_have_ds(conf, kctx, key, timeout, &max_ds_ttl)) {
+                       if (parents_have_ds(conf, kctx, key, server, timeout, &max_ds_ttl)) {
                                return knot_dnssec_ksk_sbm_confirm(kctx, max_ds_ttl + kctx->policy->ksk_sbm_delay);
                        } else {
                                return KNOT_ENOENT;
index 1144d21d396d58085b51260d1efa0c8c6d65641e..f5415e4ff4b610eef576216f48a02999486b3659 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -19,4 +19,7 @@
 #include "knot/dnssec/zone-keys.h"
 #include "knot/dnssec/context.h"
 
-int knot_parent_ds_query(conf_t *conf, kdnssec_ctx_t *kctx, size_t timeout);
+struct server;
+
+int knot_parent_ds_query(conf_t *conf, kdnssec_ctx_t *kctx, struct server *server,
+                         size_t timeout);
index 0138beda20f1d4ad0ddef0c5ac684fccee2b36c2..7d5af9d36eaa6e000d29f5274dc6dbc54d620c0d 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -26,7 +26,8 @@ int event_ds_check(conf_t *conf, zone_t *zone)
                return ret;
        }
 
-       ret = knot_parent_ds_query(conf, &ctx, conf->cache.srv_tcp_remote_io_timeout);
+       ret = knot_parent_ds_query(conf, &ctx, zone->server,
+                                  conf->cache.srv_tcp_remote_io_timeout);
 
        zone->timers.next_ds_check = 0;
        switch (ret) {
index a3ba936b2c9d92792e9c7540a0120387915867dc..24e87779f6c17924ce80260370235a49198927f5 100644 (file)
@@ -20,6 +20,7 @@
 #include "knot/conf/conf.h"
 #include "knot/query/query.h"
 #include "knot/query/requestor.h"
+#include "knot/server/server.h"
 #include "knot/zone/zone.h"
 #include "libknot/errcode.h"
 
@@ -198,7 +199,8 @@ static int send_ds_push(conf_t *conf, zone_t *zone,
                return KNOT_ENOMEM;
        }
 
-       knot_request_t *req = knot_request_make(NULL, parent, pkt, 0);
+       knot_request_t *req = knot_request_make(NULL, parent, pkt,
+                                               zone->server->quic_creds, 0);
        if (req == NULL) {
                knot_rdataset_clear(&data.del_old_ds.rrs, NULL);
                knot_request_free(req, NULL);
index 5c0a4dc20d815425c48aaf3ec821325af58a57b2..26fe7df1b49dd2db14a32b7ee03a0f5e1b111d22 100644 (file)
@@ -21,6 +21,7 @@
 #include "knot/conf/conf.h"
 #include "knot/query/query.h"
 #include "knot/query/requestor.h"
+#include "knot/server/server.h"
 #include "knot/zone/zone.h"
 #include "libknot/errcode.h"
 
@@ -106,7 +107,8 @@ static int send_notify(conf_t *conf, zone_t *zone, const knot_rrset_t *soa,
        }
 
        knot_request_flag_t flags = conf->cache.srv_tcp_fastopen ? KNOT_REQUEST_TFO : 0;
-       knot_request_t *req = knot_request_make(NULL, slave, pkt, flags);
+       knot_request_t *req = knot_request_make(NULL, slave, pkt,
+                                               zone->server->quic_creds, flags);
        if (req == NULL) {
                knot_request_free(req, NULL);
                knot_requestor_clear(&requestor);
index cd7638d5a19854fd798323c0782135522b6b46b3..cd52feb955392403cfede40912e0b73d95552e5f 100644 (file)
@@ -28,6 +28,7 @@
 #include "knot/query/layer.h"
 #include "knot/query/query.h"
 #include "knot/query/requestor.h"
+#include "knot/server/server.h"
 #include "knot/updates/changesets.h"
 #include "knot/zone/adjust.h"
 #include "knot/zone/digest.h"
@@ -1300,7 +1301,8 @@ static int try_refresh(conf_t *conf, zone_t *zone, const conf_remote_t *master,
        }
 
        knot_request_flag_t flags = conf->cache.srv_tcp_fastopen ? KNOT_REQUEST_TFO : 0;
-       knot_request_t *req = knot_request_make(NULL, master, pkt, flags);
+       knot_request_t *req = knot_request_make(NULL, master, pkt,
+                                               zone->server->quic_creds, flags);
        if (req == NULL) {
                knot_request_free(req, NULL);
                knot_requestor_clear(&requestor);
index 1ce787d55425f957ab1171c4697e7b9186948ff7..6bcf95098614f48e7c146ff2ea46325875b08d01 100644 (file)
@@ -21,6 +21,7 @@
 #include "knot/nameserver/process_query.h"
 #include "knot/query/capture.h"
 #include "knot/query/requestor.h"
+#include "knot/server/server.h"
 #include "knot/updates/ddns.h"
 #include "knot/zone/digest.h"
 #include "knot/zone/zone.h"
@@ -214,7 +215,8 @@ static void process_requests(conf_t *conf, zone_t *zone, list_t *requests)
        zone_schedule_notify(zone, 1);
 }
 
-static int remote_forward(conf_t *conf, knot_request_t *request, conf_remote_t *remote)
+static int remote_forward(conf_t *conf, knot_request_t *request, conf_remote_t *remote,
+                          zone_t *zone)
 {
        /* Copy request (without possible TSIG) and assign new ID. */
        knot_pkt_t *query = knot_pkt_new(NULL, request->query->size +
@@ -245,7 +247,8 @@ static int remote_forward(conf_t *conf, knot_request_t *request, conf_remote_t *
 
        /* Create a request. */
        knot_request_flag_t flags = conf->cache.srv_tcp_fastopen ? KNOT_REQUEST_TFO : 0;
-       knot_request_t *req = knot_request_make(NULL, remote, query, flags);
+       knot_request_t *req = knot_request_make(NULL, remote, query,
+                                               zone->server->quic_creds, flags);
        if (req == NULL) {
                knot_requestor_clear(&re);
                knot_pkt_free(query);
@@ -280,7 +283,7 @@ static void forward_request(conf_t *conf, zone_t *zone, knot_request_t *request)
        for (size_t i = 0; i < addr_count; i++) {
                conf_remote_t master = conf_remote(conf, &remote, i);
 
-               ret = remote_forward(conf, request, &master);
+               ret = remote_forward(conf, request, &master, zone);
                if (ret == KNOT_EOK) {
                        break;
                }
index e81f49fabfe969e474b17751c0e4d58a1053b5bb..1ecd851073a4ec571f281eed0dca064e327b4d97 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -108,7 +108,7 @@ static knotd_state_t dnsproxy_fwd(knotd_state_t state, knot_pkt_t *pkt,
        const struct sockaddr_storage *dst = &proxy->remote;
        const struct sockaddr_storage *src = &proxy->via;
        knot_request_t *req = knot_request_make_generic(re.mm, dst, src, qdata->query,
-                                                       NULL, NULL, 0, flags);
+                                                       NULL, NULL, NULL, 0, flags);
        if (req == NULL) {
                knot_requestor_clear(&re);
                return state; /* Ignore, not enough memory. */
index 56b1c03f2d45d35693c645330220bebeb78d495c..d3dc3f7cd77624422183ddb9a73eb658c4b01b25 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -488,7 +488,7 @@ static knotd_in_state_t pre_routine(knotd_in_state_t state, knot_pkt_t *pkt,
        int ret = KNOT_ESEMCHECK;
        if (knot_time_cmp(ctx->event_parent_ds_q, mod->dnssec->now) <= 0) {
                pthread_rwlock_rdlock(&ctx->signing_mutex);
-               ret = knot_parent_ds_query(conf(), mod->dnssec, 1000);
+               ret = knot_parent_ds_query(conf(), mod->dnssec, qdata->params->server, 1000);
                pthread_rwlock_unlock(&ctx->signing_mutex);
                if (ret != KNOT_EOK && ret != KNOT_NO_READY_KEY && mod->dnssec->policy->ksk_sbm_check_interval > 0) {
                        ctx->event_parent_ds_q = mod->dnssec->now + mod->dnssec->policy->ksk_sbm_check_interval;
index 2e3032bff31146c1b8f953c87a8bc7df9bf47d61..7e93fdb306f1b1880b276270c09ec942a50062d7 100644 (file)
@@ -84,8 +84,9 @@ void qr_free_reply(struct knot_quic_reply *r)
 struct knot_quic_reply *knot_qreq_connect(int fd,
                                           struct sockaddr_storage *remote,
                                           struct sockaddr_storage *local,
-                                          const uint8_t *pin,
-                                          uint8_t pin_len,
+                                          const struct knot_quic_creds *local_creds,
+                                          const uint8_t *peer_pin,
+                                          uint8_t peer_pin_len,
                                           int timeout_ms)
 {
        knot_quic_reply_t *r = calloc(1, sizeof(*r) + 2 * sizeof(struct iovec) +
@@ -105,8 +106,8 @@ struct knot_quic_reply *knot_qreq_connect(int fd,
        r->send_reply = qr_send_reply;
        r->free_reply = qr_free_reply;
 
-       struct knot_quic_creds *creds = knot_quic_init_creds(false, NULL, NULL,
-                                                            pin, pin_len);
+       struct knot_quic_creds *creds = knot_quic_init_creds_peer(local_creds,
+                                                                 peer_pin, peer_pin_len);
        if (creds == NULL) {
                free(r);
                return NULL;
index 605d062b6523b7d0be5846355b71af78d5e5abe6..05b293cf8116c9bbba7ceffb39ecc64f6cced6ff 100644 (file)
 
 #include "contrib/sockaddr.h"
 
+struct knot_quic_creds;
 struct knot_quic_reply;
 
 struct knot_quic_reply *knot_qreq_connect(int fd,
                                           struct sockaddr_storage *remote,
                                           struct sockaddr_storage *local,
-                                          const uint8_t *pin,
-                                          uint8_t pin_len,
+                                          const struct knot_quic_creds *local_creds,
+                                          const uint8_t *peer_pin,
+                                          uint8_t peer_pin_len,
                                           int timeout_ms);
 
 int knot_qreq_send(struct knot_quic_reply *r, const struct iovec *data);
index 57cb8a3d0f100f521fb623dbe8d4bdb9b8f1057f..1d370e4c326f003882940a5acd40bfc64a058c49 100644 (file)
@@ -90,8 +90,9 @@ static int request_ensure_connected(knot_request_t *request, bool *reused_fd, in
                }
 #ifdef ENABLE_QUIC
                request->quic_ctx = knot_qreq_connect(request->fd, &request->remote,
-                                                     &request->source, request->pin,
-                                                     request->pin_len, timeout_ms);
+                                                     &request->source, request->creds,
+                                                     request->pin, request->pin_len,
+                                                     timeout_ms);
                if (request->quic_ctx == NULL) {
                        close(request->fd);
                        return KNOT_ECONN;
@@ -189,6 +190,7 @@ knot_request_t *knot_request_make_generic(knot_mm_t *mm,
                                           const struct sockaddr_storage *remote,
                                           const struct sockaddr_storage *source,
                                           knot_pkt_t *query,
+                                          const struct knot_quic_creds *creds,
                                           const knot_tsig_key_t *tsig_key,
                                           const uint8_t *pin,
                                           size_t pin_len,
@@ -224,6 +226,7 @@ knot_request_t *knot_request_make_generic(knot_mm_t *mm,
        }
        tsig_init(&request->tsig, tsig_key);
 
+       request->creds = creds;
        if (flags & KNOT_REQUEST_QUIC && pin_len > 0) {
                request->pin_len = pin_len;
                memcpy(request->pin, pin, pin_len);
@@ -235,6 +238,7 @@ knot_request_t *knot_request_make_generic(knot_mm_t *mm,
 knot_request_t *knot_request_make(knot_mm_t *mm,
                                   const conf_remote_t *remote,
                                   knot_pkt_t *query,
+                                  const struct knot_quic_creds *creds,
                                   knot_request_flag_t flags)
 {
        if (remote->quic) {
@@ -242,7 +246,7 @@ knot_request_t *knot_request_make(knot_mm_t *mm,
        }
 
        return knot_request_make_generic(mm, &remote->addr, &remote->via,
-                                        query, &remote->key, remote->pin,
+                                        query, creds, &remote->key, remote->pin,
                                         remote->pin_len, flags);
 }
 
index d576fd864cd53a335925234a2c22438ab775bbea..eb7bee7bbfdd8d4a7f0c04f1877b462dbcbd4b2f 100644 (file)
@@ -25,6 +25,7 @@
 #include "libknot/mm_ctx.h"
 #include "libknot/rrtype/tsig.h"
 
+struct knot_quic_creds;
 struct knot_quic_reply;
 
 typedef enum {
@@ -61,6 +62,7 @@ typedef struct {
 
        knot_sign_context_t sign; /*!< Required for async. DDNS processing. */
 
+       const struct knot_quic_creds *creds;
        size_t pin_len;
        uint8_t pin[];
 } knot_request_t;
@@ -72,6 +74,7 @@ typedef struct {
  * \param remote    Remote endpoint address.
  * \param source    Source address (or NULL).
  * \param query     Query message.
+ * \param creds     Local (server) credentials.
  * \param tsig_key  TSIG key for authentication.
  * \param pin       Possible remote certificate PIN.
  * \param pin_len   Length of the remote certificate PIN.
@@ -83,6 +86,7 @@ knot_request_t *knot_request_make_generic(knot_mm_t *mm,
                                           const struct sockaddr_storage *remote,
                                           const struct sockaddr_storage *source,
                                           knot_pkt_t *query,
+                                          const struct knot_quic_creds *creds,
                                           const knot_tsig_key_t *tsig_key,
                                           const uint8_t *pin,
                                           size_t pin_len,
@@ -97,6 +101,7 @@ knot_request_t *knot_request_make_generic(knot_mm_t *mm,
 knot_request_t *knot_request_make(knot_mm_t *mm,
                                   const conf_remote_t *remote,
                                   knot_pkt_t *query,
+                                  const struct knot_quic_creds *creds,
                                   knot_request_flag_t flags);
 
 /*!
index 05313edb31192d480f66fa17c475f8ffe8a76c93..077e4918bf7bc5922b905e38acc9700e22de90ea 100644 (file)
@@ -551,7 +551,7 @@ static int init_creds(server_t *server, conf_t *conf)
                log_debug("QUIC, using self generated key '%s' with "
                          "one-time certificate", key_file);
        }
-       server->quic_creds = knot_quic_init_creds(true, cert_file, key_file, NULL, 0);
+       server->quic_creds = knot_quic_init_creds(cert_file, key_file);
        free(cert_file);
        if (server->quic_creds == NULL) {
                log_error("QUIC, failed to initialize server credentials with key '%s'",
index e4ec5600c9637c16b9c113bbd9d5c62963a0cd1e..52898182bad235622f6233a298a05a0e75d9bcaa 100644 (file)
@@ -63,8 +63,9 @@ typedef struct knot_quic_creds {
        gnutls_certificate_credentials_t tls_cert;
        gnutls_anti_replay_t tls_anti_replay;
        gnutls_datum_t tls_ticket_key;
-       uint8_t *peer_pin;
+       bool peer;
        uint8_t peer_pin_len;
+       uint8_t peer_pin[];
 } knot_quic_creds_t;
 
 typedef struct knot_quic_session {
@@ -245,11 +246,8 @@ finish:
 }
 
 _public_
-struct knot_quic_creds *knot_quic_init_creds(bool server,
-                                             const char *cert_file,
-                                             const char *key_file,
-                                             const uint8_t *peer_pin,
-                                             uint8_t peer_pin_len)
+struct knot_quic_creds *knot_quic_init_creds(const char *cert_file,
+                                             const char *key_file)
 {
        knot_quic_creds_t *creds = calloc(1, sizeof(*creds));
        if (creds == NULL) {
@@ -261,47 +259,56 @@ struct knot_quic_creds *knot_quic_init_creds(bool server,
                goto fail;
        }
 
-       if (server) {
-               ret = gnutls_anti_replay_init(&creds->tls_anti_replay);
-               if (ret != GNUTLS_E_SUCCESS) {
-                       goto fail;
-               }
-               gnutls_anti_replay_set_add_function(creds->tls_anti_replay, tls_anti_replay_db_add_func);
-               gnutls_anti_replay_set_ptr(creds->tls_anti_replay, NULL);
-
-               if (cert_file != NULL) {
-                       ret = gnutls_certificate_set_x509_key_file(creds->tls_cert,
-                                                                  cert_file, key_file,
-                                                                  GNUTLS_X509_FMT_PEM);
-               } else {
-                       ret = self_signed_cert(creds->tls_cert, key_file);
-               }
-               if (ret != GNUTLS_E_SUCCESS) {
-                       goto fail;
-               }
+       ret = gnutls_anti_replay_init(&creds->tls_anti_replay);
+       if (ret != GNUTLS_E_SUCCESS) {
+               goto fail;
+       }
+       gnutls_anti_replay_set_add_function(creds->tls_anti_replay, tls_anti_replay_db_add_func);
+       gnutls_anti_replay_set_ptr(creds->tls_anti_replay, NULL);
 
-               ret = gnutls_session_ticket_key_generate(&creds->tls_ticket_key);
-               if (ret != GNUTLS_E_SUCCESS) {
-                       goto fail;
-               }
+       if (cert_file != NULL) {
+               ret = gnutls_certificate_set_x509_key_file(creds->tls_cert,
+                                                          cert_file, key_file,
+                                                          GNUTLS_X509_FMT_PEM);
        } else {
-               if (peer_pin_len > 0) {
-                       creds->peer_pin = malloc(peer_pin_len);
-                       if (creds->peer_pin == NULL || peer_pin == NULL) {
-                               goto fail;
-                       }
-                       memcpy(creds->peer_pin, peer_pin, peer_pin_len);
-                       creds->peer_pin_len = peer_pin_len;
-               }
+               ret = self_signed_cert(creds->tls_cert, key_file);
+       }
+       if (ret != GNUTLS_E_SUCCESS) {
+               goto fail;
        }
 
-       return creds;
+       ret = gnutls_session_ticket_key_generate(&creds->tls_ticket_key);
+       if (ret != GNUTLS_E_SUCCESS) {
+               goto fail;
+       }
 
+       return creds;
 fail:
        knot_quic_free_creds(creds);
        return NULL;
 }
 
+_public_
+struct knot_quic_creds *knot_quic_init_creds_peer(const struct knot_quic_creds *local_creds,
+                                                  const uint8_t *peer_pin,
+                                                  uint8_t peer_pin_len)
+{
+       knot_quic_creds_t *creds = calloc(1, sizeof(*creds) + peer_pin_len);
+       if (creds == NULL) {
+               return NULL;
+       }
+
+       creds->peer = true;
+       creds->tls_cert = local_creds->tls_cert;
+
+       if (peer_pin_len > 0 && peer_pin != NULL) {
+               memcpy(creds->peer_pin, peer_pin, peer_pin_len);
+               creds->peer_pin_len = peer_pin_len;
+       }
+
+       return creds;
+}
+
 _public_
 int knot_quic_creds_cert(struct knot_quic_creds *creds, struct gnutls_x509_crt_int **cert)
 {
@@ -330,12 +337,13 @@ void knot_quic_free_creds(struct knot_quic_creds *creds)
                return;
        }
 
-       gnutls_certificate_free_credentials(creds->tls_cert);
+       if (!creds->peer && creds->tls_cert != NULL) {
+               gnutls_certificate_free_credentials(creds->tls_cert);
+       }
        gnutls_anti_replay_deinit(creds->tls_anti_replay);
        if (creds->tls_ticket_key.data != NULL) {
                tls_session_ticket_key_free(&creds->tls_ticket_key);
        }
-       free(creds->peer_pin);
        free(creds);
 }
 
index d939e09c9058164e0c0b2716f78c8b2d85dd2c0d..10624319a1acef978e9ac6ce61ebfa814f430211 100644 (file)
@@ -74,19 +74,26 @@ int knot_quic_session_load(knot_quic_conn_t *conn, struct knot_quic_session *ses
 /*!
  * \brief Init server TLS certificate for DoQ.
  *
- * \param server        Initializing for server-side (client otherwise).
- * \param cert_file     X509 certificate PEM file path/name.
+ * \param cert_file     X509 certificate PEM file path/name (NULL if auto-generated).
  * \param key_file      Key PEM file path/name.
+ *
+ * \return Initialized creds.
+ */
+struct knot_quic_creds *knot_quic_init_creds(const char *cert_file,
+                                             const char *key_file);
+
+/*!
+ * \brief Init peer TLS certificate for DoQ.
+ *
+ * \param local_creds   Local credentials if server.
  * \param peer_pin      Optional peer certificate pin to check.
  * \param peer_pin_len  Length of the peer pin. Set 0 if not specified.
  *
  * \return Initialized creds.
  */
-struct knot_quic_creds *knot_quic_init_creds(bool server,
-                                             const char *cert_file,
-                                             const char *key_file,
-                                             const uint8_t *peer_pin,
-                                             uint8_t peer_pin_len);
+struct knot_quic_creds *knot_quic_init_creds_peer(const struct knot_quic_creds *local_creds,
+                                                  const uint8_t *peer_pin,
+                                                  uint8_t peer_pin_len);
 
 /*!
  * \brief Gets the certificate from credentials.
index c820855a8c4dfd2bfe298d00ca1f946ff8a09266..4fa68a85b1fc34ed92ffedb7748cda8d49110e63 100644 (file)
@@ -214,6 +214,10 @@ void quic_stream_free(knot_quic_conn_t *conn, int64_t stream_id)
 _public_
 void knot_quic_table_rem(knot_quic_conn_t *conn, knot_quic_table_t *table)
 {
+       if (conn->conn == NULL) {
+               return;
+       }
+
        if (conn->streams_count == -1) { // kxdpgun special
                conn->streams_count = 1;
        }
index c07fb7c6acf4ab28c0a3b8c522934bcac9e6ee26..73c0f88cff28ecd679d146da4f61c0e1fd3df8d7 100644 (file)
@@ -494,7 +494,7 @@ void *xdp_gun_thread(void *_ctx)
        }
        if (ctx->quic) {
 #ifdef ENABLE_QUIC
-               quic_creds = knot_quic_init_creds(false, NULL, NULL, NULL, 0);
+               quic_creds = knot_quic_init_creds_peer(NULL, NULL, 0);
                if (quic_creds == NULL) {
                        ERR2("failed to initialize QUIC context");
                        return NULL;
index d64b9ad6c9356e4ccf5ba5058eac366e48396b19..4c8f17e3e8fadf2db1362035c55d7ccf49eb5401 100644 (file)
@@ -93,7 +93,7 @@ static knot_request_t *make_query(knot_requestor_t *requestor,
        knot_request_flag_t flags = TFO ? KNOT_REQUEST_TFO: KNOT_REQUEST_NONE;
 
        return knot_request_make_generic(requestor->mm, dst, src, pkt, NULL,
-                                        NULL, 0, flags);
+                                        NULL, NULL, 0, flags);
 }
 
 static void test_disconnected(knot_requestor_t *requestor,