Logo Search packages:      
Sourcecode: unbound version File versions  Download package

context.h

Go to the documentation of this file.
/*
 * libunbound/context.h - validating context for unbound internal use
 *
 * Copyright (c) 2007, NLnet Labs. All rights reserved.
 *
 * This software is open source.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * 
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * 
 * Neither the name of the NLNET LABS nor the names of its contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * \file
 *
 * This file contains the validator context structure.
 */
#ifndef LIBUNBOUND_CONTEXT_H
#define LIBUNBOUND_CONTEXT_H
#include "util/locks.h"
#include "util/alloc.h"
#include "util/rbtree.h"
#include "services/modstack.h"
#include "libunbound/unbound.h"
#include "util/data/packed_rrset.h"
struct libworker;

/**
 * The context structure
 *
 * Contains two pipes for async service
 *    qq : write queries to the async service pid/tid.
 *    rr : read results from the async service pid/tid.
 */
00058 struct ub_ctx {
      /* --- pipes --- */
      /** mutex on query write pipe */
00061       lock_basic_t qqpipe_lock;
      /** the query write pipe, [0] read from, [1] write on */
00063       int qqpipe[2];
      /** mutex on result read pipe */
00065       lock_basic_t rrpipe_lock;
      /** the result read pipe, [0] read from, [1] write on */
00067       int rrpipe[2];

      /* --- shared data --- */
      /** mutex for access to env.cfg, finalized and dothread */
00071       lock_basic_t cfglock;
      /** 
       * The context has been finalized 
       * This is after config when the first resolve is done.
       * The modules are inited (module-init()) and shared caches created.
       */
00077       int finalized;

      /** is bg worker created yet ? */
00080       int created_bg;
      /** pid of bg worker process */
00082       pid_t bg_pid;
      /** tid of bg worker thread */
00084       ub_thread_t bg_tid;

      /** do threading (instead of forking) for async resolution */
00087       int dothread;
      /** next thread number for new threads */
00089       int thr_next_num;
      /** if logfile is overriden */
00091       int logfile_override;
      /** what logfile to use instead */
00093       FILE* log_out;
      /** 
       * List of alloc-cache-id points per threadnum for notinuse threads.
       * Simply the entire struct alloc_cache with the 'super' member used
       * to link a simply linked list. Reset super member to the superalloc
       * before use.
       */
00100       struct alloc_cache* alloc_list;

      /** shared caches, and so on */
00103       struct alloc_cache superalloc;
      /** module env master value */
00105       struct module_env* env;
      /** module stack */
00107       struct module_stack mods;
      /** local authority zones */
00109       struct local_zones* local_zones;
      /** random state used to seed new random state structures */
00111       struct ub_randstate* seed_rnd;

      /** next query number (to try) to use */
00114       int next_querynum;
      /** number of async queries outstanding */
00116       size_t num_async;
      /** 
       * Tree of outstanding queries. Indexed by querynum 
       * Used when results come in for async to lookup.
       * Used when cancel is done for lookup (and delete).
       * Used to see if querynum is free for use.
       * Content of type ctx_query.
       */ 
00124       rbtree_t queries;
};

/**
 * The queries outstanding for the libunbound resolver.
 * These are outstanding for async resolution.
 * But also, outstanding for sync resolution by one of the threads that
 * has joined the threadpool.
 */
00133 struct ctx_query {
      /** node in rbtree, must be first entry, key is ptr to the querynum */
00135       struct rbnode_t node;
      /** query id number, key for node */
00137       int querynum;
      /** was this an async query? */
00139       int async;
      /** was this query cancelled (for bg worker) */
00141       int cancelled;

      /** for async query, the callback function */
00144       ub_callback_t cb;
      /** for async query, the callback user arg */
00146       void* cb_arg;

      /** answer message, result from resolver lookup. */
00149       uint8_t* msg;
      /** resulting message length. */
00151       size_t msg_len;
      /** validation status on security */
00153       enum sec_status msg_security;
      /** store libworker that is handling this query */
00155       struct libworker* w;

      /** result structure, also contains original query, type, class.
       * malloced ptr ready to hand to the client. */
00159       struct ub_result* res;
};

/**
 * The error constants
 */
00165 enum ub_ctx_err {
      /** no error */
00167       UB_NOERROR = 0,
      /** socket operation. Set to -1, so that if an error from _fd() is
       * passed (-1) it gives a socket error. */
00170       UB_SOCKET = -1,
      /** alloc failure */
00172       UB_NOMEM = -2,
      /** syntax error */
00174       UB_SYNTAX = -3,
      /** DNS service failed */
00176       UB_SERVFAIL = -4,
      /** fork() failed */
00178       UB_FORKFAIL = -5,
      /** cfg change after finalize() */
00180       UB_AFTERFINAL = -6,
      /** initialization failed (bad settings) */
00182       UB_INITFAIL = -7,
      /** error in pipe communication with async bg worker */
00184       UB_PIPE = -8,
      /** error reading from file (resolv.conf) */
00186       UB_READFILE = -9
};

/**
 * Command codes for libunbound pipe.
 *
 * Serialization looks like this:
 *    o length (of remainder) uint32.
 *    o uint32 command code.
 *    o per command format.
 */
00197 enum ub_ctx_cmd {
      /** QUIT */
00199       UB_LIBCMD_QUIT = 0,
      /** New query, sent to bg worker */
00201       UB_LIBCMD_NEWQUERY,
      /** Cancel query, sent to bg worker */
00203       UB_LIBCMD_CANCEL,
      /** Query result, originates from bg worker */
00205       UB_LIBCMD_ANSWER
};

/** 
 * finalize a context.
 * @param ctx: context to finalize. creates shared data.
 * @return 0 if OK, or errcode.
 */
int context_finalize(struct ub_ctx* ctx);

/** compare two ctx_query elements */
int context_query_cmp(const void* a, const void* b);

/** 
 * delete context query
 * @param q: query to delete, including message packet and prealloc result
 */
void context_query_delete(struct ctx_query* q);

/**
 * Create new query in context, add to querynum list.
 * @param ctx: context
 * @param name: query name
 * @param rrtype: type
 * @param rrclass: class
 * @param cb: callback for async, or NULL for sync.
 * @param cbarg: user arg for async queries.
 * @return new ctx_query or NULL for malloc failure.
 */
struct ctx_query* context_new(struct ub_ctx* ctx, char* name, int rrtype,
        int rrclass, ub_callback_t cb, void* cbarg);

/**
 * Get a new alloc. Creates a new one or uses a cached one.
 * @param ctx: context
 * @param locking: if true, cfglock is locked while getting alloc.
 * @return an alloc, or NULL on mem error.
 */
struct alloc_cache* context_obtain_alloc(struct ub_ctx* ctx, int locking);

/**
 * Release an alloc. Puts it into the cache.
 * @param ctx: context
 * @param locking: if true, cfglock is locked while releasing alloc.
 * @param alloc: alloc to relinquish.
 */
void context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc,
      int locking);

/**
 * Serialize a context query that questions data.
 * This serializes the query name, type, ...
 * As well as command code 'new_query'.
 * @param q: context query
 * @param len: the length of the allocation is returned.
 * @return: an alloc, or NULL on mem error.
 */
uint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len);

/**
 * Serialize a context_query result to hand back to user.
 * This serializes the query name, type, ..., and result.
 * As well as command code 'answer'.
 * @param q: context query
 * @param err: error code to pass to client.
 * @param pkt: the packet to add, can be NULL.
 * @param len: the length of the allocation is returned.
 * @return: an alloc, or NULL on mem error.
 */
uint8_t* context_serialize_answer(struct ctx_query* q, int err, 
      ldns_buffer* pkt, uint32_t* len);

/**
 * Serialize a query cancellation. Serializes query async id
 * as well as command code 'cancel'
 * @param q: context query
 * @param len: the length of the allocation is returned.
 * @return: an alloc, or NULL on mem error.
 */
uint8_t* context_serialize_cancel(struct ctx_query* q, uint32_t* len);

/**
 * Serialize a 'quit' command.
 * @param len: the length of the allocation is returned.
 * @return: an alloc, or NULL on mem error.
 */
uint8_t* context_serialize_quit(uint32_t* len);

/**
 * Obtain command code from serialized buffer
 * @param p: buffer serialized.
 * @param len: length of buffer.
 * @return command code or QUIT on error.
 */
enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len);

/**
 * Lookup query from new_query buffer.
 * @param ctx: context
 * @param p: buffer serialized.
 * @param len: length of buffer.
 * @return looked up ctx_query or NULL for malloc failure.
 */
struct ctx_query* context_lookup_new_query(struct ub_ctx* ctx, 
      uint8_t* p, uint32_t len);

/**
 * Deserialize a new_query buffer.
 * @param ctx: context
 * @param p: buffer serialized.
 * @param len: length of buffer.
 * @return new ctx_query or NULL for malloc failure.
 */
struct ctx_query* context_deserialize_new_query(struct ub_ctx* ctx, 
      uint8_t* p, uint32_t len);

/**
 * Deserialize an answer buffer.
 * @param ctx: context
 * @param p: buffer serialized.
 * @param len: length of buffer.
 * @param err: error code to be returned to client is passed.
 * @return ctx_query with answer added or NULL for malloc failure.
 */
struct ctx_query* context_deserialize_answer(struct ub_ctx* ctx, 
      uint8_t* p, uint32_t len, int* err);

/**
 * Deserialize a cancel buffer.
 * @param ctx: context
 * @param p: buffer serialized.
 * @param len: length of buffer.
 * @return ctx_query to cancel or NULL for failure.
 */
struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx, 
      uint8_t* p, uint32_t len);

#endif /* LIBUNBOUND_CONTEXT_H */

Generated by  Doxygen 1.6.0   Back to index