context.h revision 269257
1227825Stheraven/* 2227825Stheraven * libunbound/context.h - validating context for unbound internal use 3227825Stheraven * 4227825Stheraven * Copyright (c) 2007, NLnet Labs. All rights reserved. 5227825Stheraven * 6227825Stheraven * This software is open source. 7227825Stheraven * 8227825Stheraven * Redistribution and use in source and binary forms, with or without 9227825Stheraven * modification, are permitted provided that the following conditions 10227825Stheraven * are met: 11227825Stheraven * 12227825Stheraven * Redistributions of source code must retain the above copyright notice, 13227825Stheraven * this list of conditions and the following disclaimer. 14227825Stheraven * 15227825Stheraven * Redistributions in binary form must reproduce the above copyright notice, 16227825Stheraven * this list of conditions and the following disclaimer in the documentation 17227825Stheraven * and/or other materials provided with the distribution. 18227825Stheraven * 19227825Stheraven * Neither the name of the NLNET LABS nor the names of its contributors may 20227825Stheraven * be used to endorse or promote products derived from this software without 21227825Stheraven * specific prior written permission. 22227825Stheraven * 23227825Stheraven * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24227825Stheraven * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25227825Stheraven * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26227825Stheraven * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27227825Stheraven * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28227825Stheraven * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29227825Stheraven * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30227825Stheraven * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31227825Stheraven * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32227825Stheraven * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33227825Stheraven * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34227825Stheraven */ 35227825Stheraven 36227825Stheraven/** 37227825Stheraven * \file 38227825Stheraven * 39227825Stheraven * This file contains the validator context structure. 40227825Stheraven */ 41227825Stheraven#ifndef LIBUNBOUND_CONTEXT_H 42227825Stheraven#define LIBUNBOUND_CONTEXT_H 43227825Stheraven#include "util/locks.h" 44227825Stheraven#include "util/alloc.h" 45227825Stheraven#include "util/rbtree.h" 46227825Stheraven#include "services/modstack.h" 47227825Stheraven#include "libunbound/unbound.h" 48227825Stheraven#include "util/data/packed_rrset.h" 49227825Stheravenstruct libworker; 50227825Stheravenstruct tube; 51227825Stheravenstruct sldns_buffer; 52227825Stheravenstruct event_base; 53227825Stheraven 54227825Stheraven/** 55227825Stheraven * The context structure 56227825Stheraven * 57227825Stheraven * Contains two pipes for async service 58227825Stheraven * qq : write queries to the async service pid/tid. 59262801Sdim * rr : read results from the async service pid/tid. 60227825Stheraven */ 61227825Stheravenstruct ub_ctx { 62227825Stheraven /* --- pipes --- */ 63227825Stheraven /** mutex on query write pipe */ 64227825Stheraven lock_basic_t qqpipe_lock; 65227825Stheraven /** the query write pipe */ 66227825Stheraven struct tube* qq_pipe; 67227825Stheraven /** mutex on result read pipe */ 68227825Stheraven lock_basic_t rrpipe_lock; 69227825Stheraven /** the result read pipe */ 70227825Stheraven struct tube* rr_pipe; 71262801Sdim 72227825Stheraven /* --- shared data --- */ 73227825Stheraven /** mutex for access to env.cfg, finalized and dothread */ 74227825Stheraven lock_basic_t cfglock; 75227825Stheraven /** 76227825Stheraven * The context has been finalized 77262801Sdim * This is after config when the first resolve is done. 78227825Stheraven * The modules are inited (module-init()) and shared caches created. 79227825Stheraven */ 80227825Stheraven int finalized; 81227825Stheraven 82227825Stheraven /** is bg worker created yet ? */ 83262801Sdim int created_bg; 84227825Stheraven /** pid of bg worker process */ 85227825Stheraven pid_t bg_pid; 86227825Stheraven /** tid of bg worker thread */ 87227825Stheraven ub_thread_t bg_tid; 88227825Stheraven 89262801Sdim /** do threading (instead of forking) for async resolution */ 90227825Stheraven int dothread; 91227825Stheraven /** next thread number for new threads */ 92227825Stheraven int thr_next_num; 93227825Stheraven /** if logfile is overriden */ 94227825Stheraven int logfile_override; 95262801Sdim /** what logfile to use instead */ 96227825Stheraven FILE* log_out; 97227825Stheraven /** 98227825Stheraven * List of alloc-cache-id points per threadnum for notinuse threads. 99227825Stheraven * Simply the entire struct alloc_cache with the 'super' member used 100227825Stheraven * to link a simply linked list. Reset super member to the superalloc 101262801Sdim * before use. 102227825Stheraven */ 103227825Stheraven struct alloc_cache* alloc_list; 104227825Stheraven 105227825Stheraven /** shared caches, and so on */ 106227825Stheraven struct alloc_cache superalloc; 107262801Sdim /** module env master value */ 108227825Stheraven struct module_env* env; 109227825Stheraven /** module stack */ 110227825Stheraven struct module_stack mods; 111227825Stheraven /** local authority zones */ 112227825Stheraven struct local_zones* local_zones; 113262801Sdim /** random state used to seed new random state structures */ 114227825Stheraven struct ub_randstate* seed_rnd; 115227825Stheraven 116227825Stheraven /** event base for event oriented interface */ 117227825Stheraven struct event_base* event_base; 118227825Stheraven /** libworker for event based interface */ 119262801Sdim struct libworker* event_worker; 120227825Stheraven 121227825Stheraven /** next query number (to try) to use */ 122227825Stheraven int next_querynum; 123227825Stheraven /** number of async queries outstanding */ 124227825Stheraven size_t num_async; 125262801Sdim /** 126227825Stheraven * Tree of outstanding queries. Indexed by querynum 127227825Stheraven * Used when results come in for async to lookup. 128227825Stheraven * Used when cancel is done for lookup (and delete). 129227825Stheraven * Used to see if querynum is free for use. 130227825Stheraven * Content of type ctx_query. 131262801Sdim */ 132227825Stheraven rbtree_t queries; 133227825Stheraven}; 134227825Stheraven 135227825Stheraven/** 136227825Stheraven * The queries outstanding for the libunbound resolver. 137262801Sdim * These are outstanding for async resolution. 138227825Stheraven * But also, outstanding for sync resolution by one of the threads that 139227825Stheraven * has joined the threadpool. 140227825Stheraven */ 141227825Stheravenstruct ctx_query { 142227825Stheraven /** node in rbtree, must be first entry, key is ptr to the querynum */ 143262801Sdim struct rbnode_t node; 144227825Stheraven /** query id number, key for node */ 145227825Stheraven int querynum; 146227825Stheraven /** was this an async query? */ 147227825Stheraven int async; 148227825Stheraven /** was this query cancelled (for bg worker) */ 149262801Sdim int cancelled; 150227825Stheraven 151227825Stheraven /** for async query, the callback function */ 152227825Stheraven ub_callback_t cb; 153227825Stheraven /** for async query, the callback user arg */ 154227825Stheraven void* cb_arg; 155262801Sdim 156227825Stheraven /** answer message, result from resolver lookup. */ 157227825Stheraven uint8_t* msg; 158227825Stheraven /** resulting message length. */ 159227825Stheraven size_t msg_len; 160227825Stheraven /** validation status on security */ 161262801Sdim enum sec_status msg_security; 162262801Sdim /** store libworker that is handling this query */ 163262801Sdim struct libworker* w; 164262801Sdim 165262801Sdim /** result structure, also contains original query, type, class. 166262801Sdim * malloced ptr ready to hand to the client. */ 167262801Sdim struct ub_result* res; 168262801Sdim}; 169262801Sdim 170262801Sdim/** 171262801Sdim * The error constants 172262801Sdim */ 173262801Sdimenum ub_ctx_err { 174262801Sdim /** no error */ 175262801Sdim UB_NOERROR = 0, 176262801Sdim /** socket operation. Set to -1, so that if an error from _fd() is 177262801Sdim * passed (-1) it gives a socket error. */ 178262801Sdim UB_SOCKET = -1, 179262801Sdim /** alloc failure */ 180262801Sdim UB_NOMEM = -2, 181262801Sdim /** syntax error */ 182262801Sdim UB_SYNTAX = -3, 183262801Sdim /** DNS service failed */ 184262801Sdim UB_SERVFAIL = -4, 185227825Stheraven /** fork() failed */ 186227825Stheraven UB_FORKFAIL = -5, 187227825Stheraven /** cfg change after finalize() */ 188227825Stheraven UB_AFTERFINAL = -6, 189227825Stheraven /** initialization failed (bad settings) */ 190227825Stheraven UB_INITFAIL = -7, 191227825Stheraven /** error in pipe communication with async bg worker */ 192227825Stheraven UB_PIPE = -8, 193227825Stheraven /** error reading from file (resolv.conf) */ 194227825Stheraven UB_READFILE = -9, 195227825Stheraven /** error async_id does not exist or result already been delivered */ 196227825Stheraven UB_NOID = -10 197227825Stheraven}; 198227825Stheraven 199227825Stheraven/** 200227825Stheraven * Command codes for libunbound pipe. 201227825Stheraven * 202227825Stheraven * Serialization looks like this: 203227825Stheraven * o length (of remainder) uint32. 204227825Stheraven * o uint32 command code. 205227825Stheraven * o per command format. 206227825Stheraven */ 207227825Stheravenenum ub_ctx_cmd { 208227825Stheraven /** QUIT */ 209227825Stheraven UB_LIBCMD_QUIT = 0, 210227825Stheraven /** New query, sent to bg worker */ 211227825Stheraven UB_LIBCMD_NEWQUERY, 212227825Stheraven /** Cancel query, sent to bg worker */ 213227825Stheraven UB_LIBCMD_CANCEL, 214227825Stheraven /** Query result, originates from bg worker */ 215227825Stheraven UB_LIBCMD_ANSWER 216227825Stheraven}; 217227825Stheraven 218227825Stheraven/** 219227825Stheraven * finalize a context. 220227825Stheraven * @param ctx: context to finalize. creates shared data. 221227825Stheraven * @return 0 if OK, or errcode. 222227825Stheraven */ 223227825Stheravenint context_finalize(struct ub_ctx* ctx); 224227825Stheraven 225232950Stheraven/** compare two ctx_query elements */ 226227825Stheravenint context_query_cmp(const void* a, const void* b); 227227825Stheraven 228227825Stheraven/** 229227825Stheraven * delete context query 230227825Stheraven * @param q: query to delete, including message packet and prealloc result 231227825Stheraven */ 232227825Stheravenvoid context_query_delete(struct ctx_query* q); 233227825Stheraven 234227825Stheraven/** 235227825Stheraven * Create new query in context, add to querynum list. 236227825Stheraven * @param ctx: context 237227825Stheraven * @param name: query name 238227825Stheraven * @param rrtype: type 239227825Stheraven * @param rrclass: class 240227825Stheraven * @param cb: callback for async, or NULL for sync. 241227825Stheraven * @param cbarg: user arg for async queries. 242227825Stheraven * @return new ctx_query or NULL for malloc failure. 243227825Stheraven */ 244227825Stheravenstruct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype, 245227825Stheraven int rrclass, ub_callback_t cb, void* cbarg); 246227825Stheraven 247227825Stheraven/** 248227825Stheraven * Get a new alloc. Creates a new one or uses a cached one. 249227825Stheraven * @param ctx: context 250227825Stheraven * @param locking: if true, cfglock is locked while getting alloc. 251227825Stheraven * @return an alloc, or NULL on mem error. 252227825Stheraven */ 253227825Stheravenstruct alloc_cache* context_obtain_alloc(struct ub_ctx* ctx, int locking); 254227825Stheraven 255227825Stheraven/** 256227825Stheraven * Release an alloc. Puts it into the cache. 257227825Stheraven * @param ctx: context 258227825Stheraven * @param locking: if true, cfglock is locked while releasing alloc. 259227825Stheraven * @param alloc: alloc to relinquish. 260227825Stheraven */ 261227825Stheravenvoid context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc, 262227825Stheraven int locking); 263227825Stheraven 264227825Stheraven/** 265227825Stheraven * Serialize a context query that questions data. 266227825Stheraven * This serializes the query name, type, ... 267227825Stheraven * As well as command code 'new_query'. 268227825Stheraven * @param q: context query 269227825Stheraven * @param len: the length of the allocation is returned. 270227825Stheraven * @return: an alloc, or NULL on mem error. 271227825Stheraven */ 272227825Stheravenuint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len); 273227825Stheraven 274227825Stheraven/** 275227825Stheraven * Serialize a context_query result to hand back to user. 276227825Stheraven * This serializes the query name, type, ..., and result. 277227825Stheraven * As well as command code 'answer'. 278227825Stheraven * @param q: context query 279227825Stheraven * @param err: error code to pass to client. 280227825Stheraven * @param pkt: the packet to add, can be NULL. 281227825Stheraven * @param len: the length of the allocation is returned. 282227825Stheraven * @return: an alloc, or NULL on mem error. 283227825Stheraven */ 284227825Stheravenuint8_t* context_serialize_answer(struct ctx_query* q, int err, 285227825Stheraven struct sldns_buffer* pkt, uint32_t* len); 286227825Stheraven 287227825Stheraven/** 288227825Stheraven * Serialize a query cancellation. Serializes query async id 289227825Stheraven * as well as command code 'cancel' 290227825Stheraven * @param q: context query 291227825Stheraven * @param len: the length of the allocation is returned. 292227825Stheraven * @return: an alloc, or NULL on mem error. 293227825Stheraven */ 294227825Stheravenuint8_t* context_serialize_cancel(struct ctx_query* q, uint32_t* len); 295227825Stheraven 296227825Stheraven/** 297227825Stheraven * Serialize a 'quit' command. 298227825Stheraven * @param len: the length of the allocation is returned. 299227825Stheraven * @return: an alloc, or NULL on mem error. 300227825Stheraven */ 301227825Stheravenuint8_t* context_serialize_quit(uint32_t* len); 302227825Stheraven 303227825Stheraven/** 304227825Stheraven * Obtain command code from serialized buffer 305227825Stheraven * @param p: buffer serialized. 306227825Stheraven * @param len: length of buffer. 307227825Stheraven * @return command code or QUIT on error. 308227825Stheraven */ 309227825Stheravenenum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len); 310227825Stheraven 311227825Stheraven/** 312227825Stheraven * Lookup query from new_query buffer. 313227825Stheraven * @param ctx: context 314227825Stheraven * @param p: buffer serialized. 315227825Stheraven * @param len: length of buffer. 316227825Stheraven * @return looked up ctx_query or NULL for malloc failure. 317227825Stheraven */ 318227825Stheravenstruct ctx_query* context_lookup_new_query(struct ub_ctx* ctx, 319227825Stheraven uint8_t* p, uint32_t len); 320227825Stheraven 321227825Stheraven/** 322227825Stheraven * Deserialize a new_query buffer. 323227825Stheraven * @param ctx: context 324227825Stheraven * @param p: buffer serialized. 325227825Stheraven * @param len: length of buffer. 326227825Stheraven * @return new ctx_query or NULL for malloc failure. 327227825Stheraven */ 328227825Stheravenstruct ctx_query* context_deserialize_new_query(struct ub_ctx* ctx, 329227825Stheraven uint8_t* p, uint32_t len); 330227825Stheraven 331227825Stheraven/** 332227825Stheraven * Deserialize an answer buffer. 333227825Stheraven * @param ctx: context 334227825Stheraven * @param p: buffer serialized. 335227825Stheraven * @param len: length of buffer. 336227825Stheraven * @param err: error code to be returned to client is passed. 337227825Stheraven * @return ctx_query with answer added or NULL for malloc failure. 338227825Stheraven */ 339227825Stheravenstruct ctx_query* context_deserialize_answer(struct ub_ctx* ctx, 340227825Stheraven uint8_t* p, uint32_t len, int* err); 341227825Stheraven 342227825Stheraven/** 343227825Stheraven * Deserialize a cancel buffer. 344227825Stheraven * @param ctx: context 345227825Stheraven * @param p: buffer serialized. 346227825Stheraven * @param len: length of buffer. 347227825Stheraven * @return ctx_query to cancel or NULL for failure. 348227825Stheraven */ 349227825Stheravenstruct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx, 350227825Stheraven uint8_t* p, uint32_t len); 351227825Stheraven 352227825Stheraven#endif /* LIBUNBOUND_CONTEXT_H */ 353227825Stheraven