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