Lines Matching defs:adb

18 /* $Id: adb.c,v 1.264 2011/12/05 17:10:51 each Exp $ */
41 #include <dns/adb.h>
102 /*% dns adb structure */
177 dns_adb_t *adb;
362 * Note: since we have removed the support of A6 in adb, FETCH_A and FETCH_AAAA
474 inc_stats(dns_adb_t *adb, isc_statscounter_t counter) {
475 if (adb->view->resstats != NULL)
476 isc_stats_increment(adb->view->resstats, counter);
507 dns_adb_t *adb;
517 adb = ev->ev_arg;
518 INSIST(DNS_ADB_VALID(adb));
527 while (nbuckets[i] != 0 && adb->nentries >= nbuckets[i])
534 DP(ISC_LOG_INFO, "adb: grow_entries to %u starting", n);
539 for (i = 0; i < adb->nentries; i++)
540 if (adb->entry_sd[i])
546 newentries = isc_mem_get(adb->mctx, sizeof(*newentries) * n);
547 newdeadentries = isc_mem_get(adb->mctx, sizeof(*newdeadentries) * n);
548 newentrylocks = isc_mem_get(adb->mctx, sizeof(*newentrylocks) * n);
549 newentry_sd = isc_mem_get(adb->mctx, sizeof(*newentry_sd) * n);
550 newentry_refcnt = isc_mem_get(adb->mctx, sizeof(*newentry_refcnt) * n);
568 adb->irefcnt++;
574 for (i = 0; i < adb->nentries; i++) {
575 e = ISC_LIST_HEAD(adb->entries[i]);
577 ISC_LIST_UNLINK(adb->entries[i], e, plink);
581 INSIST(adb->entry_refcnt[i] > 0);
582 adb->entry_refcnt[i]--;
584 e = ISC_LIST_HEAD(adb->entries[i]);
586 e = ISC_LIST_HEAD(adb->deadentries[i]);
588 ISC_LIST_UNLINK(adb->deadentries[i], e, plink);
592 INSIST(adb->entry_refcnt[i] > 0);
593 adb->entry_refcnt[i]--;
595 e = ISC_LIST_HEAD(adb->deadentries[i]);
597 INSIST(adb->entry_refcnt[i] == 0);
598 adb->irefcnt--;
604 DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
605 isc_mem_put(adb->mctx, adb->entries,
606 sizeof(*adb->entries) * adb->nentries);
607 isc_mem_put(adb->mctx, adb->deadentries,
608 sizeof(*adb->deadentries) * adb->nentries);
609 isc_mem_put(adb->mctx, adb->entrylocks,
610 sizeof(*adb->entrylocks) * adb->nentries);
611 isc_mem_put(adb->mctx, adb->entry_sd,
612 sizeof(*adb->entry_sd) * adb->nentries);
613 isc_mem_put(adb->mctx, adb->entry_refcnt,
614 sizeof(*adb->entry_refcnt) * adb->nentries);
619 adb->entries = newentries;
620 adb->deadentries = newdeadentries;
621 adb->entrylocks = newentrylocks;
622 adb->entry_sd = newentry_sd;
623 adb->entry_refcnt = newentry_refcnt;
624 adb->nentries = n;
627 * Only on success do we set adb->growentries_sent to ISC_FALSE.
630 adb->growentries_sent = ISC_FALSE;
635 isc_mem_put(adb->mctx, newentries,
638 isc_mem_put(adb->mctx, newdeadentries,
641 isc_mem_put(adb->mctx, newentrylocks,
644 isc_mem_put(adb->mctx, newentry_sd,
647 isc_mem_put(adb->mctx, newentry_refcnt,
653 LOCK(&adb->lock);
654 if (dec_adb_irefcnt(adb))
655 check_exit(adb);
656 UNLOCK(&adb->lock);
657 DP(ISC_LOG_INFO, "adb: grow_entries finished");
662 dns_adb_t *adb;
672 adb = ev->ev_arg;
673 INSIST(DNS_ADB_VALID(adb));
682 while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i])
689 DP(ISC_LOG_INFO, "adb: grow_names to %u starting", n);
694 for (i = 0; i < adb->nnames; i++)
695 if (adb->name_sd[i])
701 newnames = isc_mem_get(adb->mctx, sizeof(*newnames) * n);
702 newdeadnames = isc_mem_get(adb->mctx, sizeof(*newdeadnames) * n);
703 newnamelocks = isc_mem_get(adb->mctx, sizeof(*newnamelocks) * n);
704 newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n);
705 newname_refcnt = isc_mem_get(adb->mctx, sizeof(*newname_refcnt) * n);
723 adb->irefcnt++;
729 for (i = 0; i < adb->nnames; i++) {
730 name = ISC_LIST_HEAD(adb->names[i]);
732 ISC_LIST_UNLINK(adb->names[i], name, plink);
736 INSIST(adb->name_refcnt[i] > 0);
737 adb->name_refcnt[i]--;
739 name = ISC_LIST_HEAD(adb->names[i]);
741 name = ISC_LIST_HEAD(adb->deadnames[i]);
743 ISC_LIST_UNLINK(adb->deadnames[i], name, plink);
747 INSIST(adb->name_refcnt[i] > 0);
748 adb->name_refcnt[i]--;
750 name = ISC_LIST_HEAD(adb->deadnames[i]);
752 INSIST(adb->name_refcnt[i] == 0);
753 adb->irefcnt--;
759 DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames);
760 isc_mem_put(adb->mctx, adb->names,
761 sizeof(*adb->names) * adb->nnames);
762 isc_mem_put(adb->mctx, adb->deadnames,
763 sizeof(*adb->deadnames) * adb->nnames);
764 isc_mem_put(adb->mctx, adb->namelocks,
765 sizeof(*adb->namelocks) * adb->nnames);
766 isc_mem_put(adb->mctx, adb->name_sd,
767 sizeof(*adb->name_sd) * adb->nnames);
768 isc_mem_put(adb->mctx, adb->name_refcnt,
769 sizeof(*adb->name_refcnt) * adb->nnames);
774 adb->names = newnames;
775 adb->deadnames = newdeadnames;
776 adb->namelocks = newnamelocks;
777 adb->name_sd = newname_sd;
778 adb->name_refcnt = newname_refcnt;
779 adb->nnames = n;
782 * Only on success do we set adb->grownames_sent to ISC_FALSE.
785 adb->grownames_sent = ISC_FALSE;
790 isc_mem_put(adb->mctx, newnames, sizeof(*newnames) * n);
792 isc_mem_put(adb->mctx, newdeadnames, sizeof(*newdeadnames) * n);
794 isc_mem_put(adb->mctx, newnamelocks, sizeof(*newnamelocks) * n);
796 isc_mem_put(adb->mctx, newname_sd, sizeof(*newname_sd) * n);
798 isc_mem_put(adb->mctx, newname_refcnt,
804 LOCK(&adb->lock);
805 if (dec_adb_irefcnt(adb))
806 check_exit(adb);
807 UNLOCK(&adb->lock);
808 DP(ISC_LOG_INFO, "adb: grow_names finished");
821 dns_adb_t *adb;
836 adb = adbname->adb;
837 INSIST(DNS_ADB_VALID(adb));
867 nh = new_adbnamehook(adb, NULL);
874 foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket,
879 entry = new_adbentry(adb);
891 link_entry(adb, addr_bucket, entry);
902 free_adbnamehook(adb, &nh);
914 free_adbnamehook(adb, &nh);
917 UNLOCK(&adb->entrylocks[addr_bucket]);
959 dns_adb_t *adb;
965 adb = name->adb;
966 INSIST(DNS_ADB_VALID(adb));
975 result = unlink_name(adb, name);
976 free_adbname(adb, &name);
978 result = dec_adb_irefcnt(adb);
987 result4 = clean_namehooks(adb, &name->v4);
988 result6 = clean_namehooks(adb, &name->v6);
989 clean_target(adb, &name->target);
998 result = unlink_name(adb, name);
999 free_adbname(adb, &name);
1001 result = dec_adb_irefcnt(adb);
1006 ISC_LIST_UNLINK(adb->names[bucket], name, plink);
1007 ISC_LIST_APPEND(adb->deadnames[bucket], name, plink);
1019 dns_adb_t *adb;
1024 adb = name->adb;
1025 INSIST(DNS_ADB_VALID(adb));
1033 result4 = clean_namehooks(adb, &name->v4);
1046 result6 = clean_namehooks(adb, &name->v6);
1057 clean_target(adb, &name->target);
1067 link_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) {
1070 ISC_LIST_PREPEND(adb->names[bucket], name, plink);
1072 adb->name_refcnt[bucket]++;
1079 unlink_name(dns_adb_t *adb, dns_adbname_t *name) {
1087 ISC_LIST_UNLINK(adb->deadnames[bucket], name, plink);
1089 ISC_LIST_UNLINK(adb->names[bucket], name, plink);
1091 INSIST(adb->name_refcnt[bucket] > 0);
1092 adb->name_refcnt[bucket]--;
1093 if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
1102 link_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) {
1106 if (isc_mem_isovermem(adb->mctx)) {
1108 e = ISC_LIST_TAIL(adb->entries[bucket]);
1112 unlink_entry(adb, e);
1113 free_adbentry(adb, &e);
1118 ISC_LIST_UNLINK(adb->entries[bucket], e, plink);
1119 ISC_LIST_PREPEND(adb->deadentries[bucket], e, plink);
1123 ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
1125 adb->entry_refcnt[bucket]++;
1132 unlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) {
1140 ISC_LIST_UNLINK(adb->deadentries[bucket], entry, plink);
1142 ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
1144 INSIST(adb->entry_refcnt[bucket] > 0);
1145 adb->entry_refcnt[bucket]--;
1146 if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0)
1165 shutdown_names(dns_adb_t *adb) {
1171 for (bucket = 0; bucket < adb->nnames; bucket++) {
1172 LOCK(&adb->namelocks[bucket]);
1173 adb->name_sd[bucket] = ISC_TRUE;
1175 name = ISC_LIST_HEAD(adb->names[bucket]);
1183 result = dec_adb_irefcnt(adb);
1200 UNLOCK(&adb->namelocks[bucket]);
1210 shutdown_entries(dns_adb_t *adb) {
1216 for (bucket = 0; bucket < adb->nentries; bucket++) {
1217 LOCK(&adb->entrylocks[bucket]);
1218 adb->entry_sd[bucket] = ISC_TRUE;
1220 entry = ISC_LIST_HEAD(adb->entries[bucket]);
1221 if (adb->entry_refcnt[bucket] == 0) {
1227 result = dec_adb_irefcnt(adb);
1237 result = unlink_entry(adb, entry);
1238 free_adbentry(adb, &entry);
1240 result = dec_adb_irefcnt(adb);
1246 UNLOCK(&adb->entrylocks[bucket]);
1267 clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
1272 isc_boolean_t overmem = isc_mem_isovermem(adb->mctx);
1288 UNLOCK(&adb->entrylocks[addr_bucket]);
1291 LOCK(&adb->entrylocks[addr_bucket]);
1294 result = dec_entry_refcnt(adb, overmem, entry,
1303 free_adbnamehook(adb, &namehook);
1309 UNLOCK(&adb->entrylocks[addr_bucket]);
1314 clean_target(dns_adb_t *adb, dns_name_t *target) {
1316 dns_name_free(target, adb->mctx);
1322 set_target(dns_adb_t *adb, dns_name_t *name, dns_name_t *fname,
1348 result = dns_name_dup(&cname.cname, adb->mctx, target);
1381 result = dns_name_dup(new_target, adb->mctx, target);
1493 check_exit(dns_adb_t *adb) {
1496 * The caller must be holding the adb lock.
1498 if (adb->shutting_down) {
1503 INSIST(!adb->cevent_sent); /* Sanity check. */
1504 event = &adb->cevent;
1505 isc_task_send(adb->task, &event);
1506 adb->cevent_sent = ISC_TRUE;
1511 dec_adb_irefcnt(dns_adb_t *adb) {
1516 LOCK(&adb->reflock);
1518 INSIST(adb->irefcnt > 0);
1519 adb->irefcnt--;
1521 if (adb->irefcnt == 0) {
1522 event = ISC_LIST_HEAD(adb->whenshutdown);
1524 ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link);
1526 event->ev_sender = adb;
1528 event = ISC_LIST_HEAD(adb->whenshutdown);
1532 if (adb->irefcnt == 0 && adb->erefcnt == 0)
1534 UNLOCK(&adb->reflock);
1539 inc_adb_irefcnt(dns_adb_t *adb) {
1540 LOCK(&adb->reflock);
1541 adb->irefcnt++;
1542 UNLOCK(&adb->reflock);
1546 inc_adb_erefcnt(dns_adb_t *adb) {
1547 LOCK(&adb->reflock);
1548 adb->erefcnt++;
1549 UNLOCK(&adb->reflock);
1553 inc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {
1559 LOCK(&adb->entrylocks[bucket]);
1564 UNLOCK(&adb->entrylocks[bucket]);
1568 dec_entry_refcnt(dns_adb_t *adb, isc_boolean_t overmem, dns_adbentry_t *entry,
1578 LOCK(&adb->entrylocks[bucket]);
1585 (adb->entry_sd[bucket] || entry->expires == 0 || overmem ||
1588 result = unlink_entry(adb, entry);
1592 UNLOCK(&adb->entrylocks[bucket]);
1599 free_adbentry(adb, &entry);
1601 result = dec_adb_irefcnt(adb);
1607 new_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
1610 name = isc_mempool_get(adb->nmp);
1615 if (dns_name_dup(dnsname, adb->mctx, &name->name) != ISC_R_SUCCESS) {
1616 isc_mempool_put(adb->nmp, name);
1621 name->adb = adb;
1638 LOCK(&adb->namescntlock);
1639 adb->namescnt++;
1640 if (!adb->grownames_sent && adb->excl != NULL &&
1641 adb->namescnt > (adb->nnames * 8))
1643 isc_event_t *event = &adb->grownames;
1644 inc_adb_irefcnt(adb);
1645 isc_task_send(adb->excl, &event);
1646 adb->grownames_sent = ISC_TRUE;
1648 UNLOCK(&adb->namescntlock);
1654 free_adbname(dns_adb_t *adb, dns_adbname_t **name) {
1667 INSIST(n->adb == adb);
1670 dns_name_free(&n->name, adb->mctx);
1672 isc_mempool_put(adb->nmp, n);
1673 LOCK(&adb->namescntlock);
1674 adb->namescnt--;
1675 UNLOCK(&adb->namescntlock);
1679 new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
1682 nh = isc_mempool_get(adb->nhmp);
1694 free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
1705 isc_mempool_put(adb->nhmp, nh);
1709 new_adblameinfo(dns_adb_t *adb, dns_name_t *qname, dns_rdatatype_t qtype) {
1712 li = isc_mempool_get(adb->limp);
1717 if (dns_name_dup(qname, adb->mctx, &li->qname) != ISC_R_SUCCESS) {
1718 isc_mempool_put(adb->limp, li);
1730 free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) {
1739 dns_name_free(&li->qname, adb->mctx);
1743 isc_mempool_put(adb->limp, li);
1747 new_adbentry(dns_adb_t *adb) {
1751 e = isc_mempool_get(adb->emp);
1764 LOCK(&adb->entriescntlock);
1765 adb->entriescnt++;
1766 if (!adb->growentries_sent && adb->growentries_sent &&
1767 adb->entriescnt > (adb->nentries * 8))
1769 isc_event_t *event = &adb->growentries;
1770 inc_adb_irefcnt(adb);
1771 isc_task_send(adb->task, &event);
1772 adb->growentries_sent = ISC_TRUE;
1774 UNLOCK(&adb->entriescntlock);
1780 free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
1797 free_adblameinfo(adb, &li);
1801 isc_mempool_put(adb->emp, e);
1802 LOCK(&adb->entriescntlock);
1803 adb->entriescnt--;
1804 UNLOCK(&adb->entriescntlock);
1808 new_adbfind(dns_adb_t *adb) {
1812 h = isc_mempool_get(adb->ahmp);
1820 h->adb = adb;
1838 isc_mempool_put(adb->ahmp, h);
1845 inc_adb_irefcnt(adb);
1851 new_adbfetch(dns_adb_t *adb) {
1854 f = isc_mempool_get(adb->afmp);
1869 free_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) {
1881 isc_mempool_put(adb->afmp, f);
1885 free_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) {
1901 isc_mempool_put(adb->ahmp, find);
1902 return (dec_adb_irefcnt(adb));
1911 new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
1914 ai = isc_mempool_get(adb->aimp);
1930 free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
1942 isc_mempool_put(adb->aimp, ai);
1953 find_name_and_lock(dns_adb_t *adb, dns_name_t *name,
1959 bucket = dns_name_fullhash(name, ISC_FALSE) % adb->nnames;
1962 LOCK(&adb->namelocks[bucket]);
1965 UNLOCK(&adb->namelocks[*bucketp]);
1966 LOCK(&adb->namelocks[bucket]);
1970 adbname = ISC_LIST_HEAD(adb->names[bucket]);
1995 find_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp,
2001 bucket = isc_sockaddr_hash(addr, ISC_TRUE) % adb->nentries;
2004 LOCK(&adb->entrylocks[bucket]);
2007 UNLOCK(&adb->entrylocks[*bucketp]);
2008 LOCK(&adb->entrylocks[bucket]);
2013 for (entry = ISC_LIST_HEAD(adb->entries[bucket]);
2017 (void)check_expire_entry(adb, &entry, now);
2020 ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
2021 ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
2033 entry_is_lame(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *qname,
2052 free_adblameinfo(adb, &li);
2072 copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname,
2089 LOCK(&adb->entrylocks[bucket]);
2092 && entry_is_lame(adb, entry, qname, qtype, now)) {
2096 addrinfo = new_adbaddrinfo(adb, entry, find->port);
2104 inc_entry_refcnt(adb, entry, ISC_FALSE);
2108 UNLOCK(&adb->entrylocks[bucket]);
2120 LOCK(&adb->entrylocks[bucket]);
2123 && entry_is_lame(adb, entry, qname, qtype, now)) {
2127 addrinfo = new_adbaddrinfo(adb, entry, find->port);
2135 inc_entry_refcnt(adb, entry, ISC_FALSE);
2139 UNLOCK(&adb->entrylocks[bucket]);
2147 UNLOCK(&adb->entrylocks[bucket]);
2152 dns_adb_t *adb;
2156 adb = ev->ev_arg;
2157 INSIST(DNS_ADB_VALID(adb));
2163 LOCK(&adb->lock);
2164 UNLOCK(&adb->lock);
2165 destroy(adb);
2169 * Name bucket must be locked; adb may be locked; no other locks held.
2212 * Name bucket must be locked; adb may be locked; no other locks held.
2215 check_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
2218 isc_boolean_t overmem = isc_mem_isovermem(adb->mctx);
2231 victim = ISC_LIST_TAIL(adb->names[bucket]);
2259 * Entry bucket must be locked; adb may be locked; no other locks held.
2262 check_expire_entry(dns_adb_t *adb, dns_adbentry_t **entryp, isc_stdtime_t now)
2281 result = unlink_entry(adb, entry);
2282 free_adbentry(adb, &entry);
2284 dec_adb_irefcnt(adb);
2293 cleanup_names(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
2300 LOCK(&adb->namelocks[bucket]);
2301 if (adb->name_sd[bucket]) {
2302 UNLOCK(&adb->namelocks[bucket]);
2306 name = ISC_LIST_HEAD(adb->names[bucket]);
2315 UNLOCK(&adb->namelocks[bucket]);
2323 cleanup_entries(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
2329 LOCK(&adb->entrylocks[bucket]);
2330 entry = ISC_LIST_HEAD(adb->entries[bucket]);
2334 result = check_expire_entry(adb, &entry, now);
2337 UNLOCK(&adb->entrylocks[bucket]);
2342 destroy(dns_adb_t *adb) {
2343 adb->magic = 0;
2345 isc_task_detach(&adb->task);
2346 if (adb->excl != NULL)
2347 isc_task_detach(&adb->excl);
2349 isc_mempool_destroy(&adb->nmp);
2350 isc_mempool_destroy(&adb->nhmp);
2351 isc_mempool_destroy(&adb->limp);
2352 isc_mempool_destroy(&adb->emp);
2353 isc_mempool_destroy(&adb->ahmp);
2354 isc_mempool_destroy(&adb->aimp);
2355 isc_mempool_destroy(&adb->afmp);
2357 DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
2358 isc_mem_put(adb->mctx, adb->entries,
2359 sizeof(*adb->entries) * adb->nentries);
2360 isc_mem_put(adb->mctx, adb->deadentries,
2361 sizeof(*adb->deadentries) * adb->nentries);
2362 isc_mem_put(adb->mctx, adb->entrylocks,
2363 sizeof(*adb->entrylocks) * adb->nentries);
2364 isc_mem_put(adb->mctx, adb->entry_sd,
2365 sizeof(*adb->entry_sd) * adb->nentries);
2366 isc_mem_put(adb->mctx, adb->entry_refcnt,
2367 sizeof(*adb->entry_refcnt) * adb->nentries);
2369 DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames);
2370 isc_mem_put(adb->mctx, adb->names,
2371 sizeof(*adb->names) * adb->nnames);
2372 isc_mem_put(adb->mctx, adb->deadnames,
2373 sizeof(*adb->deadnames) * adb->nnames);
2374 isc_mem_put(adb->mctx, adb->namelocks,
2375 sizeof(*adb->namelocks) * adb->nnames);
2376 isc_mem_put(adb->mctx, adb->name_sd,
2377 sizeof(*adb->name_sd) * adb->nnames);
2378 isc_mem_put(adb->mctx, adb->name_refcnt,
2379 sizeof(*adb->name_refcnt) * adb->nnames);
2381 DESTROYLOCK(&adb->reflock);
2382 DESTROYLOCK(&adb->lock);
2383 DESTROYLOCK(&adb->mplock);
2384 DESTROYLOCK(&adb->overmemlock);
2385 DESTROYLOCK(&adb->entriescntlock);
2386 DESTROYLOCK(&adb->namescntlock);
2388 isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
2400 dns_adb_t *adb;
2412 adb = isc_mem_get(mem, sizeof(dns_adb_t));
2413 if (adb == NULL)
2420 adb->magic = 0;
2421 adb->erefcnt = 1;
2422 adb->irefcnt = 0;
2423 adb->nmp = NULL;
2424 adb->nhmp = NULL;
2425 adb->limp = NULL;
2426 adb->emp = NULL;
2427 adb->ahmp = NULL;
2428 adb->aimp = NULL;
2429 adb->afmp = NULL;
2430 adb->task = NULL;
2431 adb->excl = NULL;
2432 adb->mctx = NULL;
2433 adb->view = view;
2434 adb->taskmgr = taskmgr;
2435 adb->next_cleanbucket = 0;
2436 ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
2437 DNS_EVENT_ADBCONTROL, shutdown_task, adb,
2438 adb, NULL, NULL);
2439 adb->cevent_sent = ISC_FALSE;
2440 adb->shutting_down = ISC_FALSE;
2441 ISC_LIST_INIT(adb->whenshutdown);
2443 adb->nentries = nbuckets[0];
2444 adb->entriescnt = 0;
2445 adb->entries = NULL;
2446 adb->deadentries = NULL;
2447 adb->entry_sd = NULL;
2448 adb->entry_refcnt = NULL;
2449 adb->entrylocks = NULL;
2450 ISC_EVENT_INIT(&adb->growentries, sizeof(adb->growentries), 0, NULL,
2451 DNS_EVENT_ADBGROWENTRIES, grow_entries, adb,
2452 adb, NULL, NULL);
2453 adb->growentries_sent = ISC_FALSE;
2455 adb->nnames = nbuckets[0];
2456 adb->namescnt = 0;
2457 adb->names = NULL;
2458 adb->deadnames = NULL;
2459 adb->name_sd = NULL;
2460 adb->name_refcnt = NULL;
2461 adb->namelocks = NULL;
2462 ISC_EVENT_INIT(&adb->grownames, sizeof(adb->grownames), 0, NULL,
2463 DNS_EVENT_ADBGROWNAMES, grow_names, adb,
2464 adb, NULL, NULL);
2465 adb->grownames_sent = ISC_FALSE;
2467 result = isc_taskmgr_excltask(adb->taskmgr, &adb->excl);
2469 DP(ISC_LOG_INFO, "adb: task-exclusive mode unavailable, "
2472 adb->nentries = nbuckets[11];
2473 adb->nnames= nbuckets[11];
2477 isc_mem_attach(mem, &adb->mctx);
2479 result = isc_mutex_init(&adb->lock);
2483 result = isc_mutex_init(&adb->mplock);
2487 result = isc_mutex_init(&adb->reflock);
2491 result = isc_mutex_init(&adb->overmemlock);
2495 result = isc_mutex_init(&adb->entriescntlock);
2499 result = isc_mutex_init(&adb->namescntlock);
2503 #define ALLOCENTRY(adb, el) \
2505 (adb)->el = isc_mem_get((adb)->mctx, \
2506 sizeof(*(adb)->el) * (adb)->nentries); \
2507 if ((adb)->el == NULL) { \
2512 ALLOCENTRY(adb, entries);
2513 ALLOCENTRY(adb, deadentries);
2514 ALLOCENTRY(adb, entrylocks);
2515 ALLOCENTRY(adb, entry_sd);
2516 ALLOCENTRY(adb, entry_refcnt);
2519 #define ALLOCNAME(adb, el) \
2521 (adb)->el = isc_mem_get((adb)->mctx, \
2522 sizeof(*(adb)->el) * (adb)->nnames); \
2523 if ((adb)->el == NULL) { \
2528 ALLOCNAME(adb, names);
2529 ALLOCNAME(adb, deadnames);
2530 ALLOCNAME(adb, namelocks);
2531 ALLOCNAME(adb, name_sd);
2532 ALLOCNAME(adb, name_refcnt);
2539 result = isc_mutexblock_init(adb->namelocks, adb->nnames);
2542 for (i = 0; i < adb->nnames; i++) {
2543 ISC_LIST_INIT(adb->names[i]);
2544 ISC_LIST_INIT(adb->deadnames[i]);
2545 adb->name_sd[i] = ISC_FALSE;
2546 adb->name_refcnt[i] = 0;
2547 adb->irefcnt++;
2549 for (i = 0; i < adb->nentries; i++) {
2550 ISC_LIST_INIT(adb->entries[i]);
2551 ISC_LIST_INIT(adb->deadentries[i]);
2552 adb->entry_sd[i] = ISC_FALSE;
2553 adb->entry_refcnt[i] = 0;
2554 adb->irefcnt++;
2556 result = isc_mutexblock_init(adb->entrylocks, adb->nentries);
2570 isc_mempool_associatelock((p), &adb->mplock); \
2573 MPINIT(dns_adbname_t, adb->nmp, "adbname");
2574 MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook");
2575 MPINIT(dns_adblameinfo_t, adb->limp, "adblameinfo");
2576 MPINIT(dns_adbentry_t, adb->emp, "adbentry");
2577 MPINIT(dns_adbfind_t, adb->ahmp, "adbfind");
2578 MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo");
2579 MPINIT(dns_adbfetch_t, adb->afmp, "adbfetch");
2586 result = isc_task_create(adb->taskmgr, 0, &adb->task);
2590 isc_task_setname(adb->task, "ADB", adb);
2595 adb->magic = DNS_ADB_MAGIC;
2596 *newadb = adb;
2600 if (adb->task != NULL)
2601 isc_task_detach(&adb->task);
2604 DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
2607 DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames);
2610 if (adb->entries != NULL)
2611 isc_mem_put(adb->mctx, adb->entries,
2612 sizeof(*adb->entries) * adb->nentries);
2613 if (adb->deadentries != NULL)
2614 isc_mem_put(adb->mctx, adb->deadentries,
2615 sizeof(*adb->deadentries) * adb->nentries);
2616 if (adb->entrylocks != NULL)
2617 isc_mem_put(adb->mctx, adb->entrylocks,
2618 sizeof(*adb->entrylocks) * adb->nentries);
2619 if (adb->entry_sd != NULL)
2620 isc_mem_put(adb->mctx, adb->entry_sd,
2621 sizeof(*adb->entry_sd) * adb->nentries);
2622 if (adb->entry_refcnt != NULL)
2623 isc_mem_put(adb->mctx, adb->entry_refcnt,
2624 sizeof(*adb->entry_refcnt) * adb->nentries);
2625 if (adb->names != NULL)
2626 isc_mem_put(adb->mctx, adb->names,
2627 sizeof(*adb->names) * adb->nnames);
2628 if (adb->deadnames != NULL)
2629 isc_mem_put(adb->mctx, adb->deadnames,
2630 sizeof(*adb->deadnames) * adb->nnames);
2631 if (adb->namelocks != NULL)
2632 isc_mem_put(adb->mctx, adb->namelocks,
2633 sizeof(*adb->namelocks) * adb->nnames);
2634 if (adb->name_sd != NULL)
2635 isc_mem_put(adb->mctx, adb->name_sd,
2636 sizeof(*adb->name_sd) * adb->nnames);
2637 if (adb->name_refcnt != NULL)
2638 isc_mem_put(adb->mctx, adb->name_refcnt,
2639 sizeof(*adb->name_refcnt) * adb->nnames);
2640 if (adb->nmp != NULL)
2641 isc_mempool_destroy(&adb->nmp);
2642 if (adb->nhmp != NULL)
2643 isc_mempool_destroy(&adb->nhmp);
2644 if (adb->limp != NULL)
2645 isc_mempool_destroy(&adb->limp);
2646 if (adb->emp != NULL)
2647 isc_mempool_destroy(&adb->emp);
2648 if (adb->ahmp != NULL)
2649 isc_mempool_destroy(&adb->ahmp);
2650 if (adb->aimp != NULL)
2651 isc_mempool_destroy(&adb->aimp);
2652 if (adb->afmp != NULL)
2653 isc_mempool_destroy(&adb->afmp);
2655 DESTROYLOCK(&adb->namescntlock);
2657 DESTROYLOCK(&adb->entriescntlock);
2659 DESTROYLOCK(&adb->overmemlock);
2661 DESTROYLOCK(&adb->reflock);
2663 DESTROYLOCK(&adb->mplock);
2665 DESTROYLOCK(&adb->lock);
2667 isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
2673 dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbx) {
2675 REQUIRE(DNS_ADB_VALID(adb));
2678 inc_adb_erefcnt(adb);
2679 *adbx = adb;
2684 dns_adb_t *adb;
2689 adb = *adbx;
2692 INSIST(adb->erefcnt > 0);
2694 LOCK(&adb->reflock);
2695 adb->erefcnt--;
2696 need_exit_check = ISC_TF(adb->erefcnt == 0 && adb->irefcnt == 0);
2697 UNLOCK(&adb->reflock);
2700 LOCK(&adb->lock);
2701 INSIST(adb->shutting_down);
2702 check_exit(adb);
2703 UNLOCK(&adb->lock);
2708 dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp) {
2714 * Send '*eventp' to 'task' when 'adb' has shutdown.
2717 REQUIRE(DNS_ADB_VALID(adb));
2723 LOCK(&adb->lock);
2725 LOCK(&adb->reflock);
2726 zeroirefcnt = ISC_TF(adb->irefcnt == 0);
2728 if (adb->shutting_down && zeroirefcnt &&
2729 isc_mempool_getallocated(adb->ahmp) == 0) {
2733 event->ev_sender = adb;
2739 ISC_LIST_APPEND(adb->whenshutdown, event, ev_link);
2742 UNLOCK(&adb->reflock);
2743 UNLOCK(&adb->lock);
2747 dns_adb_shutdown(dns_adb_t *adb) {
2751 * Shutdown 'adb'.
2754 LOCK(&adb->lock);
2756 if (!adb->shutting_down) {
2757 adb->shutting_down = ISC_TRUE;
2758 isc_mem_setwater(adb->mctx, water, adb, 0, 0);
2759 need_check_exit = shutdown_names(adb);
2761 need_check_exit = shutdown_entries(adb);
2763 check_exit(adb);
2766 UNLOCK(&adb->lock);
2770 dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
2776 return (dns_adb_createfind2(adb, task, action, arg, name,
2782 dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
2798 REQUIRE(DNS_ADB_VALID(adb));
2842 find = new_adbfind(adb);
2861 adbname = find_name_and_lock(adb, name, find->options, &bucket);
2863 if (adb->name_sd[bucket]) {
2866 RUNTIME_CHECK(free_adbfind(adb, &find) == ISC_FALSE);
2879 check_stale_name(adb, bucket, now);
2881 adbname = new_adbname(adb, name);
2883 RUNTIME_CHECK(free_adbfind(adb, &find) == ISC_FALSE);
2887 link_name(adb, bucket, adbname);
2896 ISC_LIST_UNLINK(adb->names[bucket], adbname, plink);
2897 ISC_LIST_PREPEND(adb->names[bucket], adbname, plink);
3043 copy_namehook_lists(adb, find, qname, qtype, adbname, now);
3119 UNLOCK(&adb->namelocks[bucket]);
3130 dns_adb_t *adb;
3141 adb = find->adb;
3142 REQUIRE(DNS_ADB_VALID(adb));
3153 * Return the find to the memory pool, and decrement the adb's
3156 overmem = isc_mem_isovermem(adb->mctx);
3163 RUNTIME_CHECK(dec_entry_refcnt(adb, overmem, entry, ISC_TRUE) ==
3165 free_adbaddrinfo(adb, &ai);
3170 * WARNING: The find is freed with the adb locked. This is done
3176 LOCK(&adb->lock);
3177 if (free_adbfind(adb, &find))
3178 check_exit(adb);
3179 UNLOCK(&adb->lock);
3186 dns_adb_t *adb;
3194 adb = find->adb;
3195 REQUIRE(DNS_ADB_VALID(adb));
3208 violate_locking_hierarchy(&find->lock, &adb->namelocks[unlock_bucket]);
3215 UNLOCK(&adb->namelocks[unlock_bucket]);
3241 dns_adb_dump(dns_adb_t *adb, FILE *f) {
3245 REQUIRE(DNS_ADB_VALID(adb));
3249 * Lock the adb itself, lock all the name buckets, then lock all
3250 * the entry buckets. This should put the adb into a state where
3255 LOCK(&adb->lock);
3258 for (i = 0; i < adb->nnames; i++)
3259 RUNTIME_CHECK(cleanup_names(adb, i, now) == ISC_FALSE);
3260 for (i = 0; i < adb->nentries; i++)
3261 RUNTIME_CHECK(cleanup_entries(adb, i, now) == ISC_FALSE);
3263 dump_adb(adb, f, ISC_FALSE, now);
3264 UNLOCK(&adb->lock);
3275 dump_adb(dns_adb_t *adb, FILE *f, isc_boolean_t debug, isc_stdtime_t now) {
3283 adb, adb->erefcnt, adb->irefcnt,
3284 isc_mempool_getallocated(adb->nhmp));
3286 for (i = 0; i < adb->nnames; i++)
3287 LOCK(&adb->namelocks[i]);
3288 for (i = 0; i < adb->nentries; i++)
3289 LOCK(&adb->entrylocks[i]);
3294 for (i = 0; i < adb->nnames; i++) {
3295 name = ISC_LIST_HEAD(adb->names[i]);
3338 for (i = 0; i < adb->nentries; i++) {
3339 entry = ISC_LIST_HEAD(adb->entries[i]);
3350 for (i = 0; i < adb->nentries; i++)
3351 UNLOCK(&adb->entrylocks[i]);
3352 for (i = 0; i < adb->nnames; i++)
3353 UNLOCK(&adb->namelocks[i]);
3495 dns_adb_t *adb;
3500 adb = adbname->adb;
3501 INSIST(DNS_ADB_VALID(adb));
3521 result = dns_view_find2(adb->view, &adbname->name, rdtype, now,
3557 "adb name %p: Caching auth negative entry for A",
3565 "adb name %p: Caching auth negative entry for AAAA",
3588 "adb name %p: Caching negative entry for A (ttl %u)",
3592 "adb name %p: Caching negative entry for AAAA (ttl %u)",
3610 clean_target(adb, &adbname->target);
3612 result = set_target(adb, &adbname->name, fname, &rdataset,
3617 "adb name %p: caching alias target",
3638 dns_adb_t *adb;
3654 adb = name->adb;
3655 INSIST(DNS_ADB_VALID(adb));
3660 LOCK(&adb->namelocks[bucket]);
3696 free_adbfetch(adb, &fetch);
3701 UNLOCK(&adb->namelocks[bucket]);
3704 LOCK(&adb->lock);
3705 check_exit(adb);
3706 UNLOCK(&adb->lock);
3720 DP(NCACHE_LEVEL, "adb fetch name %p: "
3729 inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
3731 DP(NCACHE_LEVEL, "adb fetch name %p: "
3740 inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
3750 clean_target(adb, &name->target);
3752 result = set_target(adb, &name->name,
3758 "adb fetch name %p: caching alias target",
3773 DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s",
3786 inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
3790 inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
3810 free_adbfetch(adb, &fetch);
3815 UNLOCK(&adb->namelocks[bucket]);
3824 dns_adb_t *adb;
3832 adb = adbname->adb;
3833 INSIST(DNS_ADB_VALID(adb));
3851 result = dns_view_findzonecut2(adb->view, &adbname->name, name,
3860 fetch = new_adbfetch(adb);
3867 result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name,
3869 NULL, 0, options, depth, adb->task,
3878 inc_stats(adb, dns_resstatscounter_gluefetchv4);
3881 inc_stats(adb, dns_resstatscounter_gluefetchv6);
3887 free_adbfetch(adb, &fetch);
3895 * XXXMLG Needs to take a find argument and an address info, no zone or adb,
3899 dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname,
3906 REQUIRE(DNS_ADB_VALID(adb));
3911 LOCK(&adb->entrylocks[bucket]);
3921 li = new_adblameinfo(adb, qname, qtype);
3931 UNLOCK(&adb->entrylocks[bucket]);
3937 dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
3944 REQUIRE(DNS_ADB_VALID(adb));
3949 LOCK(&adb->entrylocks[bucket]);
3965 UNLOCK(&adb->entrylocks[bucket]);
3969 dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
3975 REQUIRE(DNS_ADB_VALID(adb));
3979 LOCK(&adb->entrylocks[bucket]);
3993 UNLOCK(&adb->entrylocks[bucket]);
3997 dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
4006 REQUIRE(DNS_ADB_VALID(adb));
4013 entry = find_entry_and_lock(adb, sa, &bucket, now);
4015 if (adb->entry_sd[bucket]) {
4023 entry = new_adbentry(adb);
4029 link_entry(adb, bucket, entry);
4035 addr = new_adbaddrinfo(adb, entry, port);
4039 inc_entry_refcnt(adb, entry, ISC_FALSE);
4044 UNLOCK(&adb->entrylocks[bucket]);
4050 dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
4058 REQUIRE(DNS_ADB_VALID(adb));
4066 overmem = isc_mem_isovermem(adb->mctx);
4069 LOCK(&adb->entrylocks[bucket]);
4076 want_check_exit = dec_entry_refcnt(adb, overmem, entry, ISC_FALSE);
4078 UNLOCK(&adb->entrylocks[bucket]);
4081 free_adbaddrinfo(adb, &addr);
4084 LOCK(&adb->lock);
4085 check_exit(adb);
4086 UNLOCK(&adb->lock);
4091 dns_adb_flush(dns_adb_t *adb) {
4094 INSIST(DNS_ADB_VALID(adb));
4096 LOCK(&adb->lock);
4101 for (i = 0; i < adb->nnames; i++)
4102 RUNTIME_CHECK(cleanup_names(adb, i, INT_MAX) == ISC_FALSE);
4103 for (i = 0; i < adb->nentries; i++)
4104 RUNTIME_CHECK(cleanup_entries(adb, i, INT_MAX) == ISC_FALSE);
4107 dump_adb(adb, stdout, ISC_TRUE, INT_MAX);
4110 UNLOCK(&adb->lock);
4114 dns_adb_flushname(dns_adb_t *adb, dns_name_t *name) {
4119 INSIST(DNS_ADB_VALID(adb));
4121 LOCK(&adb->lock);
4122 bucket = dns_name_hash(name, ISC_FALSE) % adb->nnames;
4123 LOCK(&adb->namelocks[bucket]);
4124 adbname = ISC_LIST_HEAD(adb->names[bucket]);
4135 UNLOCK(&adb->namelocks[bucket]);
4136 UNLOCK(&adb->lock);
4149 dns_adb_t *adb = arg;
4152 REQUIRE(DNS_ADB_VALID(adb));
4155 "adb reached %s water mark", overmem ? "high" : "low");
4159 dns_adb_setadbsize(dns_adb_t *adb, size_t size) {
4162 INSIST(DNS_ADB_VALID(adb));
4171 isc_mem_setwater(adb->mctx, water, adb, 0, 0);
4173 isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater);