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 whith 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_t)(void*, int, void*, int, int, char*); 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) 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 * These point to buffers inside unbound; do not deallocate the packet or 245 * error string. 246 * 247 * If an error happens during processing, your callback will be called 248 * with error set to a nonzero value (and result==NULL). 249 * For localdata (etc/hosts) the callback is called immediately, before 250 * resolve_event returns, async_id=0 is returned. 251 * @param async_id: if you pass a non-NULL value, an identifier number is 252 * returned for the query as it is in progress. It can be used to 253 * cancel the query. 254 * @return 0 if OK, else error. 255 */ 256 int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype, 257 int rrclass, void* mydata, ub_event_callback_t callback, int* async_id); 258 259 #ifdef __cplusplus 260 } 261 #endif 262 263 #endif /* _UB_UNBOUND_H */ 264