context.h revision 356345
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"
50struct libworker;
51struct tube;
52struct sldns_buffer;
53struct ub_event_base;
54
55/** store that the logfile has a debug override */
56extern 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 */
65struct 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
93	/** do threading (instead of forking) for async resolution */
94	int dothread;
95	/** next thread number for new threads */
96	int thr_next_num;
97	/** if logfile is overridden */
98	int logfile_override;
99	/** what logfile to use instead */
100	FILE* log_out;
101	/**
102	 * List of alloc-cache-id points per threadnum for notinuse threads.
103	 * Simply the entire struct alloc_cache with the 'super' member used
104	 * to link a simply linked list. Reset super member to the superalloc
105	 * before use.
106	 */
107	struct alloc_cache* alloc_list;
108
109	/** shared caches, and so on */
110	struct alloc_cache superalloc;
111	/** module env master value */
112	struct module_env* env;
113	/** module stack */
114	struct module_stack mods;
115	/** local authority zones */
116	struct local_zones* local_zones;
117	/** random state used to seed new random state structures */
118	struct ub_randstate* seed_rnd;
119
120	/** event base for event oriented interface */
121	struct ub_event_base* event_base;
122	/** true if the event_base is a pluggable base that is malloced
123	 * with a user event base inside, if so, clean up the pluggable alloc*/
124	int event_base_malloced;
125	/** libworker for event based interface */
126	struct libworker* event_worker;
127
128	/** next query number (to try) to use */
129	int next_querynum;
130	/** number of async queries outstanding */
131	size_t num_async;
132	/**
133	 * Tree of outstanding queries. Indexed by querynum
134	 * Used when results come in for async to lookup.
135	 * Used when cancel is done for lookup (and delete).
136	 * Used to see if querynum is free for use.
137	 * Content of type ctx_query.
138	 */
139	rbtree_type queries;
140};
141
142/**
143 * The queries outstanding for the libunbound resolver.
144 * These are outstanding for async resolution.
145 * But also, outstanding for sync resolution by one of the threads that
146 * has joined the threadpool.
147 */
148struct ctx_query {
149	/** node in rbtree, must be first entry, key is ptr to the querynum */
150	struct rbnode_type node;
151	/** query id number, key for node */
152	int querynum;
153	/** was this an async query? */
154	int async;
155	/** was this query cancelled (for bg worker) */
156	int cancelled;
157
158	/** for async query, the callback function of type ub_callback_type */
159	ub_callback_type cb;
160	/** for event callbacks the type is ub_event_callback_type */
161        ub_event_callback_type cb_event;
162	/** for async query, the callback user arg */
163	void* cb_arg;
164
165	/** answer message, result from resolver lookup. */
166	uint8_t* msg;
167	/** resulting message length. */
168	size_t msg_len;
169	/** validation status on security */
170	enum sec_status msg_security;
171	/** store libworker that is handling this query */
172	struct libworker* w;
173
174	/** result structure, also contains original query, type, class.
175	 * malloced ptr ready to hand to the client. */
176	struct ub_result* res;
177};
178
179/**
180 * The error constants
181 */
182enum ub_ctx_err {
183	/** no error */
184	UB_NOERROR = 0,
185	/** socket operation. Set to -1, so that if an error from _fd() is
186	 * passed (-1) it gives a socket error. */
187	UB_SOCKET = -1,
188	/** alloc failure */
189	UB_NOMEM = -2,
190	/** syntax error */
191	UB_SYNTAX = -3,
192	/** DNS service failed */
193	UB_SERVFAIL = -4,
194	/** fork() failed */
195	UB_FORKFAIL = -5,
196	/** cfg change after finalize() */
197	UB_AFTERFINAL = -6,
198	/** initialization failed (bad settings) */
199	UB_INITFAIL = -7,
200	/** error in pipe communication with async bg worker */
201	UB_PIPE = -8,
202	/** error reading from file (resolv.conf) */
203	UB_READFILE = -9,
204	/** error async_id does not exist or result already been delivered */
205	UB_NOID = -10
206};
207
208/**
209 * Command codes for libunbound pipe.
210 *
211 * Serialization looks like this:
212 * 	o length (of remainder) uint32.
213 * 	o uint32 command code.
214 * 	o per command format.
215 */
216enum ub_ctx_cmd {
217	/** QUIT */
218	UB_LIBCMD_QUIT = 0,
219	/** New query, sent to bg worker */
220	UB_LIBCMD_NEWQUERY,
221	/** Cancel query, sent to bg worker */
222	UB_LIBCMD_CANCEL,
223	/** Query result, originates from bg worker */
224	UB_LIBCMD_ANSWER
225};
226
227/**
228 * finalize a context.
229 * @param ctx: context to finalize. creates shared data.
230 * @return 0 if OK, or errcode.
231 */
232int context_finalize(struct ub_ctx* ctx);
233
234/** compare two ctx_query elements */
235int context_query_cmp(const void* a, const void* b);
236
237/**
238 * delete context query
239 * @param q: query to delete, including message packet and prealloc result
240 */
241void context_query_delete(struct ctx_query* q);
242
243/**
244 * Create new query in context, add to querynum list.
245 * @param ctx: context
246 * @param name: query name
247 * @param rrtype: type
248 * @param rrclass: class
249 * @param cb: callback for async, or NULL for sync.
250 * @param cb_event: event callback for async, or NULL for sync.
251 * @param cbarg: user arg for async queries.
252 * @return new ctx_query or NULL for malloc failure.
253 */
254struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype,
255        int rrclass,  ub_callback_type cb, ub_event_callback_type cb_event,
256	void* cbarg);
257
258/**
259 * Get a new alloc. Creates a new one or uses a cached one.
260 * @param ctx: context
261 * @param locking: if true, cfglock is locked while getting alloc.
262 * @return an alloc, or NULL on mem error.
263 */
264struct alloc_cache* context_obtain_alloc(struct ub_ctx* ctx, int locking);
265
266/**
267 * Release an alloc. Puts it into the cache.
268 * @param ctx: context
269 * @param locking: if true, cfglock is locked while releasing alloc.
270 * @param alloc: alloc to relinquish.
271 */
272void context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc,
273	int locking);
274
275/**
276 * Serialize a context query that questions data.
277 * This serializes the query name, type, ...
278 * As well as command code 'new_query'.
279 * @param q: context query
280 * @param len: the length of the allocation is returned.
281 * @return: an alloc, or NULL on mem error.
282 */
283uint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len);
284
285/**
286 * Serialize a context_query result to hand back to user.
287 * This serializes the query name, type, ..., and result.
288 * As well as command code 'answer'.
289 * @param q: context query
290 * @param err: error code to pass to client.
291 * @param pkt: the packet to add, can be NULL.
292 * @param len: the length of the allocation is returned.
293 * @return: an alloc, or NULL on mem error.
294 */
295uint8_t* context_serialize_answer(struct ctx_query* q, int err,
296	struct sldns_buffer* pkt, uint32_t* len);
297
298/**
299 * Serialize a query cancellation. Serializes query async id
300 * as well as command code 'cancel'
301 * @param q: context query
302 * @param len: the length of the allocation is returned.
303 * @return: an alloc, or NULL on mem error.
304 */
305uint8_t* context_serialize_cancel(struct ctx_query* q, uint32_t* len);
306
307/**
308 * Serialize a 'quit' command.
309 * @param len: the length of the allocation is returned.
310 * @return: an alloc, or NULL on mem error.
311 */
312uint8_t* context_serialize_quit(uint32_t* len);
313
314/**
315 * Obtain command code from serialized buffer
316 * @param p: buffer serialized.
317 * @param len: length of buffer.
318 * @return command code or QUIT on error.
319 */
320enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len);
321
322/**
323 * Lookup query from new_query buffer.
324 * @param ctx: context
325 * @param p: buffer serialized.
326 * @param len: length of buffer.
327 * @return looked up ctx_query or NULL for malloc failure.
328 */
329struct ctx_query* context_lookup_new_query(struct ub_ctx* ctx,
330	uint8_t* p, uint32_t len);
331
332/**
333 * Deserialize a new_query buffer.
334 * @param ctx: context
335 * @param p: buffer serialized.
336 * @param len: length of buffer.
337 * @return new ctx_query or NULL for malloc failure.
338 */
339struct ctx_query* context_deserialize_new_query(struct ub_ctx* ctx,
340	uint8_t* p, uint32_t len);
341
342/**
343 * Deserialize an answer buffer.
344 * @param ctx: context
345 * @param p: buffer serialized.
346 * @param len: length of buffer.
347 * @param err: error code to be returned to client is passed.
348 * @return ctx_query with answer added or NULL for malloc failure.
349 */
350struct ctx_query* context_deserialize_answer(struct ub_ctx* ctx,
351	uint8_t* p, uint32_t len, int* err);
352
353/**
354 * Deserialize a cancel buffer.
355 * @param ctx: context
356 * @param p: buffer serialized.
357 * @param len: length of buffer.
358 * @return ctx_query to cancel or NULL for failure.
359 */
360struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
361	uint8_t* p, uint32_t len);
362
363#endif /* LIBUNBOUND_CONTEXT_H */
364