1 /* Copyright © 2012 Brandon L Black <blblack@gmail.com> 2 * 3 * This file is part of gdnsd. 4 * 5 * gdnsd is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * gdnsd is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with gdnsd. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 #ifndef GDNSD_PLUGAPI_H 21 #define GDNSD_PLUGAPI_H 22 23 #include <gdnsd/vscf.h> 24 #include <gdnsd/net.h> 25 #include <gdnsd/mon.h> 26 27 #include <inttypes.h> 28 29 #include <ev.h> 30 31 // The bopts header is sort of like a "config.h" for plugin binary compat 32 // It defines only features that affect binary compatibility between plugins 33 // and the core code, so that plugins can be rejected as needing a recompile 34 // if they were built against a compatible gdnsd version but with incompatible 35 // build options. 36 #ifndef GDNSD_SOURCE_TREE 37 #include <gdnsd/bopts.h> 38 #endif 39 40 /*** 41 * Plugin API version, bumped on any change that's not backwards-compat. 42 * This is hardcoded as the return value of plugin_foo_get_api_version() 43 * in gdnsd/plugin.h, and also compiled into the gdnsd code. The two 44 * values are compared at plugin load time to ensure that plugin code 45 * which doesn't match the API of the gdnsd binary is not allowed. 46 * (Of course, in many cases the plugin never even makes it that far, 47 * because libgdnsd is missing symbols it wants to link against that 48 * were dropped in the new API. This is just to protect other cases). 49 ***/ 50 51 // We have room for 16 option bits here coming from bopts.h/config.h 52 #define API_B_OPT_QSBR_ ((GDNSD_B_QSBR ? 1 : 0) << 0) 53 #define API_B_OPTS_ (API_B_OPT_QSBR_) 54 #define API_ACTUAL_VERSION_ 17 55 #define GDNSD_PLUGIN_API_VERSION (((API_B_OPTS_) << 16) | (API_ACTUAL_VERSION_)) 56 57 #pragma GCC visibility push(default) 58 59 // Called by resolver plugins during configuration load callback 60 // Indicates the maximum count of each address family that the plugin 61 // will add to result structures at runtime. A plugin *cannot* exceed 62 // the limits it sets for itself here at startup, and every resolver 63 // plugin that can return addresses *must* call this function! 64 void gdnsd_dyn_addr_max(unsigned v4, unsigned v6); 65 66 /*** Data Types ***/ 67 68 // read-only for plugins 69 typedef struct { 70 dmn_anysin_t dns_source; // address of last source DNS cache/forwarder 71 dmn_anysin_t edns_client; // edns-client-subnet address portion 72 unsigned edns_client_mask; // edns-client-subnet mask portion 73 } client_info_t; // ^(if zero, edns_client is invalid (was not sent)) 74 75 // Private result structure for dynamic resolution plugins 76 // Modified via the functions below... 77 struct dyn_result; 78 typedef struct dyn_result dyn_result_t; 79 80 // NOTE the rules for the result-modifying functions below: 81 // A plugin cannot add more addresses of a given family than it indicated 82 // during its call to gdnsd_dyn_addr_max(). 83 // A plugin cannot add both addresses and a CNAME to the same result. 84 // A plugin cannot add more than one CNAME to the same result. 85 86 // Push an dmn_anysin_t (v4 or v6 addr) into dyn_result_t storage. 87 F_NONNULL 88 void gdnsd_result_add_anysin(dyn_result_t* result, const dmn_anysin_t* asin); 89 90 // Push a CNAME into dyn_result_t storage. 91 F_NONNULL 92 void gdnsd_result_add_cname(dyn_result_t* result, const uint8_t* dname, const uint8_t* origin); 93 94 // Wipe a result_t's storage completely, removing all addresses or the CNAME stored within 95 // (this function is valid at all times, never fails, and resets to the original state) 96 // (does not affect scope mask!) 97 F_NONNULL 98 void gdnsd_result_wipe(dyn_result_t* result); 99 100 // Wipe just one address family from a result. Does not affect the other address family, 101 // and has no effect at all if the result contained a CNAME instead. 102 // (does not affect scope mask!) 103 F_NONNULL 104 void gdnsd_result_wipe_v4(dyn_result_t* result); 105 F_NONNULL 106 void gdnsd_result_wipe_v6(dyn_result_t* result); 107 108 // Resets the edns scope mask to the default value of zero, meaning global (unspecified) scope 109 F_NONNULL 110 void gdnsd_result_reset_scope_mask(dyn_result_t* result); 111 112 // Set the edns scope mask of the result to the minimum scope (numerically-larger) of 113 // the current setting and the new input. This is correct if more than one independent 114 // calculation of scope applies to the result. 115 F_NONNULL 116 void gdnsd_result_add_scope_mask(dyn_result_t* result, unsigned scope); 117 118 /**** Typedefs for plugin callbacks ****/ 119 120 typedef unsigned (*gdnsd_apiv_cb_t)(void); 121 typedef void (*gdnsd_load_config_cb_t)(vscf_data_t* pc, const unsigned num_threads); 122 typedef int (*gdnsd_map_res_cb_t)(const char* resname, const uint8_t* origin); 123 typedef void (*gdnsd_pre_run_cb_t)(void); 124 typedef void (*gdnsd_iothread_init_cb_t)(unsigned threadnum); 125 typedef gdnsd_sttl_t (*gdnsd_resolve_cb_t)(unsigned resnum, const uint8_t* origin, const client_info_t* cinfo, dyn_result_t* result); 126 typedef void (*gdnsd_exit_cb_t)(void); 127 128 /**** New callbacks for monitoring plugins ****/ 129 130 typedef void (*gdnsd_add_svctype_cb_t)(const char* name, vscf_data_t* svc_cfg, const unsigned interval, const unsigned timeout); 131 typedef void (*gdnsd_add_mon_addr_cb_t)(const char* desc, const char* svc_name, const char* cname, const dmn_anysin_t* addr, const unsigned idx); 132 typedef void (*gdnsd_add_mon_cname_cb_t)(const char* desc, const char* svc_name, const char* cname, const unsigned idx); 133 typedef void (*gdnsd_init_monitors_cb_t)(struct ev_loop* mon_loop); 134 typedef void (*gdnsd_start_monitors_cb_t)(struct ev_loop* mon_loop); 135 136 // This is the data type for a plugin itself, holding function 137 // pointers for all of the possibly-documented callbacks 138 typedef struct { 139 const char* name; 140 bool config_loaded; 141 gdnsd_load_config_cb_t load_config; 142 gdnsd_map_res_cb_t map_res; 143 gdnsd_pre_run_cb_t pre_run; 144 gdnsd_iothread_init_cb_t iothread_init; 145 gdnsd_resolve_cb_t resolve; 146 gdnsd_exit_cb_t exit; 147 gdnsd_add_svctype_cb_t add_svctype; 148 gdnsd_add_mon_addr_cb_t add_mon_addr; 149 gdnsd_add_mon_cname_cb_t add_mon_cname; 150 gdnsd_init_monitors_cb_t init_monitors; 151 gdnsd_start_monitors_cb_t start_monitors; 152 } plugin_t; 153 154 // Find a(nother) plugin by name. Not valid at load_config() time, 155 // use later. 156 F_NONNULL F_PURE 157 plugin_t* gdnsd_plugin_find(const char* plugin_name); 158 159 // convenient macro for logging a config error and returning 160 // the error value -1 in a resolver plugin's map_res() callback 161 // without a bunch of extra clutter and bracing 162 #define map_res_err(...) \ 163 do {\ 164 log_err(__VA_ARGS__);\ 165 return -1;\ 166 } while(0) 167 168 #pragma GCC visibility pop 169 170 #endif // GDNSD_PLUGINAPI_H 171