1ae8c6e27Sflorian /* 2ae8c6e27Sflorian * libunbound/context.h - validating context for unbound internal use 3ae8c6e27Sflorian * 4ae8c6e27Sflorian * Copyright (c) 2007, NLnet Labs. All rights reserved. 5ae8c6e27Sflorian * 6ae8c6e27Sflorian * This software is open source. 7ae8c6e27Sflorian * 8ae8c6e27Sflorian * Redistribution and use in source and binary forms, with or without 9ae8c6e27Sflorian * modification, are permitted provided that the following conditions 10ae8c6e27Sflorian * are met: 11ae8c6e27Sflorian * 12ae8c6e27Sflorian * Redistributions of source code must retain the above copyright notice, 13ae8c6e27Sflorian * this list of conditions and the following disclaimer. 14ae8c6e27Sflorian * 15ae8c6e27Sflorian * Redistributions in binary form must reproduce the above copyright notice, 16ae8c6e27Sflorian * this list of conditions and the following disclaimer in the documentation 17ae8c6e27Sflorian * and/or other materials provided with the distribution. 18ae8c6e27Sflorian * 19ae8c6e27Sflorian * Neither the name of the NLNET LABS nor the names of its contributors may 20ae8c6e27Sflorian * be used to endorse or promote products derived from this software without 21ae8c6e27Sflorian * specific prior written permission. 22ae8c6e27Sflorian * 23ae8c6e27Sflorian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24ae8c6e27Sflorian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25ae8c6e27Sflorian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26ae8c6e27Sflorian * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27ae8c6e27Sflorian * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28ae8c6e27Sflorian * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29ae8c6e27Sflorian * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30ae8c6e27Sflorian * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31ae8c6e27Sflorian * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32ae8c6e27Sflorian * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33ae8c6e27Sflorian * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34ae8c6e27Sflorian */ 35ae8c6e27Sflorian 36ae8c6e27Sflorian /** 37ae8c6e27Sflorian * \file 38ae8c6e27Sflorian * 39ae8c6e27Sflorian * This file contains the validator context structure. 40ae8c6e27Sflorian */ 41ae8c6e27Sflorian #ifndef LIBUNBOUND_CONTEXT_H 42ae8c6e27Sflorian #define LIBUNBOUND_CONTEXT_H 43ae8c6e27Sflorian #include "util/locks.h" 44ae8c6e27Sflorian #include "util/alloc.h" 45ae8c6e27Sflorian #include "util/rbtree.h" 46ae8c6e27Sflorian #include "services/modstack.h" 47ae8c6e27Sflorian #include "libunbound/unbound.h" 48ae8c6e27Sflorian #include "libunbound/unbound-event.h" 49ae8c6e27Sflorian #include "util/data/packed_rrset.h" 50ae8c6e27Sflorian struct libworker; 51ae8c6e27Sflorian struct tube; 52ae8c6e27Sflorian struct sldns_buffer; 53ae8c6e27Sflorian struct ub_event_base; 54ae8c6e27Sflorian 55da8c8390Sflorian /** store that the logfile has a debug override */ 56da8c8390Sflorian extern int ctx_logfile_overridden; 57da8c8390Sflorian 58ae8c6e27Sflorian /** 59ae8c6e27Sflorian * The context structure 60ae8c6e27Sflorian * 61ae8c6e27Sflorian * Contains two pipes for async service 62ae8c6e27Sflorian * qq : write queries to the async service pid/tid. 63ae8c6e27Sflorian * rr : read results from the async service pid/tid. 64ae8c6e27Sflorian */ 65ae8c6e27Sflorian struct ub_ctx { 66ae8c6e27Sflorian /* --- pipes --- */ 67ae8c6e27Sflorian /** mutex on query write pipe */ 68ae8c6e27Sflorian lock_basic_type qqpipe_lock; 69ae8c6e27Sflorian /** the query write pipe */ 70ae8c6e27Sflorian struct tube* qq_pipe; 71ae8c6e27Sflorian /** mutex on result read pipe */ 72ae8c6e27Sflorian lock_basic_type rrpipe_lock; 73ae8c6e27Sflorian /** the result read pipe */ 74ae8c6e27Sflorian struct tube* rr_pipe; 75ae8c6e27Sflorian 76ae8c6e27Sflorian /* --- shared data --- */ 77ae8c6e27Sflorian /** mutex for access to env.cfg, finalized and dothread */ 78ae8c6e27Sflorian lock_basic_type cfglock; 79ae8c6e27Sflorian /** 80ae8c6e27Sflorian * The context has been finalized 81ae8c6e27Sflorian * This is after config when the first resolve is done. 82ae8c6e27Sflorian * The modules are inited (module-init()) and shared caches created. 83ae8c6e27Sflorian */ 84ae8c6e27Sflorian int finalized; 85ae8c6e27Sflorian 86ae8c6e27Sflorian /** is bg worker created yet ? */ 87ae8c6e27Sflorian int created_bg; 88ae8c6e27Sflorian /** pid of bg worker process */ 89ae8c6e27Sflorian pid_t bg_pid; 90ae8c6e27Sflorian /** tid of bg worker thread */ 91ae8c6e27Sflorian ub_thread_type bg_tid; 92*d500c338Sflorian /** pid when pipes are created. This was the process when the 93*d500c338Sflorian * setup was called. Helps with clean up, so we can tell after a fork 94*d500c338Sflorian * which side of the fork the delete is on. */ 95*d500c338Sflorian pid_t pipe_pid; 96*d500c338Sflorian /** when threaded, the worker that exists in the created thread. */ 97*d500c338Sflorian struct libworker* thread_worker; 98ae8c6e27Sflorian 99ae8c6e27Sflorian /** do threading (instead of forking) for async resolution */ 100ae8c6e27Sflorian int dothread; 101ae8c6e27Sflorian /** next thread number for new threads */ 102ae8c6e27Sflorian int thr_next_num; 103ae8c6e27Sflorian /** if logfile is overridden */ 104ae8c6e27Sflorian int logfile_override; 105ae8c6e27Sflorian /** what logfile to use instead */ 106ae8c6e27Sflorian FILE* log_out; 107ae8c6e27Sflorian /** 108ae8c6e27Sflorian * List of alloc-cache-id points per threadnum for notinuse threads. 109ae8c6e27Sflorian * Simply the entire struct alloc_cache with the 'super' member used 110ae8c6e27Sflorian * to link a simply linked list. Reset super member to the superalloc 111ae8c6e27Sflorian * before use. 112ae8c6e27Sflorian */ 113ae8c6e27Sflorian struct alloc_cache* alloc_list; 114ae8c6e27Sflorian 115ae8c6e27Sflorian /** shared caches, and so on */ 116ae8c6e27Sflorian struct alloc_cache superalloc; 117ae8c6e27Sflorian /** module env master value */ 118ae8c6e27Sflorian struct module_env* env; 119ae8c6e27Sflorian /** module stack */ 120ae8c6e27Sflorian struct module_stack mods; 121ae8c6e27Sflorian /** local authority zones */ 122ae8c6e27Sflorian struct local_zones* local_zones; 123ae8c6e27Sflorian /** random state used to seed new random state structures */ 124ae8c6e27Sflorian struct ub_randstate* seed_rnd; 125ae8c6e27Sflorian 126ae8c6e27Sflorian /** event base for event oriented interface */ 127ae8c6e27Sflorian struct ub_event_base* event_base; 12857403691Sflorian /** true if the event_base is a pluggable base that is malloced 12957403691Sflorian * with a user event base inside, if so, clean up the pluggable alloc*/ 13057403691Sflorian int event_base_malloced; 131ae8c6e27Sflorian /** libworker for event based interface */ 132ae8c6e27Sflorian struct libworker* event_worker; 133ae8c6e27Sflorian 134ae8c6e27Sflorian /** next query number (to try) to use */ 135ae8c6e27Sflorian int next_querynum; 136ae8c6e27Sflorian /** number of async queries outstanding */ 137ae8c6e27Sflorian size_t num_async; 138ae8c6e27Sflorian /** 139ae8c6e27Sflorian * Tree of outstanding queries. Indexed by querynum 140ae8c6e27Sflorian * Used when results come in for async to lookup. 141ae8c6e27Sflorian * Used when cancel is done for lookup (and delete). 142ae8c6e27Sflorian * Used to see if querynum is free for use. 143ae8c6e27Sflorian * Content of type ctx_query. 144ae8c6e27Sflorian */ 145ae8c6e27Sflorian rbtree_type queries; 146ae8c6e27Sflorian }; 147ae8c6e27Sflorian 148ae8c6e27Sflorian /** 149ae8c6e27Sflorian * The queries outstanding for the libunbound resolver. 150ae8c6e27Sflorian * These are outstanding for async resolution. 151ae8c6e27Sflorian * But also, outstanding for sync resolution by one of the threads that 152ae8c6e27Sflorian * has joined the threadpool. 153ae8c6e27Sflorian */ 154ae8c6e27Sflorian struct ctx_query { 155ae8c6e27Sflorian /** node in rbtree, must be first entry, key is ptr to the querynum */ 156ae8c6e27Sflorian struct rbnode_type node; 157ae8c6e27Sflorian /** query id number, key for node */ 158ae8c6e27Sflorian int querynum; 159ae8c6e27Sflorian /** was this an async query? */ 160ae8c6e27Sflorian int async; 161ae8c6e27Sflorian /** was this query cancelled (for bg worker) */ 162ae8c6e27Sflorian int cancelled; 163ae8c6e27Sflorian 164ae8c6e27Sflorian /** for async query, the callback function of type ub_callback_type */ 165ae8c6e27Sflorian ub_callback_type cb; 166ae8c6e27Sflorian /** for event callbacks the type is ub_event_callback_type */ 167ae8c6e27Sflorian ub_event_callback_type cb_event; 168ae8c6e27Sflorian /** for async query, the callback user arg */ 169ae8c6e27Sflorian void* cb_arg; 170ae8c6e27Sflorian 171ae8c6e27Sflorian /** answer message, result from resolver lookup. */ 172ae8c6e27Sflorian uint8_t* msg; 173ae8c6e27Sflorian /** resulting message length. */ 174ae8c6e27Sflorian size_t msg_len; 175ae8c6e27Sflorian /** validation status on security */ 176ae8c6e27Sflorian enum sec_status msg_security; 177ae8c6e27Sflorian /** store libworker that is handling this query */ 178ae8c6e27Sflorian struct libworker* w; 179ae8c6e27Sflorian 180ae8c6e27Sflorian /** result structure, also contains original query, type, class. 181ae8c6e27Sflorian * malloced ptr ready to hand to the client. */ 182ae8c6e27Sflorian struct ub_result* res; 183ae8c6e27Sflorian }; 184ae8c6e27Sflorian 185ae8c6e27Sflorian /** 186ae8c6e27Sflorian * Command codes for libunbound pipe. 187ae8c6e27Sflorian * 188ae8c6e27Sflorian * Serialization looks like this: 189ae8c6e27Sflorian * o length (of remainder) uint32. 190ae8c6e27Sflorian * o uint32 command code. 191ae8c6e27Sflorian * o per command format. 192ae8c6e27Sflorian */ 193ae8c6e27Sflorian enum ub_ctx_cmd { 194ae8c6e27Sflorian /** QUIT */ 195ae8c6e27Sflorian UB_LIBCMD_QUIT = 0, 196ae8c6e27Sflorian /** New query, sent to bg worker */ 197ae8c6e27Sflorian UB_LIBCMD_NEWQUERY, 198ae8c6e27Sflorian /** Cancel query, sent to bg worker */ 199ae8c6e27Sflorian UB_LIBCMD_CANCEL, 200ae8c6e27Sflorian /** Query result, originates from bg worker */ 201ae8c6e27Sflorian UB_LIBCMD_ANSWER 202ae8c6e27Sflorian }; 203ae8c6e27Sflorian 204ae8c6e27Sflorian /** 205ae8c6e27Sflorian * finalize a context. 206ae8c6e27Sflorian * @param ctx: context to finalize. creates shared data. 207ae8c6e27Sflorian * @return 0 if OK, or errcode. 208ae8c6e27Sflorian */ 209ae8c6e27Sflorian int context_finalize(struct ub_ctx* ctx); 210ae8c6e27Sflorian 211ae8c6e27Sflorian /** compare two ctx_query elements */ 212ae8c6e27Sflorian int context_query_cmp(const void* a, const void* b); 213ae8c6e27Sflorian 214ae8c6e27Sflorian /** 215ae8c6e27Sflorian * delete context query 216ae8c6e27Sflorian * @param q: query to delete, including message packet and prealloc result 217ae8c6e27Sflorian */ 218ae8c6e27Sflorian void context_query_delete(struct ctx_query* q); 219ae8c6e27Sflorian 220ae8c6e27Sflorian /** 221ae8c6e27Sflorian * Create new query in context, add to querynum list. 222ae8c6e27Sflorian * @param ctx: context 223ae8c6e27Sflorian * @param name: query name 224ae8c6e27Sflorian * @param rrtype: type 225ae8c6e27Sflorian * @param rrclass: class 226ae8c6e27Sflorian * @param cb: callback for async, or NULL for sync. 227ae8c6e27Sflorian * @param cb_event: event callback for async, or NULL for sync. 228ae8c6e27Sflorian * @param cbarg: user arg for async queries. 229ae8c6e27Sflorian * @return new ctx_query or NULL for malloc failure. 230ae8c6e27Sflorian */ 231ae8c6e27Sflorian struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype, 232ae8c6e27Sflorian int rrclass, ub_callback_type cb, ub_event_callback_type cb_event, 233ae8c6e27Sflorian void* cbarg); 234ae8c6e27Sflorian 235ae8c6e27Sflorian /** 236ae8c6e27Sflorian * Get a new alloc. Creates a new one or uses a cached one. 237ae8c6e27Sflorian * @param ctx: context 238ae8c6e27Sflorian * @param locking: if true, cfglock is locked while getting alloc. 239ae8c6e27Sflorian * @return an alloc, or NULL on mem error. 240ae8c6e27Sflorian */ 241ae8c6e27Sflorian struct alloc_cache* context_obtain_alloc(struct ub_ctx* ctx, int locking); 242ae8c6e27Sflorian 243ae8c6e27Sflorian /** 244ae8c6e27Sflorian * Release an alloc. Puts it into the cache. 245ae8c6e27Sflorian * @param ctx: context 246ae8c6e27Sflorian * @param locking: if true, cfglock is locked while releasing alloc. 247ae8c6e27Sflorian * @param alloc: alloc to relinquish. 248ae8c6e27Sflorian */ 249ae8c6e27Sflorian void context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc, 250ae8c6e27Sflorian int locking); 251ae8c6e27Sflorian 252ae8c6e27Sflorian /** 253ae8c6e27Sflorian * Serialize a context query that questions data. 254ae8c6e27Sflorian * This serializes the query name, type, ... 255ae8c6e27Sflorian * As well as command code 'new_query'. 256ae8c6e27Sflorian * @param q: context query 257ae8c6e27Sflorian * @param len: the length of the allocation is returned. 258ae8c6e27Sflorian * @return: an alloc, or NULL on mem error. 259ae8c6e27Sflorian */ 260ae8c6e27Sflorian uint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len); 261ae8c6e27Sflorian 262ae8c6e27Sflorian /** 263ae8c6e27Sflorian * Serialize a context_query result to hand back to user. 264ae8c6e27Sflorian * This serializes the query name, type, ..., and result. 265ae8c6e27Sflorian * As well as command code 'answer'. 266ae8c6e27Sflorian * @param q: context query 267ae8c6e27Sflorian * @param err: error code to pass to client. 268ae8c6e27Sflorian * @param pkt: the packet to add, can be NULL. 269ae8c6e27Sflorian * @param len: the length of the allocation is returned. 270ae8c6e27Sflorian * @return: an alloc, or NULL on mem error. 271ae8c6e27Sflorian */ 272ae8c6e27Sflorian uint8_t* context_serialize_answer(struct ctx_query* q, int err, 273ae8c6e27Sflorian struct sldns_buffer* pkt, uint32_t* len); 274ae8c6e27Sflorian 275ae8c6e27Sflorian /** 276ae8c6e27Sflorian * Serialize a query cancellation. Serializes query async id 277ae8c6e27Sflorian * as well as command code 'cancel' 278ae8c6e27Sflorian * @param q: context query 279ae8c6e27Sflorian * @param len: the length of the allocation is returned. 280ae8c6e27Sflorian * @return: an alloc, or NULL on mem error. 281ae8c6e27Sflorian */ 282ae8c6e27Sflorian uint8_t* context_serialize_cancel(struct ctx_query* q, uint32_t* len); 283ae8c6e27Sflorian 284ae8c6e27Sflorian /** 285ae8c6e27Sflorian * Serialize a 'quit' command. 286ae8c6e27Sflorian * @param len: the length of the allocation is returned. 287ae8c6e27Sflorian * @return: an alloc, or NULL on mem error. 288ae8c6e27Sflorian */ 289ae8c6e27Sflorian uint8_t* context_serialize_quit(uint32_t* len); 290ae8c6e27Sflorian 291ae8c6e27Sflorian /** 292ae8c6e27Sflorian * Obtain command code from serialized buffer 293ae8c6e27Sflorian * @param p: buffer serialized. 294ae8c6e27Sflorian * @param len: length of buffer. 295ae8c6e27Sflorian * @return command code or QUIT on error. 296ae8c6e27Sflorian */ 297ae8c6e27Sflorian enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len); 298ae8c6e27Sflorian 299ae8c6e27Sflorian /** 300ae8c6e27Sflorian * Lookup query from new_query buffer. 301ae8c6e27Sflorian * @param ctx: context 302ae8c6e27Sflorian * @param p: buffer serialized. 303ae8c6e27Sflorian * @param len: length of buffer. 304ae8c6e27Sflorian * @return looked up ctx_query or NULL for malloc failure. 305ae8c6e27Sflorian */ 306ae8c6e27Sflorian struct ctx_query* context_lookup_new_query(struct ub_ctx* ctx, 307ae8c6e27Sflorian uint8_t* p, uint32_t len); 308ae8c6e27Sflorian 309ae8c6e27Sflorian /** 310ae8c6e27Sflorian * Deserialize a new_query buffer. 311ae8c6e27Sflorian * @param ctx: context 312ae8c6e27Sflorian * @param p: buffer serialized. 313ae8c6e27Sflorian * @param len: length of buffer. 314ae8c6e27Sflorian * @return new ctx_query or NULL for malloc failure. 315ae8c6e27Sflorian */ 316ae8c6e27Sflorian struct ctx_query* context_deserialize_new_query(struct ub_ctx* ctx, 317ae8c6e27Sflorian uint8_t* p, uint32_t len); 318ae8c6e27Sflorian 319ae8c6e27Sflorian /** 320ae8c6e27Sflorian * Deserialize an answer buffer. 321ae8c6e27Sflorian * @param ctx: context 322ae8c6e27Sflorian * @param p: buffer serialized. 323ae8c6e27Sflorian * @param len: length of buffer. 324ae8c6e27Sflorian * @param err: error code to be returned to client is passed. 325ae8c6e27Sflorian * @return ctx_query with answer added or NULL for malloc failure. 326ae8c6e27Sflorian */ 327ae8c6e27Sflorian struct ctx_query* context_deserialize_answer(struct ub_ctx* ctx, 328ae8c6e27Sflorian uint8_t* p, uint32_t len, int* err); 329ae8c6e27Sflorian 330ae8c6e27Sflorian /** 331ae8c6e27Sflorian * Deserialize a cancel buffer. 332ae8c6e27Sflorian * @param ctx: context 333ae8c6e27Sflorian * @param p: buffer serialized. 334ae8c6e27Sflorian * @param len: length of buffer. 335ae8c6e27Sflorian * @return ctx_query to cancel or NULL for failure. 336ae8c6e27Sflorian */ 337ae8c6e27Sflorian struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx, 338ae8c6e27Sflorian uint8_t* p, uint32_t len); 339ae8c6e27Sflorian 340ae8c6e27Sflorian #endif /* LIBUNBOUND_CONTEXT_H */ 341