process_query.h 5.43 KB
Newer Older
1
/*!
2
 * \file process_query.h
3 4 5
 *
 * \author Marek Vavrusa <marek.vavrusa@nic.cz>
 *
6
 * \brief Query processor.
7
 *
8
 * \addtogroup query_processing
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 * @{
 */
/*  Copyright (C) 2013 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/>.
 */

27 28
#ifndef _PROCESS_QUERY_H_
#define _PROCESS_QUERY_H_
29

30
#include "libknot/processing/process.h"
31
#include "knot/server/server.h"
32
#include "knot/updates/acl.h"
33

34
/* Query processing module implementation. */
35 36
extern const knot_process_module_t _process_query;
#define NS_PROC_QUERY (&_process_query)
37 38
#define NS_PROC_QUERY_ID 1

39 40
/*! \brief Query processing logging common base. */
#define NS_PROC_LOG(severity, qdata, what, msg, ...) do { \
41
	char addr_str[SOCKADDR_STRLEN] = {0}; \
42
	sockaddr_tostr((qdata)->param->query_source, addr_str, sizeof(addr_str)); \
43
	char *zone_str = knot_dname_to_str(knot_pkt_qname((qdata)->query)); \
44
	log_msg(LOG_SERVER, severity, what msg "\n", \
45
	                zone_str, addr_str, ##__VA_ARGS__); \
46
	free(zone_str); \
47 48 49 50
	} while (0)

/*! \brief Query logging common base. */
#define QUERY_LOG(severity, qdata, what, msg...) \
51
	NS_PROC_LOG(severity, qdata, what " of '%s' from '%s': ", msg)
52 53 54

/*! \brief Answer logging common base. */
#define ANSWER_LOG(severity, qdata, what, msg...)  \
55
	NS_PROC_LOG(severity, qdata, what " of '%s' to '%s': ", msg)
56

57
/* Query processing specific flags. */
58
enum process_query_flag {
59 60 61 62 63
	NS_QUERY_NO_AXFR    = 1 << 0, /* Don't process AXFR */
	NS_QUERY_NO_IXFR    = 1 << 1, /* Don't process IXFR */
	NS_QUERY_LIMIT_ANY  = 1 << 2, /* Limit ANY QTYPE (respond with TC=1) */
	NS_QUERY_LIMIT_RATE = 1 << 3, /* Apply rate limits. */
	NS_QUERY_LIMIT_SIZE = 1 << 4  /* Apply UDP size limit. */
64 65
};

66
/* Module load parameters. */
67
struct process_query_param {
68
	uint16_t   proc_flags;
69
	int        query_socket;
70
	struct sockaddr_storage *query_source;
71
	server_t   *server;
72 73
};

74
/*! \brief Query processing intermediate data. */
75
struct query_data {
76 77 78 79 80 81
	uint16_t rcode;       /*!< Resulting RCODE. */
	uint16_t rcode_tsig;  /*!< Resulting TSIG RCODE. */
	uint16_t packet_type; /*!< Resolved packet type. */
	knot_pkt_t *query;    /*!< Query to be solved. */
	const zone_t *zone;   /*!< Zone from which is answered. */
	list_t wildcards;     /*!< Visited wildcards. */
82

83
	/* Current processed name and nodes. */
84
	const knot_node_t *node, *encloser, *previous;
85
	const knot_dname_t *name;
86

87
	/* Original QNAME case. */
88
	uint8_t orig_qname[KNOT_DNAME_MAXLEN];
89

90 91 92
	/* Extensions. */
	void *ext;
	void (*ext_cleanup)(struct query_data*); /*!< Extensions cleanup callback. */
93
	knot_sign_context_t sign;            /*!< Signing context. */
94 95

	/* Everything below should be kept on reset. */
96
	struct process_query_param *param; /*!< Module parameters. */
97
	mm_ctx_t *mm;                      /*!< Memory context. */
98 99
};

100
/*! \brief Visited wildcard node list. */
101 102
struct wildcard_hit {
	node_t n;
103 104
	const knot_node_t *node;   /* Visited node. */
	const knot_dname_t *sname; /* Name leading to this node. */
105 106
};

107 108 109 110 111 112 113
/*!
 * \brief Initialize query processing context.
 *
 * \param ctx
 * \param module_param
 * \return MORE (awaits query)
 */
114
int process_query_begin(knot_process_t *ctx, void *module_param);
115 116 117 118 119 120 121

/*!
 * \brief Reset query processing context.
 *
 * \param ctx
 * \return MORE (awaits next query)
 */
122
int process_query_reset(knot_process_t *ctx);
123 124 125 126 127 128 129

/*!
 * \brief Finish and close current query processing.
 *
 * \param ctx
 * \return NOOP (context will be inoperable further on)
 */
130
int process_query_finish(knot_process_t *ctx);
131 132 133 134 135 136 137

/*!
 * \brief Put query into query processing context.
 *
 * \param pkt
 * \param ctx
 * \retval NOOP (unsupported query)
138
 * \retval FULL (ready to write answer)
139
 */
140
int process_query_in(knot_pkt_t *pkt, knot_process_t *ctx);
141 142 143 144 145 146 147 148 149 150

/*!
 * \brief Make query response.
 *
 * \param pkt
 * \param ctx
 * \retval DONE (finished response)
 * \retval FULL (partial response, send it and call again)
 * \retval FAIL (failure)
 */
151
int process_query_out(knot_pkt_t *pkt, knot_process_t *ctx);
152 153 154 155 156 157 158 159 160

/*!
 * \brief Make an error response.
 *
 * \param pkt
 * \param ctx
 * \retval DONE (finished response)
 * \retval FAIL (failure)
 */
161
int process_query_err(knot_pkt_t *pkt, knot_process_t *ctx);
162

163 164 165 166 167 168 169
/*!
 * \brief Check current query against ACL.
 *
 * \param acl
 * \param qdata
 * \return true if accepted, false if denied.
 */
170
bool process_query_acl_check(acl_t *acl, struct query_data *qdata);
171 172 173 174 175 176 177 178 179 180 181

/*!
 * \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)
 */
182
int process_query_verify(struct query_data *qdata);
183 184 185 186 187 188 189 190 191

/*!
 * \brief Sign query response if applicable.
 *
 * \param pkt
 * \param qdata
 * \retval KNOT_EOK
 * \retval (other generic errors)
 */
192
int process_query_sign_response(knot_pkt_t *pkt, struct query_data *qdata);
193

194
#endif /* _PROCESS_QUERY_H_ */
195 196

/*! @} */