Attachment 'resolve.h'
Download 1 /* Copyright (C) 2014-2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <https://www.gnu.org/licenses/>.
15 */
16
17 #pragma once
18
19 #include <netinet/in.h>
20 #include <sys/socket.h>
21 #include <libknot/packet/pkt.h>
22
23 #include "lib/cookies/control.h"
24 #include "lib/cookies/lru_cache.h"
25 #include "lib/layer.h"
26 #include "lib/generic/map.h"
27 #include "lib/generic/array.h"
28 #include "lib/nsrep.h"
29 #include "lib/rplan.h"
30 #include "lib/module.h"
31 #include "lib/cache.h"
32
33 /**
34 * @file resolve.h
35 * @brief The API provides an API providing a "consumer-producer"-like interface to enable
36 * user to plug it into existing event loop or I/O code.
37 *
38 * # Example usage of the iterative API:
39 *
40 * @code{.c}
41 *
42 * // Create request and its memory pool
43 * struct kr_request req = {
44 * .pool = {
45 * .ctx = mp_new (4096),
46 * .alloc = (mm_alloc_t) mp_alloc
47 * }
48 * };
49 *
50 * // Setup and provide input query
51 * int state = kr_resolve_begin(&req, ctx, final_answer);
52 * state = kr_resolve_consume(&req, query);
53 *
54 * // Generate answer
55 * while (state == KR_STATE_PRODUCE) {
56 *
57 * // Additional query generate, do the I/O and pass back answer
58 * state = kr_resolve_produce(&req, &addr, &type, query);
59 * while (state == KR_STATE_CONSUME) {
60 * int ret = sendrecv(addr, proto, query, resp);
61 *
62 * // If I/O fails, make "resp" empty
63 * state = kr_resolve_consume(&request, addr, resp);
64 * knot_pkt_clear(resp);
65 * }
66 * knot_pkt_clear(query);
67 * }
68 *
69 * // "state" is either DONE or FAIL
70 * kr_resolve_finish(&request, state);
71 *
72 * @endcode
73 */
74
75 /** Validation rank */
76 typedef enum kr_validation_rank {
77 KR_VLDRANK_INITIAL = 0, /* Entry was just added; not validated yet. */
78 KR_VLDRANK_INSECURE = 1, /* Entry is DNSSEC insecure (e.g. RRSIG not exists). */
79 KR_VLDRANK_BAD = 2, /* Matching RRSIG found, but validation fails. */
80 KR_VLDRANK_MISMATCH = 3, /* RRSIG signer name is */
81 KR_VLDRANK_UNKNOWN = 4, /* Unknown */
82 KR_VLDRANK_SECURE = 5 /* Entry is DNSSEC valid (e.g. RRSIG exists). */
83 } kr_validation_rank_t;
84
85 /** @cond internal Array of modules. */
86 typedef array_t(struct kr_module *) module_array_t;
87 /* @endcond */
88
89 /**
90 * Name resolution context.
91 *
92 * Resolution context provides basic services like cache, configuration and options.
93 *
94 * @note This structure is persistent between name resolutions and may
95 * be shared between threads.
96 */
97 struct kr_context
98 {
99 uint32_t options;
100 knot_rrset_t *opt_rr;
101 map_t trust_anchors;
102 map_t negative_anchors;
103 struct kr_zonecut root_hints;
104 struct kr_cache cache;
105 kr_nsrep_lru_t *cache_rtt;
106 kr_nsrep_lru_t *cache_rep;
107 module_array_t *modules;
108 /* The cookie context structure should not be held within the cookies
109 * module because of better access. */
110 struct kr_cookie_ctx cookie_ctx;
111 kr_cookie_lru_t *cache_cookie;
112 uint32_t tls_padding; /**< See net.tls_padding in ../daemon/README.rst */
113 knot_mm_t *pool;
114 };
115
116 /**
117 * Name resolution request.
118 *
119 * Keeps information about current query processing between calls to
120 * processing APIs, i.e. current resolved query, resolution plan, ...
121 * Use this instead of the simple interface if you want to implement
122 * multiplexing or custom I/O.
123 *
124 * @note All data for this request must be allocated from the given pool.
125 */
126 struct kr_request {
127 struct kr_context *ctx;
128 knot_pkt_t *answer;
129 struct kr_query *current_query; /**< Current evaluated query. */
130 struct {
131 const knot_rrset_t *key;
132 const struct sockaddr *addr;
133 const struct sockaddr *dst_addr;
134 const knot_pkt_t *packet;
135 const knot_rrset_t *opt;
136 bool tcp; /**< true if the request is on tcp; only meaningful if (dst_addr) */
137 } qsource;
138 struct {
139 unsigned rtt; /**< Current upstream RTT */
140 const struct sockaddr *addr; /**< Current upstream address */
141 } upstream; /**< Upstream information, valid only in consume() phase */
142 uint32_t options;
143 int state;
144 ranked_rr_array_t answ_selected;
145 ranked_rr_array_t auth_selected;
146 rr_array_t additional;
147 bool answ_validated;
148 bool auth_validated;
149 struct kr_rplan rplan;
150 int has_tls;
151 knot_mm_t pool;
152 };
153
154 /**
155 * Begin name resolution.
156 *
157 * @note Expects a request to have an initialized mempool, the "answer" packet will
158 * be kept during the resolution and will contain the final answer at the end.
159 *
160 * @param request request state with initialized mempool
161 * @param ctx resolution context
162 * @param answer allocated packet for final answer
163 * @return CONSUME (expecting query)
164 */
165 KR_EXPORT
166 int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pkt_t *answer);
167
168 /**
169 * Consume input packet (may be either first query or answer to query originated from kr_resolve_produce())
170 *
171 * @note If the I/O fails, provide an empty or NULL packet, this will make iterator recognize nameserver failure.
172 *
173 * @param request request state (awaiting input)
174 * @param src [in] packet source address
175 * @param packet [in] input packet
176 * @return any state
177 */
178 KR_EXPORT
179 int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, knot_pkt_t *packet);
180
181 /**
182 * Produce either next additional query or finish.
183 *
184 * If the CONSUME is returned then dst, type and packet will be filled with
185 * appropriate values and caller is responsible to send them and receive answer.
186 * If it returns any other state, then content of the variables is undefined.
187 *
188 * @param request request state (in PRODUCE state)
189 * @param dst [out] possible address of the next nameserver
190 * @param type [out] possible used socket type (SOCK_STREAM, SOCK_DGRAM)
191 * @param packet [out] packet to be filled with additional query
192 * @return any state
193 */
194 KR_EXPORT
195 int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *type, knot_pkt_t *packet);
196
197 /**
198 * Finalises the outbound query packet with the knowledge of the IP addresses.
199 *
200 * @note The function must be called before actual sending of the request packet.
201 *
202 * @param request request state (in PRODUCE state)
203 * @param src address from which the query is going to be sent
204 * @param dst address of the name server
205 * @param type used socket type (SOCK_STREAM, SOCK_DGRAM)
206 * @param packet [in,out] query packet to be finalised
207 * @return kr_ok() or error code
208 */
209 KR_EXPORT
210 int kr_resolve_checkout(struct kr_request *request, struct sockaddr *src,
211 struct sockaddr *dst, int type, knot_pkt_t *packet);
212
213 /**
214 * Finish resolution and commit results if the state is DONE.
215 *
216 * @note The structures will be deinitialized, but the assigned memory pool is not going to
217 * be destroyed, as it's owned by caller.
218 *
219 * @param request request state
220 * @param state either DONE or FAIL state
221 * @return DONE
222 */
223 KR_EXPORT
224 int kr_resolve_finish(struct kr_request *request, int state);
225
226 /**
227 * Return resolution plan.
228 * @param request request state
229 * @return pointer to rplan
230 */
231 KR_EXPORT KR_PURE
232 struct kr_rplan *kr_resolve_plan(struct kr_request *request);
233
234 /**
235 * Return memory pool associated with request.
236 * @param request request state
237 * @return mempool
238 */
239 KR_EXPORT KR_PURE
240 knot_mm_t *kr_resolve_pool(struct kr_request *request);
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.