context.h revision 269257
1227825Stheraven/*
2227825Stheraven * libunbound/context.h - validating context for unbound internal use
3227825Stheraven *
4227825Stheraven * Copyright (c) 2007, NLnet Labs. All rights reserved.
5227825Stheraven *
6227825Stheraven * This software is open source.
7227825Stheraven *
8227825Stheraven * Redistribution and use in source and binary forms, with or without
9227825Stheraven * modification, are permitted provided that the following conditions
10227825Stheraven * are met:
11227825Stheraven *
12227825Stheraven * Redistributions of source code must retain the above copyright notice,
13227825Stheraven * this list of conditions and the following disclaimer.
14227825Stheraven *
15227825Stheraven * Redistributions in binary form must reproduce the above copyright notice,
16227825Stheraven * this list of conditions and the following disclaimer in the documentation
17227825Stheraven * and/or other materials provided with the distribution.
18227825Stheraven *
19227825Stheraven * Neither the name of the NLNET LABS nor the names of its contributors may
20227825Stheraven * be used to endorse or promote products derived from this software without
21227825Stheraven * specific prior written permission.
22227825Stheraven *
23227825Stheraven * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24227825Stheraven * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25227825Stheraven * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26227825Stheraven * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27227825Stheraven * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28227825Stheraven * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29227825Stheraven * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30227825Stheraven * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31227825Stheraven * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32227825Stheraven * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33227825Stheraven * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34227825Stheraven */
35227825Stheraven
36227825Stheraven/**
37227825Stheraven * \file
38227825Stheraven *
39227825Stheraven * This file contains the validator context structure.
40227825Stheraven */
41227825Stheraven#ifndef LIBUNBOUND_CONTEXT_H
42227825Stheraven#define LIBUNBOUND_CONTEXT_H
43227825Stheraven#include "util/locks.h"
44227825Stheraven#include "util/alloc.h"
45227825Stheraven#include "util/rbtree.h"
46227825Stheraven#include "services/modstack.h"
47227825Stheraven#include "libunbound/unbound.h"
48227825Stheraven#include "util/data/packed_rrset.h"
49227825Stheravenstruct libworker;
50227825Stheravenstruct tube;
51227825Stheravenstruct sldns_buffer;
52227825Stheravenstruct event_base;
53227825Stheraven
54227825Stheraven/**
55227825Stheraven * The context structure
56227825Stheraven *
57227825Stheraven * Contains two pipes for async service
58227825Stheraven *	qq : write queries to the async service pid/tid.
59262801Sdim *	rr : read results from the async service pid/tid.
60227825Stheraven */
61227825Stheravenstruct ub_ctx {
62227825Stheraven	/* --- pipes --- */
63227825Stheraven	/** mutex on query write pipe */
64227825Stheraven	lock_basic_t qqpipe_lock;
65227825Stheraven	/** the query write pipe */
66227825Stheraven	struct tube* qq_pipe;
67227825Stheraven	/** mutex on result read pipe */
68227825Stheraven	lock_basic_t rrpipe_lock;
69227825Stheraven	/** the result read pipe */
70227825Stheraven	struct tube* rr_pipe;
71262801Sdim
72227825Stheraven	/* --- shared data --- */
73227825Stheraven	/** mutex for access to env.cfg, finalized and dothread */
74227825Stheraven	lock_basic_t cfglock;
75227825Stheraven	/**
76227825Stheraven	 * The context has been finalized
77262801Sdim	 * This is after config when the first resolve is done.
78227825Stheraven	 * The modules are inited (module-init()) and shared caches created.
79227825Stheraven	 */
80227825Stheraven	int finalized;
81227825Stheraven
82227825Stheraven	/** is bg worker created yet ? */
83262801Sdim	int created_bg;
84227825Stheraven	/** pid of bg worker process */
85227825Stheraven	pid_t bg_pid;
86227825Stheraven	/** tid of bg worker thread */
87227825Stheraven	ub_thread_t bg_tid;
88227825Stheraven
89262801Sdim	/** do threading (instead of forking) for async resolution */
90227825Stheraven	int dothread;
91227825Stheraven	/** next thread number for new threads */
92227825Stheraven	int thr_next_num;
93227825Stheraven	/** if logfile is overriden */
94227825Stheraven	int logfile_override;
95262801Sdim	/** what logfile to use instead */
96227825Stheraven	FILE* log_out;
97227825Stheraven	/**
98227825Stheraven	 * List of alloc-cache-id points per threadnum for notinuse threads.
99227825Stheraven	 * Simply the entire struct alloc_cache with the 'super' member used
100227825Stheraven	 * to link a simply linked list. Reset super member to the superalloc
101262801Sdim	 * before use.
102227825Stheraven	 */
103227825Stheraven	struct alloc_cache* alloc_list;
104227825Stheraven
105227825Stheraven	/** shared caches, and so on */
106227825Stheraven	struct alloc_cache superalloc;
107262801Sdim	/** module env master value */
108227825Stheraven	struct module_env* env;
109227825Stheraven	/** module stack */
110227825Stheraven	struct module_stack mods;
111227825Stheraven	/** local authority zones */
112227825Stheraven	struct local_zones* local_zones;
113262801Sdim	/** random state used to seed new random state structures */
114227825Stheraven	struct ub_randstate* seed_rnd;
115227825Stheraven
116227825Stheraven	/** event base for event oriented interface */
117227825Stheraven	struct event_base* event_base;
118227825Stheraven	/** libworker for event based interface */
119262801Sdim	struct libworker* event_worker;
120227825Stheraven
121227825Stheraven	/** next query number (to try) to use */
122227825Stheraven	int next_querynum;
123227825Stheraven	/** number of async queries outstanding */
124227825Stheraven	size_t num_async;
125262801Sdim	/**
126227825Stheraven	 * Tree of outstanding queries. Indexed by querynum
127227825Stheraven	 * Used when results come in for async to lookup.
128227825Stheraven	 * Used when cancel is done for lookup (and delete).
129227825Stheraven	 * Used to see if querynum is free for use.
130227825Stheraven	 * Content of type ctx_query.
131262801Sdim	 */
132227825Stheraven	rbtree_t queries;
133227825Stheraven};
134227825Stheraven
135227825Stheraven/**
136227825Stheraven * The queries outstanding for the libunbound resolver.
137262801Sdim * These are outstanding for async resolution.
138227825Stheraven * But also, outstanding for sync resolution by one of the threads that
139227825Stheraven * has joined the threadpool.
140227825Stheraven */
141227825Stheravenstruct ctx_query {
142227825Stheraven	/** node in rbtree, must be first entry, key is ptr to the querynum */
143262801Sdim	struct rbnode_t node;
144227825Stheraven	/** query id number, key for node */
145227825Stheraven	int querynum;
146227825Stheraven	/** was this an async query? */
147227825Stheraven	int async;
148227825Stheraven	/** was this query cancelled (for bg worker) */
149262801Sdim	int cancelled;
150227825Stheraven
151227825Stheraven	/** for async query, the callback function */
152227825Stheraven	ub_callback_t cb;
153227825Stheraven	/** for async query, the callback user arg */
154227825Stheraven	void* cb_arg;
155262801Sdim
156227825Stheraven	/** answer message, result from resolver lookup. */
157227825Stheraven	uint8_t* msg;
158227825Stheraven	/** resulting message length. */
159227825Stheraven	size_t msg_len;
160227825Stheraven	/** validation status on security */
161262801Sdim	enum sec_status msg_security;
162262801Sdim	/** store libworker that is handling this query */
163262801Sdim	struct libworker* w;
164262801Sdim
165262801Sdim	/** result structure, also contains original query, type, class.
166262801Sdim	 * malloced ptr ready to hand to the client. */
167262801Sdim	struct ub_result* res;
168262801Sdim};
169262801Sdim
170262801Sdim/**
171262801Sdim * The error constants
172262801Sdim */
173262801Sdimenum ub_ctx_err {
174262801Sdim	/** no error */
175262801Sdim	UB_NOERROR = 0,
176262801Sdim	/** socket operation. Set to -1, so that if an error from _fd() is
177262801Sdim	 * passed (-1) it gives a socket error. */
178262801Sdim	UB_SOCKET = -1,
179262801Sdim	/** alloc failure */
180262801Sdim	UB_NOMEM = -2,
181262801Sdim	/** syntax error */
182262801Sdim	UB_SYNTAX = -3,
183262801Sdim	/** DNS service failed */
184262801Sdim	UB_SERVFAIL = -4,
185227825Stheraven	/** fork() failed */
186227825Stheraven	UB_FORKFAIL = -5,
187227825Stheraven	/** cfg change after finalize() */
188227825Stheraven	UB_AFTERFINAL = -6,
189227825Stheraven	/** initialization failed (bad settings) */
190227825Stheraven	UB_INITFAIL = -7,
191227825Stheraven	/** error in pipe communication with async bg worker */
192227825Stheraven	UB_PIPE = -8,
193227825Stheraven	/** error reading from file (resolv.conf) */
194227825Stheraven	UB_READFILE = -9,
195227825Stheraven	/** error async_id does not exist or result already been delivered */
196227825Stheraven	UB_NOID = -10
197227825Stheraven};
198227825Stheraven
199227825Stheraven/**
200227825Stheraven * Command codes for libunbound pipe.
201227825Stheraven *
202227825Stheraven * Serialization looks like this:
203227825Stheraven * 	o length (of remainder) uint32.
204227825Stheraven * 	o uint32 command code.
205227825Stheraven * 	o per command format.
206227825Stheraven */
207227825Stheravenenum ub_ctx_cmd {
208227825Stheraven	/** QUIT */
209227825Stheraven	UB_LIBCMD_QUIT = 0,
210227825Stheraven	/** New query, sent to bg worker */
211227825Stheraven	UB_LIBCMD_NEWQUERY,
212227825Stheraven	/** Cancel query, sent to bg worker */
213227825Stheraven	UB_LIBCMD_CANCEL,
214227825Stheraven	/** Query result, originates from bg worker */
215227825Stheraven	UB_LIBCMD_ANSWER
216227825Stheraven};
217227825Stheraven
218227825Stheraven/**
219227825Stheraven * finalize a context.
220227825Stheraven * @param ctx: context to finalize. creates shared data.
221227825Stheraven * @return 0 if OK, or errcode.
222227825Stheraven */
223227825Stheravenint context_finalize(struct ub_ctx* ctx);
224227825Stheraven
225232950Stheraven/** compare two ctx_query elements */
226227825Stheravenint context_query_cmp(const void* a, const void* b);
227227825Stheraven
228227825Stheraven/**
229227825Stheraven * delete context query
230227825Stheraven * @param q: query to delete, including message packet and prealloc result
231227825Stheraven */
232227825Stheravenvoid context_query_delete(struct ctx_query* q);
233227825Stheraven
234227825Stheraven/**
235227825Stheraven * Create new query in context, add to querynum list.
236227825Stheraven * @param ctx: context
237227825Stheraven * @param name: query name
238227825Stheraven * @param rrtype: type
239227825Stheraven * @param rrclass: class
240227825Stheraven * @param cb: callback for async, or NULL for sync.
241227825Stheraven * @param cbarg: user arg for async queries.
242227825Stheraven * @return new ctx_query or NULL for malloc failure.
243227825Stheraven */
244227825Stheravenstruct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype,
245227825Stheraven        int rrclass, ub_callback_t cb, void* cbarg);
246227825Stheraven
247227825Stheraven/**
248227825Stheraven * Get a new alloc. Creates a new one or uses a cached one.
249227825Stheraven * @param ctx: context
250227825Stheraven * @param locking: if true, cfglock is locked while getting alloc.
251227825Stheraven * @return an alloc, or NULL on mem error.
252227825Stheraven */
253227825Stheravenstruct alloc_cache* context_obtain_alloc(struct ub_ctx* ctx, int locking);
254227825Stheraven
255227825Stheraven/**
256227825Stheraven * Release an alloc. Puts it into the cache.
257227825Stheraven * @param ctx: context
258227825Stheraven * @param locking: if true, cfglock is locked while releasing alloc.
259227825Stheraven * @param alloc: alloc to relinquish.
260227825Stheraven */
261227825Stheravenvoid context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc,
262227825Stheraven	int locking);
263227825Stheraven
264227825Stheraven/**
265227825Stheraven * Serialize a context query that questions data.
266227825Stheraven * This serializes the query name, type, ...
267227825Stheraven * As well as command code 'new_query'.
268227825Stheraven * @param q: context query
269227825Stheraven * @param len: the length of the allocation is returned.
270227825Stheraven * @return: an alloc, or NULL on mem error.
271227825Stheraven */
272227825Stheravenuint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len);
273227825Stheraven
274227825Stheraven/**
275227825Stheraven * Serialize a context_query result to hand back to user.
276227825Stheraven * This serializes the query name, type, ..., and result.
277227825Stheraven * As well as command code 'answer'.
278227825Stheraven * @param q: context query
279227825Stheraven * @param err: error code to pass to client.
280227825Stheraven * @param pkt: the packet to add, can be NULL.
281227825Stheraven * @param len: the length of the allocation is returned.
282227825Stheraven * @return: an alloc, or NULL on mem error.
283227825Stheraven */
284227825Stheravenuint8_t* context_serialize_answer(struct ctx_query* q, int err,
285227825Stheraven	struct sldns_buffer* pkt, uint32_t* len);
286227825Stheraven
287227825Stheraven/**
288227825Stheraven * Serialize a query cancellation. Serializes query async id
289227825Stheraven * as well as command code 'cancel'
290227825Stheraven * @param q: context query
291227825Stheraven * @param len: the length of the allocation is returned.
292227825Stheraven * @return: an alloc, or NULL on mem error.
293227825Stheraven */
294227825Stheravenuint8_t* context_serialize_cancel(struct ctx_query* q, uint32_t* len);
295227825Stheraven
296227825Stheraven/**
297227825Stheraven * Serialize a 'quit' command.
298227825Stheraven * @param len: the length of the allocation is returned.
299227825Stheraven * @return: an alloc, or NULL on mem error.
300227825Stheraven */
301227825Stheravenuint8_t* context_serialize_quit(uint32_t* len);
302227825Stheraven
303227825Stheraven/**
304227825Stheraven * Obtain command code from serialized buffer
305227825Stheraven * @param p: buffer serialized.
306227825Stheraven * @param len: length of buffer.
307227825Stheraven * @return command code or QUIT on error.
308227825Stheraven */
309227825Stheravenenum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len);
310227825Stheraven
311227825Stheraven/**
312227825Stheraven * Lookup query from new_query buffer.
313227825Stheraven * @param ctx: context
314227825Stheraven * @param p: buffer serialized.
315227825Stheraven * @param len: length of buffer.
316227825Stheraven * @return looked up ctx_query or NULL for malloc failure.
317227825Stheraven */
318227825Stheravenstruct ctx_query* context_lookup_new_query(struct ub_ctx* ctx,
319227825Stheraven	uint8_t* p, uint32_t len);
320227825Stheraven
321227825Stheraven/**
322227825Stheraven * Deserialize a new_query buffer.
323227825Stheraven * @param ctx: context
324227825Stheraven * @param p: buffer serialized.
325227825Stheraven * @param len: length of buffer.
326227825Stheraven * @return new ctx_query or NULL for malloc failure.
327227825Stheraven */
328227825Stheravenstruct ctx_query* context_deserialize_new_query(struct ub_ctx* ctx,
329227825Stheraven	uint8_t* p, uint32_t len);
330227825Stheraven
331227825Stheraven/**
332227825Stheraven * Deserialize an answer buffer.
333227825Stheraven * @param ctx: context
334227825Stheraven * @param p: buffer serialized.
335227825Stheraven * @param len: length of buffer.
336227825Stheraven * @param err: error code to be returned to client is passed.
337227825Stheraven * @return ctx_query with answer added or NULL for malloc failure.
338227825Stheraven */
339227825Stheravenstruct ctx_query* context_deserialize_answer(struct ub_ctx* ctx,
340227825Stheraven	uint8_t* p, uint32_t len, int* err);
341227825Stheraven
342227825Stheraven/**
343227825Stheraven * Deserialize a cancel buffer.
344227825Stheraven * @param ctx: context
345227825Stheraven * @param p: buffer serialized.
346227825Stheraven * @param len: length of buffer.
347227825Stheraven * @return ctx_query to cancel or NULL for failure.
348227825Stheraven */
349227825Stheravenstruct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
350227825Stheraven	uint8_t* p, uint32_t len);
351227825Stheraven
352227825Stheraven#endif /* LIBUNBOUND_CONTEXT_H */
353227825Stheraven