1 1.1 christos /* $NetBSD: peer.c,v 1.1 2024/02/18 20:57:33 christos Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 1.1 christos * 6 1.1 christos * SPDX-License-Identifier: MPL-2.0 7 1.1 christos * 8 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public 9 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this 10 1.1 christos * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 1.1 christos * 12 1.1 christos * See the COPYRIGHT file distributed with this work for additional 13 1.1 christos * information regarding copyright ownership. 14 1.1 christos */ 15 1.1 christos 16 1.1 christos /*! \file */ 17 1.1 christos 18 1.1 christos #include <inttypes.h> 19 1.1 christos #include <stdbool.h> 20 1.1 christos 21 1.1 christos #include <isc/mem.h> 22 1.1 christos #include <isc/sockaddr.h> 23 1.1 christos #include <isc/string.h> 24 1.1 christos #include <isc/util.h> 25 1.1 christos 26 1.1 christos #include <dns/bit.h> 27 1.1 christos #include <dns/fixedname.h> 28 1.1 christos #include <dns/name.h> 29 1.1 christos #include <dns/peer.h> 30 1.1 christos 31 1.1 christos /*% 32 1.1 christos * Bit positions in the dns_peer_t structure flags field 33 1.1 christos */ 34 1.1 christos #define BOGUS_BIT 0 35 1.1 christos #define SERVER_TRANSFER_FORMAT_BIT 1 36 1.1 christos #define TRANSFERS_BIT 2 37 1.1 christos #define PROVIDE_IXFR_BIT 3 38 1.1 christos #define REQUEST_IXFR_BIT 4 39 1.1 christos #define SUPPORT_EDNS_BIT 5 40 1.1 christos #define SERVER_UDPSIZE_BIT 6 41 1.1 christos #define SERVER_MAXUDP_BIT 7 42 1.1 christos #define REQUEST_NSID_BIT 8 43 1.1 christos #define SEND_COOKIE_BIT 9 44 1.1 christos #define NOTIFY_DSCP_BIT 10 45 1.1 christos #define TRANSFER_DSCP_BIT 11 46 1.1 christos #define QUERY_DSCP_BIT 12 47 1.1 christos #define REQUEST_EXPIRE_BIT 13 48 1.1 christos #define EDNS_VERSION_BIT 14 49 1.1 christos #define FORCE_TCP_BIT 15 50 1.1 christos #define SERVER_PADDING_BIT 16 51 1.1 christos #define REQUEST_TCP_KEEPALIVE_BIT 17 52 1.1 christos 53 1.1 christos static void 54 1.1 christos peerlist_delete(dns_peerlist_t **list); 55 1.1 christos 56 1.1 christos static void 57 1.1 christos peer_delete(dns_peer_t **peer); 58 1.1 christos 59 1.1 christos isc_result_t 60 1.1 christos dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) { 61 1.1 christos dns_peerlist_t *l; 62 1.1 christos 63 1.1 christos REQUIRE(list != NULL); 64 1.1 christos 65 1.1 christos l = isc_mem_get(mem, sizeof(*l)); 66 1.1 christos 67 1.1 christos ISC_LIST_INIT(l->elements); 68 1.1 christos l->mem = mem; 69 1.1 christos isc_refcount_init(&l->refs, 1); 70 1.1 christos l->magic = DNS_PEERLIST_MAGIC; 71 1.1 christos 72 1.1 christos *list = l; 73 1.1 christos 74 1.1 christos return (ISC_R_SUCCESS); 75 1.1 christos } 76 1.1 christos 77 1.1 christos void 78 1.1 christos dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) { 79 1.1 christos REQUIRE(DNS_PEERLIST_VALID(source)); 80 1.1 christos REQUIRE(target != NULL); 81 1.1 christos REQUIRE(*target == NULL); 82 1.1 christos 83 1.1 christos isc_refcount_increment(&source->refs); 84 1.1 christos 85 1.1 christos *target = source; 86 1.1 christos } 87 1.1 christos 88 1.1 christos void 89 1.1 christos dns_peerlist_detach(dns_peerlist_t **list) { 90 1.1 christos dns_peerlist_t *plist; 91 1.1 christos 92 1.1 christos REQUIRE(list != NULL); 93 1.1 christos REQUIRE(*list != NULL); 94 1.1 christos REQUIRE(DNS_PEERLIST_VALID(*list)); 95 1.1 christos 96 1.1 christos plist = *list; 97 1.1 christos *list = NULL; 98 1.1 christos 99 1.1 christos if (isc_refcount_decrement(&plist->refs) == 1) { 100 1.1 christos peerlist_delete(&plist); 101 1.1 christos } 102 1.1 christos } 103 1.1 christos 104 1.1 christos static void 105 1.1 christos peerlist_delete(dns_peerlist_t **list) { 106 1.1 christos dns_peerlist_t *l; 107 1.1 christos dns_peer_t *server, *stmp; 108 1.1 christos 109 1.1 christos REQUIRE(list != NULL); 110 1.1 christos REQUIRE(DNS_PEERLIST_VALID(*list)); 111 1.1 christos 112 1.1 christos l = *list; 113 1.1 christos *list = NULL; 114 1.1 christos 115 1.1 christos isc_refcount_destroy(&l->refs); 116 1.1 christos 117 1.1 christos server = ISC_LIST_HEAD(l->elements); 118 1.1 christos while (server != NULL) { 119 1.1 christos stmp = ISC_LIST_NEXT(server, next); 120 1.1 christos ISC_LIST_UNLINK(l->elements, server, next); 121 1.1 christos dns_peer_detach(&server); 122 1.1 christos server = stmp; 123 1.1 christos } 124 1.1 christos 125 1.1 christos l->magic = 0; 126 1.1 christos isc_mem_put(l->mem, l, sizeof(*l)); 127 1.1 christos } 128 1.1 christos 129 1.1 christos void 130 1.1 christos dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer) { 131 1.1 christos dns_peer_t *p = NULL; 132 1.1 christos 133 1.1 christos dns_peer_attach(peer, &p); 134 1.1 christos 135 1.1 christos /* 136 1.1 christos * More specifics to front of list. 137 1.1 christos */ 138 1.1 christos for (p = ISC_LIST_HEAD(peers->elements); p != NULL; 139 1.1 christos p = ISC_LIST_NEXT(p, next)) 140 1.1 christos { 141 1.1 christos if (p->prefixlen < peer->prefixlen) { 142 1.1 christos break; 143 1.1 christos } 144 1.1 christos } 145 1.1 christos 146 1.1 christos if (p != NULL) { 147 1.1 christos ISC_LIST_INSERTBEFORE(peers->elements, p, peer, next); 148 1.1 christos } else { 149 1.1 christos ISC_LIST_APPEND(peers->elements, peer, next); 150 1.1 christos } 151 1.1 christos } 152 1.1 christos 153 1.1 christos isc_result_t 154 1.1 christos dns_peerlist_peerbyaddr(dns_peerlist_t *servers, const isc_netaddr_t *addr, 155 1.1 christos dns_peer_t **retval) { 156 1.1 christos dns_peer_t *server; 157 1.1 christos isc_result_t res; 158 1.1 christos 159 1.1 christos REQUIRE(retval != NULL); 160 1.1 christos REQUIRE(DNS_PEERLIST_VALID(servers)); 161 1.1 christos 162 1.1 christos server = ISC_LIST_HEAD(servers->elements); 163 1.1 christos while (server != NULL) { 164 1.1 christos if (isc_netaddr_eqprefix(addr, &server->address, 165 1.1 christos server->prefixlen)) 166 1.1 christos { 167 1.1 christos break; 168 1.1 christos } 169 1.1 christos 170 1.1 christos server = ISC_LIST_NEXT(server, next); 171 1.1 christos } 172 1.1 christos 173 1.1 christos if (server != NULL) { 174 1.1 christos *retval = server; 175 1.1 christos res = ISC_R_SUCCESS; 176 1.1 christos } else { 177 1.1 christos res = ISC_R_NOTFOUND; 178 1.1 christos } 179 1.1 christos 180 1.1 christos return (res); 181 1.1 christos } 182 1.1 christos 183 1.1 christos isc_result_t 184 1.1 christos dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval) { 185 1.1 christos dns_peer_t *p = NULL; 186 1.1 christos 187 1.1 christos p = ISC_LIST_TAIL(peers->elements); 188 1.1 christos 189 1.1 christos dns_peer_attach(p, retval); 190 1.1 christos 191 1.1 christos return (ISC_R_SUCCESS); 192 1.1 christos } 193 1.1 christos 194 1.1 christos isc_result_t 195 1.1 christos dns_peer_new(isc_mem_t *mem, const isc_netaddr_t *addr, dns_peer_t **peerptr) { 196 1.1 christos unsigned int prefixlen = 0; 197 1.1 christos 198 1.1 christos REQUIRE(peerptr != NULL); 199 1.1 christos switch (addr->family) { 200 1.1 christos case AF_INET: 201 1.1 christos prefixlen = 32; 202 1.1 christos break; 203 1.1 christos case AF_INET6: 204 1.1 christos prefixlen = 128; 205 1.1 christos break; 206 1.1 christos default: 207 1.1 christos UNREACHABLE(); 208 1.1 christos } 209 1.1 christos 210 1.1 christos return (dns_peer_newprefix(mem, addr, prefixlen, peerptr)); 211 1.1 christos } 212 1.1 christos 213 1.1 christos isc_result_t 214 1.1 christos dns_peer_newprefix(isc_mem_t *mem, const isc_netaddr_t *addr, 215 1.1 christos unsigned int prefixlen, dns_peer_t **peerptr) { 216 1.1 christos dns_peer_t *peer; 217 1.1 christos 218 1.1 christos REQUIRE(peerptr != NULL && *peerptr == NULL); 219 1.1 christos 220 1.1 christos peer = isc_mem_get(mem, sizeof(*peer)); 221 1.1 christos 222 1.1 christos *peer = (dns_peer_t){ 223 1.1 christos .magic = DNS_PEER_MAGIC, 224 1.1 christos .address = *addr, 225 1.1 christos .prefixlen = prefixlen, 226 1.1 christos .mem = mem, 227 1.1 christos .transfer_format = dns_one_answer, 228 1.1 christos }; 229 1.1 christos 230 1.1 christos isc_refcount_init(&peer->refs, 1); 231 1.1 christos 232 1.1 christos ISC_LINK_INIT(peer, next); 233 1.1 christos 234 1.1 christos *peerptr = peer; 235 1.1 christos 236 1.1 christos return (ISC_R_SUCCESS); 237 1.1 christos } 238 1.1 christos 239 1.1 christos void 240 1.1 christos dns_peer_attach(dns_peer_t *source, dns_peer_t **target) { 241 1.1 christos REQUIRE(DNS_PEER_VALID(source)); 242 1.1 christos REQUIRE(target != NULL); 243 1.1 christos REQUIRE(*target == NULL); 244 1.1 christos 245 1.1 christos isc_refcount_increment(&source->refs); 246 1.1 christos 247 1.1 christos *target = source; 248 1.1 christos } 249 1.1 christos 250 1.1 christos void 251 1.1 christos dns_peer_detach(dns_peer_t **peer) { 252 1.1 christos dns_peer_t *p; 253 1.1 christos 254 1.1 christos REQUIRE(peer != NULL); 255 1.1 christos REQUIRE(*peer != NULL); 256 1.1 christos REQUIRE(DNS_PEER_VALID(*peer)); 257 1.1 christos 258 1.1 christos p = *peer; 259 1.1 christos *peer = NULL; 260 1.1 christos 261 1.1 christos if (isc_refcount_decrement(&p->refs) == 1) { 262 1.1 christos peer_delete(&p); 263 1.1 christos } 264 1.1 christos } 265 1.1 christos 266 1.1 christos static void 267 1.1 christos peer_delete(dns_peer_t **peer) { 268 1.1 christos dns_peer_t *p; 269 1.1 christos isc_mem_t *mem; 270 1.1 christos 271 1.1 christos REQUIRE(peer != NULL); 272 1.1 christos REQUIRE(DNS_PEER_VALID(*peer)); 273 1.1 christos 274 1.1 christos p = *peer; 275 1.1 christos *peer = NULL; 276 1.1 christos 277 1.1 christos isc_refcount_destroy(&p->refs); 278 1.1 christos 279 1.1 christos mem = p->mem; 280 1.1 christos p->mem = NULL; 281 1.1 christos p->magic = 0; 282 1.1 christos 283 1.1 christos if (p->key != NULL) { 284 1.1 christos dns_name_free(p->key, mem); 285 1.1 christos isc_mem_put(mem, p->key, sizeof(dns_name_t)); 286 1.1 christos } 287 1.1 christos 288 1.1 christos if (p->query_source != NULL) { 289 1.1 christos isc_mem_put(mem, p->query_source, sizeof(*p->query_source)); 290 1.1 christos } 291 1.1 christos 292 1.1 christos if (p->notify_source != NULL) { 293 1.1 christos isc_mem_put(mem, p->notify_source, sizeof(*p->notify_source)); 294 1.1 christos } 295 1.1 christos 296 1.1 christos if (p->transfer_source != NULL) { 297 1.1 christos isc_mem_put(mem, p->transfer_source, 298 1.1 christos sizeof(*p->transfer_source)); 299 1.1 christos } 300 1.1 christos 301 1.1 christos isc_mem_put(mem, p, sizeof(*p)); 302 1.1 christos } 303 1.1 christos 304 1.1 christos isc_result_t 305 1.1 christos dns_peer_setbogus(dns_peer_t *peer, bool newval) { 306 1.1 christos bool existed; 307 1.1 christos 308 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 309 1.1 christos 310 1.1 christos existed = DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags); 311 1.1 christos 312 1.1 christos peer->bogus = newval; 313 1.1 christos DNS_BIT_SET(BOGUS_BIT, &peer->bitflags); 314 1.1 christos 315 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 316 1.1 christos } 317 1.1 christos 318 1.1 christos isc_result_t 319 1.1 christos dns_peer_getbogus(dns_peer_t *peer, bool *retval) { 320 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 321 1.1 christos REQUIRE(retval != NULL); 322 1.1 christos 323 1.1 christos if (DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags)) { 324 1.1 christos *retval = peer->bogus; 325 1.1 christos return (ISC_R_SUCCESS); 326 1.1 christos } else { 327 1.1 christos return (ISC_R_NOTFOUND); 328 1.1 christos } 329 1.1 christos } 330 1.1 christos 331 1.1 christos isc_result_t 332 1.1 christos dns_peer_setprovideixfr(dns_peer_t *peer, bool newval) { 333 1.1 christos bool existed; 334 1.1 christos 335 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 336 1.1 christos 337 1.1 christos existed = DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags); 338 1.1 christos 339 1.1 christos peer->provide_ixfr = newval; 340 1.1 christos DNS_BIT_SET(PROVIDE_IXFR_BIT, &peer->bitflags); 341 1.1 christos 342 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 343 1.1 christos } 344 1.1 christos 345 1.1 christos isc_result_t 346 1.1 christos dns_peer_getprovideixfr(dns_peer_t *peer, bool *retval) { 347 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 348 1.1 christos REQUIRE(retval != NULL); 349 1.1 christos 350 1.1 christos if (DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags)) { 351 1.1 christos *retval = peer->provide_ixfr; 352 1.1 christos return (ISC_R_SUCCESS); 353 1.1 christos } else { 354 1.1 christos return (ISC_R_NOTFOUND); 355 1.1 christos } 356 1.1 christos } 357 1.1 christos 358 1.1 christos isc_result_t 359 1.1 christos dns_peer_setrequestixfr(dns_peer_t *peer, bool newval) { 360 1.1 christos bool existed; 361 1.1 christos 362 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 363 1.1 christos 364 1.1 christos existed = DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags); 365 1.1 christos 366 1.1 christos peer->request_ixfr = newval; 367 1.1 christos DNS_BIT_SET(REQUEST_IXFR_BIT, &peer->bitflags); 368 1.1 christos 369 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 370 1.1 christos } 371 1.1 christos 372 1.1 christos isc_result_t 373 1.1 christos dns_peer_getrequestixfr(dns_peer_t *peer, bool *retval) { 374 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 375 1.1 christos REQUIRE(retval != NULL); 376 1.1 christos 377 1.1 christos if (DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags)) { 378 1.1 christos *retval = peer->request_ixfr; 379 1.1 christos return (ISC_R_SUCCESS); 380 1.1 christos } else { 381 1.1 christos return (ISC_R_NOTFOUND); 382 1.1 christos } 383 1.1 christos } 384 1.1 christos 385 1.1 christos isc_result_t 386 1.1 christos dns_peer_setsupportedns(dns_peer_t *peer, bool newval) { 387 1.1 christos bool existed; 388 1.1 christos 389 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 390 1.1 christos 391 1.1 christos existed = DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags); 392 1.1 christos 393 1.1 christos peer->support_edns = newval; 394 1.1 christos DNS_BIT_SET(SUPPORT_EDNS_BIT, &peer->bitflags); 395 1.1 christos 396 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 397 1.1 christos } 398 1.1 christos 399 1.1 christos isc_result_t 400 1.1 christos dns_peer_getsupportedns(dns_peer_t *peer, bool *retval) { 401 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 402 1.1 christos REQUIRE(retval != NULL); 403 1.1 christos 404 1.1 christos if (DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags)) { 405 1.1 christos *retval = peer->support_edns; 406 1.1 christos return (ISC_R_SUCCESS); 407 1.1 christos } else { 408 1.1 christos return (ISC_R_NOTFOUND); 409 1.1 christos } 410 1.1 christos } 411 1.1 christos 412 1.1 christos isc_result_t 413 1.1 christos dns_peer_setrequestnsid(dns_peer_t *peer, bool newval) { 414 1.1 christos bool existed; 415 1.1 christos 416 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 417 1.1 christos 418 1.1 christos existed = DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags); 419 1.1 christos 420 1.1 christos peer->request_nsid = newval; 421 1.1 christos DNS_BIT_SET(REQUEST_NSID_BIT, &peer->bitflags); 422 1.1 christos 423 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 424 1.1 christos } 425 1.1 christos 426 1.1 christos isc_result_t 427 1.1 christos dns_peer_getrequestnsid(dns_peer_t *peer, bool *retval) { 428 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 429 1.1 christos REQUIRE(retval != NULL); 430 1.1 christos 431 1.1 christos if (DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags)) { 432 1.1 christos *retval = peer->request_nsid; 433 1.1 christos return (ISC_R_SUCCESS); 434 1.1 christos } else { 435 1.1 christos return (ISC_R_NOTFOUND); 436 1.1 christos } 437 1.1 christos } 438 1.1 christos 439 1.1 christos isc_result_t 440 1.1 christos dns_peer_setsendcookie(dns_peer_t *peer, bool newval) { 441 1.1 christos bool existed; 442 1.1 christos 443 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 444 1.1 christos 445 1.1 christos existed = DNS_BIT_CHECK(SEND_COOKIE_BIT, &peer->bitflags); 446 1.1 christos 447 1.1 christos peer->send_cookie = newval; 448 1.1 christos DNS_BIT_SET(SEND_COOKIE_BIT, &peer->bitflags); 449 1.1 christos 450 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 451 1.1 christos } 452 1.1 christos 453 1.1 christos isc_result_t 454 1.1 christos dns_peer_getsendcookie(dns_peer_t *peer, bool *retval) { 455 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 456 1.1 christos REQUIRE(retval != NULL); 457 1.1 christos 458 1.1 christos if (DNS_BIT_CHECK(SEND_COOKIE_BIT, &peer->bitflags)) { 459 1.1 christos *retval = peer->send_cookie; 460 1.1 christos return (ISC_R_SUCCESS); 461 1.1 christos } else { 462 1.1 christos return (ISC_R_NOTFOUND); 463 1.1 christos } 464 1.1 christos } 465 1.1 christos 466 1.1 christos isc_result_t 467 1.1 christos dns_peer_setrequestexpire(dns_peer_t *peer, bool newval) { 468 1.1 christos bool existed; 469 1.1 christos 470 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 471 1.1 christos 472 1.1 christos existed = DNS_BIT_CHECK(REQUEST_EXPIRE_BIT, &peer->bitflags); 473 1.1 christos 474 1.1 christos peer->request_expire = newval; 475 1.1 christos DNS_BIT_SET(REQUEST_EXPIRE_BIT, &peer->bitflags); 476 1.1 christos 477 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 478 1.1 christos } 479 1.1 christos 480 1.1 christos isc_result_t 481 1.1 christos dns_peer_getrequestexpire(dns_peer_t *peer, bool *retval) { 482 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 483 1.1 christos REQUIRE(retval != NULL); 484 1.1 christos 485 1.1 christos if (DNS_BIT_CHECK(REQUEST_EXPIRE_BIT, &peer->bitflags)) { 486 1.1 christos *retval = peer->request_expire; 487 1.1 christos return (ISC_R_SUCCESS); 488 1.1 christos } else { 489 1.1 christos return (ISC_R_NOTFOUND); 490 1.1 christos } 491 1.1 christos } 492 1.1 christos 493 1.1 christos isc_result_t 494 1.1 christos dns_peer_setforcetcp(dns_peer_t *peer, bool newval) { 495 1.1 christos bool existed; 496 1.1 christos 497 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 498 1.1 christos 499 1.1 christos existed = DNS_BIT_CHECK(FORCE_TCP_BIT, &peer->bitflags); 500 1.1 christos 501 1.1 christos peer->force_tcp = newval; 502 1.1 christos DNS_BIT_SET(FORCE_TCP_BIT, &peer->bitflags); 503 1.1 christos 504 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 505 1.1 christos } 506 1.1 christos 507 1.1 christos isc_result_t 508 1.1 christos dns_peer_getforcetcp(dns_peer_t *peer, bool *retval) { 509 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 510 1.1 christos REQUIRE(retval != NULL); 511 1.1 christos 512 1.1 christos if (DNS_BIT_CHECK(FORCE_TCP_BIT, &peer->bitflags)) { 513 1.1 christos *retval = peer->force_tcp; 514 1.1 christos return (ISC_R_SUCCESS); 515 1.1 christos } else { 516 1.1 christos return (ISC_R_NOTFOUND); 517 1.1 christos } 518 1.1 christos } 519 1.1 christos 520 1.1 christos isc_result_t 521 1.1 christos dns_peer_settcpkeepalive(dns_peer_t *peer, bool newval) { 522 1.1 christos bool existed; 523 1.1 christos 524 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 525 1.1 christos 526 1.1 christos existed = DNS_BIT_CHECK(REQUEST_TCP_KEEPALIVE_BIT, &peer->bitflags); 527 1.1 christos 528 1.1 christos peer->tcp_keepalive = newval; 529 1.1 christos DNS_BIT_SET(REQUEST_TCP_KEEPALIVE_BIT, &peer->bitflags); 530 1.1 christos 531 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 532 1.1 christos } 533 1.1 christos 534 1.1 christos isc_result_t 535 1.1 christos dns_peer_gettcpkeepalive(dns_peer_t *peer, bool *retval) { 536 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 537 1.1 christos REQUIRE(retval != NULL); 538 1.1 christos 539 1.1 christos if (DNS_BIT_CHECK(REQUEST_TCP_KEEPALIVE_BIT, &peer->bitflags)) { 540 1.1 christos *retval = peer->tcp_keepalive; 541 1.1 christos return (ISC_R_SUCCESS); 542 1.1 christos } else { 543 1.1 christos return (ISC_R_NOTFOUND); 544 1.1 christos } 545 1.1 christos } 546 1.1 christos 547 1.1 christos isc_result_t 548 1.1 christos dns_peer_settransfers(dns_peer_t *peer, uint32_t newval) { 549 1.1 christos bool existed; 550 1.1 christos 551 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 552 1.1 christos 553 1.1 christos existed = DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags); 554 1.1 christos 555 1.1 christos peer->transfers = newval; 556 1.1 christos DNS_BIT_SET(TRANSFERS_BIT, &peer->bitflags); 557 1.1 christos 558 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 559 1.1 christos } 560 1.1 christos 561 1.1 christos isc_result_t 562 1.1 christos dns_peer_gettransfers(dns_peer_t *peer, uint32_t *retval) { 563 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 564 1.1 christos REQUIRE(retval != NULL); 565 1.1 christos 566 1.1 christos if (DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags)) { 567 1.1 christos *retval = peer->transfers; 568 1.1 christos return (ISC_R_SUCCESS); 569 1.1 christos } else { 570 1.1 christos return (ISC_R_NOTFOUND); 571 1.1 christos } 572 1.1 christos } 573 1.1 christos 574 1.1 christos isc_result_t 575 1.1 christos dns_peer_settransferformat(dns_peer_t *peer, dns_transfer_format_t newval) { 576 1.1 christos bool existed; 577 1.1 christos 578 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 579 1.1 christos 580 1.1 christos existed = DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags); 581 1.1 christos 582 1.1 christos peer->transfer_format = newval; 583 1.1 christos DNS_BIT_SET(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags); 584 1.1 christos 585 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 586 1.1 christos } 587 1.1 christos 588 1.1 christos isc_result_t 589 1.1 christos dns_peer_gettransferformat(dns_peer_t *peer, dns_transfer_format_t *retval) { 590 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 591 1.1 christos REQUIRE(retval != NULL); 592 1.1 christos 593 1.1 christos if (DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags)) { 594 1.1 christos *retval = peer->transfer_format; 595 1.1 christos return (ISC_R_SUCCESS); 596 1.1 christos } else { 597 1.1 christos return (ISC_R_NOTFOUND); 598 1.1 christos } 599 1.1 christos } 600 1.1 christos 601 1.1 christos isc_result_t 602 1.1 christos dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval) { 603 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 604 1.1 christos REQUIRE(retval != NULL); 605 1.1 christos 606 1.1 christos if (peer->key != NULL) { 607 1.1 christos *retval = peer->key; 608 1.1 christos } 609 1.1 christos 610 1.1 christos return (peer->key == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS); 611 1.1 christos } 612 1.1 christos 613 1.1 christos isc_result_t 614 1.1 christos dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval) { 615 1.1 christos bool exists = false; 616 1.1 christos 617 1.1 christos if (peer->key != NULL) { 618 1.1 christos dns_name_free(peer->key, peer->mem); 619 1.1 christos isc_mem_put(peer->mem, peer->key, sizeof(dns_name_t)); 620 1.1 christos exists = true; 621 1.1 christos } 622 1.1 christos 623 1.1 christos peer->key = *keyval; 624 1.1 christos *keyval = NULL; 625 1.1 christos 626 1.1 christos return (exists ? ISC_R_EXISTS : ISC_R_SUCCESS); 627 1.1 christos } 628 1.1 christos 629 1.1 christos isc_result_t 630 1.1 christos dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) { 631 1.1 christos isc_buffer_t b; 632 1.1 christos dns_fixedname_t fname; 633 1.1 christos dns_name_t *name; 634 1.1 christos isc_result_t result; 635 1.1 christos 636 1.1 christos dns_fixedname_init(&fname); 637 1.1 christos isc_buffer_constinit(&b, keyval, strlen(keyval)); 638 1.1 christos isc_buffer_add(&b, strlen(keyval)); 639 1.1 christos result = dns_name_fromtext(dns_fixedname_name(&fname), &b, dns_rootname, 640 1.1 christos 0, NULL); 641 1.1 christos if (result != ISC_R_SUCCESS) { 642 1.1 christos return (result); 643 1.1 christos } 644 1.1 christos 645 1.1 christos name = isc_mem_get(peer->mem, sizeof(dns_name_t)); 646 1.1 christos 647 1.1 christos dns_name_init(name, NULL); 648 1.1 christos dns_name_dup(dns_fixedname_name(&fname), peer->mem, name); 649 1.1 christos 650 1.1 christos result = dns_peer_setkey(peer, &name); 651 1.1 christos if (result != ISC_R_SUCCESS) { 652 1.1 christos isc_mem_put(peer->mem, name, sizeof(dns_name_t)); 653 1.1 christos } 654 1.1 christos 655 1.1 christos return (result); 656 1.1 christos } 657 1.1 christos 658 1.1 christos isc_result_t 659 1.1 christos dns_peer_settransfersource(dns_peer_t *peer, 660 1.1 christos const isc_sockaddr_t *transfer_source) { 661 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 662 1.1 christos 663 1.1 christos if (peer->transfer_source != NULL) { 664 1.1 christos isc_mem_put(peer->mem, peer->transfer_source, 665 1.1 christos sizeof(*peer->transfer_source)); 666 1.1 christos peer->transfer_source = NULL; 667 1.1 christos } 668 1.1 christos if (transfer_source != NULL) { 669 1.1 christos peer->transfer_source = 670 1.1 christos isc_mem_get(peer->mem, sizeof(*peer->transfer_source)); 671 1.1 christos 672 1.1 christos *peer->transfer_source = *transfer_source; 673 1.1 christos } 674 1.1 christos return (ISC_R_SUCCESS); 675 1.1 christos } 676 1.1 christos 677 1.1 christos isc_result_t 678 1.1 christos dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) { 679 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 680 1.1 christos REQUIRE(transfer_source != NULL); 681 1.1 christos 682 1.1 christos if (peer->transfer_source == NULL) { 683 1.1 christos return (ISC_R_NOTFOUND); 684 1.1 christos } 685 1.1 christos *transfer_source = *peer->transfer_source; 686 1.1 christos return (ISC_R_SUCCESS); 687 1.1 christos } 688 1.1 christos 689 1.1 christos isc_result_t 690 1.1 christos dns_peer_setnotifysource(dns_peer_t *peer, 691 1.1 christos const isc_sockaddr_t *notify_source) { 692 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 693 1.1 christos 694 1.1 christos if (peer->notify_source != NULL) { 695 1.1 christos isc_mem_put(peer->mem, peer->notify_source, 696 1.1 christos sizeof(*peer->notify_source)); 697 1.1 christos peer->notify_source = NULL; 698 1.1 christos } 699 1.1 christos if (notify_source != NULL) { 700 1.1 christos peer->notify_source = isc_mem_get(peer->mem, 701 1.1 christos sizeof(*peer->notify_source)); 702 1.1 christos 703 1.1 christos *peer->notify_source = *notify_source; 704 1.1 christos } 705 1.1 christos return (ISC_R_SUCCESS); 706 1.1 christos } 707 1.1 christos 708 1.1 christos isc_result_t 709 1.1 christos dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source) { 710 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 711 1.1 christos REQUIRE(notify_source != NULL); 712 1.1 christos 713 1.1 christos if (peer->notify_source == NULL) { 714 1.1 christos return (ISC_R_NOTFOUND); 715 1.1 christos } 716 1.1 christos *notify_source = *peer->notify_source; 717 1.1 christos return (ISC_R_SUCCESS); 718 1.1 christos } 719 1.1 christos 720 1.1 christos isc_result_t 721 1.1 christos dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source) { 722 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 723 1.1 christos 724 1.1 christos if (peer->query_source != NULL) { 725 1.1 christos isc_mem_put(peer->mem, peer->query_source, 726 1.1 christos sizeof(*peer->query_source)); 727 1.1 christos peer->query_source = NULL; 728 1.1 christos } 729 1.1 christos if (query_source != NULL) { 730 1.1 christos peer->query_source = isc_mem_get(peer->mem, 731 1.1 christos sizeof(*peer->query_source)); 732 1.1 christos 733 1.1 christos *peer->query_source = *query_source; 734 1.1 christos } 735 1.1 christos return (ISC_R_SUCCESS); 736 1.1 christos } 737 1.1 christos 738 1.1 christos isc_result_t 739 1.1 christos dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source) { 740 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 741 1.1 christos REQUIRE(query_source != NULL); 742 1.1 christos 743 1.1 christos if (peer->query_source == NULL) { 744 1.1 christos return (ISC_R_NOTFOUND); 745 1.1 christos } 746 1.1 christos *query_source = *peer->query_source; 747 1.1 christos return (ISC_R_SUCCESS); 748 1.1 christos } 749 1.1 christos 750 1.1 christos isc_result_t 751 1.1 christos dns_peer_setudpsize(dns_peer_t *peer, uint16_t udpsize) { 752 1.1 christos bool existed; 753 1.1 christos 754 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 755 1.1 christos 756 1.1 christos existed = DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags); 757 1.1 christos 758 1.1 christos peer->udpsize = udpsize; 759 1.1 christos DNS_BIT_SET(SERVER_UDPSIZE_BIT, &peer->bitflags); 760 1.1 christos 761 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 762 1.1 christos } 763 1.1 christos 764 1.1 christos isc_result_t 765 1.1 christos dns_peer_getudpsize(dns_peer_t *peer, uint16_t *udpsize) { 766 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 767 1.1 christos REQUIRE(udpsize != NULL); 768 1.1 christos 769 1.1 christos if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags)) { 770 1.1 christos *udpsize = peer->udpsize; 771 1.1 christos return (ISC_R_SUCCESS); 772 1.1 christos } else { 773 1.1 christos return (ISC_R_NOTFOUND); 774 1.1 christos } 775 1.1 christos } 776 1.1 christos 777 1.1 christos isc_result_t 778 1.1 christos dns_peer_setmaxudp(dns_peer_t *peer, uint16_t maxudp) { 779 1.1 christos bool existed; 780 1.1 christos 781 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 782 1.1 christos 783 1.1 christos existed = DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags); 784 1.1 christos 785 1.1 christos peer->maxudp = maxudp; 786 1.1 christos DNS_BIT_SET(SERVER_MAXUDP_BIT, &peer->bitflags); 787 1.1 christos 788 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 789 1.1 christos } 790 1.1 christos 791 1.1 christos isc_result_t 792 1.1 christos dns_peer_getmaxudp(dns_peer_t *peer, uint16_t *maxudp) { 793 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 794 1.1 christos REQUIRE(maxudp != NULL); 795 1.1 christos 796 1.1 christos if (DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags)) { 797 1.1 christos *maxudp = peer->maxudp; 798 1.1 christos return (ISC_R_SUCCESS); 799 1.1 christos } else { 800 1.1 christos return (ISC_R_NOTFOUND); 801 1.1 christos } 802 1.1 christos } 803 1.1 christos 804 1.1 christos isc_result_t 805 1.1 christos dns_peer_setpadding(dns_peer_t *peer, uint16_t padding) { 806 1.1 christos bool existed; 807 1.1 christos 808 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 809 1.1 christos 810 1.1 christos existed = DNS_BIT_CHECK(SERVER_PADDING_BIT, &peer->bitflags); 811 1.1 christos 812 1.1 christos if (padding > 512) { 813 1.1 christos padding = 512; 814 1.1 christos } 815 1.1 christos peer->padding = padding; 816 1.1 christos DNS_BIT_SET(SERVER_PADDING_BIT, &peer->bitflags); 817 1.1 christos 818 1.1 christos return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); 819 1.1 christos } 820 1.1 christos 821 1.1 christos isc_result_t 822 1.1 christos dns_peer_getpadding(dns_peer_t *peer, uint16_t *padding) { 823 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 824 1.1 christos REQUIRE(padding != NULL); 825 1.1 christos 826 1.1 christos if (DNS_BIT_CHECK(SERVER_PADDING_BIT, &peer->bitflags)) { 827 1.1 christos *padding = peer->padding; 828 1.1 christos return (ISC_R_SUCCESS); 829 1.1 christos } else { 830 1.1 christos return (ISC_R_NOTFOUND); 831 1.1 christos } 832 1.1 christos } 833 1.1 christos 834 1.1 christos isc_result_t 835 1.1 christos dns_peer_setnotifydscp(dns_peer_t *peer, isc_dscp_t dscp) { 836 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 837 1.1 christos REQUIRE(dscp < 64); 838 1.1 christos 839 1.1 christos peer->notify_dscp = dscp; 840 1.1 christos DNS_BIT_SET(NOTIFY_DSCP_BIT, &peer->bitflags); 841 1.1 christos return (ISC_R_SUCCESS); 842 1.1 christos } 843 1.1 christos 844 1.1 christos isc_result_t 845 1.1 christos dns_peer_getnotifydscp(dns_peer_t *peer, isc_dscp_t *dscpp) { 846 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 847 1.1 christos REQUIRE(dscpp != NULL); 848 1.1 christos 849 1.1 christos if (DNS_BIT_CHECK(NOTIFY_DSCP_BIT, &peer->bitflags)) { 850 1.1 christos *dscpp = peer->notify_dscp; 851 1.1 christos return (ISC_R_SUCCESS); 852 1.1 christos } 853 1.1 christos return (ISC_R_NOTFOUND); 854 1.1 christos } 855 1.1 christos 856 1.1 christos isc_result_t 857 1.1 christos dns_peer_settransferdscp(dns_peer_t *peer, isc_dscp_t dscp) { 858 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 859 1.1 christos REQUIRE(dscp < 64); 860 1.1 christos 861 1.1 christos peer->transfer_dscp = dscp; 862 1.1 christos DNS_BIT_SET(TRANSFER_DSCP_BIT, &peer->bitflags); 863 1.1 christos return (ISC_R_SUCCESS); 864 1.1 christos } 865 1.1 christos 866 1.1 christos isc_result_t 867 1.1 christos dns_peer_gettransferdscp(dns_peer_t *peer, isc_dscp_t *dscpp) { 868 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 869 1.1 christos REQUIRE(dscpp != NULL); 870 1.1 christos 871 1.1 christos if (DNS_BIT_CHECK(TRANSFER_DSCP_BIT, &peer->bitflags)) { 872 1.1 christos *dscpp = peer->transfer_dscp; 873 1.1 christos return (ISC_R_SUCCESS); 874 1.1 christos } 875 1.1 christos return (ISC_R_NOTFOUND); 876 1.1 christos } 877 1.1 christos 878 1.1 christos isc_result_t 879 1.1 christos dns_peer_setquerydscp(dns_peer_t *peer, isc_dscp_t dscp) { 880 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 881 1.1 christos REQUIRE(dscp < 64); 882 1.1 christos 883 1.1 christos peer->query_dscp = dscp; 884 1.1 christos DNS_BIT_SET(QUERY_DSCP_BIT, &peer->bitflags); 885 1.1 christos return (ISC_R_SUCCESS); 886 1.1 christos } 887 1.1 christos 888 1.1 christos isc_result_t 889 1.1 christos dns_peer_getquerydscp(dns_peer_t *peer, isc_dscp_t *dscpp) { 890 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 891 1.1 christos REQUIRE(dscpp != NULL); 892 1.1 christos 893 1.1 christos if (DNS_BIT_CHECK(QUERY_DSCP_BIT, &peer->bitflags)) { 894 1.1 christos *dscpp = peer->query_dscp; 895 1.1 christos return (ISC_R_SUCCESS); 896 1.1 christos } 897 1.1 christos return (ISC_R_NOTFOUND); 898 1.1 christos } 899 1.1 christos 900 1.1 christos isc_result_t 901 1.1 christos dns_peer_setednsversion(dns_peer_t *peer, uint8_t ednsversion) { 902 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 903 1.1 christos 904 1.1 christos peer->ednsversion = ednsversion; 905 1.1 christos DNS_BIT_SET(EDNS_VERSION_BIT, &peer->bitflags); 906 1.1 christos 907 1.1 christos return (ISC_R_SUCCESS); 908 1.1 christos } 909 1.1 christos 910 1.1 christos isc_result_t 911 1.1 christos dns_peer_getednsversion(dns_peer_t *peer, uint8_t *ednsversion) { 912 1.1 christos REQUIRE(DNS_PEER_VALID(peer)); 913 1.1 christos REQUIRE(ednsversion != NULL); 914 1.1 christos 915 1.1 christos if (DNS_BIT_CHECK(EDNS_VERSION_BIT, &peer->bitflags)) { 916 1.1 christos *ednsversion = peer->ednsversion; 917 1.1 christos return (ISC_R_SUCCESS); 918 1.1 christos } else { 919 1.1 christos return (ISC_R_NOTFOUND); 920 1.1 christos } 921 1.1 christos } 922