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