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