1 /* $NetBSD: adb.c,v 1.13 2025/01/26 16:25:21 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <inttypes.h> 19 #include <limits.h> 20 #include <stdbool.h> 21 22 #include <isc/async.h> 23 #include <isc/atomic.h> 24 #include <isc/hash.h> 25 #include <isc/hashmap.h> 26 #include <isc/list.h> 27 #include <isc/loop.h> 28 #include <isc/mutex.h> 29 #include <isc/netaddr.h> 30 #include <isc/random.h> 31 #include <isc/result.h> 32 #include <isc/rwlock.h> 33 #include <isc/stats.h> 34 #include <isc/string.h> 35 #include <isc/tid.h> 36 #include <isc/util.h> 37 38 #include <dns/adb.h> 39 #include <dns/db.h> 40 #include <dns/log.h> 41 #include <dns/rdata.h> 42 #include <dns/rdataset.h> 43 #include <dns/rdatastruct.h> 44 #include <dns/rdatatype.h> 45 #include <dns/resolver.h> 46 #include <dns/stats.h> 47 #include <dns/transport.h> 48 49 #define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b') 50 #define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC) 51 #define DNS_ADBNAME_MAGIC ISC_MAGIC('a', 'd', 'b', 'N') 52 #define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC) 53 #define DNS_ADBNAMEHOOK_MAGIC ISC_MAGIC('a', 'd', 'N', 'H') 54 #define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC) 55 #define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E') 56 #define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC) 57 #define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4') 58 #define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC) 59 #define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6') 60 #define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC) 61 62 /*! 63 * For type 3 negative cache entries, we will remember that the address is 64 * broken for this long. XXXMLG This is also used for actual addresses, too. 65 * The intent is to keep us from constantly asking about A/AAAA records 66 * if the zone has extremely low TTLs. 67 */ 68 #define ADB_CACHE_MINIMUM 10 /*%< seconds */ 69 #define ADB_CACHE_MAXIMUM 86400 /*%< seconds (86400 = 24 hours) */ 70 #define ADB_ENTRY_WINDOW 60 /*%< seconds */ 71 72 #ifndef ADB_HASH_BITS 73 #define ADB_HASH_BITS 12 74 #endif /* ifndef ADB_HASH_BITS */ 75 76 /*% 77 * The period in seconds after which an ADB name entry is regarded as stale 78 * and forced to be cleaned up. 79 * TODO: This should probably be configurable at run-time. 80 */ 81 #ifndef ADB_STALE_MARGIN 82 #define ADB_STALE_MARGIN 1800 83 #endif /* ifndef ADB_STALE_MARGIN */ 84 85 #define DNS_ADB_MINADBSIZE (1024U * 1024U) /*%< 1 Megabyte */ 86 87 typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t; 88 typedef struct dns_adbnamehook dns_adbnamehook_t; 89 typedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t; 90 typedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t; 91 typedef struct dns_adbfetch dns_adbfetch_t; 92 typedef struct dns_adbfetch6 dns_adbfetch6_t; 93 94 /*% dns adb structure */ 95 struct dns_adb { 96 unsigned int magic; 97 98 isc_mutex_t lock; 99 isc_mem_t *mctx; 100 isc_mem_t *hmctx; 101 dns_view_t *view; 102 dns_resolver_t *res; 103 104 isc_refcount_t references; 105 106 dns_adbnamelist_t names_lru; 107 isc_stdtime_t names_last_update; 108 isc_hashmap_t *names; 109 isc_rwlock_t names_lock; 110 111 dns_adbentrylist_t entries_lru; 112 isc_stdtime_t entries_last_update; 113 isc_hashmap_t *entries; 114 isc_rwlock_t entries_lock; 115 116 isc_stats_t *stats; 117 118 atomic_bool exiting; 119 120 uint32_t quota; 121 uint32_t atr_freq; 122 double atr_low; 123 double atr_high; 124 double atr_discount; 125 }; 126 127 /*% 128 * dns_adbname structure: 129 * 130 * This is the structure representing a nameserver name; it can be looked 131 * up via the adb->names hash table. It holds references to fetches 132 * for A and AAAA records while they are ongoing (fetch_a, fetch_aaaa), and 133 * lists of records pointing to address information when the fetches are 134 * complete (v4, v6). 135 */ 136 struct dns_adbname { 137 unsigned int magic; 138 isc_refcount_t references; 139 dns_adb_t *adb; 140 dns_fixedname_t fname; 141 dns_name_t *name; 142 unsigned int partial_result; 143 unsigned int flags; 144 dns_name_t target; 145 isc_stdtime_t expire_target; 146 isc_stdtime_t expire_v4; 147 isc_stdtime_t expire_v6; 148 dns_adbnamehooklist_t v4; 149 dns_adbnamehooklist_t v6; 150 dns_adbfetch_t *fetch_a; 151 dns_adbfetch_t *fetch_aaaa; 152 unsigned int fetch_err; 153 unsigned int fetch6_err; 154 dns_adbfindlist_t finds; 155 isc_mutex_t lock; 156 isc_stdtime_t last_used; 157 /* for LRU-based management */ 158 159 ISC_LINK(dns_adbname_t) link; 160 }; 161 162 #if DNS_ADB_TRACE 163 #define dns_adbname_ref(ptr) dns_adbname__ref(ptr, __func__, __FILE__, __LINE__) 164 #define dns_adbname_unref(ptr) \ 165 dns_adbname__unref(ptr, __func__, __FILE__, __LINE__) 166 #define dns_adbname_attach(ptr, ptrp) \ 167 dns_adbname__attach(ptr, ptrp, __func__, __FILE__, __LINE__) 168 #define dns_adbname_detach(ptrp) \ 169 dns_adbname__detach(ptrp, __func__, __FILE__, __LINE__) 170 ISC_REFCOUNT_TRACE_DECL(dns_adbname); 171 #else 172 ISC_REFCOUNT_DECL(dns_adbname); 173 #endif 174 175 /*% 176 * dns_adbfetch structure: 177 * Stores the state for an ongoing A or AAAA fetch. 178 */ 179 struct dns_adbfetch { 180 unsigned int magic; 181 dns_fetch_t *fetch; 182 dns_rdataset_t rdataset; 183 unsigned int depth; 184 }; 185 186 /*% 187 * dns_adbnamehook structure: 188 * 189 * This is a small widget that dangles off a dns_adbname_t. It contains a 190 * pointer to the address information about this host, and a link to the next 191 * namehook that will contain the next address this host has. 192 */ 193 struct dns_adbnamehook { 194 unsigned int magic; 195 dns_adbentry_t *entry; 196 ISC_LINK(dns_adbnamehook_t) name_link; 197 ISC_LINK(dns_adbnamehook_t) entry_link; 198 }; 199 200 /*% 201 * dns_adbentry structure: 202 * 203 * This is the structure representing a nameserver address; it can be looked 204 * up via the adb->entries hash table. Also, each dns_adbnamehook and 205 * and dns_adbaddrinfo object will contain a pointer to one of these. 206 * 207 * The structure holds quite a bit of information about addresses, 208 * including edns state (in "flags"), RTT, and of course the address of 209 * the host. 210 */ 211 struct dns_adbentry { 212 unsigned int magic; 213 214 dns_adb_t *adb; 215 216 isc_mutex_t lock; 217 isc_stdtime_t last_used; 218 219 isc_refcount_t references; 220 dns_adbnamehooklist_t nhs; 221 222 atomic_uint flags; 223 atomic_uint srtt; 224 unsigned int completed; 225 unsigned int timeouts; 226 unsigned char plain; 227 unsigned char plainto; 228 unsigned char edns; 229 unsigned char ednsto; 230 uint16_t udpsize; 231 232 uint8_t mode; 233 atomic_uint_fast32_t quota; 234 atomic_uint_fast32_t active; 235 double atr; 236 237 isc_sockaddr_t sockaddr; 238 unsigned char *cookie; 239 uint16_t cookielen; 240 241 isc_stdtime_t expires; 242 _Atomic(isc_stdtime_t) lastage; 243 /*%< 244 * A nonzero 'expires' field indicates that the entry should 245 * persist until that time. This allows entries found 246 * using dns_adb_findaddrinfo() to persist for a limited time 247 * even though they are not necessarily associated with a 248 * entry. 249 */ 250 251 ISC_LINK(dns_adbentry_t) link; 252 }; 253 254 #if DNS_ADB_TRACE 255 #define dns_adbentry_ref(ptr) \ 256 dns_adbentry__ref(ptr, __func__, __FILE__, __LINE__) 257 #define dns_adbentry_unref(ptr) \ 258 dns_adbentry__unref(ptr, __func__, __FILE__, __LINE__) 259 #define dns_adbentry_attach(ptr, ptrp) \ 260 dns_adbentry__attach(ptr, ptrp, __func__, __FILE__, __LINE__) 261 #define dns_adbentry_detach(ptrp) \ 262 dns_adbentry__detach(ptrp, __func__, __FILE__, __LINE__) 263 ISC_REFCOUNT_TRACE_DECL(dns_adbentry); 264 #else 265 ISC_REFCOUNT_DECL(dns_adbentry); 266 #endif 267 268 /* 269 * Internal functions (and prototypes). 270 */ 271 static dns_adbname_t * 272 new_adbname(dns_adb_t *adb, const dns_name_t *, unsigned int flags); 273 static void 274 destroy_adbname(dns_adbname_t *); 275 static bool 276 match_adbname(void *node, const void *key); 277 static uint32_t 278 hash_adbname(const dns_adbname_t *adbname); 279 static dns_adbnamehook_t * 280 new_adbnamehook(dns_adb_t *adb); 281 static void 282 free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehookp); 283 static dns_adbentry_t * 284 new_adbentry(dns_adb_t *adb, const isc_sockaddr_t *addr, isc_stdtime_t now); 285 static void 286 destroy_adbentry(dns_adbentry_t *entry); 287 static bool 288 match_adbentry(void *node, const void *key); 289 static dns_adbfind_t * 290 new_adbfind(dns_adb_t *, in_port_t); 291 static void 292 free_adbfind(dns_adbfind_t **); 293 static dns_adbaddrinfo_t * 294 new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *, in_port_t); 295 static dns_adbfetch_t * 296 new_adbfetch(dns_adb_t *); 297 static void 298 free_adbfetch(dns_adb_t *, dns_adbfetch_t **); 299 static void 300 purge_stale_names(dns_adb_t *adb, isc_stdtime_t now); 301 static dns_adbname_t * 302 get_attached_and_locked_name(dns_adb_t *, const dns_name_t *, 303 unsigned int flags, isc_stdtime_t now); 304 static void 305 purge_stale_entries(dns_adb_t *adb, isc_stdtime_t now); 306 static dns_adbentry_t * 307 get_attached_and_locked_entry(dns_adb_t *adb, isc_stdtime_t now, 308 const isc_sockaddr_t *addr); 309 static void 310 dump_adb(dns_adb_t *, FILE *, bool debug, isc_stdtime_t); 311 static void 312 print_namehook_list(FILE *, const char *legend, dns_adb_t *adb, 313 dns_adbnamehooklist_t *list, bool debug, isc_stdtime_t now); 314 static void 315 print_find_list(FILE *, dns_adbname_t *); 316 static void 317 print_fetch_list(FILE *, dns_adbname_t *); 318 static void 319 clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *); 320 static void 321 clean_target(dns_adb_t *, dns_name_t *); 322 static void 323 clean_finds_at_name(dns_adbname_t *, dns_adbstatus_t, unsigned int); 324 static void 325 maybe_expire_namehooks(dns_adbname_t *, isc_stdtime_t); 326 static bool 327 maybe_expire_name(dns_adbname_t *adbname, isc_stdtime_t now); 328 static void 329 expire_name(dns_adbname_t *adbname, dns_adbstatus_t astat); 330 static bool 331 entry_expired(dns_adbentry_t *adbentry, isc_stdtime_t now); 332 static bool 333 maybe_expire_entry(dns_adbentry_t *adbentry, isc_stdtime_t now); 334 static void 335 expire_entry(dns_adbentry_t *adbentry); 336 static isc_result_t 337 dbfind_name(dns_adbname_t *, isc_stdtime_t, dns_rdatatype_t); 338 static isc_result_t 339 fetch_name(dns_adbname_t *, bool, unsigned int, isc_counter_t *qc, 340 dns_rdatatype_t); 341 static void 342 destroy(dns_adb_t *); 343 static void 344 shutdown_names(dns_adb_t *); 345 static void 346 shutdown_entries(dns_adb_t *); 347 static void 348 dump_entry(FILE *, dns_adb_t *, dns_adbentry_t *, bool, isc_stdtime_t); 349 static void 350 adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor, 351 isc_stdtime_t now); 352 static void 353 log_quota(dns_adbentry_t *entry, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); 354 355 static bool 356 adbentry_overquota(dns_adbentry_t *entry); 357 358 /* 359 * Private flag(s) for adbfind objects. These are used internally and 360 * are not meant to be seen or used by the caller; however, we use the 361 * same flags field as for DNS_ADBFIND_xxx flags, so we must be careful 362 * that there is no overlap between these values and those. To make it 363 * easier, we will number these starting from the most significant bit 364 * instead of the least significant. 365 */ 366 enum { 367 FIND_EVENT_SENT = 1 << 31, 368 }; 369 #define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0) 370 371 /* 372 * Private flag(s) for adbname objects. 373 */ 374 enum { 375 NAME_IS_DEAD = 1 << 31, 376 }; 377 #define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0) 378 379 /* 380 * Private flag(s) for adbentry objects. Note that these will also 381 * be used for addrinfo flags, and in resolver.c we'll use the same 382 * field for FCTX_ADDRINFO_xxx flags to store information about remote 383 * servers, so we must be careful that there is no overlap between 384 * these values and those. To make it easier, we will number these 385 * starting from the most significant bit instead of the least 386 * significant. 387 */ 388 enum { 389 ENTRY_IS_DEAD = 1 << 31, 390 }; 391 #define ENTRY_DEAD(e) ((atomic_load(&(e)->flags) & ENTRY_IS_DEAD) != 0) 392 393 /* 394 * To the name, address classes are all that really exist. If it has a 395 * V6 address it doesn't care if it came from a AAAA query. 396 */ 397 #define NAME_HAS_V4(n) (!ISC_LIST_EMPTY((n)->v4)) 398 #define NAME_HAS_V6(n) (!ISC_LIST_EMPTY((n)->v6)) 399 400 /* 401 * Fetches are broken out into A and AAAA types. In some cases, 402 * however, it makes more sense to test for a particular class of fetches, 403 * like V4 or V6 above. 404 */ 405 #define NAME_FETCH_A(n) ((n)->fetch_a != NULL) 406 #define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL) 407 #define NAME_FETCH(n) (NAME_FETCH_A(n) || NAME_FETCH_AAAA(n)) 408 409 /* 410 * Find options and tests to see if there are addresses on the list. 411 */ 412 #define FIND_WANTEVENT(fn) (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0) 413 #define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0) 414 #define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) != 0) 415 #define FIND_STARTATZONE(fn) (((fn)->options & DNS_ADBFIND_STARTATZONE) != 0) 416 #define FIND_STATICSTUB(fn) (((fn)->options & DNS_ADBFIND_STATICSTUB) != 0) 417 #define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list)) 418 #define FIND_NOFETCH(fn) (((fn)->options & DNS_ADBFIND_NOFETCH) != 0) 419 420 #define ADBNAME_FLAGS_MASK (DNS_ADBFIND_STARTATZONE | DNS_ADBFIND_STATICSTUB) 421 422 /* 423 * These are currently used on simple unsigned ints, so they are 424 * not really associated with any particular type. 425 */ 426 #define WANT_INET(x) (((x) & DNS_ADBFIND_INET) != 0) 427 #define WANT_INET6(x) (((x) & DNS_ADBFIND_INET6) != 0) 428 429 #define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now)) 430 431 /* 432 * Find out if the flags on a name (nf) indicate if it is a hint or 433 * glue, and compare this to the appropriate bits set in o, to see if 434 * this is ok. 435 */ 436 #define STARTATZONE_MATCHES(nf, o) \ 437 (((nf)->flags & DNS_ADBFIND_STARTATZONE) == \ 438 ((o) & DNS_ADBFIND_STARTATZONE)) 439 440 #define ENTER_LEVEL ISC_LOG_DEBUG(50) 441 #define CLEAN_LEVEL ISC_LOG_DEBUG(100) 442 #define DEF_LEVEL ISC_LOG_DEBUG(5) 443 #define NCACHE_LEVEL ISC_LOG_DEBUG(20) 444 445 #define NCACHE_RESULT(r) \ 446 ((r) == DNS_R_NCACHENXDOMAIN || (r) == DNS_R_NCACHENXRRSET) 447 #define AUTH_NX(r) ((r) == DNS_R_NXDOMAIN || (r) == DNS_R_NXRRSET) 448 449 /* 450 * Due to the ttlclamp(), the TTL is never 0 unless the trust is ultimate, 451 * in which case we need to set the expiration to have immediate effect. 452 */ 453 #define ADJUSTED_EXPIRE(expire, now, ttl) \ 454 ((ttl != 0) \ 455 ? ISC_MIN(expire, ISC_MAX(now + ADB_ENTRY_WINDOW, now + ttl)) \ 456 : INT_MAX) 457 458 /* 459 * Error states. 460 */ 461 enum { 462 FIND_ERR_SUCCESS = 0, 463 FIND_ERR_CANCELED, 464 FIND_ERR_FAILURE, 465 FIND_ERR_NXDOMAIN, 466 FIND_ERR_NXRRSET, 467 FIND_ERR_UNEXPECTED, 468 FIND_ERR_NOTFOUND, 469 }; 470 471 static const char *errnames[] = { "success", "canceled", "failure", 472 "nxdomain", "nxrrset", "unexpected", 473 "not_found" }; 474 475 static isc_result_t find_err_map[] = { 476 ISC_R_SUCCESS, ISC_R_CANCELED, ISC_R_FAILURE, DNS_R_NXDOMAIN, 477 DNS_R_NXRRSET, ISC_R_UNEXPECTED, ISC_R_NOTFOUND /* not YET found */ 478 }; 479 480 static void 481 DP(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3); 482 483 static void 484 DP(int level, const char *format, ...) { 485 va_list args; 486 487 va_start(args, format); 488 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, 489 level, format, args); 490 va_end(args); 491 } 492 493 /*% 494 * Increment resolver-related statistics counters. 495 */ 496 static void 497 inc_resstats(dns_adb_t *adb, isc_statscounter_t counter) { 498 if (adb->res != NULL) { 499 dns_resolver_incstats(adb->res, counter); 500 } 501 } 502 503 /*% 504 * Set adb-related statistics counters. 505 */ 506 static void 507 set_adbstat(dns_adb_t *adb, uint64_t val, isc_statscounter_t counter) { 508 if (adb->stats != NULL) { 509 isc_stats_set(adb->stats, val, counter); 510 } 511 } 512 513 static void 514 dec_adbstats(dns_adb_t *adb, isc_statscounter_t counter) { 515 if (adb->stats != NULL) { 516 isc_stats_decrement(adb->stats, counter); 517 } 518 } 519 520 static void 521 inc_adbstats(dns_adb_t *adb, isc_statscounter_t counter) { 522 if (adb->stats != NULL) { 523 isc_stats_increment(adb->stats, counter); 524 } 525 } 526 527 static dns_ttl_t 528 ttlclamp(dns_ttl_t ttl) { 529 if (ttl < ADB_CACHE_MINIMUM) { 530 ttl = ADB_CACHE_MINIMUM; 531 } 532 if (ttl > ADB_CACHE_MAXIMUM) { 533 ttl = ADB_CACHE_MAXIMUM; 534 } 535 536 return ttl; 537 } 538 539 /* 540 * Requires the name to be locked and that no entries to be locked. 541 * 542 * This code handles A and AAAA rdatasets only. 543 */ 544 static isc_result_t 545 import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset, 546 isc_stdtime_t now) { 547 isc_result_t result; 548 dns_adb_t *adb = NULL; 549 dns_rdatatype_t rdtype; 550 551 REQUIRE(DNS_ADBNAME_VALID(adbname)); 552 553 adb = adbname->adb; 554 555 REQUIRE(DNS_ADB_VALID(adb)); 556 557 rdtype = rdataset->type; 558 559 switch (rdataset->trust) { 560 case dns_trust_glue: 561 case dns_trust_additional: 562 rdataset->ttl = ADB_CACHE_MINIMUM; 563 break; 564 case dns_trust_ultimate: 565 rdataset->ttl = 0; 566 break; 567 default: 568 rdataset->ttl = ttlclamp(rdataset->ttl); 569 } 570 571 REQUIRE(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa); 572 573 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 574 result = dns_rdataset_next(rdataset)) 575 { 576 /* FIXME: Move to a separate function */ 577 dns_adbnamehooklist_t *hookhead = NULL; 578 dns_adbentry_t *entry = NULL; 579 dns_adbnamehook_t *nh = NULL; 580 dns_rdata_t rdata = DNS_RDATA_INIT; 581 isc_sockaddr_t sockaddr; 582 struct in_addr ina; 583 struct in6_addr in6a; 584 585 dns_rdataset_current(rdataset, &rdata); 586 switch (rdtype) { 587 case dns_rdatatype_a: 588 INSIST(rdata.length == 4); 589 memmove(&ina.s_addr, rdata.data, 4); 590 isc_sockaddr_fromin(&sockaddr, &ina, 0); 591 hookhead = &adbname->v4; 592 break; 593 case dns_rdatatype_aaaa: 594 INSIST(rdata.length == 16); 595 memmove(in6a.s6_addr, rdata.data, 16); 596 isc_sockaddr_fromin6(&sockaddr, &in6a, 0); 597 hookhead = &adbname->v6; 598 break; 599 default: 600 UNREACHABLE(); 601 } 602 603 entry = get_attached_and_locked_entry(adb, now, &sockaddr); 604 INSIST(!ENTRY_DEAD(entry)); 605 606 dns_adbnamehook_t *anh = NULL; 607 for (anh = ISC_LIST_HEAD(*hookhead); anh != NULL; 608 anh = ISC_LIST_NEXT(anh, name_link)) 609 { 610 if (anh->entry == entry) { 611 break; 612 } 613 } 614 if (anh == NULL) { 615 nh = new_adbnamehook(adb); 616 dns_adbentry_attach(entry, &nh->entry); 617 ISC_LIST_APPEND(*hookhead, nh, name_link); 618 ISC_LIST_APPEND(entry->nhs, nh, entry_link); 619 } 620 UNLOCK(&entry->lock); 621 dns_adbentry_detach(&entry); 622 } 623 if (result == ISC_R_NOMORE) { 624 result = ISC_R_SUCCESS; 625 } 626 INSIST(result == ISC_R_SUCCESS); 627 628 switch (rdtype) { 629 case dns_rdatatype_a: 630 adbname->expire_v4 = ADJUSTED_EXPIRE(adbname->expire_v4, now, 631 rdataset->ttl); 632 DP(NCACHE_LEVEL, "expire_v4 set to %u import_rdataset", 633 adbname->expire_v4); 634 break; 635 case dns_rdatatype_aaaa: 636 adbname->expire_v6 = ADJUSTED_EXPIRE(adbname->expire_v6, now, 637 rdataset->ttl); 638 DP(NCACHE_LEVEL, "expire_v6 set to %u import_rdataset", 639 adbname->expire_v6); 640 break; 641 default: 642 UNREACHABLE(); 643 } 644 645 return ISC_R_SUCCESS; 646 } 647 648 static bool 649 match_ptr(void *node, const void *key) { 650 return node == key; 651 } 652 653 /* 654 * Requires the name to be locked. 655 */ 656 static void 657 expire_name(dns_adbname_t *adbname, dns_adbstatus_t astat) { 658 isc_result_t result; 659 660 REQUIRE(DNS_ADBNAME_VALID(adbname)); 661 662 dns_adb_t *adb = adbname->adb; 663 664 REQUIRE(DNS_ADB_VALID(adb)); 665 666 DP(DEF_LEVEL, "killing name %p", adbname); 667 668 /* 669 * Clean up the name's various contents. These functions 670 * are destructive in that they will always empty the lists 671 * of finds and namehooks. 672 */ 673 clean_finds_at_name(adbname, astat, DNS_ADBFIND_ADDRESSMASK); 674 clean_namehooks(adb, &adbname->v4); 675 clean_namehooks(adb, &adbname->v6); 676 clean_target(adb, &adbname->target); 677 678 if (NAME_FETCH_A(adbname)) { 679 dns_resolver_cancelfetch(adbname->fetch_a->fetch); 680 } 681 682 if (NAME_FETCH_AAAA(adbname)) { 683 dns_resolver_cancelfetch(adbname->fetch_aaaa->fetch); 684 } 685 686 adbname->flags |= NAME_IS_DEAD; 687 688 /* 689 * Remove the adbname from the hashtable... 690 */ 691 result = isc_hashmap_delete(adb->names, hash_adbname(adbname), 692 match_ptr, adbname); 693 RUNTIME_CHECK(result == ISC_R_SUCCESS); 694 /* ... and LRU list */ 695 ISC_LIST_UNLINK(adb->names_lru, adbname, link); 696 697 dns_adbname_unref(adbname); 698 } 699 700 /* 701 * Requires the name to be locked and no entries to be locked. 702 */ 703 static void 704 maybe_expire_namehooks(dns_adbname_t *adbname, isc_stdtime_t now) { 705 REQUIRE(DNS_ADBNAME_VALID(adbname)); 706 REQUIRE(DNS_ADB_VALID(adbname->adb)); 707 708 dns_adb_t *adb = adbname->adb; 709 710 /* 711 * Check to see if we need to remove the v4 addresses 712 */ 713 if (!NAME_FETCH_A(adbname) && EXPIRE_OK(adbname->expire_v4, now)) { 714 if (NAME_HAS_V4(adbname)) { 715 DP(DEF_LEVEL, "expiring v4 for name %p", adbname); 716 clean_namehooks(adb, &adbname->v4); 717 adbname->partial_result &= ~DNS_ADBFIND_INET; 718 } 719 adbname->expire_v4 = INT_MAX; 720 adbname->fetch_err = FIND_ERR_UNEXPECTED; 721 } 722 723 /* 724 * Check to see if we need to remove the v6 addresses 725 */ 726 if (!NAME_FETCH_AAAA(adbname) && EXPIRE_OK(adbname->expire_v6, now)) { 727 if (NAME_HAS_V6(adbname)) { 728 DP(DEF_LEVEL, "expiring v6 for name %p", adbname); 729 clean_namehooks(adb, &adbname->v6); 730 adbname->partial_result &= ~DNS_ADBFIND_INET6; 731 } 732 adbname->expire_v6 = INT_MAX; 733 adbname->fetch6_err = FIND_ERR_UNEXPECTED; 734 } 735 736 /* 737 * Check to see if we need to remove the alias target. 738 */ 739 if (EXPIRE_OK(adbname->expire_target, now)) { 740 clean_target(adb, &adbname->target); 741 adbname->expire_target = INT_MAX; 742 } 743 } 744 745 static void 746 shutdown_names(dns_adb_t *adb) { 747 dns_adbname_t *next = NULL; 748 749 RWLOCK(&adb->names_lock, isc_rwlocktype_write); 750 for (dns_adbname_t *name = ISC_LIST_HEAD(adb->names_lru); name != NULL; 751 name = next) 752 { 753 next = ISC_LIST_NEXT(name, link); 754 dns_adbname_ref(name); 755 LOCK(&name->lock); 756 /* 757 * Run through the list. For each name, clean up finds 758 * found there, and cancel any fetches running. When 759 * all the fetches are canceled, the name will destroy 760 * itself. 761 */ 762 expire_name(name, DNS_ADB_SHUTTINGDOWN); 763 UNLOCK(&name->lock); 764 dns_adbname_detach(&name); 765 } 766 RWUNLOCK(&adb->names_lock, isc_rwlocktype_write); 767 } 768 769 static void 770 shutdown_entries(dns_adb_t *adb) { 771 dns_adbentry_t *next = NULL; 772 RWLOCK(&adb->entries_lock, isc_rwlocktype_write); 773 for (dns_adbentry_t *adbentry = ISC_LIST_HEAD(adb->entries_lru); 774 adbentry != NULL; adbentry = next) 775 { 776 next = ISC_LIST_NEXT(adbentry, link); 777 expire_entry(adbentry); 778 } 779 RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write); 780 } 781 782 /* 783 * The name containing the 'namehooks' list must be locked. 784 */ 785 static void 786 clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) { 787 dns_adbnamehook_t *namehook = NULL; 788 789 namehook = ISC_LIST_HEAD(*namehooks); 790 while (namehook != NULL) { 791 INSIST(DNS_ADBNAMEHOOK_VALID(namehook)); 792 INSIST(DNS_ADBENTRY_VALID(namehook->entry)); 793 794 dns_adbentry_t *adbentry = namehook->entry; 795 namehook->entry = NULL; 796 797 /* 798 * Free the namehook 799 */ 800 ISC_LIST_UNLINK(*namehooks, namehook, name_link); 801 802 LOCK(&adbentry->lock); 803 ISC_LIST_UNLINK(adbentry->nhs, namehook, entry_link); 804 UNLOCK(&adbentry->lock); 805 dns_adbentry_detach(&adbentry); 806 807 free_adbnamehook(adb, &namehook); 808 809 namehook = ISC_LIST_HEAD(*namehooks); 810 } 811 } 812 813 static void 814 clean_target(dns_adb_t *adb, dns_name_t *target) { 815 if (dns_name_countlabels(target) > 0) { 816 dns_name_free(target, adb->mctx); 817 dns_name_init(target, NULL); 818 } 819 } 820 821 static isc_result_t 822 set_target(dns_adb_t *adb, const dns_name_t *name, const dns_name_t *fname, 823 dns_rdataset_t *rdataset, dns_name_t *target) { 824 isc_result_t result; 825 dns_rdata_t rdata = DNS_RDATA_INIT; 826 827 REQUIRE(dns_name_countlabels(target) == 0); 828 829 if (rdataset->type == dns_rdatatype_cname) { 830 dns_rdata_cname_t cname; 831 832 /* 833 * Copy the CNAME's target into the target name. 834 */ 835 result = dns_rdataset_first(rdataset); 836 if (result != ISC_R_SUCCESS) { 837 return result; 838 } 839 dns_rdataset_current(rdataset, &rdata); 840 result = dns_rdata_tostruct(&rdata, &cname, NULL); 841 if (result != ISC_R_SUCCESS) { 842 return result; 843 } 844 dns_name_dup(&cname.cname, adb->mctx, target); 845 dns_rdata_freestruct(&cname); 846 } else { 847 dns_fixedname_t fixed1, fixed2; 848 dns_name_t *prefix = NULL, *new_target = NULL; 849 dns_rdata_dname_t dname; 850 dns_namereln_t namereln; 851 unsigned int nlabels; 852 int order; 853 854 INSIST(rdataset->type == dns_rdatatype_dname); 855 namereln = dns_name_fullcompare(name, fname, &order, &nlabels); 856 INSIST(namereln == dns_namereln_subdomain); 857 858 /* 859 * Get the target name of the DNAME. 860 */ 861 result = dns_rdataset_first(rdataset); 862 if (result != ISC_R_SUCCESS) { 863 return result; 864 } 865 dns_rdataset_current(rdataset, &rdata); 866 result = dns_rdata_tostruct(&rdata, &dname, NULL); 867 if (result != ISC_R_SUCCESS) { 868 return result; 869 } 870 871 /* 872 * Construct the new target name. 873 */ 874 prefix = dns_fixedname_initname(&fixed1); 875 new_target = dns_fixedname_initname(&fixed2); 876 dns_name_split(name, nlabels, prefix, NULL); 877 result = dns_name_concatenate(prefix, &dname.dname, new_target, 878 NULL); 879 dns_rdata_freestruct(&dname); 880 if (result != ISC_R_SUCCESS) { 881 return result; 882 } 883 dns_name_dup(new_target, adb->mctx, target); 884 } 885 886 return ISC_R_SUCCESS; 887 } 888 889 /* 890 * The name must be locked. 891 */ 892 static void 893 clean_finds_at_name(dns_adbname_t *name, dns_adbstatus_t astat, 894 unsigned int addrs) { 895 dns_adbfind_t *find = NULL, *next = NULL; 896 897 DP(ENTER_LEVEL, 898 "ENTER clean_finds_at_name, name %p, astat %08x, addrs %08x", name, 899 astat, addrs); 900 901 for (find = ISC_LIST_HEAD(name->finds); find != NULL; find = next) { 902 bool process = false; 903 unsigned int wanted, notify; 904 905 LOCK(&find->lock); 906 next = ISC_LIST_NEXT(find, plink); 907 908 wanted = find->flags & DNS_ADBFIND_ADDRESSMASK; 909 notify = wanted & addrs; 910 911 switch (astat) { 912 case DNS_ADB_MOREADDRESSES: 913 DP(ISC_LOG_DEBUG(3), "more addresses"); 914 if ((notify) != 0) { 915 find->flags &= ~addrs; 916 process = true; 917 } 918 break; 919 case DNS_ADB_NOMOREADDRESSES: 920 DP(ISC_LOG_DEBUG(3), "no more addresses"); 921 find->flags &= ~addrs; 922 wanted = find->flags & DNS_ADBFIND_ADDRESSMASK; 923 if (wanted == 0) { 924 process = true; 925 } 926 break; 927 default: 928 find->flags &= ~addrs; 929 process = true; 930 } 931 932 if (process) { 933 DP(DEF_LEVEL, "cfan: processing find %p", find); 934 935 /* 936 * Unlink the find from the name, letting the caller 937 * call dns_adb_destroyfind() on it to clean it up 938 * later. 939 */ 940 ISC_LIST_UNLINK(name->finds, find, plink); 941 find->adbname = NULL; 942 943 INSIST(!FIND_EVENTSENT(find)); 944 945 atomic_store(&find->status, astat); 946 947 DP(DEF_LEVEL, "cfan: sending find %p to caller", find); 948 949 isc_async_run(find->loop, find->cb, find); 950 find->flags |= FIND_EVENT_SENT; 951 } else { 952 DP(DEF_LEVEL, "cfan: skipping find %p", find); 953 } 954 955 UNLOCK(&find->lock); 956 } 957 DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name); 958 } 959 960 static dns_adbname_t * 961 new_adbname(dns_adb_t *adb, const dns_name_t *dnsname, unsigned int flags) { 962 dns_adbname_t *name = NULL; 963 964 name = isc_mem_get(adb->mctx, sizeof(*name)); 965 *name = (dns_adbname_t){ 966 .adb = dns_adb_ref(adb), 967 .expire_v4 = INT_MAX, 968 .expire_v6 = INT_MAX, 969 .expire_target = INT_MAX, 970 .fetch_err = FIND_ERR_UNEXPECTED, 971 .fetch6_err = FIND_ERR_UNEXPECTED, 972 .v4 = ISC_LIST_INITIALIZER, 973 .v6 = ISC_LIST_INITIALIZER, 974 .finds = ISC_LIST_INITIALIZER, 975 .link = ISC_LINK_INITIALIZER, 976 .flags = flags & ADBNAME_FLAGS_MASK, 977 .magic = DNS_ADBNAME_MAGIC, 978 }; 979 980 #if DNS_ADB_TRACE 981 fprintf(stderr, "dns_adbname__init:%s:%s:%d:%p->references = 1\n", 982 __func__, __FILE__, __LINE__ + 1, name); 983 #endif 984 isc_refcount_init(&name->references, 1); 985 986 isc_mutex_init(&name->lock); 987 988 name->name = dns_fixedname_initname(&name->fname); 989 dns_name_copy(dnsname, name->name); 990 dns_name_init(&name->target, NULL); 991 992 inc_adbstats(adb, dns_adbstats_namescnt); 993 return name; 994 } 995 996 #if DNS_ADB_TRACE 997 ISC_REFCOUNT_TRACE_IMPL(dns_adbname, destroy_adbname); 998 #else 999 ISC_REFCOUNT_IMPL(dns_adbname, destroy_adbname); 1000 #endif 1001 1002 static void 1003 destroy_adbname(dns_adbname_t *name) { 1004 REQUIRE(DNS_ADBNAME_VALID(name)); 1005 1006 dns_adb_t *adb = name->adb; 1007 1008 REQUIRE(!NAME_HAS_V4(name)); 1009 REQUIRE(!NAME_HAS_V6(name)); 1010 REQUIRE(!NAME_FETCH(name)); 1011 REQUIRE(ISC_LIST_EMPTY(name->finds)); 1012 REQUIRE(!ISC_LINK_LINKED(name, link)); 1013 1014 name->magic = 0; 1015 1016 isc_mutex_destroy(&name->lock); 1017 1018 isc_mem_put(adb->mctx, name, sizeof(*name)); 1019 1020 dec_adbstats(adb, dns_adbstats_namescnt); 1021 dns_adb_detach(&adb); 1022 } 1023 1024 static dns_adbnamehook_t * 1025 new_adbnamehook(dns_adb_t *adb) { 1026 dns_adbnamehook_t *nh = isc_mem_get(adb->mctx, sizeof(*nh)); 1027 *nh = (dns_adbnamehook_t){ 1028 .name_link = ISC_LINK_INITIALIZER, 1029 .entry_link = ISC_LINK_INITIALIZER, 1030 .magic = DNS_ADBNAMEHOOK_MAGIC, 1031 }; 1032 1033 return nh; 1034 } 1035 1036 static void 1037 free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) { 1038 dns_adbnamehook_t *nh = NULL; 1039 1040 REQUIRE(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook)); 1041 1042 nh = *namehook; 1043 *namehook = NULL; 1044 1045 REQUIRE(nh->entry == NULL); 1046 REQUIRE(!ISC_LINK_LINKED(nh, name_link)); 1047 REQUIRE(!ISC_LINK_LINKED(nh, entry_link)); 1048 1049 nh->magic = 0; 1050 1051 isc_mem_put(adb->mctx, nh, sizeof(*nh)); 1052 } 1053 1054 static dns_adbentry_t * 1055 new_adbentry(dns_adb_t *adb, const isc_sockaddr_t *addr, isc_stdtime_t now) { 1056 dns_adbentry_t *entry = NULL; 1057 1058 entry = isc_mem_get(adb->mctx, sizeof(*entry)); 1059 *entry = (dns_adbentry_t){ 1060 .srtt = isc_random_uniform(0x1f) + 1, 1061 .sockaddr = *addr, 1062 .link = ISC_LINK_INITIALIZER, 1063 .quota = adb->quota, 1064 .references = ISC_REFCOUNT_INITIALIZER(1), 1065 .adb = dns_adb_ref(adb), 1066 .expires = now + ADB_ENTRY_WINDOW, 1067 .magic = DNS_ADBENTRY_MAGIC, 1068 }; 1069 1070 #if DNS_ADB_TRACE 1071 fprintf(stderr, "dns_adbentry__init:%s:%s:%d:%p->references = 1\n", 1072 __func__, __FILE__, __LINE__ + 1, entry); 1073 #endif 1074 isc_mutex_init(&entry->lock); 1075 1076 inc_adbstats(adb, dns_adbstats_entriescnt); 1077 1078 return entry; 1079 } 1080 1081 static void 1082 destroy_adbentry(dns_adbentry_t *entry) { 1083 REQUIRE(DNS_ADBENTRY_VALID(entry)); 1084 1085 dns_adb_t *adb = entry->adb; 1086 uint_fast32_t active; 1087 1088 entry->magic = 0; 1089 1090 INSIST(!ISC_LINK_LINKED(entry, link)); 1091 1092 INSIST(ISC_LIST_EMPTY(entry->nhs)); 1093 1094 active = atomic_load_acquire(&entry->active); 1095 INSIST(active == 0); 1096 1097 if (entry->cookie != NULL) { 1098 isc_mem_put(adb->mctx, entry->cookie, entry->cookielen); 1099 } 1100 1101 isc_mutex_destroy(&entry->lock); 1102 isc_mem_put(adb->mctx, entry, sizeof(*entry)); 1103 1104 dec_adbstats(adb, dns_adbstats_entriescnt); 1105 1106 dns_adb_detach(&adb); 1107 } 1108 1109 #if DNS_ADB_TRACE 1110 ISC_REFCOUNT_TRACE_IMPL(dns_adbentry, destroy_adbentry); 1111 #else 1112 ISC_REFCOUNT_IMPL(dns_adbentry, destroy_adbentry); 1113 #endif 1114 1115 static dns_adbfind_t * 1116 new_adbfind(dns_adb_t *adb, in_port_t port) { 1117 dns_adbfind_t *find = NULL; 1118 1119 find = isc_mem_get(adb->mctx, sizeof(*find)); 1120 *find = (dns_adbfind_t){ 1121 .port = port, 1122 .result_v4 = ISC_R_UNEXPECTED, 1123 .result_v6 = ISC_R_UNEXPECTED, 1124 .publink = ISC_LINK_INITIALIZER, 1125 .plink = ISC_LINK_INITIALIZER, 1126 .list = ISC_LIST_INITIALIZER, 1127 }; 1128 1129 dns_adb_attach(adb, &find->adb); 1130 isc_mutex_init(&find->lock); 1131 1132 find->magic = DNS_ADBFIND_MAGIC; 1133 1134 return find; 1135 } 1136 1137 static void 1138 free_adbfind(dns_adbfind_t **findp) { 1139 dns_adb_t *adb = NULL; 1140 dns_adbfind_t *find = NULL; 1141 1142 REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp)); 1143 1144 find = *findp; 1145 *findp = NULL; 1146 1147 adb = find->adb; 1148 1149 REQUIRE(!FIND_HAS_ADDRS(find)); 1150 REQUIRE(!ISC_LINK_LINKED(find, publink)); 1151 REQUIRE(!ISC_LINK_LINKED(find, plink)); 1152 REQUIRE(find->adbname == NULL); 1153 1154 find->magic = 0; 1155 1156 isc_mutex_destroy(&find->lock); 1157 1158 isc_mem_put(adb->mctx, find, sizeof(*find)); 1159 dns_adb_detach(&adb); 1160 } 1161 1162 static dns_adbfetch_t * 1163 new_adbfetch(dns_adb_t *adb) { 1164 dns_adbfetch_t *fetch = NULL; 1165 1166 fetch = isc_mem_get(adb->mctx, sizeof(*fetch)); 1167 *fetch = (dns_adbfetch_t){ 0 }; 1168 dns_rdataset_init(&fetch->rdataset); 1169 1170 fetch->magic = DNS_ADBFETCH_MAGIC; 1171 1172 return fetch; 1173 } 1174 1175 static void 1176 free_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetchp) { 1177 dns_adbfetch_t *fetch = NULL; 1178 1179 REQUIRE(fetchp != NULL && DNS_ADBFETCH_VALID(*fetchp)); 1180 1181 fetch = *fetchp; 1182 *fetchp = NULL; 1183 1184 fetch->magic = 0; 1185 1186 if (dns_rdataset_isassociated(&fetch->rdataset)) { 1187 dns_rdataset_disassociate(&fetch->rdataset); 1188 } 1189 1190 isc_mem_put(adb->mctx, fetch, sizeof(*fetch)); 1191 } 1192 1193 /* 1194 * Copy bits from an adbentry into a newly allocated adb_addrinfo structure. 1195 * The entry must be locked, and its reference count must be incremented. 1196 */ 1197 static dns_adbaddrinfo_t * 1198 new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) { 1199 dns_adbaddrinfo_t *ai = NULL; 1200 1201 ai = isc_mem_get(adb->mctx, sizeof(*ai)); 1202 *ai = (dns_adbaddrinfo_t){ 1203 .srtt = atomic_load(&entry->srtt), 1204 .flags = atomic_load(&entry->flags), 1205 .publink = ISC_LINK_INITIALIZER, 1206 .sockaddr = entry->sockaddr, 1207 .entry = dns_adbentry_ref(entry), 1208 .magic = DNS_ADBADDRINFO_MAGIC, 1209 }; 1210 1211 isc_sockaddr_setport(&ai->sockaddr, port); 1212 1213 return ai; 1214 } 1215 1216 static void 1217 free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) { 1218 dns_adbaddrinfo_t *ai = NULL; 1219 1220 REQUIRE(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo)); 1221 1222 ai = *ainfo; 1223 *ainfo = NULL; 1224 1225 REQUIRE(!ISC_LINK_LINKED(ai, publink)); 1226 1227 ai->magic = 0; 1228 1229 if (ai->transport != NULL) { 1230 dns_transport_detach(&ai->transport); 1231 } 1232 dns_adbentry_detach(&ai->entry); 1233 1234 isc_mem_put(adb->mctx, ai, sizeof(*ai)); 1235 } 1236 1237 static bool 1238 match_adbname(void *node, const void *key) { 1239 const dns_adbname_t *adbname0 = node; 1240 const dns_adbname_t *adbname1 = key; 1241 1242 if ((adbname0->flags & ADBNAME_FLAGS_MASK) != 1243 (adbname1->flags & ADBNAME_FLAGS_MASK)) 1244 { 1245 return false; 1246 } 1247 1248 return dns_name_equal(adbname0->name, adbname1->name); 1249 } 1250 1251 static uint32_t 1252 hash_adbname(const dns_adbname_t *adbname) { 1253 isc_hash32_t hash; 1254 unsigned int flags = adbname->flags & ADBNAME_FLAGS_MASK; 1255 1256 isc_hash32_init(&hash); 1257 isc_hash32_hash(&hash, adbname->name->ndata, adbname->name->length, 1258 false); 1259 isc_hash32_hash(&hash, &flags, sizeof(flags), true); 1260 return isc_hash32_finalize(&hash); 1261 } 1262 1263 /* 1264 * Search for the name in the hash table. 1265 */ 1266 static dns_adbname_t * 1267 get_attached_and_locked_name(dns_adb_t *adb, const dns_name_t *name, 1268 unsigned int flags, isc_stdtime_t now) { 1269 isc_result_t result; 1270 dns_adbname_t *adbname = NULL; 1271 isc_time_t timenow; 1272 isc_stdtime_t last_update; 1273 dns_adbname_t key = { 1274 .name = UNCONST(name), 1275 .flags = flags & ADBNAME_FLAGS_MASK, 1276 }; 1277 uint32_t hashval = hash_adbname(&key); 1278 isc_rwlocktype_t locktype = isc_rwlocktype_read; 1279 1280 isc_time_set(&timenow, now, 0); 1281 1282 RWLOCK(&adb->names_lock, locktype); 1283 last_update = adb->names_last_update; 1284 1285 if (last_update + ADB_STALE_MARGIN >= now || 1286 isc_mem_isovermem(adb->mctx)) 1287 { 1288 last_update = now; 1289 UPGRADELOCK(&adb->names_lock, locktype); 1290 purge_stale_names(adb, now); 1291 adb->names_last_update = last_update; 1292 } 1293 1294 result = isc_hashmap_find(adb->names, hashval, match_adbname, 1295 (void *)&key, (void **)&adbname); 1296 switch (result) { 1297 case ISC_R_NOTFOUND: 1298 UPGRADELOCK(&adb->names_lock, locktype); 1299 1300 /* Allocate a new name and add it to the hash table. */ 1301 adbname = new_adbname(adb, name, key.flags); 1302 1303 void *found = NULL; 1304 result = isc_hashmap_add(adb->names, hashval, match_adbname, 1305 (void *)&key, adbname, &found); 1306 if (result == ISC_R_EXISTS) { 1307 destroy_adbname(adbname); 1308 adbname = found; 1309 result = ISC_R_SUCCESS; 1310 ISC_LIST_UNLINK(adb->names_lru, adbname, link); 1311 } 1312 INSIST(result == ISC_R_SUCCESS); 1313 1314 break; 1315 case ISC_R_SUCCESS: 1316 if (locktype == isc_rwlocktype_write) { 1317 ISC_LIST_UNLINK(adb->names_lru, adbname, link); 1318 } 1319 break; 1320 default: 1321 UNREACHABLE(); 1322 } 1323 1324 dns_adbname_ref(adbname); 1325 1326 LOCK(&adbname->lock); /* Must be unlocked by the caller */ 1327 if (adbname->last_used + ADB_CACHE_MINIMUM <= last_update) { 1328 adbname->last_used = now; 1329 } 1330 if (locktype == isc_rwlocktype_write) { 1331 ISC_LIST_PREPEND(adb->names_lru, adbname, link); 1332 } 1333 1334 /* 1335 * The refcount is now 2 and the final detach will happen in 1336 * expire_name() - the unused adbname stored in the hashtable and lru 1337 * has always refcount == 1 1338 */ 1339 RWUNLOCK(&adb->names_lock, locktype); 1340 1341 return adbname; 1342 } 1343 1344 static void 1345 upgrade_entries_lock(dns_adb_t *adb, isc_rwlocktype_t *locktypep, 1346 isc_stdtime_t now) { 1347 if (*locktypep == isc_rwlocktype_read) { 1348 UPGRADELOCK(&adb->entries_lock, *locktypep); 1349 purge_stale_entries(adb, now); 1350 adb->entries_last_update = now; 1351 } 1352 } 1353 1354 static bool 1355 match_adbentry(void *node, const void *key) { 1356 dns_adbentry_t *adbentry = node; 1357 1358 return isc_sockaddr_equal(&adbentry->sockaddr, key); 1359 } 1360 1361 /* 1362 * Find the entry in the adb->entries hashtable. 1363 */ 1364 static dns_adbentry_t * 1365 get_attached_and_locked_entry(dns_adb_t *adb, isc_stdtime_t now, 1366 const isc_sockaddr_t *addr) { 1367 isc_result_t result; 1368 dns_adbentry_t *adbentry = NULL; 1369 isc_time_t timenow; 1370 isc_stdtime_t last_update; 1371 uint32_t hashval = isc_sockaddr_hash(addr, true); 1372 isc_rwlocktype_t locktype = isc_rwlocktype_read; 1373 1374 isc_time_set(&timenow, now, 0); 1375 1376 RWLOCK(&adb->entries_lock, locktype); 1377 last_update = adb->entries_last_update; 1378 1379 if (now - last_update > ADB_STALE_MARGIN || 1380 isc_mem_isovermem(adb->mctx)) 1381 { 1382 last_update = now; 1383 1384 upgrade_entries_lock(adb, &locktype, now); 1385 } 1386 1387 result = isc_hashmap_find(adb->entries, hashval, match_adbentry, 1388 (const unsigned char *)addr, 1389 (void **)&adbentry); 1390 if (result == ISC_R_NOTFOUND) { 1391 upgrade_entries_lock(adb, &locktype, now); 1392 1393 create: 1394 INSIST(locktype == isc_rwlocktype_write); 1395 1396 /* Allocate a new entry and add it to the hash table. */ 1397 adbentry = new_adbentry(adb, addr, now); 1398 1399 void *found = NULL; 1400 result = isc_hashmap_add(adb->entries, hashval, match_adbentry, 1401 &adbentry->sockaddr, adbentry, &found); 1402 if (result == ISC_R_SUCCESS) { 1403 ISC_LIST_PREPEND(adb->entries_lru, adbentry, link); 1404 } else if (result == ISC_R_EXISTS) { 1405 dns_adbentry_detach(&adbentry); 1406 adbentry = found; 1407 result = ISC_R_SUCCESS; 1408 } 1409 } 1410 INSIST(result == ISC_R_SUCCESS); 1411 1412 /* 1413 * The dns_adbentry_ref() must stay here before trying to expire 1414 * the ADB entry, so it is not destroyed under the lock. 1415 */ 1416 dns_adbentry_ref(adbentry); 1417 LOCK(&adbentry->lock); /* Must be unlocked by the caller */ 1418 switch (locktype) { 1419 case isc_rwlocktype_read: 1420 if (!entry_expired(adbentry, now)) { 1421 break; 1422 } 1423 1424 /* We need to upgrade the LRU lock */ 1425 UNLOCK(&adbentry->lock); 1426 upgrade_entries_lock(adb, &locktype, now); 1427 LOCK(&adbentry->lock); 1428 FALLTHROUGH; 1429 case isc_rwlocktype_write: 1430 if (ENTRY_DEAD(adbentry) || maybe_expire_entry(adbentry, now)) { 1431 UNLOCK(&adbentry->lock); 1432 dns_adbentry_detach(&adbentry); 1433 goto create; 1434 } 1435 break; 1436 default: 1437 UNREACHABLE(); 1438 } 1439 1440 /* Did enough time pass to update the LRU? */ 1441 if (adbentry->last_used + ADB_CACHE_MINIMUM <= last_update) { 1442 adbentry->last_used = now; 1443 if (locktype == isc_rwlocktype_write) { 1444 ISC_LIST_UNLINK(adb->entries_lru, adbentry, link); 1445 ISC_LIST_PREPEND(adb->entries_lru, adbentry, link); 1446 } 1447 } 1448 1449 RWUNLOCK(&adb->entries_lock, locktype); 1450 1451 return adbentry; 1452 } 1453 1454 static void 1455 log_quota(dns_adbentry_t *entry, const char *fmt, ...) { 1456 va_list ap; 1457 char msgbuf[2048]; 1458 char addrbuf[ISC_NETADDR_FORMATSIZE]; 1459 isc_netaddr_t netaddr; 1460 1461 va_start(ap, fmt); 1462 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 1463 va_end(ap); 1464 1465 isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr); 1466 isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); 1467 1468 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, 1469 ISC_LOG_INFO, 1470 "adb: quota %s (%" PRIuFAST32 "/%" PRIuFAST32 "): %s", 1471 addrbuf, atomic_load_relaxed(&entry->active), 1472 atomic_load_relaxed(&entry->quota), msgbuf); 1473 } 1474 1475 static void 1476 copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_adbname_t *name) { 1477 dns_adbnamehook_t *namehook = NULL; 1478 dns_adbentry_t *entry = NULL; 1479 1480 if ((find->options & DNS_ADBFIND_INET) != 0) { 1481 namehook = ISC_LIST_HEAD(name->v4); 1482 while (namehook != NULL) { 1483 dns_adbaddrinfo_t *addrinfo = NULL; 1484 entry = namehook->entry; 1485 1486 if ((find->options & DNS_ADBFIND_QUOTAEXEMPT) == 0 && 1487 adbentry_overquota(entry)) 1488 { 1489 find->options |= DNS_ADBFIND_OVERQUOTA; 1490 goto nextv4; 1491 } 1492 1493 addrinfo = new_adbaddrinfo(adb, entry, find->port); 1494 1495 /* 1496 * Found a valid entry. Add it to the find's list. 1497 */ 1498 ISC_LIST_APPEND(find->list, addrinfo, publink); 1499 nextv4: 1500 namehook = ISC_LIST_NEXT(namehook, name_link); 1501 } 1502 } 1503 1504 if ((find->options & DNS_ADBFIND_INET6) != 0) { 1505 namehook = ISC_LIST_HEAD(name->v6); 1506 while (namehook != NULL) { 1507 dns_adbaddrinfo_t *addrinfo = NULL; 1508 entry = namehook->entry; 1509 1510 if ((find->options & DNS_ADBFIND_QUOTAEXEMPT) == 0 && 1511 adbentry_overquota(entry)) 1512 { 1513 find->options |= DNS_ADBFIND_OVERQUOTA; 1514 goto nextv6; 1515 } 1516 1517 addrinfo = new_adbaddrinfo(adb, entry, find->port); 1518 1519 /* 1520 * Found a valid entry. Add it to the find's list. 1521 */ 1522 ISC_LIST_APPEND(find->list, addrinfo, publink); 1523 nextv6: 1524 namehook = ISC_LIST_NEXT(namehook, name_link); 1525 } 1526 } 1527 } 1528 1529 /* 1530 * The name must be locked and write lock on adb->names_lock must be held. 1531 */ 1532 static bool 1533 maybe_expire_name(dns_adbname_t *adbname, isc_stdtime_t now) { 1534 REQUIRE(DNS_ADBNAME_VALID(adbname)); 1535 1536 /* Leave this name alone if it still has active namehooks... */ 1537 if (NAME_HAS_V4(adbname) || NAME_HAS_V6(adbname)) { 1538 return false; 1539 } 1540 1541 /* ...an active fetch in progres... */ 1542 if (NAME_FETCH(adbname)) { 1543 return false; 1544 } 1545 1546 /* ... or is not yet expired. */ 1547 if (!EXPIRE_OK(adbname->expire_v4, now) || 1548 !EXPIRE_OK(adbname->expire_v6, now) || 1549 !EXPIRE_OK(adbname->expire_target, now)) 1550 { 1551 return false; 1552 } 1553 1554 expire_name(adbname, DNS_ADB_EXPIRED); 1555 1556 return true; 1557 } 1558 1559 static void 1560 expire_entry(dns_adbentry_t *adbentry) { 1561 isc_result_t result; 1562 dns_adb_t *adb = adbentry->adb; 1563 1564 if (!ENTRY_DEAD(adbentry)) { 1565 (void)atomic_fetch_or(&adbentry->flags, ENTRY_IS_DEAD); 1566 1567 result = isc_hashmap_delete( 1568 adb->entries, 1569 isc_sockaddr_hash(&adbentry->sockaddr, true), match_ptr, 1570 adbentry); 1571 RUNTIME_CHECK(result == ISC_R_SUCCESS); 1572 ISC_LIST_UNLINK(adb->entries_lru, adbentry, link); 1573 } 1574 1575 dns_adbentry_detach(&adbentry); 1576 } 1577 1578 static bool 1579 entry_expired(dns_adbentry_t *adbentry, isc_stdtime_t now) { 1580 if (!ISC_LIST_EMPTY(adbentry->nhs)) { 1581 return false; 1582 } 1583 1584 if (!EXPIRE_OK(adbentry->expires, now)) { 1585 return false; 1586 } 1587 1588 return true; 1589 } 1590 1591 static bool 1592 maybe_expire_entry(dns_adbentry_t *adbentry, isc_stdtime_t now) { 1593 REQUIRE(DNS_ADBENTRY_VALID(adbentry)); 1594 1595 if (entry_expired(adbentry, now)) { 1596 expire_entry(adbentry); 1597 return true; 1598 } 1599 1600 return false; 1601 } 1602 1603 /*% 1604 * Examine the tail entry of the LRU list to see if it expires or is stale 1605 * (unused for some period); if so, the name entry will be freed. If the ADB 1606 * is in the overmem condition, the tail and the next to tail entries 1607 * will be unconditionally removed (unless they have an outstanding fetch). 1608 * We don't care about a race on 'overmem' at the risk of causing some 1609 * collateral damage or a small delay in starting cleanup. 1610 * 1611 * adb->names_lock MUST be write locked 1612 */ 1613 static void 1614 purge_stale_names(dns_adb_t *adb, isc_stdtime_t now) { 1615 bool overmem = isc_mem_isovermem(adb->mctx); 1616 int max_removed = overmem ? 2 : 1; 1617 int scans = 0, removed = 0; 1618 dns_adbname_t *prev = NULL; 1619 1620 /* 1621 * We limit the number of scanned entries to 10 (arbitrary choice) 1622 * in order to avoid examining too many entries when there are many 1623 * tail entries that have fetches (this should be rare, but could 1624 * happen). 1625 */ 1626 1627 for (dns_adbname_t *adbname = ISC_LIST_TAIL(adb->names_lru); 1628 adbname != NULL && removed < max_removed && scans < 10; 1629 adbname = prev) 1630 { 1631 prev = ISC_LIST_PREV(adbname, link); 1632 1633 dns_adbname_ref(adbname); 1634 LOCK(&adbname->lock); 1635 1636 scans++; 1637 1638 /* 1639 * Remove the name if it's expired or unused, 1640 * has no address data. 1641 */ 1642 maybe_expire_namehooks(adbname, now); 1643 if (maybe_expire_name(adbname, now)) { 1644 removed++; 1645 goto next; 1646 } 1647 1648 /* 1649 * Make sure that we are not purging ADB names that has been 1650 * just created. 1651 */ 1652 if (adbname->last_used + ADB_CACHE_MINIMUM >= now) { 1653 prev = NULL; 1654 goto next; 1655 } 1656 1657 if (overmem) { 1658 expire_name(adbname, DNS_ADB_CANCELED); 1659 removed++; 1660 goto next; 1661 } 1662 1663 if (adbname->last_used + ADB_STALE_MARGIN < now) { 1664 expire_name(adbname, DNS_ADB_CANCELED); 1665 removed++; 1666 goto next; 1667 } 1668 1669 /* 1670 * We won't expire anything on the LRU list as the 1671 * .last_used + ADB_STALE_MARGIN will always be bigger 1672 * than `now` for all previous entries, so we just stop 1673 * the scanning. 1674 */ 1675 prev = NULL; 1676 next: 1677 UNLOCK(&adbname->lock); 1678 dns_adbname_detach(&adbname); 1679 } 1680 } 1681 1682 static void 1683 cleanup_names(dns_adb_t *adb, isc_stdtime_t now) { 1684 dns_adbname_t *next = NULL; 1685 1686 RWLOCK(&adb->names_lock, isc_rwlocktype_write); 1687 for (dns_adbname_t *adbname = ISC_LIST_HEAD(adb->names_lru); 1688 adbname != NULL; adbname = next) 1689 { 1690 next = ISC_LIST_NEXT(adbname, link); 1691 1692 dns_adbname_ref(adbname); 1693 LOCK(&adbname->lock); 1694 /* 1695 * Name hooks expire after the address record's TTL 1696 * or 30 minutes, whichever is shorter. If after cleaning 1697 * those up there are no name hooks left, and no active 1698 * fetches, we can remove this name from the bucket. 1699 */ 1700 maybe_expire_namehooks(adbname, now); 1701 (void)maybe_expire_name(adbname, now); 1702 UNLOCK(&adbname->lock); 1703 dns_adbname_detach(&adbname); 1704 } 1705 RWUNLOCK(&adb->names_lock, isc_rwlocktype_write); 1706 } 1707 1708 /*% 1709 * Examine the tail entry of the LRU list to see if it expires or is stale 1710 * (unused for some period); if so, the name entry will be freed. If the ADB 1711 * is in the overmem condition, the tail and the next to tail entries 1712 * will be unconditionally removed (unless they have an outstanding fetch). 1713 * We don't care about a race on 'overmem' at the risk of causing some 1714 * collateral damage or a small delay in starting cleanup. 1715 * 1716 * adb->entries_lock MUST be write locked 1717 */ 1718 static void 1719 purge_stale_entries(dns_adb_t *adb, isc_stdtime_t now) { 1720 bool overmem = isc_mem_isovermem(adb->mctx); 1721 int max_removed = overmem ? 2 : 1; 1722 int scans = 0, removed = 0; 1723 dns_adbentry_t *prev = NULL; 1724 1725 /* 1726 * We limit the number of scanned entries to 10 (arbitrary choice) 1727 * in order to avoid examining too many entries when there are many 1728 * tail entries that have fetches (this should be rare, but could 1729 * happen). 1730 */ 1731 1732 for (dns_adbentry_t *adbentry = ISC_LIST_TAIL(adb->entries_lru); 1733 adbentry != NULL && removed < max_removed && scans < 10; 1734 adbentry = prev) 1735 { 1736 prev = ISC_LIST_PREV(adbentry, link); 1737 1738 dns_adbentry_ref(adbentry); 1739 LOCK(&adbentry->lock); 1740 1741 scans++; 1742 1743 /* 1744 * Remove the entry if it's expired and unused. 1745 */ 1746 if (maybe_expire_entry(adbentry, now)) { 1747 removed++; 1748 goto next; 1749 } 1750 1751 /* 1752 * Make sure that we are not purging ADB entry that has been 1753 * just created. 1754 */ 1755 if (adbentry->last_used + ADB_CACHE_MINIMUM >= now) { 1756 prev = NULL; 1757 goto next; 1758 } 1759 1760 if (overmem) { 1761 maybe_expire_entry(adbentry, INT_MAX); 1762 removed++; 1763 goto next; 1764 } 1765 1766 if (adbentry->last_used + ADB_STALE_MARGIN < now) { 1767 maybe_expire_entry(adbentry, INT_MAX); 1768 removed++; 1769 goto next; 1770 } 1771 1772 /* 1773 * We won't expire anything on the LRU list as the 1774 * .last_used + ADB_STALE_MARGIN will always be bigger 1775 * than `now` for all previous entries, so we just stop 1776 * the scanning 1777 */ 1778 prev = NULL; 1779 next: 1780 UNLOCK(&adbentry->lock); 1781 dns_adbentry_detach(&adbentry); 1782 } 1783 } 1784 1785 static void 1786 cleanup_entries(dns_adb_t *adb, isc_stdtime_t now) { 1787 dns_adbentry_t *next = NULL; 1788 1789 RWLOCK(&adb->entries_lock, isc_rwlocktype_write); 1790 for (dns_adbentry_t *adbentry = ISC_LIST_HEAD(adb->entries_lru); 1791 adbentry != NULL; adbentry = next) 1792 { 1793 next = ISC_LIST_NEXT(adbentry, link); 1794 1795 dns_adbentry_ref(adbentry); 1796 LOCK(&adbentry->lock); 1797 maybe_expire_entry(adbentry, now); 1798 UNLOCK(&adbentry->lock); 1799 dns_adbentry_detach(&adbentry); 1800 } 1801 RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write); 1802 } 1803 1804 static void 1805 destroy(dns_adb_t *adb) { 1806 DP(DEF_LEVEL, "destroying ADB %p", adb); 1807 1808 adb->magic = 0; 1809 1810 RWLOCK(&adb->names_lock, isc_rwlocktype_write); 1811 INSIST(isc_hashmap_count(adb->names) == 0); 1812 isc_hashmap_destroy(&adb->names); 1813 RWUNLOCK(&adb->names_lock, isc_rwlocktype_write); 1814 isc_rwlock_destroy(&adb->names_lock); 1815 1816 RWLOCK(&adb->entries_lock, isc_rwlocktype_write); 1817 /* There are no unassociated entries */ 1818 INSIST(isc_hashmap_count(adb->entries) == 0); 1819 isc_hashmap_destroy(&adb->entries); 1820 RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write); 1821 isc_rwlock_destroy(&adb->entries_lock); 1822 1823 isc_mem_detach(&adb->hmctx); 1824 1825 isc_mutex_destroy(&adb->lock); 1826 1827 isc_stats_detach(&adb->stats); 1828 dns_resolver_detach(&adb->res); 1829 dns_view_weakdetach(&adb->view); 1830 isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t)); 1831 } 1832 1833 #if DNS_ADB_TRACE 1834 ISC_REFCOUNT_TRACE_IMPL(dns_adb, destroy); 1835 #else 1836 ISC_REFCOUNT_IMPL(dns_adb, destroy); 1837 #endif 1838 1839 /* 1840 * Public functions. 1841 */ 1842 1843 void 1844 dns_adb_create(isc_mem_t *mem, dns_view_t *view, dns_adb_t **newadb) { 1845 dns_adb_t *adb = NULL; 1846 1847 REQUIRE(mem != NULL); 1848 REQUIRE(view != NULL); 1849 REQUIRE(newadb != NULL && *newadb == NULL); 1850 1851 adb = isc_mem_get(mem, sizeof(dns_adb_t)); 1852 *adb = (dns_adb_t){ 1853 .names_lru = ISC_LIST_INITIALIZER, 1854 .entries_lru = ISC_LIST_INITIALIZER, 1855 }; 1856 1857 /* 1858 * Initialize things here that cannot fail, and especially things 1859 * that must be NULL for the error return to work properly. 1860 */ 1861 #if DNS_ADB_TRACE 1862 fprintf(stderr, "dns_adb__init:%s:%s:%d:%p->references = 1\n", __func__, 1863 __FILE__, __LINE__ + 1, adb); 1864 #endif 1865 isc_refcount_init(&adb->references, 1); 1866 dns_view_weakattach(view, &adb->view); 1867 dns_resolver_attach(view->resolver, &adb->res); 1868 isc_mem_attach(mem, &adb->mctx); 1869 1870 isc_mem_create(&adb->hmctx); 1871 isc_mem_setname(adb->hmctx, "ADB_hashmaps"); 1872 1873 isc_hashmap_create(adb->hmctx, ADB_HASH_BITS, &adb->names); 1874 isc_rwlock_init(&adb->names_lock); 1875 1876 isc_hashmap_create(adb->hmctx, ADB_HASH_BITS, &adb->entries); 1877 isc_rwlock_init(&adb->entries_lock); 1878 1879 isc_mutex_init(&adb->lock); 1880 1881 isc_stats_create(adb->mctx, &adb->stats, dns_adbstats_max); 1882 1883 set_adbstat(adb, 0, dns_adbstats_nnames); 1884 set_adbstat(adb, 0, dns_adbstats_nentries); 1885 1886 /* 1887 * Normal return. 1888 */ 1889 adb->magic = DNS_ADB_MAGIC; 1890 *newadb = adb; 1891 } 1892 1893 void 1894 dns_adb_shutdown(dns_adb_t *adb) { 1895 if (!atomic_compare_exchange_strong(&adb->exiting, &(bool){ false }, 1896 true)) 1897 { 1898 return; 1899 } 1900 1901 DP(DEF_LEVEL, "shutting down ADB %p", adb); 1902 1903 isc_mem_clearwater(adb->mctx); 1904 1905 shutdown_names(adb); 1906 shutdown_entries(adb); 1907 } 1908 1909 /* 1910 * Look up the name in our internal database. 1911 * 1912 * There are three possibilities. Note that these are not always exclusive. 1913 * 1914 * - No name found. In this case, allocate a new name header and 1915 * an initial namehook or two. 1916 * 1917 * - Name found, valid addresses present. Allocate one addrinfo 1918 * structure for each found and append it to the linked list 1919 * of addresses for this header. 1920 * 1921 * - Name found, queries pending. In this case, if a loop was 1922 * passed in, allocate a job id, attach it to the name's job 1923 * list and remember to tell the caller that there will be 1924 * more info coming later. 1925 */ 1926 isc_result_t 1927 dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg, 1928 const dns_name_t *name, const dns_name_t *qname, 1929 dns_rdatatype_t qtype ISC_ATTR_UNUSED, unsigned int options, 1930 isc_stdtime_t now, dns_name_t *target, in_port_t port, 1931 unsigned int depth, isc_counter_t *qc, 1932 dns_adbfind_t **findp) { 1933 isc_result_t result = ISC_R_UNEXPECTED; 1934 dns_adbfind_t *find = NULL; 1935 dns_adbname_t *adbname = NULL; 1936 bool want_event = true; 1937 bool start_at_zone = false; 1938 bool alias = false; 1939 bool have_address = false; 1940 unsigned int wanted_addresses = (options & DNS_ADBFIND_ADDRESSMASK); 1941 unsigned int wanted_fetches = 0; 1942 unsigned int query_pending = 0; 1943 char namebuf[DNS_NAME_FORMATSIZE] = { 0 }; 1944 1945 REQUIRE(DNS_ADB_VALID(adb)); 1946 if (loop != NULL) { 1947 REQUIRE(cb != NULL); 1948 } 1949 REQUIRE(name != NULL); 1950 REQUIRE(qname != NULL); 1951 REQUIRE(findp != NULL && *findp == NULL); 1952 REQUIRE(target == NULL || dns_name_hasbuffer(target)); 1953 1954 REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0); 1955 1956 if (atomic_load(&adb->exiting)) { 1957 DP(DEF_LEVEL, "dns_adb_createfind: returning " 1958 "ISC_R_SHUTTINGDOWN"); 1959 1960 return ISC_R_SHUTTINGDOWN; 1961 } 1962 1963 if (now == 0) { 1964 now = isc_stdtime_now(); 1965 } 1966 1967 /* 1968 * If STATICSTUB is set we always want to have STARTATZONE set. 1969 */ 1970 if (options & DNS_ADBFIND_STATICSTUB) { 1971 options |= DNS_ADBFIND_STARTATZONE; 1972 } 1973 1974 /* 1975 * Remember what types of addresses we are interested in. 1976 */ 1977 find = new_adbfind(adb, port); 1978 find->options = options; 1979 find->flags |= wanted_addresses; 1980 if (FIND_WANTEVENT(find)) { 1981 REQUIRE(loop != NULL); 1982 } 1983 1984 if (isc_log_wouldlog(dns_lctx, DEF_LEVEL)) { 1985 dns_name_format(name, namebuf, sizeof(namebuf)); 1986 } 1987 1988 again: 1989 /* Try to see if we know anything about this name at all. */ 1990 adbname = get_attached_and_locked_name(adb, name, find->options, now); 1991 1992 if (NAME_DEAD(adbname)) { 1993 UNLOCK(&adbname->lock); 1994 dns_adbname_detach(&adbname); 1995 goto again; 1996 } 1997 1998 /* 1999 * Name hooks expire after the address record's TTL or 30 minutes, 2000 * whichever is shorter. If there are expired name hooks, remove 2001 * them so we'll send a new fetch. 2002 */ 2003 maybe_expire_namehooks(adbname, now); 2004 2005 /* 2006 * Do we know that the name is an alias? 2007 */ 2008 if (!EXPIRE_OK(adbname->expire_target, now)) { 2009 /* Yes, it is. */ 2010 DP(DEF_LEVEL, 2011 "dns_adb_createfind: name %s (%p) is an alias (cached)", 2012 namebuf, adbname); 2013 alias = true; 2014 goto post_copy; 2015 } 2016 2017 /* 2018 * Try to populate the name from the database and/or 2019 * start fetches. First try looking for an A record 2020 * in the database. 2021 */ 2022 if (!NAME_HAS_V4(adbname) && EXPIRE_OK(adbname->expire_v4, now) && 2023 WANT_INET(wanted_addresses)) 2024 { 2025 result = dbfind_name(adbname, now, dns_rdatatype_a); 2026 switch (result) { 2027 case ISC_R_SUCCESS: 2028 /* Found an A; now we proceed to check for AAAA */ 2029 DP(DEF_LEVEL, 2030 "dns_adb_createfind: found A for name %s (%p) in db", 2031 namebuf, adbname); 2032 break; 2033 2034 case DNS_R_ALIAS: 2035 /* Got a CNAME or DNAME. */ 2036 DP(DEF_LEVEL, 2037 "dns_adb_createfind: name %s (%p) is an alias", 2038 namebuf, adbname); 2039 alias = true; 2040 goto post_copy; 2041 2042 case DNS_R_NXDOMAIN: 2043 case DNS_R_NCACHENXDOMAIN: 2044 /* 2045 * If the name doesn't exist at all, don't bother with 2046 * v6 queries; they won't work. 2047 */ 2048 goto fetch; 2049 2050 case DNS_R_NXRRSET: 2051 case DNS_R_NCACHENXRRSET: 2052 case DNS_R_HINTNXRRSET: 2053 /* 2054 * The name does exist but we didn't get our data, go 2055 * ahead and try AAAA. 2056 */ 2057 break; 2058 2059 default: 2060 /* 2061 * Any other result, start a fetch for A, then fall 2062 * through to AAAA. 2063 */ 2064 if (!NAME_FETCH_A(adbname) && !FIND_STATICSTUB(find)) { 2065 wanted_fetches |= DNS_ADBFIND_INET; 2066 } 2067 break; 2068 } 2069 } 2070 2071 /* 2072 * Now look up or start fetches for AAAA. 2073 */ 2074 if (!NAME_HAS_V6(adbname) && EXPIRE_OK(adbname->expire_v6, now) && 2075 WANT_INET6(wanted_addresses)) 2076 { 2077 result = dbfind_name(adbname, now, dns_rdatatype_aaaa); 2078 switch (result) { 2079 case ISC_R_SUCCESS: 2080 DP(DEF_LEVEL, 2081 "dns_adb_createfind: found AAAA for name %s (%p)", 2082 namebuf, adbname); 2083 break; 2084 2085 case DNS_R_ALIAS: 2086 /* Got a CNAME or DNAME. */ 2087 DP(DEF_LEVEL, 2088 "dns_adb_createfind: name %s (%p) is an alias", 2089 namebuf, adbname); 2090 alias = true; 2091 goto post_copy; 2092 2093 case DNS_R_NXDOMAIN: 2094 case DNS_R_NCACHENXDOMAIN: 2095 case DNS_R_NXRRSET: 2096 case DNS_R_NCACHENXRRSET: 2097 /* 2098 * Name doens't exist or was found in the negative 2099 * cache to have no AAAA, don't bother fetching. 2100 */ 2101 break; 2102 2103 default: 2104 /* 2105 * Any other result, start a fetch for AAAA. 2106 */ 2107 if (!NAME_FETCH_AAAA(adbname) && !FIND_STATICSTUB(find)) 2108 { 2109 wanted_fetches |= DNS_ADBFIND_INET6; 2110 } 2111 break; 2112 } 2113 } 2114 2115 fetch: 2116 if ((WANT_INET(wanted_addresses) && NAME_HAS_V4(adbname)) || 2117 (WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname))) 2118 { 2119 have_address = true; 2120 } else { 2121 have_address = false; 2122 } 2123 if (wanted_fetches != 0 && !(FIND_AVOIDFETCHES(find) && have_address) && 2124 !FIND_NOFETCH(find)) 2125 { 2126 /* 2127 * We're missing at least one address family. Either the 2128 * caller hasn't instructed us to avoid fetches, or we don't 2129 * know anything about any of the address families that would 2130 * be acceptable so we have to launch fetches. 2131 */ 2132 2133 if (FIND_STARTATZONE(find)) { 2134 start_at_zone = true; 2135 } 2136 2137 /* 2138 * Start V4. 2139 */ 2140 if (WANT_INET(wanted_fetches) && 2141 fetch_name(adbname, start_at_zone, depth, qc, 2142 dns_rdatatype_a) == ISC_R_SUCCESS) 2143 { 2144 DP(DEF_LEVEL, 2145 "dns_adb_createfind: " 2146 "started A fetch for name %s (%p)", 2147 namebuf, adbname); 2148 } 2149 2150 /* 2151 * Start V6. 2152 */ 2153 if (WANT_INET6(wanted_fetches) && 2154 fetch_name(adbname, start_at_zone, depth, qc, 2155 dns_rdatatype_aaaa) == ISC_R_SUCCESS) 2156 { 2157 DP(DEF_LEVEL, 2158 "dns_adb_createfind: " 2159 "started AAAA fetch for name %s (%p)", 2160 namebuf, adbname); 2161 } 2162 } 2163 2164 /* 2165 * Run through the name and copy out the bits we are 2166 * interested in. 2167 */ 2168 copy_namehook_lists(adb, find, adbname); 2169 2170 post_copy: 2171 if (NAME_FETCH_A(adbname)) { 2172 query_pending |= DNS_ADBFIND_INET; 2173 } 2174 if (NAME_FETCH_AAAA(adbname)) { 2175 query_pending |= DNS_ADBFIND_INET6; 2176 } 2177 2178 /* 2179 * Attach to the name's query list if there are queries 2180 * already running, and we have been asked to. 2181 */ 2182 if (!FIND_WANTEVENT(find)) { 2183 want_event = false; 2184 } 2185 if (FIND_WANTEMPTYEVENT(find) && FIND_HAS_ADDRS(find)) { 2186 want_event = false; 2187 } 2188 if ((wanted_addresses & query_pending) == 0) { 2189 want_event = false; 2190 } 2191 if (alias) { 2192 want_event = false; 2193 } 2194 if (want_event) { 2195 bool empty; 2196 2197 find->adbname = adbname; 2198 empty = ISC_LIST_EMPTY(adbname->finds); 2199 ISC_LIST_APPEND(adbname->finds, find, plink); 2200 find->query_pending = (query_pending & wanted_addresses); 2201 find->flags &= ~DNS_ADBFIND_ADDRESSMASK; 2202 find->flags |= (find->query_pending & DNS_ADBFIND_ADDRESSMASK); 2203 DP(DEF_LEVEL, "createfind: attaching find %p to adbname %p %d", 2204 find, adbname, empty); 2205 } else { 2206 /* 2207 * Remove the flag so the caller knows there will never 2208 * be an event, and set internal flags to fake that 2209 * the event was sent and freed, so dns_adb_destroyfind() will 2210 * do the right thing. 2211 */ 2212 find->query_pending = (query_pending & wanted_addresses); 2213 find->options &= ~DNS_ADBFIND_WANTEVENT; 2214 find->flags |= FIND_EVENT_SENT; 2215 find->flags &= ~DNS_ADBFIND_ADDRESSMASK; 2216 } 2217 2218 find->partial_result |= (adbname->partial_result & wanted_addresses); 2219 if (alias) { 2220 if (target != NULL) { 2221 dns_name_copy(&adbname->target, target); 2222 } 2223 result = DNS_R_ALIAS; 2224 } else { 2225 result = ISC_R_SUCCESS; 2226 } 2227 2228 /* 2229 * Copy out error flags from the name structure into the find. 2230 */ 2231 find->result_v4 = find_err_map[adbname->fetch_err]; 2232 find->result_v6 = find_err_map[adbname->fetch6_err]; 2233 2234 if (want_event) { 2235 INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0); 2236 find->loop = loop; 2237 atomic_store(&find->status, DNS_ADB_UNSET); 2238 find->cb = cb; 2239 find->cbarg = cbarg; 2240 } 2241 2242 *findp = find; 2243 2244 UNLOCK(&adbname->lock); 2245 dns_adbname_detach(&adbname); 2246 2247 return result; 2248 } 2249 2250 void 2251 dns_adb_destroyfind(dns_adbfind_t **findp) { 2252 dns_adbfind_t *find = NULL; 2253 dns_adbaddrinfo_t *ai = NULL; 2254 dns_adb_t *adb = NULL; 2255 2256 REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp)); 2257 2258 find = *findp; 2259 *findp = NULL; 2260 2261 DP(DEF_LEVEL, "dns_adb_destroyfind on find %p", find); 2262 2263 adb = find->adb; 2264 2265 LOCK(&find->lock); 2266 2267 REQUIRE(find->adbname == NULL); 2268 2269 /* 2270 * Free the addrinfo objects on the find's list. Note that 2271 * we also need to decrement the reference counter in the 2272 * associated adbentry every time we remove one from the list. 2273 */ 2274 ai = ISC_LIST_HEAD(find->list); 2275 while (ai != NULL) { 2276 ISC_LIST_UNLINK(find->list, ai, publink); 2277 free_adbaddrinfo(adb, &ai); 2278 ai = ISC_LIST_HEAD(find->list); 2279 } 2280 UNLOCK(&find->lock); 2281 2282 free_adbfind(&find); 2283 } 2284 2285 /* 2286 * Caller must hold find lock. 2287 */ 2288 static void 2289 find_sendevent(dns_adbfind_t *find) { 2290 if (!FIND_EVENTSENT(find)) { 2291 atomic_store(&find->status, DNS_ADB_CANCELED); 2292 2293 DP(DEF_LEVEL, "sending find %p to caller", find); 2294 2295 isc_async_run(find->loop, find->cb, find); 2296 } 2297 } 2298 2299 void 2300 dns_adb_cancelfind(dns_adbfind_t *find) { 2301 dns_adbname_t *adbname = NULL; 2302 2303 DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find); 2304 2305 REQUIRE(DNS_ADBFIND_VALID(find)); 2306 REQUIRE(DNS_ADB_VALID(find->adb)); 2307 2308 LOCK(&find->lock); 2309 REQUIRE(FIND_WANTEVENT(find)); 2310 2311 adbname = find->adbname; 2312 2313 if (adbname == NULL) { 2314 find_sendevent(find); 2315 UNLOCK(&find->lock); 2316 } else { 2317 /* 2318 * Release the find lock, then acquire the name and find 2319 * locks in that order, to match locking hierarchy 2320 * elsewhere. 2321 */ 2322 dns_adbname_ref(adbname); 2323 UNLOCK(&find->lock); 2324 2325 /* 2326 * Other thread could cancel the find between the unlock and 2327 * lock, so we need to recheck whether the adbname is still 2328 * valid and reference the adbname, so it does not vanish before 2329 * we have a chance to lock it again. 2330 */ 2331 2332 LOCK(&adbname->lock); 2333 LOCK(&find->lock); 2334 2335 if (find->adbname != NULL) { 2336 ISC_LIST_UNLINK(find->adbname->finds, find, plink); 2337 find->adbname = NULL; 2338 } 2339 2340 find_sendevent(find); 2341 2342 UNLOCK(&find->lock); 2343 UNLOCK(&adbname->lock); 2344 dns_adbname_detach(&adbname); 2345 } 2346 } 2347 2348 unsigned int 2349 dns_adb_findstatus(dns_adbfind_t *find) { 2350 REQUIRE(DNS_ADBFIND_VALID(find)); 2351 2352 return atomic_load(&find->status); 2353 } 2354 2355 void 2356 dns_adb_dump(dns_adb_t *adb, FILE *f) { 2357 isc_stdtime_t now = isc_stdtime_now(); 2358 2359 REQUIRE(DNS_ADB_VALID(adb)); 2360 REQUIRE(f != NULL); 2361 2362 if (atomic_load(&adb->exiting)) { 2363 return; 2364 } 2365 2366 cleanup_names(adb, now); 2367 cleanup_entries(adb, now); 2368 dump_adb(adb, f, false, now); 2369 } 2370 2371 static void 2372 dump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) { 2373 if (value == INT_MAX) { 2374 return; 2375 } 2376 fprintf(f, " [%s TTL %d]", legend, (int)(value - now)); 2377 } 2378 2379 /* 2380 * Both rwlocks for the hash tables need to be held by the caller. 2381 */ 2382 static void 2383 dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) { 2384 fprintf(f, ";\n; Address database dump\n;\n"); 2385 fprintf(f, "; [edns success/timeout]\n"); 2386 fprintf(f, "; [plain success/timeout]\n;\n"); 2387 if (debug) { 2388 fprintf(f, "; addr %p, references %" PRIuFAST32 "\n", adb, 2389 isc_refcount_current(&adb->references)); 2390 } 2391 2392 /* 2393 * Ensure this operation is applied to both hash tables at once. 2394 */ 2395 RWLOCK(&adb->names_lock, isc_rwlocktype_write); 2396 2397 for (dns_adbname_t *name = ISC_LIST_HEAD(adb->names_lru); name != NULL; 2398 name = ISC_LIST_NEXT(name, link)) 2399 { 2400 LOCK(&name->lock); 2401 /* 2402 * Dump the names 2403 */ 2404 if (debug) { 2405 fprintf(f, "; name %p (flags %08x)\n", name, 2406 name->flags); 2407 } 2408 fprintf(f, "; "); 2409 dns_name_print(name->name, f); 2410 if (dns_name_countlabels(&name->target) > 0) { 2411 fprintf(f, " alias "); 2412 dns_name_print(&name->target, f); 2413 } 2414 2415 dump_ttl(f, "v4", name->expire_v4, now); 2416 dump_ttl(f, "v6", name->expire_v6, now); 2417 dump_ttl(f, "target", name->expire_target, now); 2418 2419 fprintf(f, " [v4 %s] [v6 %s]", errnames[name->fetch_err], 2420 errnames[name->fetch6_err]); 2421 2422 fprintf(f, "\n"); 2423 2424 print_namehook_list(f, "v4", adb, &name->v4, debug, now); 2425 print_namehook_list(f, "v6", adb, &name->v6, debug, now); 2426 2427 if (debug) { 2428 print_fetch_list(f, name); 2429 print_find_list(f, name); 2430 } 2431 UNLOCK(&name->lock); 2432 } 2433 2434 RWLOCK(&adb->entries_lock, isc_rwlocktype_write); 2435 fprintf(f, ";\n; Unassociated entries\n;\n"); 2436 for (dns_adbentry_t *adbentry = ISC_LIST_HEAD(adb->entries_lru); 2437 adbentry != NULL; adbentry = ISC_LIST_NEXT(adbentry, link)) 2438 { 2439 LOCK(&adbentry->lock); 2440 if (ISC_LIST_EMPTY(adbentry->nhs)) { 2441 dump_entry(f, adb, adbentry, debug, now); 2442 } 2443 UNLOCK(&adbentry->lock); 2444 } 2445 2446 RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write); 2447 RWUNLOCK(&adb->names_lock, isc_rwlocktype_write); 2448 } 2449 2450 static void 2451 dump_entry(FILE *f, dns_adb_t *adb, dns_adbentry_t *entry, bool debug, 2452 isc_stdtime_t now) { 2453 char addrbuf[ISC_NETADDR_FORMATSIZE]; 2454 isc_netaddr_t netaddr; 2455 2456 isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr); 2457 isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); 2458 2459 if (debug) { 2460 fprintf(f, ";\t%p: refcnt %" PRIuFAST32 "\n", entry, 2461 isc_refcount_current(&entry->references)); 2462 } 2463 2464 fprintf(f, 2465 ";\t%s [srtt %u] [flags %08x] [edns %u/%u] " 2466 "[plain %u/%u]", 2467 addrbuf, atomic_load(&entry->srtt), atomic_load(&entry->flags), 2468 entry->edns, entry->ednsto, entry->plain, entry->plainto); 2469 if (entry->udpsize != 0U) { 2470 fprintf(f, " [udpsize %u]", entry->udpsize); 2471 } 2472 if (entry->cookie != NULL) { 2473 unsigned int i; 2474 fprintf(f, " [cookie="); 2475 for (i = 0; i < entry->cookielen; i++) { 2476 fprintf(f, "%02x", entry->cookie[i]); 2477 } 2478 fprintf(f, "]"); 2479 } 2480 fprintf(f, " [ttl %d]", entry->expires - now); 2481 2482 if (adb != NULL && adb->quota != 0 && adb->atr_freq != 0) { 2483 uint_fast32_t quota = atomic_load_relaxed(&entry->quota); 2484 fprintf(f, " [atr %0.2f] [quota %" PRIuFAST32 "]", entry->atr, 2485 quota); 2486 } 2487 2488 fprintf(f, "\n"); 2489 } 2490 2491 static void 2492 dumpfind(dns_adbfind_t *find, FILE *f) { 2493 char tmp[512]; 2494 const char *tmpp = NULL; 2495 dns_adbaddrinfo_t *ai = NULL; 2496 isc_sockaddr_t *sa = NULL; 2497 2498 /* 2499 * Not used currently, in the API Just In Case we 2500 * want to dump out the name and/or entries too. 2501 */ 2502 2503 LOCK(&find->lock); 2504 2505 fprintf(f, ";Find %p\n", find); 2506 fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n", 2507 find->query_pending, find->partial_result, find->options, 2508 find->flags); 2509 fprintf(f, ";\tname %p\n", find->adbname); 2510 2511 ai = ISC_LIST_HEAD(find->list); 2512 if (ai != NULL) { 2513 fprintf(f, "\tAddresses:\n"); 2514 } 2515 while (ai != NULL) { 2516 sa = &ai->sockaddr; 2517 switch (sa->type.sa.sa_family) { 2518 case AF_INET: 2519 tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr, tmp, 2520 sizeof(tmp)); 2521 break; 2522 case AF_INET6: 2523 tmpp = inet_ntop(AF_INET6, &sa->type.sin6.sin6_addr, 2524 tmp, sizeof(tmp)); 2525 break; 2526 default: 2527 tmpp = "UnkFamily"; 2528 } 2529 2530 if (tmpp == NULL) { 2531 tmpp = "BadAddress"; 2532 } 2533 2534 fprintf(f, 2535 "\t\tentry %p, flags %08x" 2536 " srtt %u addr %s\n", 2537 ai->entry, ai->flags, ai->srtt, tmpp); 2538 2539 ai = ISC_LIST_NEXT(ai, publink); 2540 } 2541 2542 UNLOCK(&find->lock); 2543 } 2544 2545 static void 2546 print_namehook_list(FILE *f, const char *legend, dns_adb_t *adb, 2547 dns_adbnamehooklist_t *list, bool debug, 2548 isc_stdtime_t now) { 2549 dns_adbnamehook_t *nh = NULL; 2550 2551 for (nh = ISC_LIST_HEAD(*list); nh != NULL; 2552 nh = ISC_LIST_NEXT(nh, name_link)) 2553 { 2554 if (debug) { 2555 fprintf(f, ";\tHook(%s) %p\n", legend, nh); 2556 } 2557 LOCK(&nh->entry->lock); 2558 dump_entry(f, adb, nh->entry, debug, now); 2559 UNLOCK(&nh->entry->lock); 2560 } 2561 } 2562 2563 static void 2564 print_fetch(FILE *f, dns_adbfetch_t *ft, const char *type) { 2565 fprintf(f, "\t\tFetch(%s): %p -> { fetch %p }\n", type, ft, ft->fetch); 2566 } 2567 2568 static void 2569 print_fetch_list(FILE *f, dns_adbname_t *n) { 2570 if (NAME_FETCH_A(n)) { 2571 print_fetch(f, n->fetch_a, "A"); 2572 } 2573 if (NAME_FETCH_AAAA(n)) { 2574 print_fetch(f, n->fetch_aaaa, "AAAA"); 2575 } 2576 } 2577 2578 static void 2579 print_find_list(FILE *f, dns_adbname_t *name) { 2580 dns_adbfind_t *find = NULL; 2581 2582 find = ISC_LIST_HEAD(name->finds); 2583 while (find != NULL) { 2584 dumpfind(find, f); 2585 find = ISC_LIST_NEXT(find, plink); 2586 } 2587 } 2588 2589 static isc_result_t 2590 putstr(isc_buffer_t **b, const char *str) { 2591 isc_result_t result; 2592 2593 result = isc_buffer_reserve(*b, strlen(str)); 2594 if (result != ISC_R_SUCCESS) { 2595 return result; 2596 } 2597 2598 isc_buffer_putstr(*b, str); 2599 return ISC_R_SUCCESS; 2600 } 2601 2602 isc_result_t 2603 dns_adb_dumpquota(dns_adb_t *adb, isc_buffer_t **buf) { 2604 REQUIRE(DNS_ADB_VALID(adb)); 2605 2606 isc_hashmap_iter_t *it = NULL; 2607 isc_result_t result; 2608 2609 RWLOCK(&adb->entries_lock, isc_rwlocktype_read); 2610 isc_hashmap_iter_create(adb->entries, &it); 2611 for (result = isc_hashmap_iter_first(it); result == ISC_R_SUCCESS; 2612 result = isc_hashmap_iter_next(it)) 2613 { 2614 dns_adbentry_t *entry = NULL; 2615 isc_hashmap_iter_current(it, (void **)&entry); 2616 2617 LOCK(&entry->lock); 2618 char addrbuf[ISC_NETADDR_FORMATSIZE]; 2619 char text[ISC_NETADDR_FORMATSIZE + BUFSIZ]; 2620 isc_netaddr_t netaddr; 2621 2622 if (entry->atr == 0.0 && entry->quota == adb->quota) { 2623 goto unlock; 2624 } 2625 2626 isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr); 2627 isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); 2628 2629 snprintf(text, sizeof(text), 2630 "\n- quota %s (%" PRIuFAST32 "/%d) atr %0.2f", addrbuf, 2631 atomic_load_relaxed(&entry->quota), adb->quota, 2632 entry->atr); 2633 putstr(buf, text); 2634 unlock: 2635 UNLOCK(&entry->lock); 2636 } 2637 isc_hashmap_iter_destroy(&it); 2638 RWUNLOCK(&adb->entries_lock, isc_rwlocktype_read); 2639 2640 return ISC_R_SUCCESS; 2641 } 2642 2643 static isc_result_t 2644 dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) { 2645 isc_result_t result; 2646 dns_rdataset_t rdataset; 2647 dns_adb_t *adb = NULL; 2648 dns_fixedname_t foundname; 2649 dns_name_t *fname = NULL; 2650 2651 REQUIRE(DNS_ADBNAME_VALID(adbname)); 2652 2653 adb = adbname->adb; 2654 2655 REQUIRE(DNS_ADB_VALID(adb)); 2656 REQUIRE(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa); 2657 2658 fname = dns_fixedname_initname(&foundname); 2659 dns_rdataset_init(&rdataset); 2660 2661 if (rdtype == dns_rdatatype_a) { 2662 adbname->fetch_err = FIND_ERR_UNEXPECTED; 2663 } else { 2664 adbname->fetch6_err = FIND_ERR_UNEXPECTED; 2665 } 2666 2667 /* 2668 * We need to specify whether to search static-stub zones (if 2669 * configured) depending on whether this is a "start at zone" lookup, 2670 * i.e., whether it's a "bailiwick" glue. If it's bailiwick (in which 2671 * case DNS_ADBFIND_STARTATZONE is set) we need to stop the search at 2672 * any matching static-stub zone without looking into the cache to honor 2673 * the configuration on which server we should send queries to. 2674 */ 2675 result = 2676 dns_view_find(adb->view, adbname->name, rdtype, now, 2677 DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, true, 2678 ((adbname->flags & DNS_ADBFIND_STARTATZONE) != 0), 2679 NULL, NULL, fname, &rdataset, NULL); 2680 2681 switch (result) { 2682 case DNS_R_GLUE: 2683 case DNS_R_HINT: 2684 case ISC_R_SUCCESS: 2685 /* 2686 * Found in the database. Even if we can't copy out 2687 * any information, return success, or else a fetch 2688 * will be made, which will only make things worse. 2689 */ 2690 if (rdtype == dns_rdatatype_a) { 2691 adbname->fetch_err = FIND_ERR_SUCCESS; 2692 } else { 2693 adbname->fetch6_err = FIND_ERR_SUCCESS; 2694 } 2695 result = import_rdataset(adbname, &rdataset, now); 2696 break; 2697 case DNS_R_NXDOMAIN: 2698 case DNS_R_NXRRSET: 2699 /* 2700 * We're authoritative and the data doesn't exist. 2701 * Make up a negative cache entry so we don't ask again 2702 * for a while. 2703 * 2704 * XXXRTH What time should we use? I'm putting in 30 seconds 2705 * for now. 2706 */ 2707 if (rdtype == dns_rdatatype_a) { 2708 adbname->expire_v4 = now + 30; 2709 DP(NCACHE_LEVEL, 2710 "adb name %p: Caching auth negative entry for A", 2711 adbname); 2712 if (result == DNS_R_NXDOMAIN) { 2713 adbname->fetch_err = FIND_ERR_NXDOMAIN; 2714 } else { 2715 adbname->fetch_err = FIND_ERR_NXRRSET; 2716 } 2717 } else { 2718 DP(NCACHE_LEVEL, 2719 "adb name %p: Caching auth negative entry for AAAA", 2720 adbname); 2721 adbname->expire_v6 = now + 30; 2722 if (result == DNS_R_NXDOMAIN) { 2723 adbname->fetch6_err = FIND_ERR_NXDOMAIN; 2724 } else { 2725 adbname->fetch6_err = FIND_ERR_NXRRSET; 2726 } 2727 } 2728 break; 2729 case DNS_R_NCACHENXDOMAIN: 2730 case DNS_R_NCACHENXRRSET: 2731 /* 2732 * We found a negative cache entry. Pull the TTL from it 2733 * so we won't ask again for a while. 2734 */ 2735 rdataset.ttl = ttlclamp(rdataset.ttl); 2736 if (rdtype == dns_rdatatype_a) { 2737 adbname->expire_v4 = rdataset.ttl + now; 2738 if (result == DNS_R_NCACHENXDOMAIN) { 2739 adbname->fetch_err = FIND_ERR_NXDOMAIN; 2740 } else { 2741 adbname->fetch_err = FIND_ERR_NXRRSET; 2742 } 2743 DP(NCACHE_LEVEL, 2744 "adb name %p: Caching negative entry for A (ttl %u)", 2745 adbname, rdataset.ttl); 2746 } else { 2747 DP(NCACHE_LEVEL, 2748 "adb name %p: Caching negative entry for AAAA (ttl " 2749 "%u)", 2750 adbname, rdataset.ttl); 2751 adbname->expire_v6 = rdataset.ttl + now; 2752 if (result == DNS_R_NCACHENXDOMAIN) { 2753 adbname->fetch6_err = FIND_ERR_NXDOMAIN; 2754 } else { 2755 adbname->fetch6_err = FIND_ERR_NXRRSET; 2756 } 2757 } 2758 break; 2759 case DNS_R_CNAME: 2760 case DNS_R_DNAME: 2761 rdataset.ttl = ttlclamp(rdataset.ttl); 2762 clean_target(adb, &adbname->target); 2763 adbname->expire_target = INT_MAX; 2764 result = set_target(adb, adbname->name, fname, &rdataset, 2765 &adbname->target); 2766 if (result == ISC_R_SUCCESS) { 2767 result = DNS_R_ALIAS; 2768 DP(NCACHE_LEVEL, "adb name %p: caching alias target", 2769 adbname); 2770 adbname->expire_target = ADJUSTED_EXPIRE( 2771 adbname->expire_target, now, rdataset.ttl); 2772 } 2773 if (rdtype == dns_rdatatype_a) { 2774 adbname->fetch_err = FIND_ERR_SUCCESS; 2775 } else { 2776 adbname->fetch6_err = FIND_ERR_SUCCESS; 2777 } 2778 break; 2779 default: 2780 break; 2781 } 2782 2783 if (dns_rdataset_isassociated(&rdataset)) { 2784 dns_rdataset_disassociate(&rdataset); 2785 } 2786 2787 return result; 2788 } 2789 2790 static void 2791 fetch_callback(void *arg) { 2792 dns_fetchresponse_t *resp = (dns_fetchresponse_t *)arg; 2793 dns_adbname_t *name = resp->arg; 2794 dns_adb_t *adb = NULL; 2795 dns_adbfetch_t *fetch = NULL; 2796 dns_adbstatus_t astat = DNS_ADB_NOMOREADDRESSES; 2797 isc_stdtime_t now; 2798 isc_result_t result; 2799 unsigned int address_type; 2800 2801 REQUIRE(DNS_ADBNAME_VALID(name)); 2802 dns_adb_attach(name->adb, &adb); 2803 2804 REQUIRE(DNS_ADB_VALID(adb)); 2805 2806 LOCK(&name->lock); 2807 2808 INSIST(NAME_FETCH_A(name) || NAME_FETCH_AAAA(name)); 2809 address_type = 0; 2810 if (NAME_FETCH_A(name) && (name->fetch_a->fetch == resp->fetch)) { 2811 address_type = DNS_ADBFIND_INET; 2812 fetch = name->fetch_a; 2813 name->fetch_a = NULL; 2814 } else if (NAME_FETCH_AAAA(name) && 2815 (name->fetch_aaaa->fetch == resp->fetch)) 2816 { 2817 address_type = DNS_ADBFIND_INET6; 2818 fetch = name->fetch_aaaa; 2819 name->fetch_aaaa = NULL; 2820 } else { 2821 fetch = NULL; 2822 } 2823 2824 INSIST(address_type != 0 && fetch != NULL); 2825 2826 /* 2827 * Cleanup things we don't care about. 2828 */ 2829 if (resp->node != NULL) { 2830 dns_db_detachnode(resp->db, &resp->node); 2831 } 2832 if (resp->db != NULL) { 2833 dns_db_detach(&resp->db); 2834 } 2835 2836 /* 2837 * If this name is marked as dead, clean up, throwing away 2838 * potentially good data. 2839 */ 2840 if (NAME_DEAD(name)) { 2841 astat = DNS_ADB_CANCELED; 2842 goto out; 2843 } 2844 2845 now = isc_stdtime_now(); 2846 2847 /* 2848 * If we got a negative cache response, remember it. 2849 */ 2850 if (NCACHE_RESULT(resp->result)) { 2851 resp->rdataset->ttl = ttlclamp(resp->rdataset->ttl); 2852 if (address_type == DNS_ADBFIND_INET) { 2853 name->expire_v4 = ADJUSTED_EXPIRE(name->expire_v4, now, 2854 resp->rdataset->ttl); 2855 DP(NCACHE_LEVEL, 2856 "adb fetch name %p: " 2857 "caching negative entry for A (ttl %u)", 2858 name, name->expire_v4); 2859 if (resp->result == DNS_R_NCACHENXDOMAIN) { 2860 name->fetch_err = FIND_ERR_NXDOMAIN; 2861 } else { 2862 name->fetch_err = FIND_ERR_NXRRSET; 2863 } 2864 inc_resstats(adb, dns_resstatscounter_gluefetchv4fail); 2865 } else { 2866 name->expire_v6 = ADJUSTED_EXPIRE(name->expire_v6, now, 2867 resp->rdataset->ttl); 2868 DP(NCACHE_LEVEL, 2869 "adb fetch name %p: " 2870 "caching negative entry for AAAA (ttl %u)", 2871 name, name->expire_v6); 2872 if (resp->result == DNS_R_NCACHENXDOMAIN) { 2873 name->fetch6_err = FIND_ERR_NXDOMAIN; 2874 } else { 2875 name->fetch6_err = FIND_ERR_NXRRSET; 2876 } 2877 inc_resstats(adb, dns_resstatscounter_gluefetchv6fail); 2878 } 2879 goto out; 2880 } 2881 2882 /* 2883 * Handle CNAME/DNAME. 2884 */ 2885 if (resp->result == DNS_R_CNAME || resp->result == DNS_R_DNAME) { 2886 resp->rdataset->ttl = ttlclamp(resp->rdataset->ttl); 2887 clean_target(adb, &name->target); 2888 name->expire_target = INT_MAX; 2889 result = set_target(adb, name->name, resp->foundname, 2890 resp->rdataset, &name->target); 2891 if (result == ISC_R_SUCCESS) { 2892 DP(NCACHE_LEVEL, 2893 "adb fetch name %p: caching alias target", name); 2894 name->expire_target = ADJUSTED_EXPIRE( 2895 name->expire_target, now, resp->rdataset->ttl); 2896 } 2897 goto check_result; 2898 } 2899 2900 /* 2901 * Did we get back junk? If so, and there are no more fetches 2902 * sitting out there, tell all the finds about it. 2903 */ 2904 if (resp->result != ISC_R_SUCCESS) { 2905 char buf[DNS_NAME_FORMATSIZE]; 2906 2907 dns_name_format(name->name, buf, sizeof(buf)); 2908 DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s", buf, 2909 address_type == DNS_ADBFIND_INET ? "A" : "AAAA", 2910 isc_result_totext(resp->result)); 2911 /* 2912 * Don't record a failure unless this is the initial 2913 * fetch of a chain. 2914 */ 2915 if (fetch->depth > 1) { 2916 goto out; 2917 } 2918 /* XXXMLG Don't pound on bad servers. */ 2919 if (address_type == DNS_ADBFIND_INET) { 2920 name->expire_v4 = ISC_MIN(name->expire_v4, now + 10); 2921 name->fetch_err = FIND_ERR_FAILURE; 2922 inc_resstats(adb, dns_resstatscounter_gluefetchv4fail); 2923 } else { 2924 name->expire_v6 = ISC_MIN(name->expire_v6, now + 10); 2925 name->fetch6_err = FIND_ERR_FAILURE; 2926 inc_resstats(adb, dns_resstatscounter_gluefetchv6fail); 2927 } 2928 goto out; 2929 } 2930 2931 /* 2932 * We got something potentially useful. 2933 */ 2934 result = import_rdataset(name, &fetch->rdataset, now); 2935 2936 check_result: 2937 if (result == ISC_R_SUCCESS) { 2938 astat = DNS_ADB_MOREADDRESSES; 2939 if (address_type == DNS_ADBFIND_INET) { 2940 name->fetch_err = FIND_ERR_SUCCESS; 2941 } else { 2942 name->fetch6_err = FIND_ERR_SUCCESS; 2943 } 2944 } 2945 2946 out: 2947 dns_resolver_destroyfetch(&fetch->fetch); 2948 free_adbfetch(adb, &fetch); 2949 isc_mem_putanddetach(&resp->mctx, resp, sizeof(*resp)); 2950 if (astat != DNS_ADB_CANCELED) { 2951 clean_finds_at_name(name, astat, address_type); 2952 } 2953 UNLOCK(&name->lock); 2954 dns_adbname_detach(&name); 2955 dns_adb_detach(&adb); 2956 } 2957 2958 static isc_result_t 2959 fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth, 2960 isc_counter_t *qc, dns_rdatatype_t type) { 2961 isc_result_t result; 2962 dns_adbfetch_t *fetch = NULL; 2963 dns_adb_t *adb = NULL; 2964 dns_fixedname_t fixed; 2965 dns_name_t *name = NULL; 2966 dns_rdataset_t rdataset; 2967 dns_rdataset_t *nameservers = NULL; 2968 unsigned int options; 2969 2970 REQUIRE(DNS_ADBNAME_VALID(adbname)); 2971 2972 adb = adbname->adb; 2973 2974 REQUIRE(DNS_ADB_VALID(adb)); 2975 2976 REQUIRE((type == dns_rdatatype_a && !NAME_FETCH_A(adbname)) || 2977 (type == dns_rdatatype_aaaa && !NAME_FETCH_AAAA(adbname))); 2978 2979 adbname->fetch_err = FIND_ERR_NOTFOUND; 2980 2981 dns_rdataset_init(&rdataset); 2982 2983 options = DNS_FETCHOPT_NOVALIDATE; 2984 2985 if (start_at_zone) { 2986 DP(ENTER_LEVEL, "fetch_name: starting at zone for name %p", 2987 adbname); 2988 name = dns_fixedname_initname(&fixed); 2989 result = dns_view_findzonecut(adb->view, adbname->name, name, 2990 NULL, 0, 0, true, false, 2991 &rdataset, NULL); 2992 if (result != ISC_R_SUCCESS && result != DNS_R_HINT) { 2993 goto cleanup; 2994 } 2995 nameservers = &rdataset; 2996 options |= DNS_FETCHOPT_UNSHARED; 2997 } else if (adb->view->qminimization) { 2998 options |= DNS_FETCHOPT_QMINIMIZE | DNS_FETCHOPT_QMIN_SKIP_IP6A; 2999 if (adb->view->qmin_strict) { 3000 options |= DNS_FETCHOPT_QMIN_STRICT; 3001 } 3002 } 3003 3004 fetch = new_adbfetch(adb); 3005 fetch->depth = depth; 3006 3007 /* 3008 * We're not minimizing this query, as nothing user-related should 3009 * be leaked here. 3010 * However, if we'd ever want to change it we'd have to modify 3011 * createfetch to find deepest cached name when we're providing 3012 * domain and nameservers. 3013 */ 3014 result = dns_resolver_createfetch( 3015 adb->res, adbname->name, type, name, nameservers, NULL, NULL, 0, 3016 options, depth, qc, isc_loop(), fetch_callback, adbname, 3017 &fetch->rdataset, NULL, &fetch->fetch); 3018 if (result != ISC_R_SUCCESS) { 3019 DP(ENTER_LEVEL, "fetch_name: createfetch failed with %s", 3020 isc_result_totext(result)); 3021 goto cleanup; 3022 } 3023 3024 dns_adbname_ref(adbname); 3025 3026 if (type == dns_rdatatype_a) { 3027 adbname->fetch_a = fetch; 3028 inc_resstats(adb, dns_resstatscounter_gluefetchv4); 3029 } else { 3030 adbname->fetch_aaaa = fetch; 3031 inc_resstats(adb, dns_resstatscounter_gluefetchv6); 3032 } 3033 fetch = NULL; /* Keep us from cleaning this up below. */ 3034 3035 cleanup: 3036 if (fetch != NULL) { 3037 free_adbfetch(adb, &fetch); 3038 } 3039 if (dns_rdataset_isassociated(&rdataset)) { 3040 dns_rdataset_disassociate(&rdataset); 3041 } 3042 3043 return result; 3044 } 3045 3046 void 3047 dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int rtt, 3048 unsigned int factor) { 3049 REQUIRE(DNS_ADB_VALID(adb)); 3050 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3051 REQUIRE(factor <= 10); 3052 3053 isc_stdtime_t now = 0; 3054 if (factor == DNS_ADB_RTTADJAGE) { 3055 now = isc_stdtime_now(); 3056 } 3057 3058 adjustsrtt(addr, rtt, factor, now); 3059 } 3060 3061 void 3062 dns_adb_agesrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now) { 3063 REQUIRE(DNS_ADB_VALID(adb)); 3064 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3065 3066 adjustsrtt(addr, 0, DNS_ADB_RTTADJAGE, now); 3067 } 3068 3069 static void 3070 adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor, 3071 isc_stdtime_t now) { 3072 unsigned int new_srtt; 3073 3074 if (factor == DNS_ADB_RTTADJAGE) { 3075 if (atomic_load(&addr->entry->lastage) != now) { 3076 new_srtt = (uint64_t)atomic_load(&addr->entry->srtt) * 3077 98 / 100; 3078 atomic_store(&addr->entry->lastage, now); 3079 atomic_store(&addr->entry->srtt, new_srtt); 3080 addr->srtt = new_srtt; 3081 } 3082 } else { 3083 new_srtt = ((uint64_t)atomic_load(&addr->entry->srtt) / 10 * 3084 factor) + 3085 ((uint64_t)rtt / 10 * (10 - factor)); 3086 atomic_store(&addr->entry->srtt, new_srtt); 3087 addr->srtt = new_srtt; 3088 } 3089 } 3090 3091 void 3092 dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits, 3093 unsigned int mask) { 3094 REQUIRE(DNS_ADB_VALID(adb)); 3095 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3096 3097 dns_adbentry_t *entry = addr->entry; 3098 3099 unsigned int flags = atomic_load(&entry->flags); 3100 while (!atomic_compare_exchange_strong(&entry->flags, &flags, 3101 (flags & ~mask) | (bits & mask))) 3102 { 3103 /* repeat */ 3104 } 3105 3106 /* 3107 * Note that we do not update the other bits in addr->flags with 3108 * the most recent values from addr->entry->flags. 3109 */ 3110 addr->flags = (addr->flags & ~mask) | (bits & mask); 3111 } 3112 3113 /* 3114 * The polynomial backoff curve (10000 / ((10 + n) / 10)^(3/2)) <0..99> drops 3115 * fairly aggressively at first, then slows down and tails off at around 2-3%. 3116 * 3117 * These will be used to make quota adjustments. 3118 */ 3119 static int quota_adj[] = { 3120 10000, 8668, 7607, 6747, 6037, 5443, 4941, 4512, 4141, 3818, 3536, 3121 3286, 3065, 2867, 2690, 2530, 2385, 2254, 2134, 2025, 1925, 1832, 3122 1747, 1668, 1595, 1527, 1464, 1405, 1350, 1298, 1250, 1205, 1162, 3123 1121, 1083, 1048, 1014, 981, 922, 894, 868, 843, 820, 797, 3124 775, 755, 735, 716, 698, 680, 664, 648, 632, 618, 603, 3125 590, 577, 564, 552, 540, 529, 518, 507, 497, 487, 477, 3126 468, 459, 450, 442, 434, 426, 418, 411, 404, 397, 390, 3127 383, 377, 370, 364, 358, 353, 347, 342, 336, 331, 326, 3128 321, 316, 312, 307, 303, 298, 294, 290, 286, 282, 278 3129 }; 3130 3131 #define QUOTA_ADJ_SIZE (sizeof(quota_adj) / sizeof(quota_adj[0])) 3132 3133 /* 3134 * The adb entry associated with 'addr' must be locked. 3135 */ 3136 static void 3137 maybe_adjust_quota(dns_adb_t *adb, dns_adbaddrinfo_t *addr, bool timeout) { 3138 double tr; 3139 3140 UNUSED(adb); 3141 3142 if (adb->quota == 0 || adb->atr_freq == 0) { 3143 return; 3144 } 3145 3146 if (timeout) { 3147 addr->entry->timeouts++; 3148 } 3149 3150 if (addr->entry->completed++ <= adb->atr_freq) { 3151 return; 3152 } 3153 3154 /* 3155 * Calculate an exponential rolling average of the timeout ratio 3156 * 3157 * XXX: Integer arithmetic might be better than floating point 3158 */ 3159 tr = (double)addr->entry->timeouts / addr->entry->completed; 3160 addr->entry->timeouts = addr->entry->completed = 0; 3161 INSIST(addr->entry->atr >= 0.0); 3162 INSIST(addr->entry->atr <= 1.0); 3163 INSIST(adb->atr_discount >= 0.0); 3164 INSIST(adb->atr_discount <= 1.0); 3165 addr->entry->atr *= 1.0 - adb->atr_discount; 3166 addr->entry->atr += tr * adb->atr_discount; 3167 addr->entry->atr = ISC_CLAMP(addr->entry->atr, 0.0, 1.0); 3168 3169 if (addr->entry->atr < adb->atr_low && addr->entry->mode > 0) { 3170 uint_fast32_t new_quota = 3171 adb->quota * quota_adj[--addr->entry->mode] / 10000; 3172 atomic_store_release(&addr->entry->quota, 3173 ISC_MAX(1, new_quota)); 3174 log_quota(addr->entry, 3175 "atr %0.2f, quota increased to %" PRIuFAST32, 3176 addr->entry->atr, new_quota); 3177 } else if (addr->entry->atr > adb->atr_high && 3178 addr->entry->mode < (QUOTA_ADJ_SIZE - 1)) 3179 { 3180 uint_fast32_t new_quota = 3181 adb->quota * quota_adj[++addr->entry->mode] / 10000; 3182 atomic_store_release(&addr->entry->quota, 3183 ISC_MAX(1, new_quota)); 3184 log_quota(addr->entry, 3185 "atr %0.2f, quota decreased to %" PRIuFAST32, 3186 addr->entry->atr, new_quota); 3187 } 3188 } 3189 3190 #define EDNSTOS 3U 3191 3192 void 3193 dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { 3194 REQUIRE(DNS_ADB_VALID(adb)); 3195 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3196 3197 dns_adbentry_t *entry = addr->entry; 3198 LOCK(&entry->lock); 3199 3200 maybe_adjust_quota(adb, addr, false); 3201 3202 entry->plain++; 3203 if (entry->plain == 0xff) { 3204 entry->edns >>= 1; 3205 entry->ednsto >>= 1; 3206 entry->plain >>= 1; 3207 entry->plainto >>= 1; 3208 } 3209 UNLOCK(&entry->lock); 3210 } 3211 3212 void 3213 dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { 3214 REQUIRE(DNS_ADB_VALID(adb)); 3215 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3216 3217 dns_adbentry_t *entry = addr->entry; 3218 LOCK(&entry->lock); 3219 3220 maybe_adjust_quota(adb, addr, true); 3221 3222 addr->entry->plainto++; 3223 if (addr->entry->plainto == 0xff) { 3224 addr->entry->edns >>= 1; 3225 addr->entry->ednsto >>= 1; 3226 addr->entry->plain >>= 1; 3227 addr->entry->plainto >>= 1; 3228 } 3229 UNLOCK(&entry->lock); 3230 } 3231 3232 void 3233 dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { 3234 REQUIRE(DNS_ADB_VALID(adb)); 3235 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3236 3237 dns_adbentry_t *entry = addr->entry; 3238 LOCK(&entry->lock); 3239 3240 maybe_adjust_quota(adb, addr, true); 3241 3242 entry->ednsto++; 3243 if (addr->entry->ednsto == 0xff) { 3244 entry->edns >>= 1; 3245 entry->ednsto >>= 1; 3246 entry->plain >>= 1; 3247 entry->plainto >>= 1; 3248 } 3249 UNLOCK(&entry->lock); 3250 } 3251 3252 void 3253 dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) { 3254 REQUIRE(DNS_ADB_VALID(adb)); 3255 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3256 3257 dns_adbentry_t *entry = addr->entry; 3258 3259 LOCK(&entry->lock); 3260 if (size < 512U) { 3261 size = 512U; 3262 } 3263 if (size > addr->entry->udpsize) { 3264 addr->entry->udpsize = size; 3265 } 3266 3267 maybe_adjust_quota(adb, addr, false); 3268 3269 entry->edns++; 3270 if (entry->edns == 0xff) { 3271 entry->edns >>= 1; 3272 entry->ednsto >>= 1; 3273 entry->plain >>= 1; 3274 entry->plainto >>= 1; 3275 } 3276 UNLOCK(&entry->lock); 3277 } 3278 3279 unsigned int 3280 dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { 3281 REQUIRE(DNS_ADB_VALID(adb)); 3282 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3283 3284 unsigned int size; 3285 dns_adbentry_t *entry = addr->entry; 3286 3287 LOCK(&entry->lock); 3288 size = entry->udpsize; 3289 UNLOCK(&entry->lock); 3290 3291 return size; 3292 } 3293 3294 void 3295 dns_adb_setcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr, 3296 const unsigned char *cookie, size_t len) { 3297 REQUIRE(DNS_ADB_VALID(adb)); 3298 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3299 3300 dns_adbentry_t *entry = addr->entry; 3301 3302 LOCK(&entry->lock); 3303 3304 if (entry->cookie != NULL && 3305 (cookie == NULL || len != entry->cookielen)) 3306 { 3307 isc_mem_put(adb->mctx, entry->cookie, entry->cookielen); 3308 entry->cookie = NULL; 3309 entry->cookielen = 0; 3310 } 3311 3312 if (entry->cookie == NULL && cookie != NULL && len != 0U) { 3313 entry->cookie = isc_mem_get(adb->mctx, len); 3314 entry->cookielen = (uint16_t)len; 3315 } 3316 3317 if (entry->cookie != NULL) { 3318 memmove(entry->cookie, cookie, len); 3319 } 3320 UNLOCK(&entry->lock); 3321 } 3322 3323 size_t 3324 dns_adb_getcookie(dns_adbaddrinfo_t *addr, unsigned char *cookie, size_t len) { 3325 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3326 3327 dns_adbentry_t *entry = addr->entry; 3328 3329 LOCK(&entry->lock); 3330 if (entry->cookie == NULL) { 3331 len = 0; 3332 goto unlock; 3333 } 3334 if (cookie != NULL) { 3335 if (len < entry->cookielen) { 3336 len = 0; 3337 goto unlock; 3338 } 3339 memmove(cookie, entry->cookie, entry->cookielen); 3340 } 3341 len = entry->cookielen; 3342 3343 unlock: 3344 UNLOCK(&entry->lock); 3345 3346 return len; 3347 } 3348 3349 isc_result_t 3350 dns_adb_findaddrinfo(dns_adb_t *adb, const isc_sockaddr_t *sa, 3351 dns_adbaddrinfo_t **addrp, isc_stdtime_t now) { 3352 REQUIRE(DNS_ADB_VALID(adb)); 3353 REQUIRE(addrp != NULL && *addrp == NULL); 3354 UNUSED(now); 3355 3356 isc_result_t result = ISC_R_SUCCESS; 3357 dns_adbentry_t *entry = NULL; 3358 dns_adbaddrinfo_t *addr = NULL; 3359 in_port_t port; 3360 3361 if (atomic_load(&adb->exiting)) { 3362 return ISC_R_SHUTTINGDOWN; 3363 } 3364 3365 entry = get_attached_and_locked_entry(adb, now, sa); 3366 3367 UNLOCK(&entry->lock); 3368 3369 port = isc_sockaddr_getport(sa); 3370 addr = new_adbaddrinfo(adb, entry, port); 3371 *addrp = addr; 3372 3373 dns_adbentry_detach(&entry); 3374 3375 return result; 3376 } 3377 3378 void 3379 dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) { 3380 dns_adbaddrinfo_t *addr = NULL; 3381 dns_adbentry_t *entry = NULL; 3382 3383 REQUIRE(DNS_ADB_VALID(adb)); 3384 REQUIRE(addrp != NULL); 3385 3386 addr = *addrp; 3387 *addrp = NULL; 3388 3389 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3390 3391 entry = addr->entry; 3392 3393 REQUIRE(DNS_ADBENTRY_VALID(entry)); 3394 3395 free_adbaddrinfo(adb, &addr); 3396 } 3397 3398 void 3399 dns_adb_flush(dns_adb_t *adb) { 3400 REQUIRE(DNS_ADB_VALID(adb)); 3401 3402 if (atomic_load(&adb->exiting)) { 3403 return; 3404 } 3405 3406 cleanup_names(adb, INT_MAX); 3407 cleanup_entries(adb, INT_MAX); 3408 #ifdef DUMP_ADB_AFTER_CLEANING 3409 dump_adb(adb, stdout, true, INT_MAX); 3410 #endif /* ifdef DUMP_ADB_AFTER_CLEANING */ 3411 } 3412 3413 void 3414 dns_adb_flushname(dns_adb_t *adb, const dns_name_t *name) { 3415 dns_adbname_t *adbname = NULL; 3416 isc_result_t result; 3417 bool start_at_zone = false; 3418 bool static_stub = false; 3419 dns_adbname_t key = { .name = UNCONST(name) }; 3420 3421 REQUIRE(DNS_ADB_VALID(adb)); 3422 REQUIRE(name != NULL); 3423 3424 if (atomic_load(&adb->exiting)) { 3425 return; 3426 } 3427 3428 RWLOCK(&adb->names_lock, isc_rwlocktype_write); 3429 again: 3430 /* 3431 * Delete all entries - with and without DNS_ADBFIND_STARTATZONE set 3432 * and with and without DNS_ADBFIND_STATICSTUB set. 3433 */ 3434 key.flags = ((static_stub) ? DNS_ADBFIND_STATICSTUB : 0) | 3435 ((start_at_zone) ? DNS_ADBFIND_STARTATZONE : 0); 3436 3437 result = isc_hashmap_find(adb->names, hash_adbname(&key), match_adbname, 3438 (void *)&key, (void **)&adbname); 3439 if (result == ISC_R_SUCCESS) { 3440 dns_adbname_ref(adbname); 3441 LOCK(&adbname->lock); 3442 if (dns_name_equal(name, adbname->name)) { 3443 expire_name(adbname, DNS_ADB_CANCELED); 3444 } 3445 UNLOCK(&adbname->lock); 3446 dns_adbname_detach(&adbname); 3447 } 3448 if (!start_at_zone) { 3449 start_at_zone = true; 3450 goto again; 3451 } 3452 if (!static_stub) { 3453 static_stub = true; 3454 goto again; 3455 } 3456 RWUNLOCK(&adb->names_lock, isc_rwlocktype_write); 3457 } 3458 3459 void 3460 dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name) { 3461 dns_adbname_t *next = NULL; 3462 3463 REQUIRE(DNS_ADB_VALID(adb)); 3464 REQUIRE(name != NULL); 3465 3466 if (atomic_load(&adb->exiting)) { 3467 return; 3468 } 3469 3470 RWLOCK(&adb->names_lock, isc_rwlocktype_write); 3471 for (dns_adbname_t *adbname = ISC_LIST_HEAD(adb->names_lru); 3472 adbname != NULL; adbname = next) 3473 { 3474 next = ISC_LIST_NEXT(adbname, link); 3475 dns_adbname_ref(adbname); 3476 LOCK(&adbname->lock); 3477 if (dns_name_issubdomain(adbname->name, name)) { 3478 expire_name(adbname, DNS_ADB_CANCELED); 3479 } 3480 UNLOCK(&adbname->lock); 3481 dns_adbname_detach(&adbname); 3482 } 3483 RWUNLOCK(&adb->names_lock, isc_rwlocktype_write); 3484 } 3485 3486 void 3487 dns_adb_setadbsize(dns_adb_t *adb, size_t size) { 3488 size_t hiwater, lowater; 3489 3490 REQUIRE(DNS_ADB_VALID(adb)); 3491 3492 if (size != 0U && size < DNS_ADB_MINADBSIZE) { 3493 size = DNS_ADB_MINADBSIZE; 3494 } 3495 3496 hiwater = size - (size >> 3); /* Approximately 7/8ths. */ 3497 lowater = size - (size >> 2); /* Approximately 3/4ths. */ 3498 3499 if (size == 0U || hiwater == 0U || lowater == 0U) { 3500 isc_mem_clearwater(adb->mctx); 3501 } else { 3502 isc_mem_setwater(adb->mctx, hiwater, lowater); 3503 } 3504 } 3505 3506 void 3507 dns_adb_setquota(dns_adb_t *adb, uint32_t quota, uint32_t freq, double low, 3508 double high, double discount) { 3509 REQUIRE(DNS_ADB_VALID(adb)); 3510 3511 adb->quota = quota; 3512 adb->atr_freq = freq; 3513 adb->atr_low = low; 3514 adb->atr_high = high; 3515 adb->atr_discount = discount; 3516 } 3517 3518 void 3519 dns_adb_getquota(dns_adb_t *adb, uint32_t *quotap, uint32_t *freqp, 3520 double *lowp, double *highp, double *discountp) { 3521 REQUIRE(DNS_ADB_VALID(adb)); 3522 3523 SET_IF_NOT_NULL(quotap, adb->quota); 3524 3525 SET_IF_NOT_NULL(freqp, adb->atr_freq); 3526 3527 SET_IF_NOT_NULL(lowp, adb->atr_low); 3528 3529 SET_IF_NOT_NULL(highp, adb->atr_high); 3530 3531 SET_IF_NOT_NULL(discountp, adb->atr_discount); 3532 } 3533 3534 static bool 3535 adbentry_overquota(dns_adbentry_t *entry) { 3536 REQUIRE(DNS_ADBENTRY_VALID(entry)); 3537 3538 uint_fast32_t quota = atomic_load_relaxed(&entry->quota); 3539 uint_fast32_t active = atomic_load_acquire(&entry->active); 3540 3541 return quota != 0 && active >= quota; 3542 } 3543 3544 bool 3545 dns_adb_overquota(dns_adb_t *adb ISC_ATTR_UNUSED, dns_adbaddrinfo_t *addrinfo) { 3546 REQUIRE(DNS_ADBADDRINFO_VALID(addrinfo)); 3547 3548 return adbentry_overquota(addrinfo->entry); 3549 } 3550 3551 void 3552 dns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { 3553 uint_fast32_t active; 3554 3555 REQUIRE(DNS_ADB_VALID(adb)); 3556 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3557 3558 active = atomic_fetch_add_relaxed(&addr->entry->active, 1); 3559 INSIST(active != UINT32_MAX); 3560 } 3561 3562 void 3563 dns_adb_endudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { 3564 uint_fast32_t active; 3565 3566 REQUIRE(DNS_ADB_VALID(adb)); 3567 REQUIRE(DNS_ADBADDRINFO_VALID(addr)); 3568 3569 active = atomic_fetch_sub_release(&addr->entry->active, 1); 3570 INSIST(active != 0); 3571 } 3572 3573 isc_stats_t * 3574 dns_adb_getstats(dns_adb_t *adb) { 3575 REQUIRE(DNS_ADB_VALID(adb)); 3576 3577 return adb->stats; 3578 } 3579