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