layer/stats.h \
layer/stats.c \
layer.h \
- utils.h \
- utils.c \
context.h \
context.c \
resolve.h \
#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__)
#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)
}
}
-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 */
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;
}
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. */
continue;
}
- state = rr_update_nameserver(rr, param);
+ state = rr_update_nameserver(rr, 0, param);
if (state != KNOT_NS_PROC_MORE) {
break;
}
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;
}
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;
}
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);
#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__)
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)
#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"
#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__)
+++ /dev/null
-#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;
-}
+++ /dev/null
-/* 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);
#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__)
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) {
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.
*/
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
* \return KNOT_E*
*/
int kr_find_zone_cut(struct kr_zonecut *cut, const knot_dname_t *name, namedb_txn_t *txn, uint32_t timestamp);
+