Deleted Added
full compact
context.h (256281) context.h (269257)
1/*
2 * libunbound/context.h - validating context for unbound internal use
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1/*
2 * libunbound/context.h - validating context for unbound internal use
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36/**
37 * \file
38 *
39 * This file contains the validator context structure.
40 */
41#ifndef LIBUNBOUND_CONTEXT_H
42#define LIBUNBOUND_CONTEXT_H
43#include "util/locks.h"
44#include "util/alloc.h"
45#include "util/rbtree.h"
46#include "services/modstack.h"
47#include "libunbound/unbound.h"
48#include "util/data/packed_rrset.h"
49struct libworker;
50struct tube;
34 */
35
36/**
37 * \file
38 *
39 * This file contains the validator context structure.
40 */
41#ifndef LIBUNBOUND_CONTEXT_H
42#define LIBUNBOUND_CONTEXT_H
43#include "util/locks.h"
44#include "util/alloc.h"
45#include "util/rbtree.h"
46#include "services/modstack.h"
47#include "libunbound/unbound.h"
48#include "util/data/packed_rrset.h"
49struct libworker;
50struct tube;
51struct sldns_buffer;
52struct event_base;
51
52/**
53 * The context structure
54 *
55 * Contains two pipes for async service
56 * qq : write queries to the async service pid/tid.
57 * rr : read results from the async service pid/tid.
58 */
59struct ub_ctx {
60 /* --- pipes --- */
61 /** mutex on query write pipe */
62 lock_basic_t qqpipe_lock;
63 /** the query write pipe */
64 struct tube* qq_pipe;
65 /** mutex on result read pipe */
66 lock_basic_t rrpipe_lock;
67 /** the result read pipe */
68 struct tube* rr_pipe;
69
70 /* --- shared data --- */
71 /** mutex for access to env.cfg, finalized and dothread */
72 lock_basic_t cfglock;
73 /**
74 * The context has been finalized
75 * This is after config when the first resolve is done.
76 * The modules are inited (module-init()) and shared caches created.
77 */
78 int finalized;
79
80 /** is bg worker created yet ? */
81 int created_bg;
82 /** pid of bg worker process */
83 pid_t bg_pid;
84 /** tid of bg worker thread */
85 ub_thread_t bg_tid;
86
87 /** do threading (instead of forking) for async resolution */
88 int dothread;
89 /** next thread number for new threads */
90 int thr_next_num;
91 /** if logfile is overriden */
92 int logfile_override;
93 /** what logfile to use instead */
94 FILE* log_out;
95 /**
96 * List of alloc-cache-id points per threadnum for notinuse threads.
97 * Simply the entire struct alloc_cache with the 'super' member used
98 * to link a simply linked list. Reset super member to the superalloc
99 * before use.
100 */
101 struct alloc_cache* alloc_list;
102
103 /** shared caches, and so on */
104 struct alloc_cache superalloc;
105 /** module env master value */
106 struct module_env* env;
107 /** module stack */
108 struct module_stack mods;
109 /** local authority zones */
110 struct local_zones* local_zones;
111 /** random state used to seed new random state structures */
112 struct ub_randstate* seed_rnd;
113
53
54/**
55 * The context structure
56 *
57 * Contains two pipes for async service
58 * qq : write queries to the async service pid/tid.
59 * rr : read results from the async service pid/tid.
60 */
61struct ub_ctx {
62 /* --- pipes --- */
63 /** mutex on query write pipe */
64 lock_basic_t qqpipe_lock;
65 /** the query write pipe */
66 struct tube* qq_pipe;
67 /** mutex on result read pipe */
68 lock_basic_t rrpipe_lock;
69 /** the result read pipe */
70 struct tube* rr_pipe;
71
72 /* --- shared data --- */
73 /** mutex for access to env.cfg, finalized and dothread */
74 lock_basic_t cfglock;
75 /**
76 * The context has been finalized
77 * This is after config when the first resolve is done.
78 * The modules are inited (module-init()) and shared caches created.
79 */
80 int finalized;
81
82 /** is bg worker created yet ? */
83 int created_bg;
84 /** pid of bg worker process */
85 pid_t bg_pid;
86 /** tid of bg worker thread */
87 ub_thread_t bg_tid;
88
89 /** do threading (instead of forking) for async resolution */
90 int dothread;
91 /** next thread number for new threads */
92 int thr_next_num;
93 /** if logfile is overriden */
94 int logfile_override;
95 /** what logfile to use instead */
96 FILE* log_out;
97 /**
98 * List of alloc-cache-id points per threadnum for notinuse threads.
99 * Simply the entire struct alloc_cache with the 'super' member used
100 * to link a simply linked list. Reset super member to the superalloc
101 * before use.
102 */
103 struct alloc_cache* alloc_list;
104
105 /** shared caches, and so on */
106 struct alloc_cache superalloc;
107 /** module env master value */
108 struct module_env* env;
109 /** module stack */
110 struct module_stack mods;
111 /** local authority zones */
112 struct local_zones* local_zones;
113 /** random state used to seed new random state structures */
114 struct ub_randstate* seed_rnd;
115
116 /** event base for event oriented interface */
117 struct event_base* event_base;
118 /** libworker for event based interface */
119 struct libworker* event_worker;
120
114 /** next query number (to try) to use */
115 int next_querynum;
116 /** number of async queries outstanding */
117 size_t num_async;
118 /**
119 * Tree of outstanding queries. Indexed by querynum
120 * Used when results come in for async to lookup.
121 * Used when cancel is done for lookup (and delete).
122 * Used to see if querynum is free for use.
123 * Content of type ctx_query.
124 */
125 rbtree_t queries;
126};
127
128/**
129 * The queries outstanding for the libunbound resolver.
130 * These are outstanding for async resolution.
131 * But also, outstanding for sync resolution by one of the threads that
132 * has joined the threadpool.
133 */
134struct ctx_query {
135 /** node in rbtree, must be first entry, key is ptr to the querynum */
136 struct rbnode_t node;
137 /** query id number, key for node */
138 int querynum;
139 /** was this an async query? */
140 int async;
141 /** was this query cancelled (for bg worker) */
142 int cancelled;
143
144 /** for async query, the callback function */
145 ub_callback_t cb;
146 /** for async query, the callback user arg */
147 void* cb_arg;
148
149 /** answer message, result from resolver lookup. */
150 uint8_t* msg;
151 /** resulting message length. */
152 size_t msg_len;
153 /** validation status on security */
154 enum sec_status msg_security;
155 /** store libworker that is handling this query */
156 struct libworker* w;
157
158 /** result structure, also contains original query, type, class.
159 * malloced ptr ready to hand to the client. */
160 struct ub_result* res;
161};
162
163/**
164 * The error constants
165 */
166enum ub_ctx_err {
167 /** no error */
168 UB_NOERROR = 0,
169 /** socket operation. Set to -1, so that if an error from _fd() is
170 * passed (-1) it gives a socket error. */
171 UB_SOCKET = -1,
172 /** alloc failure */
173 UB_NOMEM = -2,
174 /** syntax error */
175 UB_SYNTAX = -3,
176 /** DNS service failed */
177 UB_SERVFAIL = -4,
178 /** fork() failed */
179 UB_FORKFAIL = -5,
180 /** cfg change after finalize() */
181 UB_AFTERFINAL = -6,
182 /** initialization failed (bad settings) */
183 UB_INITFAIL = -7,
184 /** error in pipe communication with async bg worker */
185 UB_PIPE = -8,
186 /** error reading from file (resolv.conf) */
187 UB_READFILE = -9,
188 /** error async_id does not exist or result already been delivered */
189 UB_NOID = -10
190};
191
192/**
193 * Command codes for libunbound pipe.
194 *
195 * Serialization looks like this:
196 * o length (of remainder) uint32.
197 * o uint32 command code.
198 * o per command format.
199 */
200enum ub_ctx_cmd {
201 /** QUIT */
202 UB_LIBCMD_QUIT = 0,
203 /** New query, sent to bg worker */
204 UB_LIBCMD_NEWQUERY,
205 /** Cancel query, sent to bg worker */
206 UB_LIBCMD_CANCEL,
207 /** Query result, originates from bg worker */
208 UB_LIBCMD_ANSWER
209};
210
211/**
212 * finalize a context.
213 * @param ctx: context to finalize. creates shared data.
214 * @return 0 if OK, or errcode.
215 */
216int context_finalize(struct ub_ctx* ctx);
217
218/** compare two ctx_query elements */
219int context_query_cmp(const void* a, const void* b);
220
221/**
222 * delete context query
223 * @param q: query to delete, including message packet and prealloc result
224 */
225void context_query_delete(struct ctx_query* q);
226
227/**
228 * Create new query in context, add to querynum list.
229 * @param ctx: context
230 * @param name: query name
231 * @param rrtype: type
232 * @param rrclass: class
233 * @param cb: callback for async, or NULL for sync.
234 * @param cbarg: user arg for async queries.
235 * @return new ctx_query or NULL for malloc failure.
236 */
121 /** next query number (to try) to use */
122 int next_querynum;
123 /** number of async queries outstanding */
124 size_t num_async;
125 /**
126 * Tree of outstanding queries. Indexed by querynum
127 * Used when results come in for async to lookup.
128 * Used when cancel is done for lookup (and delete).
129 * Used to see if querynum is free for use.
130 * Content of type ctx_query.
131 */
132 rbtree_t queries;
133};
134
135/**
136 * The queries outstanding for the libunbound resolver.
137 * These are outstanding for async resolution.
138 * But also, outstanding for sync resolution by one of the threads that
139 * has joined the threadpool.
140 */
141struct ctx_query {
142 /** node in rbtree, must be first entry, key is ptr to the querynum */
143 struct rbnode_t node;
144 /** query id number, key for node */
145 int querynum;
146 /** was this an async query? */
147 int async;
148 /** was this query cancelled (for bg worker) */
149 int cancelled;
150
151 /** for async query, the callback function */
152 ub_callback_t cb;
153 /** for async query, the callback user arg */
154 void* cb_arg;
155
156 /** answer message, result from resolver lookup. */
157 uint8_t* msg;
158 /** resulting message length. */
159 size_t msg_len;
160 /** validation status on security */
161 enum sec_status msg_security;
162 /** store libworker that is handling this query */
163 struct libworker* w;
164
165 /** result structure, also contains original query, type, class.
166 * malloced ptr ready to hand to the client. */
167 struct ub_result* res;
168};
169
170/**
171 * The error constants
172 */
173enum ub_ctx_err {
174 /** no error */
175 UB_NOERROR = 0,
176 /** socket operation. Set to -1, so that if an error from _fd() is
177 * passed (-1) it gives a socket error. */
178 UB_SOCKET = -1,
179 /** alloc failure */
180 UB_NOMEM = -2,
181 /** syntax error */
182 UB_SYNTAX = -3,
183 /** DNS service failed */
184 UB_SERVFAIL = -4,
185 /** fork() failed */
186 UB_FORKFAIL = -5,
187 /** cfg change after finalize() */
188 UB_AFTERFINAL = -6,
189 /** initialization failed (bad settings) */
190 UB_INITFAIL = -7,
191 /** error in pipe communication with async bg worker */
192 UB_PIPE = -8,
193 /** error reading from file (resolv.conf) */
194 UB_READFILE = -9,
195 /** error async_id does not exist or result already been delivered */
196 UB_NOID = -10
197};
198
199/**
200 * Command codes for libunbound pipe.
201 *
202 * Serialization looks like this:
203 * o length (of remainder) uint32.
204 * o uint32 command code.
205 * o per command format.
206 */
207enum ub_ctx_cmd {
208 /** QUIT */
209 UB_LIBCMD_QUIT = 0,
210 /** New query, sent to bg worker */
211 UB_LIBCMD_NEWQUERY,
212 /** Cancel query, sent to bg worker */
213 UB_LIBCMD_CANCEL,
214 /** Query result, originates from bg worker */
215 UB_LIBCMD_ANSWER
216};
217
218/**
219 * finalize a context.
220 * @param ctx: context to finalize. creates shared data.
221 * @return 0 if OK, or errcode.
222 */
223int context_finalize(struct ub_ctx* ctx);
224
225/** compare two ctx_query elements */
226int context_query_cmp(const void* a, const void* b);
227
228/**
229 * delete context query
230 * @param q: query to delete, including message packet and prealloc result
231 */
232void context_query_delete(struct ctx_query* q);
233
234/**
235 * Create new query in context, add to querynum list.
236 * @param ctx: context
237 * @param name: query name
238 * @param rrtype: type
239 * @param rrclass: class
240 * @param cb: callback for async, or NULL for sync.
241 * @param cbarg: user arg for async queries.
242 * @return new ctx_query or NULL for malloc failure.
243 */
237struct ctx_query* context_new(struct ub_ctx* ctx, const char* name,
238 int rrtype, int rrclass, ub_callback_t cb, void* cbarg);
244struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype,
245 int rrclass, ub_callback_t cb, void* cbarg);
239
240/**
241 * Get a new alloc. Creates a new one or uses a cached one.
242 * @param ctx: context
243 * @param locking: if true, cfglock is locked while getting alloc.
244 * @return an alloc, or NULL on mem error.
245 */
246struct alloc_cache* context_obtain_alloc(struct ub_ctx* ctx, int locking);
247
248/**
249 * Release an alloc. Puts it into the cache.
250 * @param ctx: context
251 * @param locking: if true, cfglock is locked while releasing alloc.
252 * @param alloc: alloc to relinquish.
253 */
254void context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc,
255 int locking);
256
257/**
258 * Serialize a context query that questions data.
259 * This serializes the query name, type, ...
260 * As well as command code 'new_query'.
261 * @param q: context query
262 * @param len: the length of the allocation is returned.
263 * @return: an alloc, or NULL on mem error.
264 */
265uint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len);
266
267/**
268 * Serialize a context_query result to hand back to user.
269 * This serializes the query name, type, ..., and result.
270 * As well as command code 'answer'.
271 * @param q: context query
272 * @param err: error code to pass to client.
273 * @param pkt: the packet to add, can be NULL.
274 * @param len: the length of the allocation is returned.
275 * @return: an alloc, or NULL on mem error.
276 */
277uint8_t* context_serialize_answer(struct ctx_query* q, int err,
246
247/**
248 * Get a new alloc. Creates a new one or uses a cached one.
249 * @param ctx: context
250 * @param locking: if true, cfglock is locked while getting alloc.
251 * @return an alloc, or NULL on mem error.
252 */
253struct alloc_cache* context_obtain_alloc(struct ub_ctx* ctx, int locking);
254
255/**
256 * Release an alloc. Puts it into the cache.
257 * @param ctx: context
258 * @param locking: if true, cfglock is locked while releasing alloc.
259 * @param alloc: alloc to relinquish.
260 */
261void context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc,
262 int locking);
263
264/**
265 * Serialize a context query that questions data.
266 * This serializes the query name, type, ...
267 * As well as command code 'new_query'.
268 * @param q: context query
269 * @param len: the length of the allocation is returned.
270 * @return: an alloc, or NULL on mem error.
271 */
272uint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len);
273
274/**
275 * Serialize a context_query result to hand back to user.
276 * This serializes the query name, type, ..., and result.
277 * As well as command code 'answer'.
278 * @param q: context query
279 * @param err: error code to pass to client.
280 * @param pkt: the packet to add, can be NULL.
281 * @param len: the length of the allocation is returned.
282 * @return: an alloc, or NULL on mem error.
283 */
284uint8_t* context_serialize_answer(struct ctx_query* q, int err,
278 ldns_buffer* pkt, uint32_t* len);
285 struct sldns_buffer* pkt, uint32_t* len);
279
280/**
281 * Serialize a query cancellation. Serializes query async id
282 * as well as command code 'cancel'
283 * @param q: context query
284 * @param len: the length of the allocation is returned.
285 * @return: an alloc, or NULL on mem error.
286 */
287uint8_t* context_serialize_cancel(struct ctx_query* q, uint32_t* len);
288
289/**
290 * Serialize a 'quit' command.
291 * @param len: the length of the allocation is returned.
292 * @return: an alloc, or NULL on mem error.
293 */
294uint8_t* context_serialize_quit(uint32_t* len);
295
296/**
297 * Obtain command code from serialized buffer
298 * @param p: buffer serialized.
299 * @param len: length of buffer.
300 * @return command code or QUIT on error.
301 */
302enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len);
303
304/**
305 * Lookup query from new_query buffer.
306 * @param ctx: context
307 * @param p: buffer serialized.
308 * @param len: length of buffer.
309 * @return looked up ctx_query or NULL for malloc failure.
310 */
311struct ctx_query* context_lookup_new_query(struct ub_ctx* ctx,
312 uint8_t* p, uint32_t len);
313
314/**
315 * Deserialize a new_query buffer.
316 * @param ctx: context
317 * @param p: buffer serialized.
318 * @param len: length of buffer.
319 * @return new ctx_query or NULL for malloc failure.
320 */
321struct ctx_query* context_deserialize_new_query(struct ub_ctx* ctx,
322 uint8_t* p, uint32_t len);
323
324/**
325 * Deserialize an answer buffer.
326 * @param ctx: context
327 * @param p: buffer serialized.
328 * @param len: length of buffer.
329 * @param err: error code to be returned to client is passed.
330 * @return ctx_query with answer added or NULL for malloc failure.
331 */
332struct ctx_query* context_deserialize_answer(struct ub_ctx* ctx,
333 uint8_t* p, uint32_t len, int* err);
334
335/**
336 * Deserialize a cancel buffer.
337 * @param ctx: context
338 * @param p: buffer serialized.
339 * @param len: length of buffer.
340 * @return ctx_query to cancel or NULL for failure.
341 */
342struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
343 uint8_t* p, uint32_t len);
344
345#endif /* LIBUNBOUND_CONTEXT_H */
286
287/**
288 * Serialize a query cancellation. Serializes query async id
289 * as well as command code 'cancel'
290 * @param q: context query
291 * @param len: the length of the allocation is returned.
292 * @return: an alloc, or NULL on mem error.
293 */
294uint8_t* context_serialize_cancel(struct ctx_query* q, uint32_t* len);
295
296/**
297 * Serialize a 'quit' command.
298 * @param len: the length of the allocation is returned.
299 * @return: an alloc, or NULL on mem error.
300 */
301uint8_t* context_serialize_quit(uint32_t* len);
302
303/**
304 * Obtain command code from serialized buffer
305 * @param p: buffer serialized.
306 * @param len: length of buffer.
307 * @return command code or QUIT on error.
308 */
309enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len);
310
311/**
312 * Lookup query from new_query buffer.
313 * @param ctx: context
314 * @param p: buffer serialized.
315 * @param len: length of buffer.
316 * @return looked up ctx_query or NULL for malloc failure.
317 */
318struct ctx_query* context_lookup_new_query(struct ub_ctx* ctx,
319 uint8_t* p, uint32_t len);
320
321/**
322 * Deserialize a new_query buffer.
323 * @param ctx: context
324 * @param p: buffer serialized.
325 * @param len: length of buffer.
326 * @return new ctx_query or NULL for malloc failure.
327 */
328struct ctx_query* context_deserialize_new_query(struct ub_ctx* ctx,
329 uint8_t* p, uint32_t len);
330
331/**
332 * Deserialize an answer buffer.
333 * @param ctx: context
334 * @param p: buffer serialized.
335 * @param len: length of buffer.
336 * @param err: error code to be returned to client is passed.
337 * @return ctx_query with answer added or NULL for malloc failure.
338 */
339struct ctx_query* context_deserialize_answer(struct ub_ctx* ctx,
340 uint8_t* p, uint32_t len, int* err);
341
342/**
343 * Deserialize a cancel buffer.
344 * @param ctx: context
345 * @param p: buffer serialized.
346 * @param len: length of buffer.
347 * @return ctx_query to cancel or NULL for failure.
348 */
349struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
350 uint8_t* p, uint32_t len);
351
352#endif /* LIBUNBOUND_CONTEXT_H */