Commit 90a8e181 authored by Daniel Salzman's avatar Daniel Salzman

nameserver: move ns_put_rr from internet to process_query + cleanup

parent 7df6c41b
This diff is collapsed.
......@@ -13,24 +13,12 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file
*
* \brief IN zone lookup.
*
* \addtogroup query_processing
* @{
*/
#pragma once
#include "libknot/packet/pkt.h"
#include "knot/query/layer.h"
/* Query data (from query processing). */
struct query_data;
struct query_plan;
struct query_module;
struct answer_data;
/*! \brief Internet query processing states. */
......@@ -48,37 +36,20 @@ enum {
/*!
* \brief Answer query from an IN class zone.
*
* \retval FAIL if it encountered an error.
* \retval DONE if finished.
* \retval KNOT_STATE_FAIL if it encountered an error.
* \retval KNOT_STATE_DONE if finished.
*/
int internet_process_query(knot_pkt_t *resp, struct query_data *qdata);
int internet_process_query(knot_pkt_t *pkt, struct query_data *qdata);
/*!
* \brief Process answer in an IN class zone.
*
* \retval FAIL if it encountered an error.
* \retval DONE if finished.
* \retval NOOP if not supported.
* \retval KNOT_STATE_FAIL if it encountered an error.
* \retval KNOT_STATE_DONE if finished.
* \retval KNOT_STATE_NOOP if not supported.
*/
int internet_process_answer(knot_pkt_t *pkt, struct answer_data *data);
/*!
* \brief Puts RRSet to packet, will store its RRSIG for later use.
*
* \param pkt Packet to store RRSet into.
* \param rr RRSet to be stored.
* \param rrsigs RRSIGs to be stored.
* \param compr_hint Compression hint.
* \param flags Flags.
* \param expand Set to true if wildcards should be expanded.
* \param qdata Query data structure.
*
* \return KNOT_E*
*/
int ns_put_rr(knot_pkt_t *pkt, const knot_rrset_t *rr,
const knot_rrset_t *rrsigs, uint16_t compr_hint,
uint32_t flags, struct query_data *qdata);
/*! \brief Require given QUERY TYPE or return error code. */
#define NS_NEED_QTYPE(qdata, qtype_want, error_rcode) \
if (knot_pkt_qtype((qdata)->query) != (qtype_want)) { \
......@@ -117,9 +88,8 @@ int ns_put_rr(knot_pkt_t *pkt, const knot_rrset_t *rr,
} \
}
/*! \brief Require maximum number of unsigned messages. */
#define NS_NEED_TSIG_SIGNED(tsig_ctx, max_unsigned) \
if (tsig_unsigned_count(tsig_ctx) > max_unsigned) { \
return KNOT_STATE_FAIL; \
}
/*! @} */
......@@ -173,8 +173,8 @@ static int put_nxt_from_node(const zone_node_t *node,
knot_rrset_t rrsigs = node_rrset(node, KNOT_RRTYPE_RRSIG);
return ns_put_rr(resp, &rrset, &rrsigs, KNOT_COMPR_HINT_NONE,
KNOT_PF_CHECKDUP, qdata);
return process_query_put_rr(resp, qdata, &rrset, &rrsigs,
KNOT_COMPR_HINT_NONE, KNOT_PF_CHECKDUP);
}
/*!
......@@ -667,7 +667,8 @@ int nsec_prove_dp_security(knot_pkt_t *pkt, struct query_data *qdata)
knot_rrset_t rrset = node_rrset(qdata->node, KNOT_RRTYPE_DS);
if (!knot_rrset_empty(&rrset)) {
knot_rrset_t rrsigs = node_rrset(qdata->node, KNOT_RRTYPE_RRSIG);
return ns_put_rr(pkt, &rrset, &rrsigs, KNOT_COMPR_HINT_NONE, 0, qdata);
return process_query_put_rr(pkt, qdata, &rrset, &rrsigs,
KNOT_COMPR_HINT_NONE, 0);
}
// Alternatively prove that DS doesn't exist.
......
......@@ -18,6 +18,7 @@
#include "dnssec/tsig.h"
#include "knot/common/log.h"
#include "knot/dnssec/rrset-sign.h"
#include "knot/nameserver/process_query.h"
#include "knot/nameserver/query_module.h"
#include "knot/nameserver/chaos.h"
......@@ -748,6 +749,102 @@ int process_query_qname_case_lower(knot_pkt_t *pkt)
return knot_dname_to_lower(qname);
}
/*! \brief Synthesize RRSIG for given parameters, store in 'qdata' for later use */
static int put_rrsig(const knot_dname_t *sig_owner, uint16_t type,
const knot_rrset_t *rrsigs, knot_rrinfo_t *rrinfo,
struct query_data *qdata)
{
knot_rdataset_t synth_rrs;
knot_rdataset_init(&synth_rrs);
int ret = knot_synth_rrsig(type, &rrsigs->rrs, &synth_rrs, qdata->mm);
if (ret == KNOT_ENOENT) {
// No signature
return KNOT_EOK;
}
if (ret != KNOT_EOK) {
return ret;
}
/* Create rrsig info structure. */
struct rrsig_info *info = mm_alloc(qdata->mm, sizeof(struct rrsig_info));
if (info == NULL) {
knot_rdataset_clear(&synth_rrs, qdata->mm);
return KNOT_ENOMEM;
}
/* Store RRSIG into info structure. */
knot_dname_t *owner_copy = knot_dname_copy(sig_owner, qdata->mm);
if (owner_copy == NULL) {
mm_free(qdata->mm, info);
knot_rdataset_clear(&synth_rrs, qdata->mm);
return KNOT_ENOMEM;
}
knot_rrset_init(&info->synth_rrsig, owner_copy, rrsigs->type, rrsigs->rclass);
/* Store filtered signature. */
info->synth_rrsig.rrs = synth_rrs;
info->rrinfo = rrinfo;
add_tail(&qdata->rrsigs, &info->n);
return KNOT_EOK;
}
int process_query_put_rr(knot_pkt_t *pkt, struct query_data *qdata,
const knot_rrset_t *rr, const knot_rrset_t *rrsigs,
uint16_t compr_hint, uint32_t flags)
{
if (rr->rrs.rr_count < 1) {
return KNOT_EMALF;
}
/* Wildcard expansion applies only for answers. */
bool expand = false;
if (pkt->current == KNOT_ANSWER) {
/* Expand if RR is wildcard & we didn't query for wildcard. */
expand = (knot_dname_is_wildcard(rr->owner) && !knot_dname_is_wildcard(qdata->name));
}
int ret = KNOT_EOK;
/* If we already have compressed name on the wire and compression hint,
* we can just insert RRSet and fake synthesis by using compression
* hint. */
knot_rrset_t to_add;
if (compr_hint == KNOT_COMPR_HINT_NONE && expand) {
knot_dname_t *qname_cpy = knot_dname_copy(qdata->name, &pkt->mm);
if (qname_cpy == NULL) {
return KNOT_ENOMEM;
}
knot_rrset_init(&to_add, qname_cpy, rr->type, rr->rclass);
ret = knot_rdataset_copy(&to_add.rrs, &rr->rrs, &pkt->mm);
if (ret != KNOT_EOK) {
knot_dname_free(&qname_cpy, &pkt->mm);
return ret;
}
to_add.additional = rr->additional;
flags |= KNOT_PF_FREE;
} else {
to_add = *rr;
}
uint16_t prev_count = pkt->rrset_count;
ret = knot_pkt_put(pkt, compr_hint, &to_add, flags);
if (ret != KNOT_EOK && (flags & KNOT_PF_FREE)) {
knot_rrset_clear(&to_add, &pkt->mm);
return ret;
}
const bool inserted = (prev_count != pkt->rrset_count);
if (inserted &&
!knot_rrset_empty(rrsigs) && rr->type != KNOT_RRTYPE_RRSIG) {
// Get rrinfo of just inserted RR.
knot_rrinfo_t *rrinfo = &pkt->rr_info[pkt->rrset_count - 1];
ret = put_rrsig(rr->owner, rr->type, rrsigs, rrinfo, qdata);
}
return ret;
}
/*! \brief Module implementation. */
const knot_layer_api_t *process_query_layer(void)
{
......
/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2016 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
......@@ -13,14 +13,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file
*
* \brief Query processor.
*
* \addtogroup query_processing
* @{
*/
#pragma once
......@@ -145,4 +137,18 @@ void process_query_qname_case_restore(knot_pkt_t *pkt, struct query_data *qdata)
*/
int process_query_qname_case_lower(knot_pkt_t *pkt);
/*! @} */
/*!
* \brief Puts RRSet to packet, will store its RRSIG for later use.
*
* \param pkt Packet to store RRSet into.
* \param qdata Query data structure.
* \param rr RRSet to be stored.
* \param rrsigs RRSIGs to be stored.
* \param compr_hint Compression hint.
* \param flags Flags.
*
* \return KNOT_E*
*/
int process_query_put_rr(knot_pkt_t *pkt, struct query_data *qdata,
const knot_rrset_t *rr, const knot_rrset_t *rrsigs,
uint16_t compr_hint, uint32_t flags);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment