]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib: zone cut api supports multi-rdata RR sets
authorMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 2 Feb 2015 19:46:53 +0000 (20:46 +0100)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 2 Feb 2015 19:46:53 +0000 (20:46 +0100)
lib/Makefile.am
lib/layer/iterate.c
lib/layer/iterate.h
lib/layer/itercache.c
lib/resolve.c
lib/rplan.c
lib/utils.c [deleted file]
lib/utils.h [deleted file]
lib/zonecut.c
lib/zonecut.h

index 91dd2caf9b445629d38280da5afda1ddf9fe8047..ba490c3ddae5dd57b6da79cef304c0432b8170d5 100644 (file)
@@ -12,8 +12,6 @@ libkresolve_static_la_SOURCES =               \
        layer/stats.h   \
        layer/stats.c   \
        layer.h                 \
-       utils.h                 \
-       utils.c                 \
        context.h               \
        context.c               \
        resolve.h               \
index b0acb11613836f912981b665fa57cd59849657a6..e30089f0f603f0fbaf6022af2b7345170c898e17 100644 (file)
@@ -24,7 +24,7 @@
 #include "lib/layer/iterate.h"
 #include "lib/resolve.h"
 #include "lib/rplan.h"
-#include "lib/utils.h"
+#include "lib/defines.h"
 
 #ifndef NDEBUG
 #define DEBUG_MSG(fmt, ...) fprintf(stderr, "[qiter] " fmt, ## __VA_ARGS__)
@@ -33,7 +33,7 @@
 #endif
 
 /* Iterator often walks through packet section, this is an abstraction. */
-typedef int (*rr_callback_t)(const knot_rrset_t *, struct kr_layer_param *);
+typedef int (*rr_callback_t)(const knot_rrset_t *, unsigned, struct kr_layer_param *);
 
 /*! \brief Return minimized QNAME/QTYPE for current zone cut. */
 static const knot_dname_t *minimized_qname(struct kr_query *query, uint16_t *qtype)
@@ -86,7 +86,7 @@ static void follow_cname_chain(const knot_dname_t **cname, const knot_rrset_t *r
        }
 }
 
-static int update_nsaddr(const knot_rrset_t *rr, struct kr_query *query)
+static int update_nsaddr(const knot_rrset_t *rr, struct kr_query *query, uint16_t index)
 {
        if (rr == NULL || query == NULL) {
                return KNOT_NS_PROC_MORE; /* Ignore */
@@ -94,7 +94,7 @@ static int update_nsaddr(const knot_rrset_t *rr, struct kr_query *query)
 
        if (rr->type == KNOT_RRTYPE_A || rr->type == KNOT_RRTYPE_AAAA) {
                if (knot_dname_is_equal(query->zone_cut.ns, rr->owner)) {
-                       int ret = kr_rrset_to_addr(&query->zone_cut.addr, rr);
+                       int ret = kr_set_zone_cut_addr(&query->zone_cut, rr, index);
                        if (ret == KNOT_EOK) {
                                return KNOT_NS_PROC_DONE;
                        }
@@ -104,44 +104,39 @@ static int update_nsaddr(const knot_rrset_t *rr, struct kr_query *query)
        return KNOT_NS_PROC_MORE;
 }
 
-static int update_glue(const knot_rrset_t *rr, struct kr_layer_param *param)
+static int update_glue(const knot_rrset_t *rr, unsigned hint, struct kr_layer_param *param)
 {
-       return update_nsaddr(rr, kr_rplan_current(param->rplan));
+       return update_nsaddr(rr, kr_rplan_current(param->rplan), hint);
 }
 
-int rr_update_parent(const knot_rrset_t *rr, struct kr_layer_param *param)
+int rr_update_parent(const knot_rrset_t *rr, unsigned hint, struct kr_layer_param *param)
 {
        struct kr_query *query = kr_rplan_current(param->rplan);
-       return update_nsaddr(rr, query->parent);
+       return update_nsaddr(rr, query->parent, hint);
 }
 
-int rr_update_answer(const knot_rrset_t *rr, struct kr_layer_param *param)
+int rr_update_answer(const knot_rrset_t *rr, unsigned hint, struct kr_layer_param *param)
 {
        knot_pkt_t *answer = param->answer;
-       knot_rrset_t *rr_copy = knot_rrset_copy(rr, &answer->mm);
-       if (rr_copy == NULL) {
-               return KNOT_NS_PROC_FAIL;
-       }
-
+       
        /* Write copied RR to the result packet. */
-       int ret = knot_pkt_put(answer, KNOT_COMPR_HINT_NONE, rr_copy, KNOT_PF_FREE);
+       int ret = knot_pkt_put(answer, KNOT_COMPR_HINT_NONE, rr, hint);
        if (ret != KNOT_EOK) {
-               knot_rrset_free(&rr_copy, &answer->mm);
+               if (hint & KNOT_PF_FREE) {
+                       knot_rrset_clear((knot_rrset_t *)rr, &answer->mm);
+               }
                knot_wire_set_tc(answer->wire);
                return KNOT_NS_PROC_DONE;
        }
 
-       /* Free just the allocated container. */
-       mm_free(&answer->mm, rr_copy);
-
        /* Update parent query as well. */
-       return rr_update_parent(rr, param);
+       return rr_update_parent(rr, hint, param);
 }
 
-int rr_update_nameserver(const knot_rrset_t *rr, struct kr_layer_param *param)
+int rr_update_nameserver(const knot_rrset_t *rr, unsigned hint, struct kr_layer_param *param)
 {
        struct kr_query *query = kr_rplan_current(param->rplan);
-       const knot_dname_t *ns_name = knot_ns_name(&rr->rrs, 0);
+       const knot_dname_t *ns_name = knot_ns_name(&rr->rrs, hint);
 
        /* Authority MUST be at/below the authority of the nameserver, otherwise
         * possible cache injection attempt. */
@@ -177,7 +172,7 @@ static int process_authority(knot_pkt_t *pkt, struct kr_layer_param *param)
                        continue;
                }
 
-               state = rr_update_nameserver(rr, param);
+               state = rr_update_nameserver(rr, 0, param);
                if (state != KNOT_NS_PROC_MORE) {
                        break;
                }
@@ -194,7 +189,7 @@ static int process_additional(knot_pkt_t *pkt, struct kr_layer_param *param)
        const knot_pktsection_t *ar = knot_pkt_section(pkt, KNOT_ADDITIONAL);
        for (unsigned i = 0; i < ar->count; ++i) {
                const knot_rrset_t *rr = knot_pkt_rr(ar, i);
-               int state = update_glue(rr, param);
+               int state = update_glue(rr, 0, param);
                if (state != KNOT_NS_PROC_MORE) {
                        return state;
                }
@@ -235,7 +230,7 @@ static int process_answer(knot_pkt_t *pkt, struct kr_layer_param *param)
        const knot_pktsection_t *an = knot_pkt_section(pkt, KNOT_ANSWER);
        for (unsigned i = 0; i < an->count; ++i) {
                const knot_rrset_t *rr = knot_pkt_rr(an, i);
-               int state = callback(rr, param);
+               int state = callback(rr, 0, param);
                if (state == KNOT_NS_PROC_FAIL) {
                        return state;
                }
index dda3c58e9c56d152b7d75db3bbcd0d015f116646..f9338c73196dcf506b2986742cfe1df0b4686193 100644 (file)
 const knot_layer_api_t *layer_iterate_module(void);
 #define LAYER_ITERATE layer_iterate_module()
 
-/*! \brief Result updates the query parent. */
-int rr_update_parent(const knot_rrset_t *rr, struct kr_layer_param *param);
+/*!
+ * \brief Result updates the query parent.
+ * \note Hint is an index of chosen RR in the set.
+ */
+int rr_update_parent(const knot_rrset_t *rr, unsigned hint, struct kr_layer_param *param);
 
-/*! \brief Result updates the original query response. */
-int rr_update_answer(const knot_rrset_t *rr, struct kr_layer_param *param);
+/*!
+ * \brief Result updates the original query response.
+ * \note When \a hint is KNOT_PF_FREE, RR is treated as a copy and answer takes its ownership.
+ */
+int rr_update_answer(const knot_rrset_t *rr, unsigned hint, struct kr_layer_param *param);
 
-/*! \brief Result updates current nameserver. */
-int rr_update_nameserver(const knot_rrset_t *rr, struct kr_layer_param *param);
+/*!
+ * \brief Result updates current nameserver.
+ * \note Hint is an index of chosen RR in the set.
+ */
+int rr_update_nameserver(const knot_rrset_t *rr, unsigned hint, struct kr_layer_param *param);
index 228e3595e6d272febb2a82279e0cbff72b98cdd0..dcb6c7c5a9087d691bee73858ca78f0f80ed1c69 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "lib/layer/static.h"
 #include "lib/layer/iterate.h"
-#include "lib/utils.h"
 
 #ifndef NDEBUG
 #define DEBUG_MSG(fmt, ...) fprintf(stderr, "[cache] " fmt, ## __VA_ARGS__)
@@ -34,7 +33,16 @@ typedef int (*rr_callback_t)(const knot_rrset_t *, unsigned, struct kr_layer_par
 
 static int update_parent(const knot_rrset_t *rr, unsigned drift, struct kr_layer_param *param)
 {
-       return rr_update_parent(rr, param);
+       /* Find a first non-expired record. */
+       uint16_t i = 0;
+       for (; i < rr->rrs.rr_count; ++i) {
+               knot_rdata_t *rd = knot_rdataset_at(&rr->rrs, i);
+               if (knot_rdata_ttl(rd) > drift) {
+                       break;
+               }
+       }
+
+       return rr_update_parent(rr, i, param);
 }
 
 static int update_answer(const knot_rrset_t *rr, unsigned drift, struct kr_layer_param *param)
index c94288dac124e74e67ee28d4f550469cde161ffa..43b67a15bb04788e8149a737b2fca6fc5d1fd336 100755 (executable)
@@ -23,7 +23,6 @@
 
 #include "lib/resolve.h"
 #include "lib/defines.h"
-#include "lib/utils.h"
 #include "lib/layer/itercache.h"
 #include "lib/layer/iterate.h"
 #include "lib/layer/static.h"
index 5680b1eadfb2e691ca8386f5a150df55f78d5116..aec9429e9570141f21a9f0c1fee546b1327921bc 100644 (file)
@@ -23,7 +23,7 @@
 #include "lib/rplan.h"
 #include "lib/context.h"
 #include "lib/cache.h"
-#include "lib/utils.h"
+#include "lib/defines.h"
 
 #ifndef NDEBUG
 #define DEBUG_MSG(fmt, ...) fprintf(stderr, "[rplan] " fmt, ## __VA_ARGS__)
diff --git a/lib/utils.c b/lib/utils.c
deleted file mode 100644 (file)
index ba689e6..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <libknot/descriptor.h>
-#include <libknot/rrtype/aaaa.h>
-#include <assert.h>
-
-#include "lib/utils.h"
-
-int kr_rrset_to_addr(struct sockaddr_storage *ss, const knot_rrset_t *rr)
-{
-       int ret = KNOT_EOK;
-
-       /* Retrieve an address from glue record. */
-       switch(rr->type) {
-       case KNOT_RRTYPE_A:
-               ret = knot_a_addr(&rr->rrs, 0, (struct sockaddr_in *)ss);
-               break;
-       case KNOT_RRTYPE_AAAA:
-               ret = knot_aaaa_addr(&rr->rrs, 0, (struct sockaddr_in6 *)ss);
-               break;
-       default:
-               return KNOT_EINVAL;
-       }
-
-       sockaddr_port_set(ss, KR_DNS_PORT);
-
-       return ret;
-}
diff --git a/lib/utils.h b/lib/utils.h
deleted file mode 100644 (file)
index c795b32..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*  Copyright (C) 2014 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
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include <libknot/rrset.h>
-#include <libknot/internal/sockaddr.h>
-
-#include "lib/defines.h"
-
-/*!
- * \brief Convert A/AAAA RRs to address with DNS port.
- * \param ss address storage
- * \param rr resource record
- * \return KNOT_E*
- */
-int kr_rrset_to_addr(struct sockaddr_storage *ss, const knot_rrset_t *rr);
index a2345b3457a89dc608ef009b2ebe3c9e3f35512b..0cd5f3f52fe93526cc63853712fd232662092bad 100644 (file)
 #include <libknot/descriptor.h>
 #include <libknot/rrtype/rdname.h>
 #include <libknot/packet/wire.h>
+#include <libknot/descriptor.h>
+#include <libknot/rrtype/aaaa.h>
 
 #include "lib/zonecut.h"
-#include "lib/utils.h"
 #include "lib/rplan.h"
+#include "lib/defines.h"
 
 #ifndef NDEBUG
 #define DEBUG_MSG(fmt, ...) fprintf(stderr, "[z-cut] " fmt, ## __VA_ARGS__)
@@ -118,6 +120,25 @@ int kr_set_zone_cut(struct kr_zonecut *cut, const knot_dname_t *name, const knot
        return KNOT_EOK;
 }
 
+int kr_set_zone_cut_addr(struct kr_zonecut *cut, const knot_rrset_t *rr, uint16_t i)
+{
+       int ret = KNOT_EOK;
+
+       switch(rr->type) {
+       case KNOT_RRTYPE_A:
+               ret = knot_a_addr(&rr->rrs, i, (struct sockaddr_in *)&cut->addr);
+               break;
+       case KNOT_RRTYPE_AAAA:
+               ret = knot_aaaa_addr(&rr->rrs, i, (struct sockaddr_in6 *)&cut->addr);
+               break;
+       default:
+               return KNOT_EINVAL;
+       }
+
+       sockaddr_port_set(&cut->addr, KR_DNS_PORT);
+
+       return ret;
+}
 int kr_find_zone_cut(struct kr_zonecut *cut, const knot_dname_t *name, namedb_txn_t *txn, uint32_t timestamp)
 {
        if (cut == NULL || name == NULL) {
index 268aff82907894405544e515508d8c805d3924d8..9284798a47de99191d3d307c0e13896fcb7658d8 100644 (file)
@@ -32,6 +32,13 @@ struct kr_zonecut {
        struct sockaddr_storage addr;         /*!< Authoritative NS address. */
 };
 
+/*!
+ * \brief Initialize zone cut with SBELT.
+ * \param cut zone cut to be set
+ * \return KNOT_E*
+ */
+int kr_init_zone_cut(struct kr_zonecut *cut);
+
 /*!
  * \brief Set zone cut to given name and name server.
  * \note Name server address is blanked.
@@ -42,6 +49,15 @@ struct kr_zonecut {
  */
 int kr_set_zone_cut(struct kr_zonecut *cut, const knot_dname_t *name, const knot_dname_t *ns);
 
+/*!
+ * \brief Convert A/AAAA RRs to address with DNS port.
+ * \param cut zone cut to be set
+ * \param rr resource record
+ * \param i  index of the set address in the rr
+ * \return KNOT_E*
+ */
+int kr_set_zone_cut_addr(struct kr_zonecut *cut, const knot_rrset_t *rr, uint16_t i);
+
 /*!
  * \brief Find the closest enclosing zone cut/nameserver from the cache.
  * \param cut zone cut to be set
@@ -51,3 +67,4 @@ int kr_set_zone_cut(struct kr_zonecut *cut, const knot_dname_t *name, const knot
  * \return KNOT_E*
  */
 int kr_find_zone_cut(struct kr_zonecut *cut, const knot_dname_t *name, namedb_txn_t *txn, uint32_t timestamp);
+