Home | History | Annotate | Line # | Download | only in libunbound
      1 /*
      2  * unbound-event.h - unbound validating resolver public API with events
      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 unbound interface for use with user defined
     40  * pluggable event bases.
     41  *
     42  * Use ub_ctx_create_event_ub_base() to create an unbound context that uses
     43  * the user provided event base API.  Then, use the ub_resolve_event call
     44  * to add DNS resolve queries to the context.  Those then run with the
     45  * provided event_base, and when they are done you get a function callback.
     46  *
     47  * This method does not fork another process or create a thread, the effort
     48  * is done by the unbound state machines that are connected to the event base.
     49  *
     50  * It is also possible to provide a libevent based event base by using
     51  * ub_ctx_create_event_base().  But you have to use the same libevent that
     52  * unbound was compiled with, otherwise it wouldn't work, the event and
     53  * event_base structures would be different.
     54  */
     55 #ifndef UB_UNBOUND_EVENT_H
     56 #define UB_UNBOUND_EVENT_H
     57 
     58 #ifdef __cplusplus
     59 extern "C" {
     60 #endif
     61 
     62 struct ub_ctx;
     63 struct ub_result;
     64 struct event_base;
     65 
     66 /** event timeout */
     67 #define UB_EV_TIMEOUT      0x01
     68 /** event fd readable */
     69 #define UB_EV_READ         0x02
     70 /** event fd writable */
     71 #define UB_EV_WRITE        0x04
     72 /** event signal */
     73 #define UB_EV_SIGNAL       0x08
     74 /** event must persist */
     75 #define UB_EV_PERSIST      0x10
     76 
     77 /** magic number to identify this version of the pluggable event api */
     78 #define UB_EVENT_MAGIC     0x44d74d78
     79 
     80 struct ub_event;
     81 struct ub_event_base;
     82 struct timeval;
     83 
     84 /**
     85  * The Virtual Method Table for and ub_event_base "object"
     86  */
     87 struct ub_event_base_vmt {
     88 	/** Destructor for the ub_event_base object,
     89 	 * (not called by libunbound) */
     90 	void (*free)(struct ub_event_base*);
     91 	/** Run the event loop
     92 	 * (not called by libunbound when using ub_resolve_event) */
     93 	int (*dispatch)(struct ub_event_base*);
     94 	/** Exit the given event loop */
     95 	int (*loopexit)(struct ub_event_base*, struct timeval*);
     96 	/** Instantiate a new ub_event associated with this event base */
     97 	struct ub_event* (*new_event)(struct ub_event_base*,
     98 		int fd, short bits, void (*cb)(int, short, void*), void* arg);
     99 	/** Instantiate a new signal associated with this event base,
    100 	 * (not called by libunbound) */
    101 	struct ub_event* (*new_signal)(struct ub_event_base*, int fd,
    102 		void (*cb)(int, short, void*), void* arg);
    103 	/** Create a new ub_event associated with the given wsaevent,
    104 	 * (not called by libunbound) */
    105 	struct ub_event* (*winsock_register_wsaevent)(struct ub_event_base*,
    106 		void* wsaevent, void (*cb)(int, short, void*), void* arg);
    107 };
    108 
    109 /**
    110  * A user defined pluggable event base is registered by providing a
    111  * ub_event_base "object" with the ub_ctx_create_ub_event() function.
    112  * The magic number must be correct and the Virtual Method Table must be
    113  * fully equipped providing the event base API to be used by libunbound.
    114  */
    115 struct ub_event_base {
    116 	/** magic must be UB_EVENT_MAGIC (0x44d74d78) */
    117 	unsigned long magic;
    118 	/** Virtual Method Table for ub_event_base */
    119 	struct ub_event_base_vmt* vmt;
    120 };
    121 
    122 /**
    123  * The Virtual Method Table for and ub_event "object"
    124  */
    125 struct ub_event_vmt {
    126 	/** Add event bits for this event to fire on.
    127 	 * The event will be deactivated before this function is called. */
    128 	void (*add_bits)(struct ub_event*, short);
    129 	/** Configure the event so it will not longer fire on given bits
    130 	 * The event will be deactivated before this function is called. */
    131 	void (*del_bits)(struct ub_event*, short);
    132 	/** Change or set the file descriptor on the event
    133 	 * The event will be deactivated before this function is called. */
    134 	void (*set_fd)(struct ub_event*, int);
    135 	/** Destructor for the ub_event object */
    136 	void (*free)(struct ub_event*);
    137 	/** Activate the event.  The given timeval is an timeout value. */
    138 	int (*add)(struct ub_event*, struct timeval*);
    139 	/** Deactivate the event */
    140 	int (*del)(struct ub_event*);
    141 	/** Reconfigure and activate a timeout event */
    142 	int (*add_timer)(struct ub_event*, struct ub_event_base*,
    143 		void (*cb)(int, short, void*), void* arg, struct timeval*);
    144 	/** Deactivate the timeout event */
    145 	int (*del_timer)(struct ub_event*);
    146 	/** Activate a signal event (not called by libunbound). */
    147 	int (*add_signal)(struct ub_event*, struct timeval*);
    148 	/** Deactivate a signal event (not called by libunbound). */
    149 	int (*del_signal)(struct ub_event*);
    150 	/** Destructor for a ub_event associated with a wsaevent,
    151 	 * (not called by libunbound)
    152 	 */
    153 	void (*winsock_unregister_wsaevent)(struct ub_event* ev);
    154 	/** Libunbound will signal the eventloop when a TCP windows socket
    155 	 * will block on next read or write (given by the eventbits), to work
    156 	 * around edge trigger event behaviour of select on windows with TCP.
    157 	 */
    158 	void (*winsock_tcp_wouldblock)(struct ub_event*, int eventbit);
    159 };
    160 
    161 /**
    162  * An "object" comprising a user defined pluggable event.
    163  * The magic number must be correct and the Virtual Method Table must be
    164  * fully equipped providing the ub_event API to be used by libunbound.
    165  */
    166 struct ub_event {
    167 	/** magic must be UB_EVENT_MAGIC (0x44d74d78) */
    168 	unsigned long magic;
    169 	/** Virtual Method Table for ub_event */
    170 	struct ub_event_vmt* vmt;
    171 };
    172 
    173 typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*, int);
    174 
    175 /**
    176  * Create a resolving and validation context.
    177  * The information from /etc/resolv.conf and /etc/hosts is not utilised by
    178  * default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them.
    179  * @param base: the pluggable event base that the caller has created.
    180  *      The unbound context uses this event base.
    181  * @return a new context. default initialisation.
    182  * 	returns NULL on error.
    183  * You must use ub_resolve_event with this context.
    184  * Do not call ub_ctx_async, ub_poll, ub_wait, ub_process, this is all done
    185  * with the event_base.  Setup the options you like with the other functions.
    186  */
    187 struct ub_ctx* ub_ctx_create_ub_event(struct ub_event_base* base);
    188 
    189 /**
    190  * Create a resolving and validation context.
    191  * The information from /etc/resolv.conf and /etc/hosts is not utilised by
    192  * default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them.
    193  * You have to use the same libevent that unbound was compiled with,
    194  * otherwise it wouldn't work, the event and event_base structures would
    195  * be different.
    196  * @param base: the event base that the caller has created.  The unbound
    197  *	context uses this event base.
    198  * @return a new context. default initialisation.
    199  * 	returns NULL on error.
    200  * You must use ub_resolve_event with this context.
    201  * Do not call ub_ctx_async, ub_poll, ub_wait, ub_process, this is all done
    202  * with the event_base.  Setup the options you like with the other functions.
    203  */
    204 struct ub_ctx* ub_ctx_create_event(struct event_base* base);
    205 
    206 /**
    207  * Set a new libevent event_base on a context created with ub_ctx_create_event.
    208  * You have to use the same libevent that unbound was compiled with,
    209  * otherwise it wouldn't work, the event and event_base structures would
    210  * be different.
    211  * Any outbound queries will be canceled.
    212  * @param ctx the ub_ctx to update.  Must have been created with ub_ctx_create_event
    213  * @param base the new event_base to attach to the ctx
    214  * @return 0 if OK, else error
    215  */
    216 int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base);
    217 
    218 /**
    219  * Perform resolution and validation of the target name.
    220  * Asynchronous, after a while, the callback will be called with your
    221  * data and the result.  Uses the event_base user installed by creating the
    222  * context with ub_ctx_create_event().
    223  * @param ctx: context with event_base in it.
    224  *	The context is finalized, and can no longer accept all config changes.
    225  * @param name: domain name in text format (a string).
    226  * @param rrtype: type of RR in host order, 1 is A.
    227  * @param rrclass: class of RR in host order, 1 is IN (for internet).
    228  * @param mydata: this data is your own data (you can pass NULL),
    229  * 	and is passed on to the callback function.
    230  * @param callback: this is called on completion of the resolution.
    231  * 	It is called as:
    232  * 	void callback(void* mydata, int rcode, void* packet, int packet_len,
    233  * 		int sec, char* why_bogus, int was_ratelimited)
    234  * 	with mydata: the same as passed here, you may pass NULL,
    235  * 	with rcode: 0 on no error, nonzero for mostly SERVFAIL situations,
    236  *		this is a DNS rcode.
    237  *	with packet: a buffer with DNS wireformat packet with the answer.
    238  *		do not inspect if rcode != 0.
    239  *		do not write or free the packet buffer, it is used internally
    240  *		in unbound (for other callbacks that want the same data).
    241  *	with packet_len: length in bytes of the packet buffer.
    242  *	with sec: 0 if insecure, 1 if bogus, 2 if DNSSEC secure.
    243  *	with why_bogus: text string explaining why it is bogus (or NULL).
    244  *	with was_ratelimited: if the query was ratelimited.
    245  *	These point to buffers inside unbound; do not deallocate the packet or
    246  *	error string.
    247  *
    248  * 	If an error happens during processing, your callback will be called
    249  * 	with error set to a nonzero value (and result==NULL).
    250  * 	For localdata (etc/hosts) the callback is called immediately, before
    251  * 	resolve_event returns, async_id=0 is returned.
    252  * @param async_id: if you pass a non-NULL value, an identifier number is
    253  *	returned for the query as it is in progress. It can be used to
    254  *	cancel the query.
    255  * @return 0 if OK, else error.
    256  */
    257 int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
    258 	int rrclass, void* mydata, ub_event_callback_type callback,
    259 	int* async_id);
    260 
    261 #ifdef __cplusplus
    262 }
    263 #endif
    264 
    265 #endif /* UB_UNBOUND_EVENT_H */
    266