]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
requestor: refactoring: add EDNS option in requestor
authorLibor Peltan <libor.peltan@nic.cz>
Fri, 30 Jun 2023 12:46:17 +0000 (14:46 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Mon, 10 Jul 2023 07:04:14 +0000 (09:04 +0200)
src/knot/dnssec/ds_query.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/query/query.c
src/knot/query/query.h
src/knot/query/requestor.c
src/knot/query/requestor.h
tests/knot/test_requestor.c

index f768d1522d7686ef372908461f21fc83f5914aac..6ade23cffd1c73e85a21504d47f4f52e0565bff7 100644 (file)
@@ -98,11 +98,6 @@ static int ds_query_produce(knot_layer_t *layer, knot_pkt_t *pkt)
                return KNOT_STATE_FAIL;
        }
 
-       r = query_put_edns(pkt, &data->edns);
-       if (r != KNOT_EOK) {
-               return KNOT_STATE_FAIL;
-       }
-
        knot_wire_set_rd(pkt->wire);
 
        return KNOT_STATE_CONSUME;
@@ -185,8 +180,7 @@ static int try_ds(conf_t *conf, const knot_dname_t *zone_name, const conf_remote
                .remote = (struct sockaddr *)&parent->addr,
                .key = key,
                .not_key = not_key,
-               .edns = query_edns_data_init(conf, parent->addr.ss_family,
-                                            QUERY_EDNS_OPT_DO),
+               .edns = query_edns_data_init(conf, parent, QUERY_EDNS_OPT_DO),
                .ds_ok = false,
                .result_logged = false,
                .ttl = 0,
@@ -201,7 +195,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, server->quic_creds, 0);
+       knot_request_t *req = knot_request_make(NULL, parent, pkt, server->quic_creds, &data.edns, 0);
        if (req == NULL) {
                knot_request_free(req, NULL);
                knot_requestor_clear(&requestor);
index 24e87779f6c17924ce80260370235a49198927f5..72cc582e293cf1825d54672ae6525e7155425f88 100644 (file)
@@ -59,11 +59,6 @@ static int parent_soa_produce(struct ds_push_data *data, knot_pkt_t *pkt)
                return KNOT_STATE_FAIL;
        }
 
-       ret = query_put_edns(pkt, &data->edns);
-       if (ret != KNOT_EOK) {
-               return KNOT_STATE_FAIL;
-       }
-
        return KNOT_STATE_CONSUME;
 }
 
@@ -101,8 +96,6 @@ static int ds_push_produce(knot_layer_t *layer, knot_pkt_t *pkt)
                }
        }
 
-       query_put_edns(pkt, &data->edns);
-
        return KNOT_STATE_CONSUME;
 }
 
@@ -180,7 +173,7 @@ static int send_ds_push(conf_t *conf, zone_t *zone,
                .parent_query = zone->name,
                .new_ds = zone_cds,
                .remote = (struct sockaddr *)&parent->addr,
-               .edns = query_edns_data_init(conf, parent->addr.ss_family, 0)
+               .edns = query_edns_data_init(conf, parent, 0)
        };
 
        knot_rrset_init(&data.del_old_ds, zone->name, KNOT_RRTYPE_DS, KNOT_CLASS_ANY, 0);
@@ -200,7 +193,7 @@ static int send_ds_push(conf_t *conf, zone_t *zone,
        }
 
        knot_request_t *req = knot_request_make(NULL, parent, pkt,
-                                               zone->server->quic_creds, 0);
+                                               zone->server->quic_creds, &data.edns, 0);
        if (req == NULL) {
                knot_rdataset_clear(&data.del_old_ds.rrs, NULL);
                knot_request_free(req, NULL);
index 26fe7df1b49dd2db14a32b7ee03a0f5e1b111d22..6e5a7547fc18241f3df1e248331346d731c5305a 100644 (file)
@@ -67,8 +67,6 @@ static int notify_produce(knot_layer_t *layer, knot_pkt_t *pkt)
                knot_pkt_put(pkt, KNOT_COMPR_HINT_QNAME, data->soa, 0);
        }
 
-       query_put_edns(pkt, &data->edns);
-
        return KNOT_STATE_CONSUME;
 }
 
@@ -94,7 +92,7 @@ static int send_notify(conf_t *conf, zone_t *zone, const knot_rrset_t *soa,
                .zone = zone->name,
                .soa = soa,
                .remote = (struct sockaddr *)&slave->addr,
-               .edns = query_edns_data_init(conf, slave->addr.ss_family, 0)
+               .edns = query_edns_data_init(conf, slave, 0)
        };
 
        knot_requestor_t requestor;
@@ -108,7 +106,7 @@ 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,
-                                               zone->server->quic_creds, flags);
+                                               zone->server->quic_creds, &data.edns, flags);
        if (req == NULL) {
                knot_request_free(req, NULL);
                knot_requestor_clear(&requestor);
index b41cfbb058b0eadcf927e8142babf490853205f9..5687edd1e2c8877548f7d6afad6518379ebb8c61 100644 (file)
@@ -104,7 +104,6 @@ struct refresh_data {
        const struct sockaddr *remote;    //!< Remote endpoint.
        const knot_rrset_t *soa;          //!< Local SOA (NULL for AXFR).
        const size_t max_zone_size;       //!< Maximal zone size.
-       bool use_edns;                    //!< Allow EDNS in SOA/AXFR/IXFR queries.
        query_edns_data_t edns;           //!< EDNS data to be used in queries.
        zone_master_fallback_t *fallback; //!< Flags allowing zone_master_try() fallbacks.
        bool fallback_axfr;               //!< Flag allowing fallback to AXFR,
@@ -1021,13 +1020,6 @@ static int soa_query_produce(knot_layer_t *layer, knot_pkt_t *pkt)
                return KNOT_STATE_FAIL;
        }
 
-       if (data->use_edns) {
-               data->ret = query_put_edns(pkt, &data->edns);
-               if (data->ret != KNOT_EOK) {
-                       return KNOT_STATE_FAIL;
-               }
-       }
-
        return KNOT_STATE_CONSUME;
 }
 
@@ -1125,13 +1117,6 @@ static int transfer_produce(knot_layer_t *layer, knot_pkt_t *pkt)
                knot_rrset_free(sending_soa, data->mm);
        }
 
-       if (data->use_edns) {
-               data->ret = query_put_edns(pkt, &data->edns);
-               if (data->ret != KNOT_EOK) {
-                       return KNOT_STATE_FAIL;
-               }
-       }
-
        return KNOT_STATE_CONSUME;
 }
 
@@ -1303,9 +1288,7 @@ static int try_refresh(conf_t *conf, zone_t *zone, const conf_remote_t *master,
                .remote = (struct sockaddr *)&master->addr,
                .soa = zone->contents && !trctx->force_axfr ? &soa : NULL,
                .max_zone_size = max_zone_size(conf, zone->name),
-               .use_edns = !master->no_edns,
-               .edns = query_edns_data_init(conf, master->addr.ss_family,
-                                            QUERY_EDNS_OPT_EXPIRE),
+               .edns = query_edns_data_init(conf, master, QUERY_EDNS_OPT_EXPIRE),
                .expire_timer = EXPIRE_TIMER_INVALID,
                .fallback = fallback,
                .fallback_axfr = false, // will be set upon IXFR consume
@@ -1322,8 +1305,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,
-                                               zone->server->quic_creds, flags);
+       knot_request_t *req = knot_request_make(NULL, master, pkt, zone->server->quic_creds,
+                                               &data.edns, flags);
        if (req == NULL) {
                knot_request_free(req, NULL);
                knot_requestor_clear(&requestor);
index b23e2bdba753a50be7f54dfad3752b162d68986a..d07715cb3d6861470e3033d4f0781a0b4411235e 100644 (file)
@@ -249,7 +249,7 @@ 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,
-                                               zone->server->quic_creds, flags);
+                                               zone->server->quic_creds, NULL, flags);
        if (req == NULL) {
                knot_requestor_clear(&re);
                knot_pkt_free(query);
index 1ecd851073a4ec571f281eed0dca064e327b4d97..111249a69cfada7125635626088ae745117fbf12 100644 (file)
@@ -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, NULL, 0, flags);
+                                                       NULL, NULL, NULL, NULL, 0, flags);
        if (req == NULL) {
                knot_requestor_clear(&re);
                return state; /* Ignore, not enough memory. */
index 877851acdcbb4b4e60fc6d9b4336bdc3497dba34..aa088c84477978b98f467e69340d612b59e0492e 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
@@ -29,15 +29,16 @@ void query_init_pkt(knot_pkt_t *pkt)
        knot_wire_set_id(pkt->wire, dnssec_random_uint16_t());
 }
 
-query_edns_data_t query_edns_data_init(conf_t *conf, int remote_family,
+query_edns_data_t query_edns_data_init(conf_t *conf, const conf_remote_t *remote,
                                        query_edns_opt_t opts)
 {
        assert(conf);
 
        query_edns_data_t edns = {
-               .max_payload = remote_family == AF_INET ?
+               .max_payload = remote->addr.ss_family == AF_INET ?
                               conf->cache.srv_udp_max_payload_ipv4 :
                               conf->cache.srv_udp_max_payload_ipv6,
+               .no_edns = remote->no_edns,
                .do_flag = (opts & QUERY_EDNS_OPT_DO),
                .expire_option = (opts & QUERY_EDNS_OPT_EXPIRE)
        };
index fbf437d9b17fcb4a96e43ac5190d3db719ab4b25..76a1e0fa86f31056a3412edc20754ffdf6998367 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
@@ -25,6 +25,7 @@
  */
 typedef struct {
        uint16_t max_payload;
+       bool no_edns;
        bool do_flag;
        bool expire_option;
 } query_edns_data_t;
@@ -46,13 +47,13 @@ void query_init_pkt(knot_pkt_t *pkt);
 /*!
  * \brief Initialize EDNS parameters from server configuration.
  *
- * \param[in]  conf           Server configuration.
- * \param[in]  remote_family  Address family for remote host.
- * \param[in]  opts           EDNS options.
+ * \param[in]  conf     Server configuration.
+ * \param[in]  remote   Remote parameters.
+ * \param[in]  opts     EDNS options.
  *
  * \return EDNS parameters.
  */
-query_edns_data_t query_edns_data_init(conf_t *conf, int remote_family,
+query_edns_data_t query_edns_data_init(conf_t *conf, const conf_remote_t *remote,
                                        query_edns_opt_t opts);
 
 /*!
index 47aeedd01a24548034560d46641d22a19e3136d0..fe0765ac553f5a33f800d0c867e9ab4cad2e84d9 100644 (file)
@@ -193,6 +193,7 @@ knot_request_t *knot_request_make_generic(knot_mm_t *mm,
                                           const struct sockaddr_storage *source,
                                           knot_pkt_t *query,
                                           const struct knot_quic_creds *creds,
+                                          const query_edns_data_t *edns,
                                           const knot_tsig_key_t *tsig_key,
                                           const uint8_t *pin,
                                           size_t pin_len,
@@ -228,6 +229,7 @@ knot_request_t *knot_request_make_generic(knot_mm_t *mm,
        }
        tsig_init(&request->tsig, tsig_key);
 
+       request->edns = edns;
        request->creds = creds;
        if (flags & KNOT_REQUEST_QUIC && pin_len > 0) {
                request->pin_len = pin_len;
@@ -241,6 +243,7 @@ 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,
+                                  const query_edns_data_t *edns,
                                   knot_request_flag_t flags)
 {
        if (remote->quic) {
@@ -248,7 +251,7 @@ knot_request_t *knot_request_make(knot_mm_t *mm,
        }
 
        return knot_request_make_generic(mm, &remote->addr, &remote->via,
-                                        query, creds, &remote->key, remote->pin,
+                                        query, creds, edns, &remote->key, remote->pin,
                                         remote->pin_len, flags);
 }
 
@@ -336,6 +339,13 @@ static int request_produce(knot_requestor_t *req, knot_request_t *last,
 {
        knot_layer_produce(&req->layer, last->query);
 
+       if (last->edns != NULL && !last->edns->no_edns) {
+               int ret = query_put_edns(last->query, last->edns);
+               if (ret != KNOT_EOK) {
+                       return ret;
+               }
+       }
+
        int ret = tsig_sign_packet(&last->tsig, last->query);
        if (ret != KNOT_EOK) {
                return ret;
index eb7bee7bbfdd8d4a7f0c04f1877b462dbcbd4b2f..e5de09e4371162954d8c73dc09559f5a473c1eab 100644 (file)
@@ -22,6 +22,7 @@
 #include "knot/conf/conf.h"
 #include "knot/nameserver/tsig_ctx.h"
 #include "knot/query/layer.h"
+#include "knot/query/query.h"
 #include "libknot/mm_ctx.h"
 #include "libknot/rrtype/tsig.h"
 
@@ -58,6 +59,7 @@ typedef struct {
        struct sockaddr_storage remote, source;
        knot_pkt_t *query;
        knot_pkt_t *resp;
+       const query_edns_data_t *edns;
        tsig_ctx_t tsig;
 
        knot_sign_context_t sign; /*!< Required for async. DDNS processing. */
@@ -75,6 +77,7 @@ typedef struct {
  * \param source    Source address (or NULL).
  * \param query     Query message.
  * \param creds     Local (server) credentials.
+ * \param edns      EDNS parameters.
  * \param tsig_key  TSIG key for authentication.
  * \param pin       Possible remote certificate PIN.
  * \param pin_len   Length of the remote certificate PIN.
@@ -87,6 +90,7 @@ knot_request_t *knot_request_make_generic(knot_mm_t *mm,
                                           const struct sockaddr_storage *source,
                                           knot_pkt_t *query,
                                           const struct knot_quic_creds *creds,
+                                          const query_edns_data_t *edns,
                                           const knot_tsig_key_t *tsig_key,
                                           const uint8_t *pin,
                                           size_t pin_len,
@@ -102,6 +106,7 @@ 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,
+                                  const query_edns_data_t *edns,
                                   knot_request_flag_t flags);
 
 /*!
index 4c8f17e3e8fadf2db1362035c55d7ccf49eb5401..809c62f6420f8b7efa6c097d2850bc9df7a3b091 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, NULL, 0, flags);
+                                        NULL, NULL, NULL, 0, flags);
 }
 
 static void test_disconnected(knot_requestor_t *requestor,