xref: /freebsd/contrib/unbound/libunbound/context.h (revision 7a789145f88a6aceacc59029a0cafe7de7aeefea)
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
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 "libunbound/unbound-event.h"
49 #include "util/data/packed_rrset.h"
50 struct libworker;
51 struct tube;
52 struct sldns_buffer;
53 struct ub_event_base;
54 
55 /** store that the logfile has a debug override */
56 extern int ctx_logfile_overridden;
57 
58 /**
59  * The context structure
60  *
61  * Contains two pipes for async service
62  *	qq : write queries to the async service pid/tid.
63  *	rr : read results from the async service pid/tid.
64  */
65 struct ub_ctx {
66 	/* --- pipes --- */
67 	/** mutex on query write pipe */
68 	lock_basic_type qqpipe_lock;
69 	/** the query write pipe */
70 	struct tube* qq_pipe;
71 	/** mutex on result read pipe */
72 	lock_basic_type rrpipe_lock;
73 	/** the result read pipe */
74 	struct tube* rr_pipe;
75 
76 	/* --- shared data --- */
77 	/** mutex for access to env.cfg, finalized and dothread */
78 	lock_basic_type cfglock;
79 	/**
80 	 * The context has been finalized
81 	 * This is after config when the first resolve is done.
82 	 * The modules are inited (module-init()) and shared caches created.
83 	 */
84 	int finalized;
85 
86 	/** is bg worker created yet ? */
87 	int created_bg;
88 	/** pid of bg worker process */
89 	pid_t bg_pid;
90 	/** tid of bg worker thread */
91 	ub_thread_type bg_tid;
92 	/** pid when pipes are created. This was the process when the
93 	 * setup was called. Helps with clean up, so we can tell after a fork
94 	 * which side of the fork the delete is on. */
95 	pid_t pipe_pid;
96 	/** when threaded, the worker that exists in the created thread. */
97 	struct libworker* thread_worker;
98 
99 	/** do threading (instead of forking) for async resolution */
100 	int dothread;
101 	/** next thread number for new threads */
102 	int thr_next_num;
103 	/** if logfile is overridden */
104 	int logfile_override;
105 	/** what logfile to use instead */
106 	FILE* log_out;
107 	/**
108 	 * List of alloc-cache-id points per threadnum for notinuse threads.
109 	 * Simply the entire struct alloc_cache with the 'super' member used
110 	 * to link a simply linked list. Reset super member to the superalloc
111 	 * before use.
112 	 */
113 	struct alloc_cache* alloc_list;
114 
115 	/** shared caches, and so on */
116 	struct alloc_cache superalloc;
117 	/** module env master value */
118 	struct module_env* env;
119 	/** module stack */
120 	struct module_stack mods;
121 	/** local authority zones */
122 	struct local_zones* local_zones;
123 	/** random state used to seed new random state structures */
124 	struct ub_randstate* seed_rnd;
125 
126 	/** event base for event oriented interface */
127 	struct ub_event_base* event_base;
128 	/** true if the event_base is a pluggable base that is malloced
129 	 * with a user event base inside, if so, clean up the pluggable alloc*/
130 	int event_base_malloced;
131 	/** libworker for event based interface */
132 	struct libworker* event_worker;
133 
134 	/** next query number (to try) to use */
135 	int next_querynum;
136 	/** number of async queries outstanding */
137 	size_t num_async;
138 	/**
139 	 * Tree of outstanding queries. Indexed by querynum
140 	 * Used when results come in for async to lookup.
141 	 * Used when cancel is done for lookup (and delete).
142 	 * Used to see if querynum is free for use.
143 	 * Content of type ctx_query.
144 	 */
145 	rbtree_type queries;
146 };
147 
148 /**
149  * The queries outstanding for the libunbound resolver.
150  * These are outstanding for async resolution.
151  * But also, outstanding for sync resolution by one of the threads that
152  * has joined the threadpool.
153  */
154 struct ctx_query {
155 	/** node in rbtree, must be first entry, key is ptr to the querynum */
156 	struct rbnode_type node;
157 	/** query id number, key for node */
158 	int querynum;
159 	/** was this an async query? */
160 	int async;
161 	/** was this query cancelled (for bg worker) */
162 	int cancelled;
163 
164 	/** for async query, the callback function of type ub_callback_type */
165 	ub_callback_type cb;
166 	/** for event callbacks the type is ub_event_callback_type */
167         ub_event_callback_type cb_event;
168 	/** for async query, the callback user arg */
169 	void* cb_arg;
170 	/** for async query the unique info */
171 	void* unique_info;
172 
173 	/** answer message, result from resolver lookup. */
174 	uint8_t* msg;
175 	/** resulting message length. */
176 	size_t msg_len;
177 	/** validation status on security */
178 	enum sec_status msg_security;
179 	/** store libworker that is handling this query */
180 	struct libworker* w;
181 
182 	/** result structure, also contains original query, type, class.
183 	 * malloced ptr ready to hand to the client. */
184 	struct ub_result* res;
185 };
186 
187 /**
188  * Command codes for libunbound pipe.
189  *
190  * Serialization looks like this:
191  * 	o length (of remainder) uint32.
192  * 	o uint32 command code.
193  * 	o per command format.
194  */
195 enum ub_ctx_cmd {
196 	/** QUIT */
197 	UB_LIBCMD_QUIT = 0,
198 	/** New query, sent to bg worker */
199 	UB_LIBCMD_NEWQUERY,
200 	/** Cancel query, sent to bg worker */
201 	UB_LIBCMD_CANCEL,
202 	/** Query result, originates from bg worker */
203 	UB_LIBCMD_ANSWER
204 };
205 
206 /**
207  * finalize a context.
208  * @param ctx: context to finalize. creates shared data.
209  * @return 0 if OK, or errcode.
210  */
211 int context_finalize(struct ub_ctx* ctx);
212 
213 /** compare two ctx_query elements */
214 int context_query_cmp(const void* a, const void* b);
215 
216 /**
217  * delete context query
218  * @param q: query to delete, including message packet and prealloc result
219  */
220 void context_query_delete(struct ctx_query* q);
221 
222 /**
223  * Create new query in context, add to querynum list.
224  * @param ctx: context
225  * @param name: query name
226  * @param rrtype: type
227  * @param rrclass: class
228  * @param cb: callback for async, or NULL for sync.
229  * @param cb_event: event callback for async, or NULL for sync.
230  * @param cbarg: user arg for async queries.
231  * @return new ctx_query or NULL for malloc failure.
232  */
233 struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype,
234         int rrclass,  ub_callback_type cb, ub_event_callback_type cb_event,
235 	void* cbarg);
236 
237 /**
238  * Get a new alloc. Creates a new one or uses a cached one.
239  * @param ctx: context
240  * @param locking: if true, cfglock is locked while getting alloc.
241  * @return an alloc, or NULL on mem error.
242  */
243 struct alloc_cache* context_obtain_alloc(struct ub_ctx* ctx, int locking);
244 
245 /**
246  * Release an alloc. Puts it into the cache.
247  * @param ctx: context
248  * @param locking: if true, cfglock is locked while releasing alloc.
249  * @param alloc: alloc to relinquish.
250  */
251 void context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc,
252 	int locking);
253 
254 /**
255  * Serialize a context query that questions data.
256  * This serializes the query name, type, ...
257  * As well as command code 'new_query'.
258  * @param q: context query
259  * @param len: the length of the allocation is returned.
260  * @return: an alloc, or NULL on mem error.
261  */
262 uint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len);
263 
264 /**
265  * Serialize a context_query result to hand back to user.
266  * This serializes the query name, type, ..., and result.
267  * As well as command code 'answer'.
268  * @param q: context query
269  * @param err: error code to pass to client.
270  * @param pkt: the packet to add, can be NULL.
271  * @param len: the length of the allocation is returned.
272  * @return: an alloc, or NULL on mem error.
273  */
274 uint8_t* context_serialize_answer(struct ctx_query* q, int err,
275 	struct sldns_buffer* pkt, uint32_t* len);
276 
277 /**
278  * Serialize a query cancellation. Serializes query async id
279  * as well as command code 'cancel'
280  * @param q: context query
281  * @param len: the length of the allocation is returned.
282  * @return: an alloc, or NULL on mem error.
283  */
284 uint8_t* context_serialize_cancel(struct ctx_query* q, uint32_t* len);
285 
286 /**
287  * Serialize a 'quit' command.
288  * @param len: the length of the allocation is returned.
289  * @return: an alloc, or NULL on mem error.
290  */
291 uint8_t* context_serialize_quit(uint32_t* len);
292 
293 /**
294  * Obtain command code from serialized buffer
295  * @param p: buffer serialized.
296  * @param len: length of buffer.
297  * @return command code or QUIT on error.
298  */
299 enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len);
300 
301 /**
302  * Lookup query from new_query buffer.
303  * @param ctx: context
304  * @param p: buffer serialized.
305  * @param len: length of buffer.
306  * @return looked up ctx_query or NULL for malloc failure.
307  */
308 struct ctx_query* context_lookup_new_query(struct ub_ctx* ctx,
309 	uint8_t* p, uint32_t len);
310 
311 /**
312  * Deserialize a new_query buffer.
313  * @param ctx: context
314  * @param p: buffer serialized.
315  * @param len: length of buffer.
316  * @return new ctx_query or NULL for malloc failure.
317  */
318 struct ctx_query* context_deserialize_new_query(struct ub_ctx* ctx,
319 	uint8_t* p, uint32_t len);
320 
321 /**
322  * Deserialize an answer buffer.
323  * @param ctx: context
324  * @param p: buffer serialized.
325  * @param len: length of buffer.
326  * @param err: error code to be returned to client is passed.
327  * @return ctx_query with answer added or NULL for malloc failure.
328  */
329 struct ctx_query* context_deserialize_answer(struct ub_ctx* ctx,
330 	uint8_t* p, uint32_t len, int* err);
331 
332 /**
333  * Deserialize a cancel buffer.
334  * @param ctx: context
335  * @param p: buffer serialized.
336  * @param len: length of buffer.
337  * @return ctx_query to cancel or NULL for failure.
338  */
339 struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
340 	uint8_t* p, uint32_t len);
341 
342 #endif /* LIBUNBOUND_CONTEXT_H */
343