117d15b25SDag-Erling Smørgrav /* 217d15b25SDag-Erling Smørgrav * unbound-event.h - unbound validating resolver public API with events 317d15b25SDag-Erling Smørgrav * 417d15b25SDag-Erling Smørgrav * Copyright (c) 2007, NLnet Labs. All rights reserved. 517d15b25SDag-Erling Smørgrav * 617d15b25SDag-Erling Smørgrav * This software is open source. 717d15b25SDag-Erling Smørgrav * 817d15b25SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 917d15b25SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 1017d15b25SDag-Erling Smørgrav * are met: 1117d15b25SDag-Erling Smørgrav * 1217d15b25SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 1317d15b25SDag-Erling Smørgrav * this list of conditions and the following disclaimer. 1417d15b25SDag-Erling Smørgrav * 1517d15b25SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 1617d15b25SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 1717d15b25SDag-Erling Smørgrav * and/or other materials provided with the distribution. 1817d15b25SDag-Erling Smørgrav * 1917d15b25SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 2017d15b25SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 2117d15b25SDag-Erling Smørgrav * specific prior written permission. 2217d15b25SDag-Erling Smørgrav * 2317d15b25SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2417d15b25SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2517d15b25SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2617d15b25SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2717d15b25SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2817d15b25SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2917d15b25SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3017d15b25SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3117d15b25SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3217d15b25SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3317d15b25SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3417d15b25SDag-Erling Smørgrav */ 3517d15b25SDag-Erling Smørgrav 3617d15b25SDag-Erling Smørgrav /** 3717d15b25SDag-Erling Smørgrav * \file 3817d15b25SDag-Erling Smørgrav * 39e2d15004SDag-Erling Smørgrav * This file contains the unbound interface for use with user defined 40e2d15004SDag-Erling Smørgrav * pluggable event bases. 4117d15b25SDag-Erling Smørgrav * 42e2d15004SDag-Erling Smørgrav * Use ub_ctx_create_event_ub_base() to create an unbound context that uses 43e2d15004SDag-Erling Smørgrav * the user provided event base API. Then, use the ub_resolve_event call 4424e36522SCy Schubert * to add DNS resolve queries to the context. Those then run with the 45e2d15004SDag-Erling Smørgrav * provided event_base, and when they are done you get a function callback. 4617d15b25SDag-Erling Smørgrav * 4717d15b25SDag-Erling Smørgrav * This method does not fork another process or create a thread, the effort 48e2d15004SDag-Erling Smørgrav * is done by the unbound state machines that are connected to the event base. 49e2d15004SDag-Erling Smørgrav * 50e2d15004SDag-Erling Smørgrav * It is also possible to provide a libevent based event base by using 51e2d15004SDag-Erling Smørgrav * ub_ctx_create_event_base(). But you have to use the same libevent that 52e2d15004SDag-Erling Smørgrav * unbound was compiled with, otherwise it wouldn't work, the event and 53e2d15004SDag-Erling Smørgrav * event_base structures would be different. 5417d15b25SDag-Erling Smørgrav */ 55*8f76bb7dSCy Schubert #ifndef UB_UNBOUND_EVENT_H 56*8f76bb7dSCy Schubert #define UB_UNBOUND_EVENT_H 5717d15b25SDag-Erling Smørgrav 5817d15b25SDag-Erling Smørgrav #ifdef __cplusplus 5917d15b25SDag-Erling Smørgrav extern "C" { 6017d15b25SDag-Erling Smørgrav #endif 6117d15b25SDag-Erling Smørgrav 6217d15b25SDag-Erling Smørgrav struct ub_ctx; 6317d15b25SDag-Erling Smørgrav struct ub_result; 6417d15b25SDag-Erling Smørgrav struct event_base; 6517d15b25SDag-Erling Smørgrav 66e2d15004SDag-Erling Smørgrav /** event timeout */ 67e2d15004SDag-Erling Smørgrav #define UB_EV_TIMEOUT 0x01 68e2d15004SDag-Erling Smørgrav /** event fd readable */ 69e2d15004SDag-Erling Smørgrav #define UB_EV_READ 0x02 70e2d15004SDag-Erling Smørgrav /** event fd writable */ 71e2d15004SDag-Erling Smørgrav #define UB_EV_WRITE 0x04 72e2d15004SDag-Erling Smørgrav /** event signal */ 73e2d15004SDag-Erling Smørgrav #define UB_EV_SIGNAL 0x08 74e2d15004SDag-Erling Smørgrav /** event must persist */ 75e2d15004SDag-Erling Smørgrav #define UB_EV_PERSIST 0x10 76e2d15004SDag-Erling Smørgrav 77e2d15004SDag-Erling Smørgrav /** magic number to identify this version of the pluggable event api */ 78e2d15004SDag-Erling Smørgrav #define UB_EVENT_MAGIC 0x44d74d78 79e2d15004SDag-Erling Smørgrav 80e2d15004SDag-Erling Smørgrav struct ub_event; 81e2d15004SDag-Erling Smørgrav struct ub_event_base; 82e2d15004SDag-Erling Smørgrav struct timeval; 83e2d15004SDag-Erling Smørgrav 84e2d15004SDag-Erling Smørgrav /** 85e2d15004SDag-Erling Smørgrav * The Virtual Method Table for and ub_event_base "object" 86e2d15004SDag-Erling Smørgrav */ 87e2d15004SDag-Erling Smørgrav struct ub_event_base_vmt { 88e2d15004SDag-Erling Smørgrav /** Destructor for the ub_event_base object, 89e2d15004SDag-Erling Smørgrav * (not called by libunbound) */ 90e2d15004SDag-Erling Smørgrav void (*free)(struct ub_event_base*); 91e2d15004SDag-Erling Smørgrav /** Run the event loop 92e2d15004SDag-Erling Smørgrav * (not called by libunbound when using ub_resolve_event) */ 93e2d15004SDag-Erling Smørgrav int (*dispatch)(struct ub_event_base*); 94e2d15004SDag-Erling Smørgrav /** Exit the given event loop */ 95e2d15004SDag-Erling Smørgrav int (*loopexit)(struct ub_event_base*, struct timeval*); 96e2d15004SDag-Erling Smørgrav /** Instantiate a new ub_event associated with this event base */ 97e2d15004SDag-Erling Smørgrav struct ub_event* (*new_event)(struct ub_event_base*, 98e2d15004SDag-Erling Smørgrav int fd, short bits, void (*cb)(int, short, void*), void* arg); 99e2d15004SDag-Erling Smørgrav /** Instantiate a new signal associated with this event base, 100e2d15004SDag-Erling Smørgrav * (not called by libunbound) */ 101e2d15004SDag-Erling Smørgrav struct ub_event* (*new_signal)(struct ub_event_base*, int fd, 102e2d15004SDag-Erling Smørgrav void (*cb)(int, short, void*), void* arg); 103e2d15004SDag-Erling Smørgrav /** Create a new ub_event associated with the given wsaevent, 104e2d15004SDag-Erling Smørgrav * (not called by libunbound) */ 105e2d15004SDag-Erling Smørgrav struct ub_event* (*winsock_register_wsaevent)(struct ub_event_base*, 106e2d15004SDag-Erling Smørgrav void* wsaevent, void (*cb)(int, short, void*), void* arg); 107e2d15004SDag-Erling Smørgrav }; 108e2d15004SDag-Erling Smørgrav 109e2d15004SDag-Erling Smørgrav /** 110e2d15004SDag-Erling Smørgrav * A user defined pluggable event base is registered by providing a 111e2d15004SDag-Erling Smørgrav * ub_event_base "object" with the ub_ctx_create_ub_event() function. 112e2d15004SDag-Erling Smørgrav * The magic number must be correct and the Virtual Method Table must be 113e2d15004SDag-Erling Smørgrav * fully equipped providing the event base API to be used by libunbound. 114e2d15004SDag-Erling Smørgrav */ 115e2d15004SDag-Erling Smørgrav struct ub_event_base { 116e2d15004SDag-Erling Smørgrav /** magic must be UB_EVENT_MAGIC (0x44d74d78) */ 117e2d15004SDag-Erling Smørgrav unsigned long magic; 118e2d15004SDag-Erling Smørgrav /** Virtual Method Table for ub_event_base */ 119e2d15004SDag-Erling Smørgrav struct ub_event_base_vmt* vmt; 120e2d15004SDag-Erling Smørgrav }; 121e2d15004SDag-Erling Smørgrav 122e2d15004SDag-Erling Smørgrav /** 123e2d15004SDag-Erling Smørgrav * The Virtual Method Table for and ub_event "object" 124e2d15004SDag-Erling Smørgrav */ 125e2d15004SDag-Erling Smørgrav struct ub_event_vmt { 126e2d15004SDag-Erling Smørgrav /** Add event bits for this event to fire on. 127e2d15004SDag-Erling Smørgrav * The event will be deactivated before this function is called. */ 128e2d15004SDag-Erling Smørgrav void (*add_bits)(struct ub_event*, short); 129e2d15004SDag-Erling Smørgrav /** Configure the event so it will not longer fire on given bits 130e2d15004SDag-Erling Smørgrav * The event will be deactivated before this function is called. */ 131e2d15004SDag-Erling Smørgrav void (*del_bits)(struct ub_event*, short); 132e2d15004SDag-Erling Smørgrav /** Change or set the file descriptor on the event 133e2d15004SDag-Erling Smørgrav * The event will be deactivated before this function is called. */ 134e2d15004SDag-Erling Smørgrav void (*set_fd)(struct ub_event*, int); 135e2d15004SDag-Erling Smørgrav /** Destructor for the ub_event object */ 136e2d15004SDag-Erling Smørgrav void (*free)(struct ub_event*); 137e2d15004SDag-Erling Smørgrav /** Activate the event. The given timeval is an timeout value. */ 138e2d15004SDag-Erling Smørgrav int (*add)(struct ub_event*, struct timeval*); 139e2d15004SDag-Erling Smørgrav /** Deactivate the event */ 140e2d15004SDag-Erling Smørgrav int (*del)(struct ub_event*); 141e2d15004SDag-Erling Smørgrav /** Reconfigure and activate a timeout event */ 142e2d15004SDag-Erling Smørgrav int (*add_timer)(struct ub_event*, struct ub_event_base*, 143e2d15004SDag-Erling Smørgrav void (*cb)(int, short, void*), void* arg, struct timeval*); 144e2d15004SDag-Erling Smørgrav /** Deactivate the timeout event */ 145e2d15004SDag-Erling Smørgrav int (*del_timer)(struct ub_event*); 146e2d15004SDag-Erling Smørgrav /** Activate a signal event (not called by libunbound). */ 147e2d15004SDag-Erling Smørgrav int (*add_signal)(struct ub_event*, struct timeval*); 148e2d15004SDag-Erling Smørgrav /** Deactivate a signal event (not called by libunbound). */ 149e2d15004SDag-Erling Smørgrav int (*del_signal)(struct ub_event*); 150e2d15004SDag-Erling Smørgrav /** Destructor for a ub_event associated with a wsaevent, 151e2d15004SDag-Erling Smørgrav * (not called by libunbound) 152e2d15004SDag-Erling Smørgrav */ 153e2d15004SDag-Erling Smørgrav void (*winsock_unregister_wsaevent)(struct ub_event* ev); 154e2d15004SDag-Erling Smørgrav /** Libunbound will signal the eventloop when a TCP windows socket 155e2d15004SDag-Erling Smørgrav * will block on next read or write (given by the eventbits), to work 156e2d15004SDag-Erling Smørgrav * around edge trigger event behaviour of select on windows with TCP. 157e2d15004SDag-Erling Smørgrav */ 158e2d15004SDag-Erling Smørgrav void (*winsock_tcp_wouldblock)(struct ub_event*, int eventbit); 159e2d15004SDag-Erling Smørgrav }; 160e2d15004SDag-Erling Smørgrav 161e2d15004SDag-Erling Smørgrav /** 162e2d15004SDag-Erling Smørgrav * An "object" comprising a user defined pluggable event. 163e2d15004SDag-Erling Smørgrav * The magic number must be correct and the Virtual Method Table must be 164e2d15004SDag-Erling Smørgrav * fully equipped providing the ub_event API to be used by libunbound. 165e2d15004SDag-Erling Smørgrav */ 166e2d15004SDag-Erling Smørgrav struct ub_event { 167e2d15004SDag-Erling Smørgrav /** magic must be UB_EVENT_MAGIC (0x44d74d78) */ 168e2d15004SDag-Erling Smørgrav unsigned long magic; 169e2d15004SDag-Erling Smørgrav /** Virtual Method Table for ub_event */ 170e2d15004SDag-Erling Smørgrav struct ub_event_vmt* vmt; 171e2d15004SDag-Erling Smørgrav }; 172e2d15004SDag-Erling Smørgrav 1734c75e3aaSDag-Erling Smørgrav typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*, int); 17417d15b25SDag-Erling Smørgrav 17517d15b25SDag-Erling Smørgrav /** 17617d15b25SDag-Erling Smørgrav * Create a resolving and validation context. 17717d15b25SDag-Erling Smørgrav * The information from /etc/resolv.conf and /etc/hosts is not utilised by 17817d15b25SDag-Erling Smørgrav * default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them. 179e2d15004SDag-Erling Smørgrav * @param base: the pluggable event base that the caller has created. 180e2d15004SDag-Erling Smørgrav * The unbound context uses this event base. 181e2d15004SDag-Erling Smørgrav * @return a new context. default initialisation. 182e2d15004SDag-Erling Smørgrav * returns NULL on error. 183e2d15004SDag-Erling Smørgrav * You must use ub_resolve_event with this context. 184e2d15004SDag-Erling Smørgrav * Do not call ub_ctx_async, ub_poll, ub_wait, ub_process, this is all done 185e2d15004SDag-Erling Smørgrav * with the event_base. Setup the options you like with the other functions. 186e2d15004SDag-Erling Smørgrav */ 187e2d15004SDag-Erling Smørgrav struct ub_ctx* ub_ctx_create_ub_event(struct ub_event_base* base); 188e2d15004SDag-Erling Smørgrav 189e2d15004SDag-Erling Smørgrav /** 190e2d15004SDag-Erling Smørgrav * Create a resolving and validation context. 191e2d15004SDag-Erling Smørgrav * The information from /etc/resolv.conf and /etc/hosts is not utilised by 192e2d15004SDag-Erling Smørgrav * default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them. 193e2d15004SDag-Erling Smørgrav * You have to use the same libevent that unbound was compiled with, 194e2d15004SDag-Erling Smørgrav * otherwise it wouldn't work, the event and event_base structures would 195e2d15004SDag-Erling Smørgrav * be different. 19617d15b25SDag-Erling Smørgrav * @param base: the event base that the caller has created. The unbound 19717d15b25SDag-Erling Smørgrav * context uses this event base. 19817d15b25SDag-Erling Smørgrav * @return a new context. default initialisation. 19917d15b25SDag-Erling Smørgrav * returns NULL on error. 20017d15b25SDag-Erling Smørgrav * You must use ub_resolve_event with this context. 20117d15b25SDag-Erling Smørgrav * Do not call ub_ctx_async, ub_poll, ub_wait, ub_process, this is all done 20217d15b25SDag-Erling Smørgrav * with the event_base. Setup the options you like with the other functions. 20317d15b25SDag-Erling Smørgrav */ 20417d15b25SDag-Erling Smørgrav struct ub_ctx* ub_ctx_create_event(struct event_base* base); 20517d15b25SDag-Erling Smørgrav 20617d15b25SDag-Erling Smørgrav /** 207e2d15004SDag-Erling Smørgrav * Set a new libevent event_base on a context created with ub_ctx_create_event. 208e2d15004SDag-Erling Smørgrav * You have to use the same libevent that unbound was compiled with, 209e2d15004SDag-Erling Smørgrav * otherwise it wouldn't work, the event and event_base structures would 210e2d15004SDag-Erling Smørgrav * be different. 21117d15b25SDag-Erling Smørgrav * Any outbound queries will be canceled. 21217d15b25SDag-Erling Smørgrav * @param ctx the ub_ctx to update. Must have been created with ub_ctx_create_event 21317d15b25SDag-Erling Smørgrav * @param base the new event_base to attach to the ctx 21417d15b25SDag-Erling Smørgrav * @return 0 if OK, else error 21517d15b25SDag-Erling Smørgrav */ 21617d15b25SDag-Erling Smørgrav int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base); 21717d15b25SDag-Erling Smørgrav 21817d15b25SDag-Erling Smørgrav /** 21917d15b25SDag-Erling Smørgrav * Perform resolution and validation of the target name. 22017d15b25SDag-Erling Smørgrav * Asynchronous, after a while, the callback will be called with your 22117d15b25SDag-Erling Smørgrav * data and the result. Uses the event_base user installed by creating the 22217d15b25SDag-Erling Smørgrav * context with ub_ctx_create_event(). 22317d15b25SDag-Erling Smørgrav * @param ctx: context with event_base in it. 22417d15b25SDag-Erling Smørgrav * The context is finalized, and can no longer accept all config changes. 22517d15b25SDag-Erling Smørgrav * @param name: domain name in text format (a string). 22617d15b25SDag-Erling Smørgrav * @param rrtype: type of RR in host order, 1 is A. 22717d15b25SDag-Erling Smørgrav * @param rrclass: class of RR in host order, 1 is IN (for internet). 22817d15b25SDag-Erling Smørgrav * @param mydata: this data is your own data (you can pass NULL), 22917d15b25SDag-Erling Smørgrav * and is passed on to the callback function. 23017d15b25SDag-Erling Smørgrav * @param callback: this is called on completion of the resolution. 23117d15b25SDag-Erling Smørgrav * It is called as: 23217d15b25SDag-Erling Smørgrav * void callback(void* mydata, int rcode, void* packet, int packet_len, 2331838dec3SCy Schubert * int sec, char* why_bogus, int was_ratelimited) 23417d15b25SDag-Erling Smørgrav * with mydata: the same as passed here, you may pass NULL, 23517d15b25SDag-Erling Smørgrav * with rcode: 0 on no error, nonzero for mostly SERVFAIL situations, 23617d15b25SDag-Erling Smørgrav * this is a DNS rcode. 23717d15b25SDag-Erling Smørgrav * with packet: a buffer with DNS wireformat packet with the answer. 23817d15b25SDag-Erling Smørgrav * do not inspect if rcode != 0. 23917d15b25SDag-Erling Smørgrav * do not write or free the packet buffer, it is used internally 24017d15b25SDag-Erling Smørgrav * in unbound (for other callbacks that want the same data). 24117d15b25SDag-Erling Smørgrav * with packet_len: length in bytes of the packet buffer. 24217d15b25SDag-Erling Smørgrav * with sec: 0 if insecure, 1 if bogus, 2 if DNSSEC secure. 24317d15b25SDag-Erling Smørgrav * with why_bogus: text string explaining why it is bogus (or NULL). 2441838dec3SCy Schubert * with was_ratelimited: if the query was ratelimited. 24517d15b25SDag-Erling Smørgrav * These point to buffers inside unbound; do not deallocate the packet or 24617d15b25SDag-Erling Smørgrav * error string. 24717d15b25SDag-Erling Smørgrav * 24817d15b25SDag-Erling Smørgrav * If an error happens during processing, your callback will be called 24917d15b25SDag-Erling Smørgrav * with error set to a nonzero value (and result==NULL). 25017d15b25SDag-Erling Smørgrav * For localdata (etc/hosts) the callback is called immediately, before 25117d15b25SDag-Erling Smørgrav * resolve_event returns, async_id=0 is returned. 25217d15b25SDag-Erling Smørgrav * @param async_id: if you pass a non-NULL value, an identifier number is 25317d15b25SDag-Erling Smørgrav * returned for the query as it is in progress. It can be used to 25417d15b25SDag-Erling Smørgrav * cancel the query. 25517d15b25SDag-Erling Smørgrav * @return 0 if OK, else error. 25617d15b25SDag-Erling Smørgrav */ 25717d15b25SDag-Erling Smørgrav int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype, 2583005e0a3SDag-Erling Smørgrav int rrclass, void* mydata, ub_event_callback_type callback, 2593005e0a3SDag-Erling Smørgrav int* async_id); 26017d15b25SDag-Erling Smørgrav 26117d15b25SDag-Erling Smørgrav #ifdef __cplusplus 26217d15b25SDag-Erling Smørgrav } 26317d15b25SDag-Erling Smørgrav #endif 26417d15b25SDag-Erling Smørgrav 265*8f76bb7dSCy Schubert #endif /* UB_UNBOUND_EVENT_H */ 266