process_query.h 3.98 KB
Newer Older
1
/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

    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/>.
 */

17
#pragma once
18

19
#include "knot/include/module.h"
20
#include "knot/query/layer.h"
21
#include "knot/updates/acl.h"
22
#include "knot/zone/zone.h"
23

24
/* Query processing module implementation. */
25
const knot_layer_api_t *process_query_layer(void);
26

27
/*! \brief Query processing intermediate data. */
28 29 30 31 32 33 34
typedef struct knotd_qdata_extra {
	const zone_t *zone;  /*!< Zone from which is answered. */
	list_t wildcards;    /*!< Visited wildcards. */
	list_t rrsigs;       /*!< Section RRSIGs. */
	uint8_t *opt_rr_pos; /*!< Place of the OPT RR in wire. */

	/* Currently processed nodes. */
35
	const zone_node_t *node, *encloser, *previous;
36

37
	/* Original QNAME case. */
38
	uint8_t orig_qname[KNOT_DNAME_MAXLEN];
39

40 41
	/* Extensions. */
	void *ext;
42 43
	void (*ext_cleanup)(knotd_qdata_t *); /*!< Extensions cleanup callback. */
} knotd_qdata_extra_t;
44

45
/*! \brief Visited wildcard node list. */
46 47
struct wildcard_hit {
	node_t n;
48
	const zone_node_t *node;   /* Visited node. */
49
	const zone_node_t *prev;   /* Previous node from the SNAME. */
50
	const knot_dname_t *sname; /* Name leading to this node. */
51 52
};

53
/*! \brief RRSIG info node list. */
54 55
struct rrsig_info {
	node_t n;
56 57
	knot_rrset_t synth_rrsig; /* Synthesized RRSIG. */
	knot_rrinfo_t *rrinfo;    /* RR info. */
58 59
};

60 61 62
/*!
 * \brief Check current query against ACL.
 *
63
 * \param conf       Configuration.
64 65 66
 * \param zone_name  Current zone name.
 * \param action     ACL action.
 * \param qdata      Query data.
67 68
 * \return true if accepted, false if denied.
 */
69
bool process_query_acl_check(conf_t *conf, const knot_dname_t *zone_name,
70
                             acl_action_t action, knotd_qdata_t *qdata);
71 72 73 74 75 76 77 78 79 80 81

/*!
 * \brief Verify current query transaction security and update query data.
 *
 * \param qdata
 * \retval KNOT_EOK
 * \retval KNOT_TSIG_EBADKEY
 * \retval KNOT_TSIG_EBADSIG
 * \retval KNOT_TSIG_EBADTIME
 * \retval (other generic errors)
 */
82
int process_query_verify(knotd_qdata_t *qdata);
83

84 85 86 87 88 89 90 91
/*!
 * \brief Sign current query using configured TSIG keys.
 *
 * \param pkt    Outgoing message.
 * \param qdata  Query data.
 *
 * \retval KNOT_E*
 */
92
int process_query_sign_response(knot_pkt_t *pkt, knotd_qdata_t *qdata);
93

94 95 96 97
/*!
 * \brief Restore QNAME letter case.
 *
 * \param pkt    Incoming message.
98
 * \param qdata  Query data.
99
 */
100 101 102 103 104 105 106 107
static inline void process_query_qname_case_restore(knot_pkt_t *pkt, knotd_qdata_t *qdata)
{
	// If original QNAME is empty, query is either unparsed or for root domain.
	if (qdata->extra->orig_qname[0] != '\0') {
		memcpy(pkt->wire + KNOT_WIRE_HEADER_SIZE,
		       qdata->extra->orig_qname, qdata->query->qname_size);
	}
}
108 109 110 111 112 113

/*!
 * \brief Convert QNAME to lowercase format for processing.
 *
 * \param pkt    Incoming message.
 */
114 115 116 117
static inline void process_query_qname_case_lower(knot_pkt_t *pkt)
{
	knot_dname_to_lower(knot_pkt_qname(pkt));
}
118

119 120 121 122 123 124 125 126 127 128 129 130
/*!
 * \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*
 */
131
int process_query_put_rr(knot_pkt_t *pkt, knotd_qdata_t *qdata,
132 133
                         const knot_rrset_t *rr, const knot_rrset_t *rrsigs,
                         uint16_t compr_hint, uint32_t flags);