1 /* $NetBSD: dlz_minimal.h,v 1.5 2022/09/23 12:15:28 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: ISC 7 * 8 * Permission to use, copy, modify, and distribute this software for any purpose 9 * with or without fee is hereby granted, provided that the above copyright 10 * notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 13 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 14 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 15 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 16 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 17 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 18 * PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 /* 22 * This header provides a minimal set of defines and typedefs needed 23 * for building an external DLZ module for bind9. When creating a new 24 * external DLZ driver, please copy this header into your own source 25 * tree. 26 */ 27 28 #ifndef DLZ_MINIMAL_H 29 #define DLZ_MINIMAL_H 1 30 31 #include <inttypes.h> 32 #include <stdbool.h> 33 #include <stdlib.h> 34 35 #include <sys/socket.h> 36 #include <sys/types.h> 37 #ifdef ISC_PLATFORM_HAVESYSUNH 38 #include <sys/un.h> 39 #endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ 40 #include <arpa/inet.h> 41 #include <net/if.h> 42 #include <netinet/in.h> 43 44 typedef unsigned int isc_result_t; 45 typedef uint32_t dns_ttl_t; 46 47 /* 48 * Define DLZ_DLOPEN_VERSION to different values to use older versions 49 * of the interface 50 */ 51 #ifndef DLZ_DLOPEN_VERSION 52 #define DLZ_DLOPEN_VERSION 3 53 #define DLZ_DLOPEN_AGE 0 54 #endif /* ifndef DLZ_DLOPEN_VERSION */ 55 56 /* return these in flags from dlz_version() */ 57 #define DNS_SDLZFLAG_THREADSAFE 0x00000001U 58 #define DNS_SDLZFLAG_RELATIVEOWNER 0x00000002U 59 #define DNS_SDLZFLAG_RELATIVERDATA 0x00000004U 60 61 /* result codes */ 62 #define ISC_R_SUCCESS 0 63 #define ISC_R_NOMEMORY 1 64 #define ISC_R_NOPERM 6 65 #define ISC_R_NOSPACE 19 66 #define ISC_R_NOTFOUND 23 67 #define ISC_R_FAILURE 25 68 #define ISC_R_NOTIMPLEMENTED 27 69 #define ISC_R_NOMORE 29 70 #define ISC_R_INVALIDFILE 30 71 #define ISC_R_UNEXPECTED 34 72 #define ISC_R_FILENOTFOUND 38 73 74 /* log levels */ 75 #define ISC_LOG_INFO (-1) 76 #define ISC_LOG_NOTICE (-2) 77 #define ISC_LOG_WARNING (-3) 78 #define ISC_LOG_ERROR (-4) 79 #define ISC_LOG_CRITICAL (-5) 80 #define ISC_LOG_DEBUG(level) (level) 81 82 /* other useful definitions */ 83 #define UNUSED(x) (void)(x) 84 #define DE_CONST(konst, var) \ 85 do { \ 86 union { \ 87 const void *k; \ 88 void *v; \ 89 } _u; \ 90 _u.k = konst; \ 91 var = _u.v; \ 92 } while (0) 93 94 #if !defined(__has_attribute) 95 #define __has_attribute(x) 0 96 #endif /* if !defined(__has_attribute) */ 97 98 #if __GNUC__ >= 7 || __has_attribute(fallthrough) 99 #define FALLTHROUGH __attribute__((fallthrough)) 100 #else 101 /* clang-format off */ 102 #define FALLTHROUGH do {} while (0) /* FALLTHROUGH */ 103 /* clang-format on */ 104 #endif 105 106 #ifdef __GNUC__ 107 #define UNREACHABLE() __builtin_unreachable() 108 #else 109 #define UNREACHABLE() abort() 110 #endif 111 112 /* opaque structures */ 113 typedef void *dns_sdlzlookup_t; 114 typedef void *dns_sdlzallnodes_t; 115 typedef void *dns_view_t; 116 typedef void *dns_dlzdb_t; 117 118 #if DLZ_DLOPEN_VERSION > 1 119 /* 120 * Method and type definitions needed for retrieval of client info 121 * from the caller. 122 */ 123 typedef struct isc_sockaddr { 124 union { 125 struct sockaddr sa; 126 struct sockaddr_in sin; 127 struct sockaddr_in6 sin6; 128 #ifdef ISC_PLATFORM_HAVESYSUNH 129 struct sockaddr_un sunix; 130 #endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ 131 } type; 132 unsigned int length; 133 void *link; 134 } isc_sockaddr_t; 135 136 typedef struct isc_netaddr { 137 unsigned int family; 138 union { 139 struct in_addr in; 140 struct in6_addr in6; 141 #ifdef ISC_PLATFORM_HAVESYSUNH 142 char un[sizeof(((struct sockaddr_un *)0)->sun_path)]; 143 #endif /* ifdef ISC_PLATFORM_HAVESYSUNH */ 144 } type; 145 uint32_t zone; 146 } isc_netaddr_t; 147 148 typedef struct dns_ecs { 149 isc_netaddr_t addr; 150 uint8_t source; 151 uint8_t scope; 152 } dns_ecs_t; 153 154 #define DNS_CLIENTINFO_VERSION 3 155 typedef struct dns_clientinfo { 156 uint16_t version; 157 void *data; 158 void *dbversion; 159 dns_ecs_t ecs; 160 } dns_clientinfo_t; 161 162 typedef isc_result_t (*dns_clientinfo_sourceip_t)(dns_clientinfo_t *client, 163 isc_sockaddr_t **addrp); 164 165 typedef isc_result_t (*dns_clientinfo_version_t)(dns_clientinfo_t *client, 166 void **addrp); 167 168 #define DNS_CLIENTINFOMETHODS_VERSION 2 169 #define DNS_CLIENTINFOMETHODS_AGE 1 170 typedef struct dns_clientinfomethods { 171 uint16_t version; 172 uint16_t age; 173 dns_clientinfo_sourceip_t sourceip; 174 } dns_clientinfomethods_t; 175 #endif /* DLZ_DLOPEN_VERSION > 1 */ 176 177 #define DNS_ECS_FORMATSIZE \ 178 sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS" \ 179 "/NNN/NNN") 180 181 /* 182 * Method definitions for callbacks provided by the dlopen driver 183 */ 184 typedef void 185 log_t(int level, const char *fmt, ...); 186 187 typedef isc_result_t 188 dns_sdlz_putrr_t(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl, 189 const char *data); 190 191 typedef isc_result_t 192 dns_sdlz_putnamedrr_t(dns_sdlzallnodes_t *allnodes, const char *name, 193 const char *type, dns_ttl_t ttl, const char *data); 194 195 #if DLZ_DLOPEN_VERSION < 3 196 typedef isc_result_t 197 dns_dlz_writeablezone_t(dns_view_t *view, const char *zone_name); 198 #else /* DLZ_DLOPEN_VERSION >= 3 */ 199 typedef isc_result_t 200 dns_dlz_writeablezone_t(dns_view_t *view, dns_dlzdb_t *dlzdb, 201 const char *zone_name); 202 #endif /* DLZ_DLOPEN_VERSION */ 203 204 /* 205 * prototypes for the functions you can include in your module 206 */ 207 208 /* 209 * dlz_version() is required for all DLZ external drivers. It should 210 * return DLZ_DLOPEN_VERSION. 'flags' is updated to indicate capabilities 211 * of the module. In particular, if the module is thread-safe then it 212 * sets 'flags' to include DNS_SDLZFLAG_THREADSAFE. Other capability 213 * flags may be added in the future. 214 */ 215 int 216 dlz_version(unsigned int *flags); 217 218 /* 219 * dlz_create() is required for all DLZ external drivers. 220 */ 221 isc_result_t 222 dlz_create(const char *dlzname, unsigned int argc, char *argv[], void **dbdata, 223 ...); 224 225 /* 226 * dlz_destroy() is optional, and will be called when the driver is 227 * unloaded if supplied 228 */ 229 void 230 dlz_destroy(void *dbdata); 231 232 /* 233 * dlz_findzonedb is required for all DLZ external drivers 234 */ 235 #if DLZ_DLOPEN_VERSION < 3 236 isc_result_t 237 dlz_findzonedb(void *dbdata, const char *name); 238 #else /* DLZ_DLOPEN_VERSION >= 3 */ 239 isc_result_t 240 dlz_findzonedb(void *dbdata, const char *name, dns_clientinfomethods_t *methods, 241 dns_clientinfo_t *clientinfo); 242 #endif /* DLZ_DLOPEN_VERSION */ 243 244 /* 245 * dlz_lookup is required for all DLZ external drivers 246 */ 247 #if DLZ_DLOPEN_VERSION == 1 248 isc_result_t 249 dlz_lookup(const char *zone, const char *name, void *dbdata, 250 dns_sdlzlookup_t *lookup); 251 #else /* DLZ_DLOPEN_VERSION > 1 */ 252 isc_result_t 253 dlz_lookup(const char *zone, const char *name, void *dbdata, 254 dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, 255 dns_clientinfo_t *clientinfo); 256 #endif /* DLZ_DLOPEN_VERSION */ 257 258 /* 259 * dlz_authority() is optional if dlz_lookup() supplies 260 * authority information (i.e., SOA, NS) for the dns record 261 */ 262 isc_result_t 263 dlz_authority(const char *zone, void *dbdata, dns_sdlzlookup_t *lookup); 264 265 /* 266 * dlz_allowzonexfr() is optional, and should be supplied if you want to 267 * support zone transfers 268 */ 269 isc_result_t 270 dlz_allowzonexfr(void *dbdata, const char *name, const char *client); 271 272 /* 273 * dlz_allnodes() is optional, but must be supplied if supply a 274 * dlz_allowzonexfr() function 275 */ 276 isc_result_t 277 dlz_allnodes(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes); 278 279 /* 280 * dlz_newversion() is optional. It should be supplied if you want to 281 * support dynamic updates. 282 */ 283 isc_result_t 284 dlz_newversion(const char *zone, void *dbdata, void **versionp); 285 286 /* 287 * dlz_closeversion() is optional, but must be supplied if you supply a 288 * dlz_newversion() function 289 */ 290 void 291 dlz_closeversion(const char *zone, bool commit, void *dbdata, void **versionp); 292 293 /* 294 * dlz_configure() is optional, but must be supplied if you want to support 295 * dynamic updates 296 */ 297 #if DLZ_DLOPEN_VERSION < 3 298 isc_result_t 299 dlz_configure(dns_view_t *view, void *dbdata); 300 #else /* DLZ_DLOPEN_VERSION >= 3 */ 301 isc_result_t 302 dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb, void *dbdata); 303 #endif /* DLZ_DLOPEN_VERSION */ 304 305 /* 306 * dlz_ssumatch() is optional, but must be supplied if you want to support 307 * dynamic updates 308 */ 309 bool 310 dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, 311 const char *type, const char *key, uint32_t keydatalen, 312 uint8_t *keydata, void *dbdata); 313 314 /* 315 * dlz_addrdataset() is optional, but must be supplied if you want to 316 * support dynamic updates 317 */ 318 isc_result_t 319 dlz_addrdataset(const char *name, const char *rdatastr, void *dbdata, 320 void *version); 321 322 /* 323 * dlz_subrdataset() is optional, but must be supplied if you want to 324 * support dynamic updates 325 */ 326 isc_result_t 327 dlz_subrdataset(const char *name, const char *rdatastr, void *dbdata, 328 void *version); 329 330 /* 331 * dlz_delrdataset() is optional, but must be supplied if you want to 332 * support dynamic updates 333 */ 334 isc_result_t 335 dlz_delrdataset(const char *name, const char *type, void *dbdata, 336 void *version); 337 338 #endif /* DLZ_MINIMAL_H */ 339