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