1933707f3Ssthen /* 2933707f3Ssthen * libunbound/context.h - validating context for unbound internal use 3933707f3Ssthen * 4933707f3Ssthen * Copyright (c) 2007, NLnet Labs. All rights reserved. 5933707f3Ssthen * 6933707f3Ssthen * This software is open source. 7933707f3Ssthen * 8933707f3Ssthen * Redistribution and use in source and binary forms, with or without 9933707f3Ssthen * modification, are permitted provided that the following conditions 10933707f3Ssthen * are met: 11933707f3Ssthen * 12933707f3Ssthen * Redistributions of source code must retain the above copyright notice, 13933707f3Ssthen * this list of conditions and the following disclaimer. 14933707f3Ssthen * 15933707f3Ssthen * Redistributions in binary form must reproduce the above copyright notice, 16933707f3Ssthen * this list of conditions and the following disclaimer in the documentation 17933707f3Ssthen * and/or other materials provided with the distribution. 18933707f3Ssthen * 19933707f3Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 20933707f3Ssthen * be used to endorse or promote products derived from this software without 21933707f3Ssthen * specific prior written permission. 22933707f3Ssthen * 23933707f3Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 245d76a658Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 255d76a658Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 265d76a658Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 275d76a658Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 285d76a658Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 295d76a658Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 305d76a658Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 315d76a658Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 325d76a658Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 335d76a658Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34933707f3Ssthen */ 35933707f3Ssthen 36933707f3Ssthen /** 37933707f3Ssthen * \file 38933707f3Ssthen * 39933707f3Ssthen * This file contains the validator context structure. 40933707f3Ssthen */ 41933707f3Ssthen #ifndef LIBUNBOUND_CONTEXT_H 42933707f3Ssthen #define LIBUNBOUND_CONTEXT_H 43933707f3Ssthen #include "util/locks.h" 44933707f3Ssthen #include "util/alloc.h" 45933707f3Ssthen #include "util/rbtree.h" 46933707f3Ssthen #include "services/modstack.h" 47933707f3Ssthen #include "libunbound/unbound.h" 4820237c55Ssthen #include "libunbound/unbound-event.h" 49933707f3Ssthen #include "util/data/packed_rrset.h" 50933707f3Ssthen struct libworker; 51933707f3Ssthen struct tube; 525d76a658Ssthen struct sldns_buffer; 532ee382b6Ssthen struct ub_event_base; 54933707f3Ssthen 558240c1b9Ssthen /** store that the logfile has a debug override */ 568240c1b9Ssthen extern int ctx_logfile_overridden; 578240c1b9Ssthen 58933707f3Ssthen /** 59933707f3Ssthen * The context structure 60933707f3Ssthen * 61933707f3Ssthen * Contains two pipes for async service 62933707f3Ssthen * qq : write queries to the async service pid/tid. 63933707f3Ssthen * rr : read results from the async service pid/tid. 64933707f3Ssthen */ 65933707f3Ssthen struct ub_ctx { 66933707f3Ssthen /* --- pipes --- */ 67933707f3Ssthen /** mutex on query write pipe */ 6877079be7Ssthen lock_basic_type qqpipe_lock; 69933707f3Ssthen /** the query write pipe */ 70933707f3Ssthen struct tube* qq_pipe; 71933707f3Ssthen /** mutex on result read pipe */ 7277079be7Ssthen lock_basic_type rrpipe_lock; 73933707f3Ssthen /** the result read pipe */ 74933707f3Ssthen struct tube* rr_pipe; 75933707f3Ssthen 76933707f3Ssthen /* --- shared data --- */ 77933707f3Ssthen /** mutex for access to env.cfg, finalized and dothread */ 7877079be7Ssthen lock_basic_type cfglock; 79933707f3Ssthen /** 80933707f3Ssthen * The context has been finalized 81933707f3Ssthen * This is after config when the first resolve is done. 82933707f3Ssthen * The modules are inited (module-init()) and shared caches created. 83933707f3Ssthen */ 84933707f3Ssthen int finalized; 85933707f3Ssthen 86933707f3Ssthen /** is bg worker created yet ? */ 87933707f3Ssthen int created_bg; 88933707f3Ssthen /** pid of bg worker process */ 89933707f3Ssthen pid_t bg_pid; 90933707f3Ssthen /** tid of bg worker thread */ 9177079be7Ssthen ub_thread_type bg_tid; 92*8b7325afSsthen /** pid when pipes are created. This was the process when the 93*8b7325afSsthen * setup was called. Helps with clean up, so we can tell after a fork 94*8b7325afSsthen * which side of the fork the delete is on. */ 95*8b7325afSsthen pid_t pipe_pid; 96*8b7325afSsthen /** when threaded, the worker that exists in the created thread. */ 97*8b7325afSsthen struct libworker* thread_worker; 98933707f3Ssthen 99933707f3Ssthen /** do threading (instead of forking) for async resolution */ 100933707f3Ssthen int dothread; 101933707f3Ssthen /** next thread number for new threads */ 102933707f3Ssthen int thr_next_num; 103bdfc4d55Sflorian /** if logfile is overridden */ 104933707f3Ssthen int logfile_override; 105933707f3Ssthen /** what logfile to use instead */ 106933707f3Ssthen FILE* log_out; 107933707f3Ssthen /** 108933707f3Ssthen * List of alloc-cache-id points per threadnum for notinuse threads. 109933707f3Ssthen * Simply the entire struct alloc_cache with the 'super' member used 110933707f3Ssthen * to link a simply linked list. Reset super member to the superalloc 111933707f3Ssthen * before use. 112933707f3Ssthen */ 113933707f3Ssthen struct alloc_cache* alloc_list; 114933707f3Ssthen 115933707f3Ssthen /** shared caches, and so on */ 116933707f3Ssthen struct alloc_cache superalloc; 117933707f3Ssthen /** module env master value */ 118933707f3Ssthen struct module_env* env; 119933707f3Ssthen /** module stack */ 120933707f3Ssthen struct module_stack mods; 121933707f3Ssthen /** local authority zones */ 122933707f3Ssthen struct local_zones* local_zones; 123933707f3Ssthen /** random state used to seed new random state structures */ 124933707f3Ssthen struct ub_randstate* seed_rnd; 125933707f3Ssthen 1265d76a658Ssthen /** event base for event oriented interface */ 1272ee382b6Ssthen struct ub_event_base* event_base; 128ebf5bb73Ssthen /** true if the event_base is a pluggable base that is malloced 129ebf5bb73Ssthen * with a user event base inside, if so, clean up the pluggable alloc*/ 130ebf5bb73Ssthen int event_base_malloced; 1315d76a658Ssthen /** libworker for event based interface */ 1325d76a658Ssthen struct libworker* event_worker; 1335d76a658Ssthen 134933707f3Ssthen /** next query number (to try) to use */ 135933707f3Ssthen int next_querynum; 136933707f3Ssthen /** number of async queries outstanding */ 137933707f3Ssthen size_t num_async; 138933707f3Ssthen /** 139933707f3Ssthen * Tree of outstanding queries. Indexed by querynum 140933707f3Ssthen * Used when results come in for async to lookup. 141933707f3Ssthen * Used when cancel is done for lookup (and delete). 142933707f3Ssthen * Used to see if querynum is free for use. 143933707f3Ssthen * Content of type ctx_query. 144933707f3Ssthen */ 14577079be7Ssthen rbtree_type queries; 146933707f3Ssthen }; 147933707f3Ssthen 148933707f3Ssthen /** 149933707f3Ssthen * The queries outstanding for the libunbound resolver. 150933707f3Ssthen * These are outstanding for async resolution. 151933707f3Ssthen * But also, outstanding for sync resolution by one of the threads that 152933707f3Ssthen * has joined the threadpool. 153933707f3Ssthen */ 154933707f3Ssthen struct ctx_query { 155933707f3Ssthen /** node in rbtree, must be first entry, key is ptr to the querynum */ 15677079be7Ssthen struct rbnode_type node; 157933707f3Ssthen /** query id number, key for node */ 158933707f3Ssthen int querynum; 159933707f3Ssthen /** was this an async query? */ 160933707f3Ssthen int async; 161933707f3Ssthen /** was this query cancelled (for bg worker) */ 162933707f3Ssthen int cancelled; 163933707f3Ssthen 16420237c55Ssthen /** for async query, the callback function of type ub_callback_type */ 16577079be7Ssthen ub_callback_type cb; 16620237c55Ssthen /** for event callbacks the type is ub_event_callback_type */ 16720237c55Ssthen ub_event_callback_type cb_event; 168933707f3Ssthen /** for async query, the callback user arg */ 169933707f3Ssthen void* cb_arg; 170933707f3Ssthen 171933707f3Ssthen /** answer message, result from resolver lookup. */ 172933707f3Ssthen uint8_t* msg; 173933707f3Ssthen /** resulting message length. */ 174933707f3Ssthen size_t msg_len; 175933707f3Ssthen /** validation status on security */ 176933707f3Ssthen enum sec_status msg_security; 177933707f3Ssthen /** store libworker that is handling this query */ 178933707f3Ssthen struct libworker* w; 179933707f3Ssthen 180933707f3Ssthen /** result structure, also contains original query, type, class. 181933707f3Ssthen * malloced ptr ready to hand to the client. */ 182933707f3Ssthen struct ub_result* res; 183933707f3Ssthen }; 184933707f3Ssthen 185933707f3Ssthen /** 186933707f3Ssthen * Command codes for libunbound pipe. 187933707f3Ssthen * 188933707f3Ssthen * Serialization looks like this: 189933707f3Ssthen * o length (of remainder) uint32. 190933707f3Ssthen * o uint32 command code. 191933707f3Ssthen * o per command format. 192933707f3Ssthen */ 193933707f3Ssthen enum ub_ctx_cmd { 194933707f3Ssthen /** QUIT */ 195933707f3Ssthen UB_LIBCMD_QUIT = 0, 196933707f3Ssthen /** New query, sent to bg worker */ 197933707f3Ssthen UB_LIBCMD_NEWQUERY, 198933707f3Ssthen /** Cancel query, sent to bg worker */ 199933707f3Ssthen UB_LIBCMD_CANCEL, 200933707f3Ssthen /** Query result, originates from bg worker */ 201933707f3Ssthen UB_LIBCMD_ANSWER 202933707f3Ssthen }; 203933707f3Ssthen 204933707f3Ssthen /** 205933707f3Ssthen * finalize a context. 206933707f3Ssthen * @param ctx: context to finalize. creates shared data. 207933707f3Ssthen * @return 0 if OK, or errcode. 208933707f3Ssthen */ 209933707f3Ssthen int context_finalize(struct ub_ctx* ctx); 210933707f3Ssthen 211933707f3Ssthen /** compare two ctx_query elements */ 212933707f3Ssthen int context_query_cmp(const void* a, const void* b); 213933707f3Ssthen 214933707f3Ssthen /** 215933707f3Ssthen * delete context query 216933707f3Ssthen * @param q: query to delete, including message packet and prealloc result 217933707f3Ssthen */ 218933707f3Ssthen void context_query_delete(struct ctx_query* q); 219933707f3Ssthen 220933707f3Ssthen /** 221933707f3Ssthen * Create new query in context, add to querynum list. 222933707f3Ssthen * @param ctx: context 223933707f3Ssthen * @param name: query name 224933707f3Ssthen * @param rrtype: type 225933707f3Ssthen * @param rrclass: class 226933707f3Ssthen * @param cb: callback for async, or NULL for sync. 22720237c55Ssthen * @param cb_event: event callback for async, or NULL for sync. 228933707f3Ssthen * @param cbarg: user arg for async queries. 229933707f3Ssthen * @return new ctx_query or NULL for malloc failure. 230933707f3Ssthen */ 231229e174cSsthen struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype, 23220237c55Ssthen int rrclass, ub_callback_type cb, ub_event_callback_type cb_event, 23320237c55Ssthen void* cbarg); 234933707f3Ssthen 235933707f3Ssthen /** 236933707f3Ssthen * Get a new alloc. Creates a new one or uses a cached one. 237933707f3Ssthen * @param ctx: context 238933707f3Ssthen * @param locking: if true, cfglock is locked while getting alloc. 239933707f3Ssthen * @return an alloc, or NULL on mem error. 240933707f3Ssthen */ 241933707f3Ssthen struct alloc_cache* context_obtain_alloc(struct ub_ctx* ctx, int locking); 242933707f3Ssthen 243933707f3Ssthen /** 244933707f3Ssthen * Release an alloc. Puts it into the cache. 245933707f3Ssthen * @param ctx: context 246933707f3Ssthen * @param locking: if true, cfglock is locked while releasing alloc. 247933707f3Ssthen * @param alloc: alloc to relinquish. 248933707f3Ssthen */ 249933707f3Ssthen void context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc, 250933707f3Ssthen int locking); 251933707f3Ssthen 252933707f3Ssthen /** 253933707f3Ssthen * Serialize a context query that questions data. 254933707f3Ssthen * This serializes the query name, type, ... 255933707f3Ssthen * As well as command code 'new_query'. 256933707f3Ssthen * @param q: context query 257933707f3Ssthen * @param len: the length of the allocation is returned. 258933707f3Ssthen * @return: an alloc, or NULL on mem error. 259933707f3Ssthen */ 260933707f3Ssthen uint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len); 261933707f3Ssthen 262933707f3Ssthen /** 263933707f3Ssthen * Serialize a context_query result to hand back to user. 264933707f3Ssthen * This serializes the query name, type, ..., and result. 265933707f3Ssthen * As well as command code 'answer'. 266933707f3Ssthen * @param q: context query 267933707f3Ssthen * @param err: error code to pass to client. 268933707f3Ssthen * @param pkt: the packet to add, can be NULL. 269933707f3Ssthen * @param len: the length of the allocation is returned. 270933707f3Ssthen * @return: an alloc, or NULL on mem error. 271933707f3Ssthen */ 272933707f3Ssthen uint8_t* context_serialize_answer(struct ctx_query* q, int err, 2735d76a658Ssthen struct sldns_buffer* pkt, uint32_t* len); 274933707f3Ssthen 275933707f3Ssthen /** 276933707f3Ssthen * Serialize a query cancellation. Serializes query async id 277933707f3Ssthen * as well as command code 'cancel' 278933707f3Ssthen * @param q: context query 279933707f3Ssthen * @param len: the length of the allocation is returned. 280933707f3Ssthen * @return: an alloc, or NULL on mem error. 281933707f3Ssthen */ 282933707f3Ssthen uint8_t* context_serialize_cancel(struct ctx_query* q, uint32_t* len); 283933707f3Ssthen 284933707f3Ssthen /** 285933707f3Ssthen * Serialize a 'quit' command. 286933707f3Ssthen * @param len: the length of the allocation is returned. 287933707f3Ssthen * @return: an alloc, or NULL on mem error. 288933707f3Ssthen */ 289933707f3Ssthen uint8_t* context_serialize_quit(uint32_t* len); 290933707f3Ssthen 291933707f3Ssthen /** 292933707f3Ssthen * Obtain command code from serialized buffer 293933707f3Ssthen * @param p: buffer serialized. 294933707f3Ssthen * @param len: length of buffer. 295933707f3Ssthen * @return command code or QUIT on error. 296933707f3Ssthen */ 297933707f3Ssthen enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len); 298933707f3Ssthen 299933707f3Ssthen /** 300933707f3Ssthen * Lookup query from new_query buffer. 301933707f3Ssthen * @param ctx: context 302933707f3Ssthen * @param p: buffer serialized. 303933707f3Ssthen * @param len: length of buffer. 304933707f3Ssthen * @return looked up ctx_query or NULL for malloc failure. 305933707f3Ssthen */ 306933707f3Ssthen struct ctx_query* context_lookup_new_query(struct ub_ctx* ctx, 307933707f3Ssthen uint8_t* p, uint32_t len); 308933707f3Ssthen 309933707f3Ssthen /** 310933707f3Ssthen * Deserialize a new_query buffer. 311933707f3Ssthen * @param ctx: context 312933707f3Ssthen * @param p: buffer serialized. 313933707f3Ssthen * @param len: length of buffer. 314933707f3Ssthen * @return new ctx_query or NULL for malloc failure. 315933707f3Ssthen */ 316933707f3Ssthen struct ctx_query* context_deserialize_new_query(struct ub_ctx* ctx, 317933707f3Ssthen uint8_t* p, uint32_t len); 318933707f3Ssthen 319933707f3Ssthen /** 320933707f3Ssthen * Deserialize an answer buffer. 321933707f3Ssthen * @param ctx: context 322933707f3Ssthen * @param p: buffer serialized. 323933707f3Ssthen * @param len: length of buffer. 324933707f3Ssthen * @param err: error code to be returned to client is passed. 325933707f3Ssthen * @return ctx_query with answer added or NULL for malloc failure. 326933707f3Ssthen */ 327933707f3Ssthen struct ctx_query* context_deserialize_answer(struct ub_ctx* ctx, 328933707f3Ssthen uint8_t* p, uint32_t len, int* err); 329933707f3Ssthen 330933707f3Ssthen /** 331933707f3Ssthen * Deserialize a cancel buffer. 332933707f3Ssthen * @param ctx: context 333933707f3Ssthen * @param p: buffer serialized. 334933707f3Ssthen * @param len: length of buffer. 335933707f3Ssthen * @return ctx_query to cancel or NULL for failure. 336933707f3Ssthen */ 337933707f3Ssthen struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx, 338933707f3Ssthen uint8_t* p, uint32_t len); 339933707f3Ssthen 340933707f3Ssthen #endif /* LIBUNBOUND_CONTEXT_H */ 341