From: Marek VavruĊĦa Date: Mon, 2 Feb 2015 19:46:53 +0000 (+0100) Subject: lib: zone cut api supports multi-rdata RR sets X-Git-Tag: v1.0.0-beta1~342^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77dda7b997d8f2d89a06d039ca97ca5f707920e6;p=thirdparty%2Fknot-resolver.git lib: zone cut api supports multi-rdata RR sets --- diff --git a/lib/Makefile.am b/lib/Makefile.am index 91dd2caf9..ba490c3dd 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -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 \ diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index b0acb1161..e30089f0f 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -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; } diff --git a/lib/layer/iterate.h b/lib/layer/iterate.h index dda3c58e9..f9338c731 100644 --- a/lib/layer/iterate.h +++ b/lib/layer/iterate.h @@ -22,11 +22,20 @@ 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); diff --git a/lib/layer/itercache.c b/lib/layer/itercache.c index 228e3595e..dcb6c7c5a 100644 --- a/lib/layer/itercache.c +++ b/lib/layer/itercache.c @@ -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) diff --git a/lib/resolve.c b/lib/resolve.c index c94288dac..43b67a15b 100755 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -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" diff --git a/lib/rplan.c b/lib/rplan.c index 5680b1ead..aec9429e9 100644 --- a/lib/rplan.c +++ b/lib/rplan.c @@ -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 index ba689e6a0..000000000 --- a/lib/utils.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include - -#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 index c795b32ac..000000000 --- a/lib/utils.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2014 CZ.NIC, z.s.p.o. - - 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 . - */ - -#pragma once - -#include -#include - -#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); diff --git a/lib/zonecut.c b/lib/zonecut.c index a2345b345..0cd5f3f52 100644 --- a/lib/zonecut.c +++ b/lib/zonecut.c @@ -18,10 +18,12 @@ #include #include #include +#include +#include #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) { diff --git a/lib/zonecut.h b/lib/zonecut.h index 268aff829..9284798a4 100644 --- a/lib/zonecut.h +++ b/lib/zonecut.h @@ -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); +