1999-09-21 22:46:42 +00:00
|
|
|
/*
|
2018-02-23 09:53:12 +01:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2000-08-01 01:33:37 +00:00
|
|
|
*
|
2021-06-03 08:37:05 +02:00
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
|
|
*
|
2016-06-27 14:56:38 +10:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
2020-09-14 16:20:40 -07:00
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
1999-09-21 22:46:42 +00:00
|
|
|
*/
|
|
|
|
|
2007-10-19 17:15:53 +00:00
|
|
|
/*! \file
|
1999-09-23 00:43:10 +00:00
|
|
|
*
|
2005-04-27 04:57:32 +00:00
|
|
|
* \note
|
1999-10-29 18:30:48 +00:00
|
|
|
* In finds, if task == NULL, no events will be generated, and no events
|
1999-09-23 00:43:10 +00:00
|
|
|
* have been sent. If task != NULL but taskaction == NULL, an event has been
|
1999-11-25 01:23:32 +00:00
|
|
|
* posted but not yet freed. If neither are NULL, no event was posted.
|
1999-09-23 00:43:10 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2018-03-28 14:19:37 +02:00
|
|
|
#include <inttypes.h>
|
2020-02-12 13:59:18 +01:00
|
|
|
#include <limits.h>
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
#include <isc/atomic.h>
|
|
|
|
#include <isc/ht.h>
|
1999-09-24 23:54:42 +00:00
|
|
|
#include <isc/mutexblock.h>
|
2000-12-18 20:03:33 +00:00
|
|
|
#include <isc/netaddr.h>
|
2015-05-23 14:21:51 +02:00
|
|
|
#include <isc/print.h>
|
1999-10-20 23:26:06 +00:00
|
|
|
#include <isc/random.h>
|
2021-10-04 17:14:53 +02:00
|
|
|
#include <isc/result.h>
|
2009-01-27 22:30:00 +00:00
|
|
|
#include <isc/stats.h>
|
2022-04-11 15:53:34 +01:00
|
|
|
#include <isc/string.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <isc/task.h>
|
1999-12-16 22:24:22 +00:00
|
|
|
#include <isc/util.h>
|
1999-09-22 00:26:20 +00:00
|
|
|
|
1999-10-22 01:02:38 +00:00
|
|
|
#include <dns/adb.h>
|
1999-10-21 01:18:06 +00:00
|
|
|
#include <dns/db.h>
|
1999-10-16 00:38:21 +00:00
|
|
|
#include <dns/events.h>
|
1999-10-29 22:28:57 +00:00
|
|
|
#include <dns/log.h>
|
1999-10-05 23:50:43 +00:00
|
|
|
#include <dns/rdata.h>
|
|
|
|
#include <dns/rdataset.h>
|
2000-10-07 00:09:28 +00:00
|
|
|
#include <dns/rdatastruct.h>
|
2005-06-23 04:22:02 +00:00
|
|
|
#include <dns/rdatatype.h>
|
1999-10-25 21:39:08 +00:00
|
|
|
#include <dns/resolver.h>
|
2008-04-03 05:55:52 +00:00
|
|
|
#include <dns/stats.h>
|
1999-09-23 00:43:10 +00:00
|
|
|
|
2022-03-24 15:58:26 -07:00
|
|
|
/* Detailed logging of attach/detach */
|
|
|
|
#ifndef ADB_TRACE
|
|
|
|
#undef ADB_TRACE
|
|
|
|
#endif
|
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b')
|
|
|
|
#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
|
|
|
|
#define DNS_ADBNAME_MAGIC ISC_MAGIC('a', 'd', 'b', 'N')
|
|
|
|
#define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
|
|
|
|
#define DNS_ADBNAMEHOOK_MAGIC ISC_MAGIC('a', 'd', 'N', 'H')
|
2020-02-12 13:59:18 +01:00
|
|
|
#define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC)
|
2020-02-13 14:44:37 -08:00
|
|
|
#define DNS_ADBLAMEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z')
|
2020-02-12 13:59:18 +01:00
|
|
|
#define DNS_ADBLAMEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBLAMEINFO_MAGIC)
|
2020-02-13 14:44:37 -08:00
|
|
|
#define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E')
|
|
|
|
#define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
|
|
|
|
#define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4')
|
|
|
|
#define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC)
|
|
|
|
#define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6')
|
|
|
|
#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
|
2007-10-19 17:15:53 +00:00
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*!
|
1999-12-01 02:05:16 +00:00
|
|
|
* For type 3 negative cache entries, we will remember that the address is
|
1999-12-11 02:30:24 +00:00
|
|
|
* broken for this long. XXXMLG This is also used for actual addresses, too.
|
2002-11-27 09:52:58 +00:00
|
|
|
* The intent is to keep us from constantly asking about A/AAAA records
|
1999-12-11 02:30:24 +00:00
|
|
|
* if the zone has extremely low TTLs.
|
1999-12-01 02:05:16 +00:00
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
#define ADB_CACHE_MINIMUM 10 /*%< seconds */
|
|
|
|
#define ADB_CACHE_MAXIMUM 86400 /*%< seconds (86400 = 24 hours) */
|
2020-02-13 14:44:37 -08:00
|
|
|
#define ADB_ENTRY_WINDOW 1800 /*%< seconds */
|
1999-09-23 00:43:10 +00:00
|
|
|
|
2007-10-19 17:15:53 +00:00
|
|
|
/*%
|
|
|
|
* The period in seconds after which an ADB name entry is regarded as stale
|
|
|
|
* and forced to be cleaned up.
|
|
|
|
* TODO: This should probably be configurable at run-time.
|
|
|
|
*/
|
|
|
|
#ifndef ADB_STALE_MARGIN
|
2020-02-12 13:59:18 +01:00
|
|
|
#define ADB_STALE_MARGIN 1800
|
2020-02-13 21:48:23 +01:00
|
|
|
#endif /* ifndef ADB_STALE_MARGIN */
|
1999-10-25 22:53:15 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#define DNS_ADB_MINADBSIZE (1024U * 1024U) /*%< 1 Megabyte */
|
2001-10-25 04:57:46 +00:00
|
|
|
|
1999-09-22 01:01:14 +00:00
|
|
|
typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
|
1999-09-22 00:26:20 +00:00
|
|
|
typedef struct dns_adbnamehook dns_adbnamehook_t;
|
1999-10-29 01:26:45 +00:00
|
|
|
typedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t;
|
2005-06-23 04:22:02 +00:00
|
|
|
typedef struct dns_adblameinfo dns_adblameinfo_t;
|
1999-09-23 00:43:10 +00:00
|
|
|
typedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
|
2020-02-13 14:44:37 -08:00
|
|
|
typedef struct dns_adbfetch dns_adbfetch_t;
|
1999-10-30 01:22:16 +00:00
|
|
|
typedef struct dns_adbfetch6 dns_adbfetch6_t;
|
1999-09-21 22:46:42 +00:00
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*% dns adb structure */
|
1999-09-21 22:46:42 +00:00
|
|
|
struct dns_adb {
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int magic;
|
2007-10-19 17:15:53 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_mutex_t lock;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_mem_t *mctx;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_view_t *view;
|
2022-05-12 15:51:10 -07:00
|
|
|
dns_resolver_t *res;
|
2007-10-19 17:15:53 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_taskmgr_t *taskmgr;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_task_t *task;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_refcount_t references;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_t *namebuckets;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_rwlock_t names_lock;
|
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_t *entrybuckets;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_rwlock_t entries_lock;
|
2020-02-12 13:59:18 +01:00
|
|
|
|
2022-05-11 15:38:54 -07:00
|
|
|
isc_stats_t *stats;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
atomic_bool exiting;
|
2020-02-12 13:59:18 +01:00
|
|
|
|
|
|
|
uint32_t quota;
|
|
|
|
uint32_t atr_freq;
|
2020-02-13 14:44:37 -08:00
|
|
|
double atr_low;
|
|
|
|
double atr_high;
|
|
|
|
double atr_discount;
|
1999-09-21 22:46:42 +00:00
|
|
|
};
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*%
|
|
|
|
* dns_adbname structure:
|
|
|
|
*
|
|
|
|
* This is the structure representing a nameserver name; it can be looked
|
|
|
|
* up via the adb->namebuckets hash table. It holds references to fetches
|
|
|
|
* for A and AAAA records while they are ongoing (fetch_a, fetch_aaaa), and
|
|
|
|
* lists of records pointing to address information when the fetches are
|
|
|
|
* complete (v4, v6).
|
1999-11-25 01:23:32 +00:00
|
|
|
*/
|
1999-09-22 00:26:20 +00:00
|
|
|
struct dns_adbname {
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int magic;
|
|
|
|
dns_name_t name;
|
|
|
|
dns_adb_t *adb;
|
|
|
|
unsigned int partial_result;
|
|
|
|
unsigned int flags;
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_adbnamebucket_t *bucket;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_name_t target;
|
|
|
|
isc_stdtime_t expire_target;
|
|
|
|
isc_stdtime_t expire_v4;
|
|
|
|
isc_stdtime_t expire_v6;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_adbnamehooklist_t v4;
|
|
|
|
dns_adbnamehooklist_t v6;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adbfetch_t *fetch_a;
|
|
|
|
dns_adbfetch_t *fetch_aaaa;
|
|
|
|
unsigned int fetch_err;
|
|
|
|
unsigned int fetch6_err;
|
|
|
|
dns_adbfindlist_t finds;
|
2008-02-07 23:46:54 +00:00
|
|
|
/* for LRU-based management */
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_stdtime_t last_used;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_LINK(dns_adbname_t) plink;
|
1999-09-22 00:26:20 +00:00
|
|
|
};
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*%
|
|
|
|
* dns_adbnamebucket structure:
|
|
|
|
*
|
|
|
|
* Hash bucket for dns_adbname objects.
|
|
|
|
*/
|
2022-03-16 21:58:55 +01:00
|
|
|
struct dns_adbnamebucket {
|
|
|
|
dns_adbnamelist_t names;
|
|
|
|
dns_adbnamelist_t deadnames;
|
|
|
|
isc_mutex_t lock;
|
|
|
|
isc_refcount_t references;
|
|
|
|
};
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*%
|
|
|
|
* dns_adbfetch structure:
|
|
|
|
* Stores the state for an ongoing A or AAAA fetch.
|
|
|
|
*/
|
1999-10-25 21:02:54 +00:00
|
|
|
struct dns_adbfetch {
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int magic;
|
|
|
|
dns_fetch_t *fetch;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_rdataset_t rdataset;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int depth;
|
1999-10-25 21:02:54 +00:00
|
|
|
};
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* dns_adbnamehook structure:
|
|
|
|
*
|
1999-09-22 00:26:20 +00:00
|
|
|
* This is a small widget that dangles off a dns_adbname_t. It contains a
|
|
|
|
* pointer to the address information about this host, and a link to the next
|
|
|
|
* namehook that will contain the next address this host has.
|
|
|
|
*/
|
|
|
|
struct dns_adbnamehook {
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int magic;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_adbentry_t *entry;
|
|
|
|
ISC_LINK(dns_adbnamehook_t) plink;
|
1999-09-21 22:46:42 +00:00
|
|
|
};
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* dns_adblameinfo structure:
|
|
|
|
*
|
2005-06-23 04:22:02 +00:00
|
|
|
* This is a small widget that holds qname-specific information about an
|
1999-09-22 00:26:20 +00:00
|
|
|
* address. Currently limited to lameness, but could just as easily be
|
|
|
|
* extended to other types of information about zones.
|
|
|
|
*/
|
2005-06-23 04:22:02 +00:00
|
|
|
struct dns_adblameinfo {
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int magic;
|
1999-09-22 00:26:20 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_name_t qname;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_rdatatype_t qtype;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_stdtime_t lame_timer;
|
1999-09-22 00:26:20 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_LINK(dns_adblameinfo_t) plink;
|
1999-09-22 00:26:20 +00:00
|
|
|
};
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* dns_adbentry structure:
|
|
|
|
*
|
|
|
|
* This is the structure representing a nameserver address; it can be looked
|
|
|
|
* up via the adb->entrybuckets hash table. Also, each dns_adbnamehook and
|
|
|
|
* and dns_adbaddrinfo object will contain a pointer to one of these.
|
|
|
|
*
|
|
|
|
* The structure holds quite a bit of information about addresses,
|
|
|
|
* including edns state (in "flags"), RTT, and of course the address of
|
2001-01-22 22:53:13 +00:00
|
|
|
* the host.
|
1999-09-22 00:26:20 +00:00
|
|
|
*/
|
1999-09-21 22:46:42 +00:00
|
|
|
struct dns_adbentry {
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int magic;
|
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_refcount_t references;
|
|
|
|
|
|
|
|
dns_adb_t *adb;
|
|
|
|
dns_adbentrybucket_t *bucket;
|
2020-02-12 13:59:18 +01:00
|
|
|
|
2022-04-06 18:37:54 +01:00
|
|
|
unsigned int nh;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int flags;
|
|
|
|
unsigned int srtt;
|
|
|
|
unsigned int completed;
|
|
|
|
unsigned int timeouts;
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned char plain;
|
|
|
|
unsigned char plainto;
|
|
|
|
unsigned char edns;
|
2020-09-23 14:47:26 +02:00
|
|
|
unsigned char ednsto;
|
2022-04-06 18:37:54 +01:00
|
|
|
uint16_t udpsize;
|
2020-02-12 13:59:18 +01:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
uint8_t mode;
|
2020-02-12 13:59:18 +01:00
|
|
|
atomic_uint_fast32_t quota;
|
|
|
|
atomic_uint_fast32_t active;
|
2020-02-13 14:44:37 -08:00
|
|
|
double atr;
|
2015-07-08 22:53:39 -07:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_sockaddr_t sockaddr;
|
|
|
|
unsigned char *cookie;
|
2020-02-13 14:44:37 -08:00
|
|
|
uint16_t cookielen;
|
2020-02-12 13:59:18 +01:00
|
|
|
|
|
|
|
isc_stdtime_t expires;
|
|
|
|
isc_stdtime_t lastage;
|
2008-02-07 23:46:54 +00:00
|
|
|
/*%<
|
|
|
|
* A nonzero 'expires' field indicates that the entry should
|
|
|
|
* persist until that time. This allows entries found
|
|
|
|
* using dns_adb_findaddrinfo() to persist for a limited time
|
|
|
|
* even though they are not necessarily associated with a
|
2022-03-16 21:58:55 +01:00
|
|
|
* entry.
|
2008-02-07 23:46:54 +00:00
|
|
|
*/
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_LIST(dns_adblameinfo_t) lameinfo;
|
|
|
|
ISC_LINK(dns_adbentry_t) plink;
|
1999-09-21 22:46:42 +00:00
|
|
|
};
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*% dns_adbentrybucket_t structure:
|
|
|
|
*
|
|
|
|
* Hash bucket for dns_adbentry objects.
|
|
|
|
*/
|
2022-03-16 21:58:55 +01:00
|
|
|
struct dns_adbentrybucket {
|
|
|
|
dns_adbentrylist_t entries;
|
|
|
|
dns_adbentrylist_t deadentries;
|
|
|
|
isc_mutex_t lock;
|
|
|
|
isc_refcount_t references;
|
|
|
|
};
|
|
|
|
|
1999-09-22 00:26:20 +00:00
|
|
|
/*
|
1999-09-23 00:43:10 +00:00
|
|
|
* Internal functions (and prototypes).
|
|
|
|
*/
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbname_t *
|
2020-02-14 08:14:03 +01:00
|
|
|
new_adbname(dns_adb_t *, const dns_name_t *);
|
2022-03-16 21:58:55 +01:00
|
|
|
static dns_adbnamebucket_t *
|
|
|
|
new_adbnamebucket(dns_adb_t *);
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
free_adbname(dns_adbname_t **);
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbnamehook_t *
|
2020-02-14 08:14:03 +01:00
|
|
|
new_adbnamehook(dns_adb_t *, dns_adbentry_t *);
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-14 08:14:03 +01:00
|
|
|
free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **);
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adblameinfo_t *
|
2020-02-12 13:59:18 +01:00
|
|
|
new_adblameinfo(dns_adb_t *, const dns_name_t *, dns_rdatatype_t);
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-14 08:14:03 +01:00
|
|
|
free_adblameinfo(dns_adb_t *, dns_adblameinfo_t **);
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbentry_t *
|
2020-02-14 08:14:03 +01:00
|
|
|
new_adbentry(dns_adb_t *);
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2022-03-16 21:58:55 +01:00
|
|
|
free_adbentry(dns_adbentry_t **);
|
|
|
|
static dns_adbentrybucket_t *
|
|
|
|
new_adbentrybucket(dns_adb_t *adb);
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbfind_t *
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
new_adbfind(dns_adb_t *, in_port_t);
|
|
|
|
static void
|
|
|
|
free_adbfind(dns_adbfind_t **);
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbaddrinfo_t *
|
2020-02-14 08:14:03 +01:00
|
|
|
new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *, in_port_t);
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbfetch_t *
|
2020-02-14 08:14:03 +01:00
|
|
|
new_adbfetch(dns_adb_t *);
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-14 08:14:03 +01:00
|
|
|
free_adbfetch(dns_adb_t *, dns_adbfetch_t **);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
|
|
|
get_namebucket(dns_adb_t *, const dns_name_t *, dns_adbnamebucket_t **);
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbname_t *
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
get_name(dns_adbnamebucket_t *, const dns_name_t *, unsigned int);
|
|
|
|
static void
|
|
|
|
get_entrybucket(dns_adb_t *, const isc_sockaddr_t *, dns_adbentrybucket_t **);
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbentry_t *
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
get_entry(dns_adbentrybucket_t *, const isc_sockaddr_t *, isc_stdtime_t);
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
dump_adb(dns_adb_t *, FILE *, bool debug, isc_stdtime_t);
|
|
|
|
static void
|
|
|
|
print_namehook_list(FILE *, const char *legend, dns_adb_t *adb,
|
|
|
|
dns_adbnamehooklist_t *list, bool debug, isc_stdtime_t now);
|
|
|
|
static void
|
|
|
|
print_find_list(FILE *, dns_adbname_t *);
|
|
|
|
static void
|
|
|
|
print_fetch_list(FILE *, dns_adbname_t *);
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-14 08:14:03 +01:00
|
|
|
clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
|
|
|
|
static void
|
|
|
|
clean_target(dns_adb_t *, dns_name_t *);
|
|
|
|
static void
|
|
|
|
clean_finds_at_name(dns_adbname_t *, isc_eventtype_t, unsigned int);
|
|
|
|
static void
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
maybe_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
|
|
|
|
static void
|
|
|
|
maybe_expire_entry(dns_adbentry_t **, isc_stdtime_t);
|
2020-02-14 08:14:03 +01:00
|
|
|
static isc_result_t
|
|
|
|
dbfind_name(dns_adbname_t *, isc_stdtime_t, dns_rdatatype_t);
|
|
|
|
static isc_result_t
|
|
|
|
fetch_name(dns_adbname_t *, bool, unsigned int, isc_counter_t *qc,
|
|
|
|
dns_rdatatype_t);
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-14 08:14:03 +01:00
|
|
|
destroy(dns_adb_t *);
|
2022-03-16 21:58:55 +01:00
|
|
|
static void
|
2020-02-14 08:14:03 +01:00
|
|
|
shutdown_names(dns_adb_t *);
|
2022-03-16 21:58:55 +01:00
|
|
|
static void
|
2020-02-14 08:14:03 +01:00
|
|
|
shutdown_entries(dns_adb_t *);
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2022-03-16 21:58:55 +01:00
|
|
|
link_name(dns_adbnamebucket_t *, dns_adbname_t *);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
2022-03-16 21:58:55 +01:00
|
|
|
unlink_name(dns_adbname_t *);
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2022-03-16 21:58:55 +01:00
|
|
|
link_entry(dns_adbentrybucket_t *, dns_adbentry_t *);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
2022-03-16 21:58:55 +01:00
|
|
|
unlink_entry(dns_adbentry_t *);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
|
|
|
expire_name(dns_adbname_t **, isc_eventtype_t);
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
water(void *, int);
|
|
|
|
static void
|
|
|
|
dump_entry(FILE *, dns_adb_t *, dns_adbentry_t *, bool, isc_stdtime_t);
|
|
|
|
static void
|
|
|
|
adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor,
|
|
|
|
isc_stdtime_t now);
|
|
|
|
static void
|
|
|
|
log_quota(dns_adbentry_t *entry, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
|
1999-10-29 01:26:45 +00:00
|
|
|
|
1999-10-30 01:58:02 +00:00
|
|
|
/*
|
|
|
|
* MUST NOT overlap DNS_ADBFIND_* flags!
|
|
|
|
*/
|
2020-02-13 14:44:37 -08:00
|
|
|
#define FIND_EVENT_SENT 0x40000000
|
|
|
|
#define FIND_EVENT_FREED 0x80000000
|
|
|
|
#define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0)
|
2020-02-12 13:59:18 +01:00
|
|
|
#define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0)
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
#define NAME_IS_DEAD 0x40000000
|
|
|
|
#define NAME_HINT_OK DNS_ADBFIND_HINTOK
|
|
|
|
#define NAME_GLUE_OK DNS_ADBFIND_GLUEOK
|
|
|
|
#define NAME_STARTATZONE DNS_ADBFIND_STARTATZONE
|
|
|
|
#define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0)
|
|
|
|
#define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0)
|
|
|
|
#define NAME_HINTOK(n) (((n)->flags & NAME_HINT_OK) != 0)
|
1999-11-02 00:29:45 +00:00
|
|
|
|
2009-01-28 23:20:23 +00:00
|
|
|
/*
|
|
|
|
* Private flag(s) for entries.
|
|
|
|
* MUST NOT overlap FCTX_ADDRINFO_xxx and DNS_FETCHOPT_NOEDNS0.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
#define ENTRY_IS_DEAD 0x00400000
|
2009-01-28 23:20:23 +00:00
|
|
|
|
1999-11-04 08:48:47 +00:00
|
|
|
/*
|
|
|
|
* To the name, address classes are all that really exist. If it has a
|
2002-11-27 09:52:58 +00:00
|
|
|
* V6 address it doesn't care if it came from a AAAA query.
|
1999-11-04 08:48:47 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
#define NAME_HAS_V4(n) (!ISC_LIST_EMPTY((n)->v4))
|
|
|
|
#define NAME_HAS_V6(n) (!ISC_LIST_EMPTY((n)->v6))
|
1999-10-26 23:44:36 +00:00
|
|
|
|
1999-11-04 08:48:47 +00:00
|
|
|
/*
|
2002-11-27 09:52:58 +00:00
|
|
|
* Fetches are broken out into A and AAAA types. In some cases,
|
1999-11-04 08:48:47 +00:00
|
|
|
* however, it makes more sense to test for a particular class of fetches,
|
|
|
|
* like V4 or V6 above.
|
|
|
|
*/
|
2020-02-13 14:44:37 -08:00
|
|
|
#define NAME_FETCH_A(n) ((n)->fetch_a != NULL)
|
2020-02-12 13:59:18 +01:00
|
|
|
#define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL)
|
2021-10-18 17:57:58 -07:00
|
|
|
#define NAME_FETCH(n) (NAME_FETCH_A(n) || NAME_FETCH_AAAA(n))
|
1999-10-29 21:48:51 +00:00
|
|
|
|
1999-11-04 08:48:47 +00:00
|
|
|
/*
|
|
|
|
* Find options and tests to see if there are addresses on the list.
|
|
|
|
*/
|
2020-02-13 14:44:37 -08:00
|
|
|
#define FIND_WANTEVENT(fn) (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0)
|
2007-10-19 17:15:53 +00:00
|
|
|
#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
|
2020-02-13 14:44:37 -08:00
|
|
|
#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) != 0)
|
|
|
|
#define FIND_STARTATZONE(fn) (((fn)->options & DNS_ADBFIND_STARTATZONE) != 0)
|
|
|
|
#define FIND_HINTOK(fn) (((fn)->options & DNS_ADBFIND_HINTOK) != 0)
|
|
|
|
#define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0)
|
|
|
|
#define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list))
|
|
|
|
#define FIND_RETURNLAME(fn) (((fn)->options & DNS_ADBFIND_RETURNLAME) != 0)
|
2020-02-06 17:19:10 +11:00
|
|
|
#define FIND_NOFETCH(fn) (((fn)->options & DNS_ADBFIND_NOFETCH) != 0)
|
1999-12-14 00:10:06 +00:00
|
|
|
|
1999-11-04 08:48:47 +00:00
|
|
|
/*
|
|
|
|
* These are currently used on simple unsigned ints, so they are
|
|
|
|
* not really associated with any particular type.
|
|
|
|
*/
|
2020-02-13 14:44:37 -08:00
|
|
|
#define WANT_INET(x) (((x)&DNS_ADBFIND_INET) != 0)
|
2020-02-12 13:59:18 +01:00
|
|
|
#define WANT_INET6(x) (((x)&DNS_ADBFIND_INET6) != 0)
|
1999-11-04 08:48:47 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now))
|
1999-11-04 06:46:05 +00:00
|
|
|
|
2000-02-02 23:24:04 +00:00
|
|
|
/*
|
|
|
|
* Find out if the flags on a name (nf) indicate if it is a hint or
|
|
|
|
* glue, and compare this to the appropriate bits set in o, to see if
|
|
|
|
* this is ok.
|
|
|
|
*/
|
2020-02-13 14:44:37 -08:00
|
|
|
#define GLUE_OK(nf, o) (!NAME_GLUEOK(nf) || (((o)&DNS_ADBFIND_GLUEOK) != 0))
|
|
|
|
#define HINT_OK(nf, o) (!NAME_HINTOK(nf) || (((o)&DNS_ADBFIND_HINTOK) != 0))
|
2000-02-02 23:24:04 +00:00
|
|
|
#define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o))
|
2020-02-12 13:59:18 +01:00
|
|
|
#define STARTATZONE_MATCHES(nf, o) \
|
|
|
|
(((nf)->flags & NAME_STARTATZONE) == ((o)&DNS_ADBFIND_STARTATZONE))
|
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define ENTER_LEVEL ISC_LOG_DEBUG(50)
|
|
|
|
#define CLEAN_LEVEL ISC_LOG_DEBUG(100)
|
|
|
|
#define DEF_LEVEL ISC_LOG_DEBUG(5)
|
2020-02-12 13:59:18 +01:00
|
|
|
#define NCACHE_LEVEL ISC_LOG_DEBUG(20)
|
|
|
|
|
|
|
|
#define NCACHE_RESULT(r) \
|
|
|
|
((r) == DNS_R_NCACHENXDOMAIN || (r) == DNS_R_NCACHENXRRSET)
|
|
|
|
#define AUTH_NX(r) ((r) == DNS_R_NXDOMAIN || (r) == DNS_R_NXRRSET)
|
1999-11-24 19:23:27 +00:00
|
|
|
|
2000-08-26 02:21:45 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Error states.
|
2000-08-26 02:21:45 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
enum {
|
|
|
|
FIND_ERR_SUCCESS = 0,
|
|
|
|
FIND_ERR_CANCELED,
|
|
|
|
FIND_ERR_FAILURE,
|
|
|
|
FIND_ERR_NXDOMAIN,
|
|
|
|
FIND_ERR_NXRRSET,
|
|
|
|
FIND_ERR_UNEXPECTED,
|
|
|
|
FIND_ERR_NOTFOUND,
|
|
|
|
};
|
2020-02-12 13:59:18 +01:00
|
|
|
|
|
|
|
static const char *errnames[] = { "success", "canceled", "failure",
|
|
|
|
"nxdomain", "nxrrset", "unexpected",
|
|
|
|
"not_found" };
|
2001-01-27 02:44:35 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static isc_result_t find_err_map[] = {
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_R_SUCCESS, ISC_R_CANCELED, ISC_R_FAILURE, DNS_R_NXDOMAIN,
|
|
|
|
DNS_R_NXRRSET, ISC_R_UNEXPECTED, ISC_R_NOTFOUND /* not YET found */
|
2000-08-26 02:21:45 +00:00
|
|
|
};
|
1999-11-24 19:23:27 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
DP(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
|
2001-08-08 22:54:55 +00:00
|
|
|
|
1999-10-29 22:28:57 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
DP(int level, const char *format, ...) {
|
2008-02-07 23:46:54 +00:00
|
|
|
va_list args;
|
1999-10-29 22:28:57 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
va_start(args, format);
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
|
2008-02-07 23:46:54 +00:00
|
|
|
level, format, args);
|
|
|
|
va_end(args);
|
1999-10-29 22:28:57 +00:00
|
|
|
}
|
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
/*%
|
|
|
|
* Increment resolver-related statistics counters.
|
|
|
|
*/
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2022-05-11 15:38:54 -07:00
|
|
|
inc_resstats(dns_adb_t *adb, isc_statscounter_t counter) {
|
2022-05-12 15:51:10 -07:00
|
|
|
if (adb->res != NULL) {
|
|
|
|
dns_resolver_incstats(adb->res, counter);
|
2022-05-11 13:55:01 -07:00
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
2012-05-14 10:06:05 -07:00
|
|
|
/*%
|
|
|
|
* Set adb-related statistics counters.
|
|
|
|
*/
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
set_adbstat(dns_adb_t *adb, uint64_t val, isc_statscounter_t counter) {
|
2022-05-11 15:38:54 -07:00
|
|
|
if (adb->stats != NULL) {
|
|
|
|
isc_stats_set(adb->stats, val, counter);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
dec_adbstats(dns_adb_t *adb, isc_statscounter_t counter) {
|
2022-05-11 15:38:54 -07:00
|
|
|
if (adb->stats != NULL) {
|
|
|
|
isc_stats_decrement(adb->stats, counter);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
inc_adbstats(dns_adb_t *adb, isc_statscounter_t counter) {
|
2022-05-11 15:38:54 -07:00
|
|
|
if (adb->stats != NULL) {
|
|
|
|
isc_stats_increment(adb->stats, counter);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_ttl_t
|
2020-02-13 14:44:37 -08:00
|
|
|
ttlclamp(dns_ttl_t ttl) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ttl < ADB_CACHE_MINIMUM) {
|
2008-02-07 23:46:54 +00:00
|
|
|
ttl = ADB_CACHE_MINIMUM;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (ttl > ADB_CACHE_MAXIMUM) {
|
2008-02-07 23:46:54 +00:00
|
|
|
ttl = ADB_CACHE_MAXIMUM;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-06-07 20:15:48 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
return (ttl);
|
2000-06-07 20:15:48 +00:00
|
|
|
}
|
|
|
|
|
2022-03-24 15:58:26 -07:00
|
|
|
#define entry_attach(s, t) _entry_attach(s, t, __func__, __FILE__, __LINE__)
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
2022-03-24 15:58:26 -07:00
|
|
|
_entry_attach(dns_adbentry_t *source, dns_adbentry_t **targetp,
|
|
|
|
const char *func, const char *file, unsigned int line) {
|
|
|
|
uint_fast32_t refs;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(DNS_ADBENTRY_VALID(source));
|
|
|
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
|
|
|
|
2022-03-24 15:58:26 -07:00
|
|
|
refs = isc_refcount_increment(&source->references);
|
|
|
|
#ifdef ADB_TRACE
|
|
|
|
fprintf(stderr, "%s:%s:%u:%s(%p, %p) = %" PRIuFAST32 "\n", func, file,
|
|
|
|
line, __func__, source, targetp, refs + 1);
|
|
|
|
#else
|
|
|
|
UNUSED(func);
|
|
|
|
UNUSED(file);
|
|
|
|
UNUSED(line);
|
|
|
|
UNUSED(refs);
|
|
|
|
#endif /* ADB_TRACE */
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
*targetp = source;
|
|
|
|
}
|
|
|
|
|
2022-03-24 15:58:26 -07:00
|
|
|
#define entry_detach(ep) _entry_detach(ep, __func__, __FILE__, __LINE__)
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
2022-03-24 15:58:26 -07:00
|
|
|
_entry_detach(dns_adbentry_t **entryp, const char *func, const char *file,
|
|
|
|
unsigned int line) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentry_t *entry = NULL;
|
|
|
|
uint_fast32_t refs;
|
|
|
|
|
|
|
|
REQUIRE(entryp != NULL);
|
|
|
|
|
|
|
|
entry = *entryp;
|
|
|
|
*entryp = NULL;
|
|
|
|
|
|
|
|
REQUIRE(DNS_ADBENTRY_VALID(entry));
|
|
|
|
|
|
|
|
refs = isc_refcount_decrement(&entry->references);
|
2022-03-24 15:58:26 -07:00
|
|
|
|
|
|
|
#ifdef ADB_TRACE
|
|
|
|
fprintf(stderr, "%s:%s:%u:%s(%p, %p), %" PRIuFAST32 "\n", func, file,
|
|
|
|
line, __func__, entry, entryp, refs - 1);
|
|
|
|
#else
|
|
|
|
UNUSED(func);
|
|
|
|
UNUSED(file);
|
|
|
|
UNUSED(line);
|
|
|
|
#endif /* ADB_TRACE */
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (refs == 1) {
|
|
|
|
/*
|
|
|
|
* If the entry is linked to a bucket, we need to
|
|
|
|
* unlink it before destroying it.
|
|
|
|
*/
|
|
|
|
if (ISC_LINK_LINKED(entry, plink)) {
|
|
|
|
unlink_entry(entry);
|
|
|
|
}
|
|
|
|
free_adbentry(&entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-27 22:24:40 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Requires the name's bucket to be locked and that no entry buckets be locked.
|
1999-10-29 19:42:06 +00:00
|
|
|
*
|
|
|
|
* This code handles A and AAAA rdatasets only.
|
1999-10-27 22:24:40 +00:00
|
|
|
*/
|
|
|
|
static isc_result_t
|
1999-10-29 19:42:06 +00:00
|
|
|
import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_stdtime_t now) {
|
|
|
|
isc_result_t result;
|
2021-10-18 17:57:58 -07:00
|
|
|
dns_adb_t *adb = NULL;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
bool new_addresses_added = false;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdatatype_t rdtype;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(DNS_ADBNAME_VALID(adbname));
|
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
adb = adbname->adb;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
rdtype = rdataset->type;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
|
|
|
|
|
|
|
|
for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
|
|
|
|
result = dns_rdataset_next(rdataset))
|
|
|
|
{
|
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
|
|
|
dns_adbnamehooklist_t *hookhead = NULL;
|
|
|
|
dns_adbentry_t *entry = NULL;
|
|
|
|
dns_adbnamehook_t *nh = NULL;
|
|
|
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
|
|
|
isc_sockaddr_t sockaddr;
|
|
|
|
struct in_addr ina;
|
|
|
|
struct in6_addr in6a;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
dns_rdataset_current(rdataset, &rdata);
|
|
|
|
if (rdtype == dns_rdatatype_a) {
|
|
|
|
INSIST(rdata.length == 4);
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(&ina.s_addr, rdata.data, 4);
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_sockaddr_fromin(&sockaddr, &ina, 0);
|
2008-03-20 19:23:42 +00:00
|
|
|
hookhead = &adbname->v4;
|
2008-02-07 23:46:54 +00:00
|
|
|
} else {
|
|
|
|
INSIST(rdata.length == 16);
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(in6a.s6_addr, rdata.data, 16);
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_sockaddr_fromin6(&sockaddr, &in6a, 0);
|
2008-03-20 19:23:42 +00:00
|
|
|
hookhead = &adbname->v6;
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nh = new_adbnamehook(adb, NULL);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
|
|
|
|
get_entrybucket(adb, &sockaddr, &ebucket);
|
|
|
|
INSIST(ebucket != NULL);
|
|
|
|
LOCK(&ebucket->lock);
|
|
|
|
|
|
|
|
entry = get_entry(ebucket, &sockaddr, now);
|
2022-03-16 21:58:55 +01:00
|
|
|
if (entry == NULL) {
|
2008-02-07 23:46:54 +00:00
|
|
|
entry = new_adbentry(adb);
|
|
|
|
entry->sockaddr = sockaddr;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry_attach(entry, &nh->entry);
|
|
|
|
link_entry(ebucket, entry);
|
2022-03-16 21:58:55 +01:00
|
|
|
entry->nh = 1;
|
2008-02-07 23:46:54 +00:00
|
|
|
} else {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamehook_t *anh = NULL;
|
2020-02-12 13:59:18 +01:00
|
|
|
for (anh = ISC_LIST_HEAD(*hookhead); anh != NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
anh = ISC_LIST_NEXT(anh, plink))
|
|
|
|
{
|
2022-03-16 21:58:55 +01:00
|
|
|
if (anh->entry == entry) {
|
2008-02-07 23:46:54 +00:00
|
|
|
break;
|
2020-02-13 18:16:57 +01:00
|
|
|
}
|
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
if (anh == NULL) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/* Move entry to the head of the LRU list */
|
|
|
|
ISC_LIST_UNLINK(ebucket->entries, entry, plink);
|
|
|
|
ISC_LIST_PREPEND(ebucket->entries, entry,
|
|
|
|
plink);
|
|
|
|
entry_attach(entry, &nh->entry);
|
2022-03-16 21:58:55 +01:00
|
|
|
entry->nh++;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
free_adbnamehook(adb, &nh);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
new_addresses_added = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (nh != NULL) {
|
2008-03-20 19:23:42 +00:00
|
|
|
ISC_LIST_APPEND(*hookhead, nh, plink);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (result == ISC_R_NOMORE) {
|
|
|
|
result = ISC_R_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
if (rdataset->trust == dns_trust_glue ||
|
2020-02-13 14:44:37 -08:00
|
|
|
rdataset->trust == dns_trust_additional)
|
|
|
|
{
|
2008-02-07 23:46:54 +00:00
|
|
|
rdataset->ttl = ADB_CACHE_MINIMUM;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (rdataset->trust == dns_trust_ultimate) {
|
2011-03-13 02:49:28 +00:00
|
|
|
rdataset->ttl = 0;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
rdataset->ttl = ttlclamp(rdataset->ttl);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
if (rdtype == dns_rdatatype_a) {
|
|
|
|
DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
|
|
|
|
adbname->expire_v4, now + rdataset->ttl);
|
2020-02-12 13:59:18 +01:00
|
|
|
adbname->expire_v4 = ISC_MIN(
|
|
|
|
adbname->expire_v4,
|
|
|
|
ISC_MIN(now + ADB_ENTRY_WINDOW, now + rdataset->ttl));
|
2008-02-07 23:46:54 +00:00
|
|
|
} else {
|
|
|
|
DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
|
|
|
|
adbname->expire_v6, now + rdataset->ttl);
|
2020-02-12 13:59:18 +01:00
|
|
|
adbname->expire_v6 = ISC_MIN(
|
|
|
|
adbname->expire_v6,
|
|
|
|
ISC_MIN(now + ADB_ENTRY_WINDOW, now + rdataset->ttl));
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (new_addresses_added) {
|
|
|
|
/*
|
|
|
|
* Lie a little here. This is more or less so code that cares
|
|
|
|
* can find out if any new information was added or not.
|
|
|
|
*/
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (result);
|
1999-10-27 22:24:40 +00:00
|
|
|
}
|
|
|
|
|
1999-10-26 23:44:36 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Requires the name's bucket to be locked.
|
1999-10-26 23:44:36 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
|
|
|
expire_name(dns_adbname_t **n, isc_eventtype_t evtype) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adb_t *adb = NULL;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbname_t *adbname = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
|
|
|
REQUIRE(n != NULL);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
adbname = *n;
|
2008-02-07 23:46:54 +00:00
|
|
|
*n = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
REQUIRE(DNS_ADBNAME_VALID(adbname));
|
2022-03-24 16:06:48 -07:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
adb = adbname->adb;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
DP(DEF_LEVEL, "killing name %p", adbname);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* If we're dead already and have no active fetch, unlink
|
|
|
|
* and free the name.
|
2008-02-07 23:46:54 +00:00
|
|
|
*/
|
2022-03-16 21:58:55 +01:00
|
|
|
if (NAME_DEAD(adbname) && !NAME_FETCH(adbname)) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
unlink_name(adbname);
|
|
|
|
free_adbname(&adbname);
|
|
|
|
return;
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Clean up the name's various contents. These functions
|
|
|
|
* are destructive in that they will always empty the lists
|
|
|
|
* of finds and namehooks.
|
2008-02-07 23:46:54 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
clean_finds_at_name(adbname, evtype, DNS_ADBFIND_ADDRESSMASK);
|
|
|
|
clean_namehooks(adb, &adbname->v4);
|
|
|
|
clean_namehooks(adb, &adbname->v6);
|
2022-03-16 21:58:55 +01:00
|
|
|
clean_target(adb, &adbname->target);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* If no fetches are running, unlink and free the name now;
|
|
|
|
* otherwise cancel them.
|
2008-02-07 23:46:54 +00:00
|
|
|
*/
|
2022-03-16 21:58:55 +01:00
|
|
|
if (!NAME_FETCH(adbname)) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
unlink_name(adbname);
|
|
|
|
free_adbname(&adbname);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NAME_FETCH_A(adbname)) {
|
|
|
|
dns_resolver_cancelfetch(adbname->fetch_a->fetch);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NAME_FETCH_AAAA(adbname)) {
|
|
|
|
dns_resolver_cancelfetch(adbname->fetch_aaaa->fetch);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* Mark the name as dead and move it from 'names' to 'deadnames';
|
|
|
|
* we'll clean it up later.
|
|
|
|
*/
|
2022-03-16 21:58:55 +01:00
|
|
|
if (!NAME_DEAD(adbname)) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = adbname->bucket;
|
|
|
|
ISC_LIST_UNLINK(nbucket->names, adbname, plink);
|
|
|
|
ISC_LIST_APPEND(nbucket->deadnames, adbname, plink);
|
2022-03-16 21:58:55 +01:00
|
|
|
adbname->flags |= NAME_IS_DEAD;
|
|
|
|
}
|
1999-10-26 23:44:36 +00:00
|
|
|
}
|
|
|
|
|
1999-10-29 01:26:45 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Requires the name's bucket to be locked and no entry buckets be locked.
|
1999-10-29 01:26:45 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
|
|
|
maybe_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adb_t *adb = NULL;
|
|
|
|
|
|
|
|
REQUIRE(DNS_ADBNAME_VALID(name));
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
adb = name->adb;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check to see if we need to remove the v4 addresses
|
|
|
|
*/
|
2021-10-18 17:57:58 -07:00
|
|
|
if (!NAME_FETCH_A(name) && EXPIRE_OK(name->expire_v4, now)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
if (NAME_HAS_V4(name)) {
|
|
|
|
DP(DEF_LEVEL, "expiring v4 for name %p", name);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
clean_namehooks(adb, &name->v4);
|
2008-02-07 23:46:54 +00:00
|
|
|
name->partial_result &= ~DNS_ADBFIND_INET;
|
|
|
|
}
|
|
|
|
name->expire_v4 = INT_MAX;
|
|
|
|
name->fetch_err = FIND_ERR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check to see if we need to remove the v6 addresses
|
|
|
|
*/
|
2021-10-18 17:57:58 -07:00
|
|
|
if (!NAME_FETCH_AAAA(name) && EXPIRE_OK(name->expire_v6, now)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
if (NAME_HAS_V6(name)) {
|
|
|
|
DP(DEF_LEVEL, "expiring v6 for name %p", name);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
clean_namehooks(adb, &name->v6);
|
2008-02-07 23:46:54 +00:00
|
|
|
name->partial_result &= ~DNS_ADBFIND_INET6;
|
|
|
|
}
|
|
|
|
name->expire_v6 = INT_MAX;
|
|
|
|
name->fetch6_err = FIND_ERR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check to see if we need to remove the alias target.
|
|
|
|
*/
|
|
|
|
if (EXPIRE_OK(name->expire_target, now)) {
|
|
|
|
clean_target(adb, &name->target);
|
|
|
|
name->expire_target = INT_MAX;
|
|
|
|
}
|
1999-10-29 01:26:45 +00:00
|
|
|
}
|
|
|
|
|
1999-10-26 23:44:36 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Requires the name's bucket to be locked.
|
1999-10-26 23:44:36 +00:00
|
|
|
*/
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
link_name(dns_adbnamebucket_t *nbucket, dns_adbname_t *name) {
|
2022-03-16 21:58:55 +01:00
|
|
|
REQUIRE(name->bucket == NULL);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(!ISC_LINK_LINKED(name, plink));
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
name->bucket = nbucket;
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_PREPEND(nbucket->names, name, plink);
|
|
|
|
isc_refcount_increment0(&nbucket->references);
|
1999-10-26 23:44:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Requires the name's bucket to be locked.
|
1999-10-26 23:44:36 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
2022-03-16 21:58:55 +01:00
|
|
|
unlink_name(dns_adbname_t *name) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADBNAME_VALID(name));
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(ISC_LINK_LINKED(name, plink));
|
1999-10-26 23:44:36 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
nbucket = name->bucket;
|
|
|
|
name->bucket = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(nbucket != NULL);
|
1999-10-26 23:44:36 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (NAME_DEAD(name)) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_UNLINK(nbucket->deadnames, name, plink);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_UNLINK(nbucket->names, name, plink);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-10-26 23:44:36 +00:00
|
|
|
}
|
1999-10-22 05:19:42 +00:00
|
|
|
|
2000-01-12 03:00:33 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Requires the entry's bucket to be locked.
|
2000-01-12 03:00:33 +00:00
|
|
|
*/
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
link_entry(dns_adbentrybucket_t *ebucket, dns_adbentry_t *entry) {
|
2022-03-16 21:58:55 +01:00
|
|
|
REQUIRE(entry != NULL && entry->bucket == NULL);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(!ISC_LINK_LINKED(entry, plink));
|
2009-01-28 23:20:23 +00:00
|
|
|
|
2022-04-05 13:16:00 +01:00
|
|
|
DP(DEF_LEVEL, "link ADB entry %p to bucket %p", entry, ebucket);
|
2022-03-24 15:58:26 -07:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* If we're in the overmem condition, take this opportunity to
|
|
|
|
* clean up the least-recently used entries in the bucket.
|
|
|
|
*/
|
|
|
|
if (isc_mem_isovermem(entry->adb->mctx)) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
DP(ISC_LOG_DEBUG(1), "adb: overmem, cleaning bucket %p",
|
|
|
|
ebucket);
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
dns_adbentry_t *e = ISC_LIST_TAIL(ebucket->entries);
|
|
|
|
if (e == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
2009-01-28 23:20:23 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* If the only reference to an entry is from
|
|
|
|
* the bucket itself, we can kill it. Otherwise
|
|
|
|
* we move it to deadentries and kill it later.
|
|
|
|
*/
|
|
|
|
if (isc_refcount_current(&e->references) == 1) {
|
|
|
|
unlink_entry(e);
|
|
|
|
entry_detach(&e);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
INSIST((e->flags & ENTRY_IS_DEAD) == 0);
|
|
|
|
e->flags |= ENTRY_IS_DEAD;
|
|
|
|
ISC_LIST_UNLINK(ebucket->entries, e, plink);
|
|
|
|
ISC_LIST_PREPEND(ebucket->deadentries, e, plink);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
entry->bucket = ebucket;
|
|
|
|
ISC_LIST_PREPEND(ebucket->entries, entry, plink);
|
|
|
|
isc_refcount_increment0(&ebucket->references);
|
2000-01-12 03:00:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Requires the entry's bucket to be locked.
|
2000-01-12 03:00:33 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
2022-03-16 21:58:55 +01:00
|
|
|
unlink_entry(dns_adbentry_t *entry) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADBENTRY_VALID(entry));
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(ISC_LINK_LINKED(entry, plink));
|
2000-01-12 03:00:33 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = entry->bucket;
|
|
|
|
entry->bucket = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(ebucket != NULL);
|
2000-01-12 03:00:33 +00:00
|
|
|
|
2022-04-05 13:16:00 +01:00
|
|
|
DP(DEF_LEVEL, "unlink ADB entry %p from bucket %p", entry, ebucket);
|
2022-03-24 15:58:26 -07:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if ((entry->flags & ENTRY_IS_DEAD) != 0) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_UNLINK(ebucket->deadentries, entry, plink);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_UNLINK(ebucket->entries, entry, plink);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
1999-10-19 01:37:22 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
shutdown_names(dns_adb_t *adb) {
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_result_t result;
|
|
|
|
isc_ht_iter_t *it = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWLOCK(&adb->names_lock, isc_rwlocktype_read);
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_iter_create(adb->namebuckets, &it);
|
|
|
|
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
|
|
|
|
result = isc_ht_iter_next(it))
|
|
|
|
{
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_adbname_t *name = NULL;
|
|
|
|
dns_adbname_t *next_name = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_ht_iter_current(it, (void **)&nbucket);
|
|
|
|
INSIST(nbucket != NULL);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
LOCK(&nbucket->lock);
|
2022-03-16 21:58:55 +01:00
|
|
|
/*
|
|
|
|
* Run through the list. For each name, clean up finds
|
|
|
|
* found there, and cancel any fetches running. When
|
|
|
|
* all the fetches are canceled, the name will destroy
|
|
|
|
* itself.
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
name = ISC_LIST_HEAD(nbucket->names);
|
2022-03-16 21:58:55 +01:00
|
|
|
while (name != NULL) {
|
|
|
|
next_name = ISC_LIST_NEXT(name, plink);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
expire_name(&name, DNS_EVENT_ADBSHUTDOWN);
|
2022-03-16 21:58:55 +01:00
|
|
|
name = next_name;
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&nbucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
2022-03-16 21:58:55 +01:00
|
|
|
|
|
|
|
isc_ht_iter_destroy(&it);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_read);
|
1999-10-19 01:37:22 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
shutdown_entries(dns_adb_t *adb) {
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_result_t result;
|
|
|
|
isc_ht_iter_t *iter = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWLOCK(&adb->entries_lock, isc_rwlocktype_read);
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_iter_create(adb->entrybuckets, &iter);
|
|
|
|
for (result = isc_ht_iter_first(iter); result == ISC_R_SUCCESS;
|
|
|
|
result = isc_ht_iter_next(iter))
|
|
|
|
{
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_adbentry_t *entry = NULL;
|
|
|
|
dns_adbentry_t *next_entry = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_ht_iter_current(iter, (void **)&ebucket);
|
|
|
|
INSIST(ebucket != NULL);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
LOCK(&ebucket->lock);
|
|
|
|
entry = ISC_LIST_HEAD(ebucket->entries);
|
2022-03-16 21:58:55 +01:00
|
|
|
while (entry != NULL) {
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Run through the list and clean up any
|
|
|
|
* entries not in use.
|
2008-02-07 23:46:54 +00:00
|
|
|
*/
|
2022-03-16 21:58:55 +01:00
|
|
|
next_entry = ISC_LIST_NEXT(entry, plink);
|
2022-04-11 17:29:03 -07:00
|
|
|
if (isc_refcount_current(&entry->references) == 1 &&
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry->expires == 0) {
|
2022-03-16 21:58:55 +01:00
|
|
|
unlink_entry(entry);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry_detach(&entry);
|
2022-03-16 21:58:55 +01:00
|
|
|
entry = next_entry;
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_read);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
|
|
|
isc_ht_iter_destroy(&iter);
|
2000-01-12 03:00:33 +00:00
|
|
|
}
|
|
|
|
|
1999-10-26 23:44:36 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* The bucket for the name containing the 'namehooks' list must be locked.
|
1999-10-26 23:44:36 +00:00
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbnamehook_t *namehook = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
namehook = ISC_LIST_HEAD(*namehooks);
|
|
|
|
while (namehook != NULL) {
|
|
|
|
INSIST(DNS_ADBNAMEHOOK_VALID(namehook));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Clean up the entry if needed.
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (namehook->entry != NULL) {
|
|
|
|
INSIST(DNS_ADBENTRY_VALID(namehook->entry));
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* If entry bucket for the next address is
|
|
|
|
* different from the previous one, then
|
|
|
|
* unlock the old one, lock the new one, and
|
|
|
|
* carry on. (This way we don't necessarily
|
|
|
|
* have to lock and unlock for every list
|
|
|
|
* member.)
|
|
|
|
*/
|
|
|
|
if (ebucket != namehook->entry->bucket) {
|
|
|
|
if (ebucket != NULL) {
|
|
|
|
UNLOCK(&ebucket->lock);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = namehook->entry->bucket;
|
|
|
|
INSIST(ebucket != NULL);
|
|
|
|
LOCK(&ebucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
namehook->entry->nh--;
|
|
|
|
entry_detach(&namehook->entry);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Free the namehook
|
|
|
|
*/
|
|
|
|
ISC_LIST_UNLINK(*namehooks, namehook, plink);
|
|
|
|
free_adbnamehook(adb, &namehook);
|
|
|
|
|
|
|
|
namehook = ISC_LIST_HEAD(*namehooks);
|
|
|
|
}
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (ebucket != NULL) {
|
|
|
|
UNLOCK(&ebucket->lock);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-10-19 01:37:22 +00:00
|
|
|
}
|
|
|
|
|
2000-01-19 01:43:58 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
clean_target(dns_adb_t *adb, dns_name_t *target) {
|
2008-02-07 23:46:54 +00:00
|
|
|
if (dns_name_countlabels(target) > 0) {
|
|
|
|
dns_name_free(target, adb->mctx);
|
|
|
|
dns_name_init(target, NULL);
|
|
|
|
}
|
2000-01-19 01:43:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
set_target(dns_adb_t *adb, const dns_name_t *name, const dns_name_t *fname,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdataset_t *rdataset, dns_name_t *target) {
|
|
|
|
isc_result_t result;
|
|
|
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
REQUIRE(dns_name_countlabels(target) == 0);
|
|
|
|
|
|
|
|
if (rdataset->type == dns_rdatatype_cname) {
|
|
|
|
dns_rdata_cname_t cname;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy the CNAME's target into the target name.
|
|
|
|
*/
|
|
|
|
result = dns_rdataset_first(rdataset);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2008-02-07 23:46:54 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_rdataset_current(rdataset, &rdata);
|
|
|
|
result = dns_rdata_tostruct(&rdata, &cname, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2008-02-07 23:46:54 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2019-11-01 08:31:13 -05:00
|
|
|
dns_name_dup(&cname.cname, adb->mctx, target);
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_rdata_freestruct(&cname);
|
|
|
|
} else {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_fixedname_t fixed1, fixed2;
|
|
|
|
dns_name_t *prefix = NULL, *new_target = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_rdata_dname_t dname;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_namereln_t namereln;
|
|
|
|
unsigned int nlabels;
|
|
|
|
int order;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
INSIST(rdataset->type == dns_rdatatype_dname);
|
|
|
|
namereln = dns_name_fullcompare(name, fname, &order, &nlabels);
|
|
|
|
INSIST(namereln == dns_namereln_subdomain);
|
2022-03-24 16:06:48 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Get the target name of the DNAME.
|
|
|
|
*/
|
|
|
|
result = dns_rdataset_first(rdataset);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2008-02-07 23:46:54 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_rdataset_current(rdataset, &rdata);
|
|
|
|
result = dns_rdata_tostruct(&rdata, &dname, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2008-02-07 23:46:54 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2022-03-24 16:06:48 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Construct the new target name.
|
|
|
|
*/
|
2018-03-28 14:38:09 +02:00
|
|
|
prefix = dns_fixedname_initname(&fixed1);
|
|
|
|
new_target = dns_fixedname_initname(&fixed2);
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_name_split(name, nlabels, prefix, NULL);
|
|
|
|
result = dns_name_concatenate(prefix, &dname.dname, new_target,
|
|
|
|
NULL);
|
|
|
|
dns_rdata_freestruct(&dname);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2008-02-07 23:46:54 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2019-11-01 08:31:13 -05:00
|
|
|
dns_name_dup(new_target, adb->mctx, target);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (ISC_R_SUCCESS);
|
2000-01-19 01:43:58 +00:00
|
|
|
}
|
|
|
|
|
1999-10-29 18:00:31 +00:00
|
|
|
static void
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
event_freefind(isc_event_t *event) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbfind_t *find = NULL;
|
|
|
|
|
|
|
|
REQUIRE(event != NULL);
|
1999-10-29 18:00:31 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
find = event->ev_destroy_arg;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADBFIND_VALID(find));
|
1999-10-29 18:00:31 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
LOCK(&find->lock);
|
|
|
|
find->flags |= FIND_EVENT_FREED;
|
|
|
|
event->ev_destroy_arg = NULL;
|
|
|
|
UNLOCK(&find->lock);
|
1999-10-29 18:00:31 +00:00
|
|
|
}
|
|
|
|
|
1999-10-20 23:26:06 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Assumes the name's bucket is locked.
|
1999-10-20 23:26:06 +00:00
|
|
|
*/
|
1999-10-19 01:37:22 +00:00
|
|
|
static void
|
1999-10-30 01:58:02 +00:00
|
|
|
clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int addrs) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbfind_t *find = NULL, *next = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
DP(ENTER_LEVEL,
|
2020-02-12 13:59:18 +01:00
|
|
|
"ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x", name,
|
|
|
|
evtype, addrs);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
for (find = ISC_LIST_HEAD(name->finds); find != NULL; find = next) {
|
2022-03-24 16:06:48 -07:00
|
|
|
bool process = false;
|
|
|
|
unsigned int wanted, notify;
|
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
LOCK(&find->lock);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
next = ISC_LIST_NEXT(find, plink);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
|
|
|
|
notify = wanted & addrs;
|
|
|
|
|
|
|
|
switch (evtype) {
|
|
|
|
case DNS_EVENT_ADBMOREADDRESSES:
|
|
|
|
DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBMOREADDRESSES");
|
|
|
|
if ((notify) != 0) {
|
|
|
|
find->flags &= ~addrs;
|
2018-04-17 08:29:14 -07:00
|
|
|
process = true;
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DNS_EVENT_ADBNOMOREADDRESSES:
|
|
|
|
DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBNOMOREADDRESSES");
|
|
|
|
find->flags &= ~addrs;
|
|
|
|
wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (wanted == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
process = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
find->flags &= ~addrs;
|
2018-04-17 08:29:14 -07:00
|
|
|
process = true;
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (process) {
|
2022-03-24 16:06:48 -07:00
|
|
|
isc_task_t *task = NULL;
|
|
|
|
isc_event_t *ev = NULL;
|
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
DP(DEF_LEVEL, "cfan: processing find %p", find);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Unlink the find from the name, letting the caller
|
|
|
|
* call dns_adb_destroyfind() on it to clean it up
|
|
|
|
* later.
|
|
|
|
*/
|
|
|
|
ISC_LIST_UNLINK(name->finds, find, plink);
|
|
|
|
find->adbname = NULL;
|
|
|
|
|
|
|
|
INSIST(!FIND_EVENTSENT(find));
|
|
|
|
|
|
|
|
ev = &find->event;
|
|
|
|
task = ev->ev_sender;
|
|
|
|
ev->ev_sender = find;
|
|
|
|
find->result_v4 = find_err_map[name->fetch_err];
|
|
|
|
find->result_v6 = find_err_map[name->fetch6_err];
|
|
|
|
ev->ev_type = evtype;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ev->ev_destroy = event_freefind;
|
2008-02-07 23:46:54 +00:00
|
|
|
ev->ev_destroy_arg = find;
|
|
|
|
|
2022-05-11 13:55:01 -07:00
|
|
|
DP(DEF_LEVEL,
|
|
|
|
"cfan: sending event %p "
|
|
|
|
"to task %p for find %p",
|
2008-02-07 23:46:54 +00:00
|
|
|
ev, task, find);
|
|
|
|
|
|
|
|
isc_task_sendanddetach(&task, (isc_event_t **)&ev);
|
2015-03-18 06:42:54 +05:30
|
|
|
find->flags |= FIND_EVENT_SENT;
|
2008-02-07 23:46:54 +00:00
|
|
|
} else {
|
|
|
|
DP(DEF_LEVEL, "cfan: skipping find %p", find);
|
|
|
|
}
|
|
|
|
|
|
|
|
UNLOCK(&find->lock);
|
|
|
|
}
|
|
|
|
DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name);
|
1999-10-19 01:37:22 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbname_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
new_adbname(dns_adb_t *adb, const dns_name_t *dnsname) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbname_t *name = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
name = isc_mem_get(adb->mctx, sizeof(*name));
|
2022-03-16 21:58:55 +01:00
|
|
|
*name = (dns_adbname_t){
|
|
|
|
.expire_v4 = INT_MAX,
|
|
|
|
.expire_v6 = INT_MAX,
|
|
|
|
.expire_target = INT_MAX,
|
|
|
|
.fetch_err = FIND_ERR_UNEXPECTED,
|
|
|
|
.fetch6_err = FIND_ERR_UNEXPECTED,
|
|
|
|
};
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adb_attach(adb, &name->adb);
|
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_name_init(&name->name, NULL);
|
2019-11-01 08:31:13 -05:00
|
|
|
dns_name_dup(dnsname, adb->mctx, &name->name);
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_name_init(&name->target, NULL);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
ISC_LIST_INIT(name->v4);
|
|
|
|
ISC_LIST_INIT(name->v6);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
ISC_LIST_INIT(name->finds);
|
|
|
|
ISC_LINK_INIT(name, plink);
|
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
name->magic = DNS_ADBNAME_MAGIC;
|
|
|
|
|
2012-05-14 10:06:05 -07:00
|
|
|
inc_adbstats(adb, dns_adbstats_namescnt);
|
2010-12-21 23:47:08 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
return (name);
|
1999-09-23 00:43:10 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
free_adbname(dns_adbname_t **namep) {
|
|
|
|
dns_adb_t *adb = NULL;
|
|
|
|
dns_adbname_t *name = NULL;
|
2007-10-19 17:15:53 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(namep != NULL && DNS_ADBNAME_VALID(*namep));
|
2007-10-19 17:15:53 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
name = *namep;
|
|
|
|
*namep = NULL;
|
2007-10-19 17:15:53 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(!NAME_HAS_V4(name));
|
|
|
|
REQUIRE(!NAME_HAS_V6(name));
|
|
|
|
REQUIRE(!NAME_FETCH(name));
|
|
|
|
REQUIRE(ISC_LIST_EMPTY(name->finds));
|
|
|
|
REQUIRE(!ISC_LINK_LINKED(name, plink));
|
|
|
|
REQUIRE(name->bucket == NULL);
|
1999-10-02 01:59:09 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
name->magic = 0;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
adb = name->adb;
|
|
|
|
dns_name_free(&name->name, adb->mctx);
|
2012-05-14 10:06:05 -07:00
|
|
|
dec_adbstats(adb, dns_adbstats_namescnt);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_mem_put(adb->mctx, name, sizeof(*name));
|
|
|
|
dns_adb_detach(&adb);
|
2022-03-16 21:58:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static dns_adbnamebucket_t *
|
|
|
|
new_adbnamebucket(dns_adb_t *adb) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
nbucket = isc_mem_get(adb->mctx, sizeof(*nbucket));
|
|
|
|
*nbucket = (dns_adbnamebucket_t){
|
|
|
|
.references = 0, /* workaround for old gcc */
|
|
|
|
};
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_INIT(nbucket->names);
|
|
|
|
ISC_LIST_INIT(nbucket->deadnames);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_mutex_init(&nbucket->lock);
|
|
|
|
isc_refcount_init(&nbucket->references, 0);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
return (nbucket);
|
1999-10-02 01:59:09 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbnamehook_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbnamehook_t *nh = NULL;
|
1999-09-23 00:43:10 +00:00
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
nh = isc_mem_get(adb->mctx, sizeof(*nh));
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
*nh = (dns_adbnamehook_t){ .entry = entry };
|
1999-09-23 00:43:10 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
ISC_LINK_INIT(nh, plink);
|
1999-09-23 00:43:10 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
nh->magic = DNS_ADBNAMEHOOK_MAGIC;
|
2008-02-07 23:46:54 +00:00
|
|
|
return (nh);
|
1999-09-23 00:43:10 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbnamehook_t *nh = NULL;
|
|
|
|
|
|
|
|
REQUIRE(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook));
|
1999-10-02 01:59:09 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
nh = *namehook;
|
|
|
|
*namehook = NULL;
|
1999-10-02 01:59:09 +00:00
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(nh->entry == NULL);
|
|
|
|
REQUIRE(!ISC_LINK_LINKED(nh, plink));
|
1999-10-02 01:59:09 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
nh->magic = 0;
|
2021-05-12 21:16:17 +02:00
|
|
|
|
|
|
|
isc_mem_put(adb->mctx, nh, sizeof(*nh));
|
1999-10-02 01:59:09 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adblameinfo_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
new_adblameinfo(dns_adb_t *adb, const dns_name_t *qname,
|
|
|
|
dns_rdatatype_t qtype) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adblameinfo_t *li = isc_mem_get(adb->mctx, sizeof(*li));
|
1999-09-23 00:43:10 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_name_init(&li->qname, NULL);
|
2019-11-01 08:31:13 -05:00
|
|
|
dns_name_dup(qname, adb->mctx, &li->qname);
|
2008-02-07 23:46:54 +00:00
|
|
|
li->magic = DNS_ADBLAMEINFO_MAGIC;
|
|
|
|
li->lame_timer = 0;
|
|
|
|
li->qtype = qtype;
|
|
|
|
ISC_LINK_INIT(li, plink);
|
1999-10-19 21:10:29 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
return (li);
|
1999-09-23 00:43:10 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adblameinfo_t *li = NULL;
|
|
|
|
|
|
|
|
REQUIRE(lameinfo != NULL && DNS_ADBLAMEINFO_VALID(*lameinfo));
|
1999-10-08 23:12:21 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
li = *lameinfo;
|
|
|
|
*lameinfo = NULL;
|
1999-10-08 23:12:21 +00:00
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(!ISC_LINK_LINKED(li, plink));
|
1999-10-08 23:12:21 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_name_free(&li->qname, adb->mctx);
|
1999-10-08 23:12:21 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
li->magic = 0;
|
1999-10-08 23:12:21 +00:00
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_mem_put(adb->mctx, li, sizeof(*li));
|
1999-10-08 23:12:21 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbentry_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
new_adbentry(dns_adb_t *adb) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentry_t *entry = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry = isc_mem_get(adb->mctx, sizeof(*entry));
|
|
|
|
*entry = (dns_adbentry_t){
|
2022-03-16 21:58:55 +01:00
|
|
|
.srtt = isc_random_uniform(0x1f) + 1,
|
|
|
|
};
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adb_attach(adb, &entry->adb);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_refcount_init(&entry->references, 1);
|
|
|
|
atomic_init(&entry->active, 0);
|
|
|
|
atomic_init(&entry->quota, adb->quota);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_INIT(entry->lameinfo);
|
|
|
|
ISC_LINK_INIT(entry, plink);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry->magic = DNS_ADBENTRY_MAGIC;
|
2022-03-16 21:58:55 +01:00
|
|
|
|
2012-05-14 10:06:05 -07:00
|
|
|
inc_adbstats(adb, dns_adbstats_entriescnt);
|
2007-10-19 17:15:53 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
return (entry);
|
1999-09-23 00:43:10 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
free_adbentry(dns_adbentry_t **entryp) {
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_adb_t *adb = NULL;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentry_t *entry = NULL;
|
|
|
|
dns_adblameinfo_t *li = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(entryp != NULL && DNS_ADBENTRY_VALID(*entryp));
|
2007-10-19 17:15:53 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry = *entryp;
|
|
|
|
*entryp = NULL;
|
1999-10-14 00:50:00 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(entry->bucket == NULL);
|
|
|
|
REQUIRE(!ISC_LINK_LINKED(entry, plink));
|
1999-10-02 01:59:09 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
adb = entry->adb;
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry->magic = 0;
|
1999-10-02 01:59:09 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (entry->cookie != NULL) {
|
|
|
|
isc_mem_put(adb->mctx, entry->cookie, entry->cookielen);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-02-19 12:53:42 +11:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
li = ISC_LIST_HEAD(entry->lameinfo);
|
2008-02-07 23:46:54 +00:00
|
|
|
while (li != NULL) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_UNLINK(entry->lameinfo, li, plink);
|
2008-02-07 23:46:54 +00:00
|
|
|
free_adblameinfo(adb, &li);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
li = ISC_LIST_HEAD(entry->lameinfo);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
1999-10-19 21:42:56 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_refcount_destroy(&entry->references);
|
2012-05-14 10:06:05 -07:00
|
|
|
dec_adbstats(adb, dns_adbstats_entriescnt);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_mem_put(adb->mctx, entry, sizeof(*entry));
|
|
|
|
dns_adb_detach(&adb);
|
2022-03-16 21:58:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static dns_adbentrybucket_t *
|
|
|
|
new_adbentrybucket(dns_adb_t *adb) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = isc_mem_get(adb->mctx, sizeof(*ebucket));
|
|
|
|
*ebucket = (dns_adbentrybucket_t){
|
|
|
|
.references = 0, /* workaround for old gcc */
|
|
|
|
};
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_INIT(ebucket->entries);
|
|
|
|
ISC_LIST_INIT(ebucket->deadentries);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_mutex_init(&ebucket->lock);
|
|
|
|
isc_refcount_init(&ebucket->references, 0);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
return (ebucket);
|
1999-10-02 01:59:09 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbfind_t *
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
new_adbfind(dns_adb_t *adb, in_port_t port) {
|
|
|
|
dns_adbfind_t *find = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
find = isc_mem_get(adb->mctx, sizeof(*find));
|
|
|
|
*find = (dns_adbfind_t){
|
|
|
|
.port = port,
|
2022-03-16 21:58:55 +01:00
|
|
|
.result_v4 = ISC_R_UNEXPECTED,
|
|
|
|
.result_v6 = ISC_R_UNEXPECTED,
|
|
|
|
};
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adb_attach(adb, &find->adb);
|
|
|
|
ISC_LINK_INIT(find, publink);
|
|
|
|
ISC_LINK_INIT(find, plink);
|
|
|
|
ISC_LIST_INIT(find->list);
|
|
|
|
isc_mutex_init(&find->lock);
|
|
|
|
ISC_EVENT_INIT(&find->event, sizeof(isc_event_t), 0, 0, 0, NULL, NULL,
|
|
|
|
NULL, NULL, find);
|
1999-09-23 00:43:10 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
find->magic = DNS_ADBFIND_MAGIC;
|
1999-10-25 21:02:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
return (find);
|
1999-10-25 21:02:54 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
free_adbfind(dns_adbfind_t **findp) {
|
|
|
|
dns_adb_t *adb = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbfind_t *find = NULL;
|
|
|
|
|
|
|
|
REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp));
|
1999-10-08 23:12:21 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
find = *findp;
|
|
|
|
*findp = NULL;
|
1999-10-08 23:12:21 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
adb = find->adb;
|
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(!FIND_HAS_ADDRS(find));
|
|
|
|
REQUIRE(!ISC_LINK_LINKED(find, publink));
|
|
|
|
REQUIRE(!ISC_LINK_LINKED(find, plink));
|
|
|
|
REQUIRE(find->adbname == NULL);
|
1999-10-14 00:50:00 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
find->magic = 0;
|
1999-10-08 23:12:21 +00:00
|
|
|
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&find->lock);
|
2021-05-12 21:16:17 +02:00
|
|
|
|
|
|
|
isc_mem_put(adb->mctx, find, sizeof(*find));
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adb_detach(&adb);
|
|
|
|
}
|
|
|
|
|
|
|
|
static dns_adbfetch_t *
|
|
|
|
new_adbfetch(dns_adb_t *adb) {
|
|
|
|
dns_adbfetch_t *fetch = NULL;
|
|
|
|
|
|
|
|
fetch = isc_mem_get(adb->mctx, sizeof(*fetch));
|
|
|
|
*fetch = (dns_adbfetch_t){ 0 };
|
|
|
|
dns_rdataset_init(&fetch->rdataset);
|
|
|
|
|
|
|
|
fetch->magic = DNS_ADBFETCH_MAGIC;
|
|
|
|
|
|
|
|
return (fetch);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetchp) {
|
|
|
|
dns_adbfetch_t *fetch = NULL;
|
|
|
|
|
|
|
|
REQUIRE(fetchp != NULL && DNS_ADBFETCH_VALID(*fetchp));
|
|
|
|
|
|
|
|
fetch = *fetchp;
|
|
|
|
*fetchp = NULL;
|
|
|
|
|
|
|
|
fetch->magic = 0;
|
|
|
|
|
|
|
|
if (dns_rdataset_isassociated(&fetch->rdataset)) {
|
|
|
|
dns_rdataset_disassociate(&fetch->rdataset);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_mem_put(adb->mctx, fetch, sizeof(*fetch));
|
1999-10-08 23:12:21 +00:00
|
|
|
}
|
|
|
|
|
1999-09-23 00:43:10 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Copy bits from an adbentry into a newly allocated adb_addrinfo structure.
|
|
|
|
* The entry must be locked, and its reference count must be incremented.
|
1999-09-22 00:26:20 +00:00
|
|
|
*/
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_adbaddrinfo_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbaddrinfo_t *ai = NULL;
|
2007-10-19 17:15:53 +00:00
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
ai = isc_mem_get(adb->mctx, sizeof(*ai));
|
2022-03-16 21:58:55 +01:00
|
|
|
*ai = (dns_adbaddrinfo_t){ .srtt = entry->srtt,
|
|
|
|
.flags = entry->flags,
|
|
|
|
.dscp = -1 };
|
2007-10-19 17:15:53 +00:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
ISC_LINK_INIT(ai, publink);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry_attach(entry, &ai->entry);
|
2008-02-07 23:46:54 +00:00
|
|
|
ai->sockaddr = entry->sockaddr;
|
|
|
|
isc_sockaddr_setport(&ai->sockaddr, port);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
|
|
|
ai->magic = DNS_ADBADDRINFO_MAGIC;
|
2007-10-19 17:15:53 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
return (ai);
|
1999-09-23 00:43:10 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbaddrinfo_t *ai = NULL;
|
|
|
|
|
|
|
|
REQUIRE(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo));
|
1999-10-14 00:50:00 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
ai = *ainfo;
|
|
|
|
*ainfo = NULL;
|
1999-10-14 00:50:00 +00:00
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(!ISC_LINK_LINKED(ai, publink));
|
1999-10-14 00:50:00 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
ai->magic = 0;
|
1999-10-14 00:50:00 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry_detach(&ai->entry);
|
|
|
|
|
2021-05-12 21:16:17 +02:00
|
|
|
isc_mem_put(adb->mctx, ai, sizeof(*ai));
|
1999-10-14 00:50:00 +00:00
|
|
|
}
|
|
|
|
|
1999-09-23 00:43:10 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Search for the name bucket in the hash table.
|
1999-09-23 00:43:10 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
|
|
|
get_namebucket(dns_adb_t *adb, const dns_name_t *name,
|
|
|
|
dns_adbnamebucket_t **nbucketp) {
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_result_t result;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(nbucketp != NULL && *nbucketp == NULL);
|
|
|
|
|
|
|
|
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
|
2022-03-16 21:58:55 +01:00
|
|
|
result = isc_ht_find(adb->namebuckets, name->ndata, name->length,
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
(void **)&nbucket);
|
2022-03-16 21:58:55 +01:00
|
|
|
if (result == ISC_R_NOTFOUND) {
|
|
|
|
/*
|
|
|
|
* Allocate a new bucket and add it to the hash table.
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
nbucket = new_adbnamebucket(adb);
|
2022-03-16 21:58:55 +01:00
|
|
|
result = isc_ht_add(adb->namebuckets, name->ndata, name->length,
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
nbucket);
|
2022-03-16 21:58:55 +01:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
|
2022-03-16 21:58:55 +01:00
|
|
|
INSIST(result == ISC_R_SUCCESS);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
*nbucketp = nbucket;
|
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* Get the name from its bucket. The bucket must be locked.
|
|
|
|
*/
|
|
|
|
static dns_adbname_t *
|
|
|
|
get_name(dns_adbnamebucket_t *nbucket, const dns_name_t *name,
|
|
|
|
unsigned int options) {
|
|
|
|
dns_adbname_t *adbname = ISC_LIST_HEAD(nbucket->names);
|
2008-02-07 23:46:54 +00:00
|
|
|
while (adbname != NULL) {
|
|
|
|
if (!NAME_DEAD(adbname)) {
|
2020-02-12 13:59:18 +01:00
|
|
|
if (dns_name_equal(name, &adbname->name) &&
|
|
|
|
GLUEHINT_OK(adbname, options) &&
|
2020-02-13 14:44:37 -08:00
|
|
|
STARTATZONE_MATCHES(adbname, options))
|
|
|
|
{
|
2008-02-07 23:46:54 +00:00
|
|
|
return (adbname);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
adbname = ISC_LIST_NEXT(adbname, plink);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (NULL);
|
1999-09-23 00:43:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Search for the entry bucket for this address in the hash table.
|
1999-09-23 00:43:10 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
|
|
|
get_entrybucket(dns_adb_t *adb, const isc_sockaddr_t *addr,
|
|
|
|
dns_adbentrybucket_t **ebucketp) {
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_result_t result;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(ebucketp != NULL && *ebucketp == NULL);
|
|
|
|
|
|
|
|
RWLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
2022-03-16 21:58:55 +01:00
|
|
|
result = isc_ht_find(adb->entrybuckets, (const unsigned char *)addr,
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
sizeof(*addr), (void **)&ebucket);
|
2022-03-16 21:58:55 +01:00
|
|
|
if (result == ISC_R_NOTFOUND) {
|
|
|
|
/*
|
|
|
|
* Allocate a new bucket and add it to the hash table.
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = new_adbentrybucket(adb);
|
2022-03-16 21:58:55 +01:00
|
|
|
result = isc_ht_add(adb->entrybuckets,
|
|
|
|
(const unsigned char *)addr, sizeof(*addr),
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket);
|
2022-03-16 21:58:55 +01:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
|
|
|
INSIST(result == ISC_R_SUCCESS);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
*ebucketp = ebucket;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Find the entry from its bucket. The bucket must be locked.
|
|
|
|
*/
|
|
|
|
static dns_adbentry_t *
|
|
|
|
get_entry(dns_adbentrybucket_t *ebucket, const isc_sockaddr_t *addr,
|
|
|
|
isc_stdtime_t now) {
|
|
|
|
dns_adbentry_t *entry = NULL, *entry_next = NULL;
|
1999-09-23 00:43:10 +00:00
|
|
|
|
2009-01-28 23:20:23 +00:00
|
|
|
/* Search the list, while cleaning up expired entries. */
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
for (entry = ISC_LIST_HEAD(ebucket->entries); entry != NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
entry = entry_next) {
|
2009-01-28 23:20:23 +00:00
|
|
|
entry_next = ISC_LIST_NEXT(entry, plink);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
|
|
|
|
/* Address entries expire after 30 minutes. */
|
|
|
|
maybe_expire_entry(&entry, now);
|
|
|
|
if (entry != NULL && isc_sockaddr_equal(addr, &entry->sockaddr))
|
2020-02-13 14:44:37 -08:00
|
|
|
{
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_UNLINK(ebucket->entries, entry, plink);
|
|
|
|
ISC_LIST_PREPEND(ebucket->entries, entry, plink);
|
2008-02-07 23:46:54 +00:00
|
|
|
return (entry);
|
2009-01-28 23:20:23 +00:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
1999-09-23 00:43:10 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
return (NULL);
|
1999-09-23 00:43:10 +00:00
|
|
|
}
|
1999-09-22 00:26:20 +00:00
|
|
|
|
1999-10-19 20:55:04 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* The entry's bucket must be locked.
|
1999-10-19 20:55:04 +00:00
|
|
|
*/
|
2018-04-17 08:29:14 -07:00
|
|
|
static bool
|
2016-12-30 15:45:08 +11:00
|
|
|
entry_is_lame(dns_adb_t *adb, dns_adbentry_t *entry, const dns_name_t *qname,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdatatype_t qtype, isc_stdtime_t now) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adblameinfo_t *li = NULL, *next_li = NULL;
|
|
|
|
bool is_bad = false;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
li = ISC_LIST_HEAD(entry->lameinfo);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (li == NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
while (li != NULL) {
|
|
|
|
next_li = ISC_LIST_NEXT(li, plink);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Has the entry expired?
|
|
|
|
*/
|
|
|
|
if (li->lame_timer < now) {
|
|
|
|
ISC_LIST_UNLINK(entry->lameinfo, li, plink);
|
|
|
|
free_adblameinfo(adb, &li);
|
|
|
|
}
|
1999-10-19 20:55:04 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Order tests from least to most expensive.
|
|
|
|
*
|
|
|
|
* We do not break out of the main loop here as
|
|
|
|
* we use the loop for house keeping.
|
|
|
|
*/
|
|
|
|
if (li != NULL && !is_bad && li->qtype == qtype &&
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_name_equal(qname, &li->qname))
|
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
is_bad = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
li = next_li;
|
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
return (is_bad);
|
1999-10-19 20:55:04 +00:00
|
|
|
}
|
|
|
|
|
2015-07-08 22:53:39 -07:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
log_quota(dns_adbentry_t *entry, const char *fmt, ...) {
|
|
|
|
va_list ap;
|
|
|
|
char msgbuf[2048];
|
|
|
|
char addrbuf[ISC_NETADDR_FORMATSIZE];
|
2015-07-08 22:53:39 -07:00
|
|
|
isc_netaddr_t netaddr;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
|
|
|
|
isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
|
|
|
|
|
|
|
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
|
2019-01-22 10:47:18 +01:00
|
|
|
ISC_LOG_INFO,
|
|
|
|
"adb: quota %s (%" PRIuFAST32 "/%" PRIuFAST32 "): %s",
|
|
|
|
addrbuf, atomic_load_relaxed(&entry->active),
|
|
|
|
atomic_load_relaxed(&entry->quota), msgbuf);
|
2015-07-08 22:53:39 -07:00
|
|
|
}
|
|
|
|
|
1999-10-08 23:12:21 +00:00
|
|
|
static void
|
2016-12-30 15:45:08 +11:00
|
|
|
copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find,
|
|
|
|
const dns_name_t *qname, dns_rdatatype_t qtype,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adbname_t *name, isc_stdtime_t now) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbnamehook_t *namehook = NULL;
|
|
|
|
dns_adbaddrinfo_t *addrinfo = NULL;
|
|
|
|
dns_adbentry_t *entry = NULL;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2018-10-11 11:57:57 +02:00
|
|
|
if ((find->options & DNS_ADBFIND_INET) != 0) {
|
2008-02-07 23:46:54 +00:00
|
|
|
namehook = ISC_LIST_HEAD(name->v4);
|
|
|
|
while (namehook != NULL) {
|
|
|
|
entry = namehook->entry;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = entry->bucket;
|
|
|
|
INSIST(ebucket != NULL);
|
|
|
|
LOCK(&ebucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2019-01-22 10:47:18 +01:00
|
|
|
if (dns_adbentry_overquota(entry)) {
|
2020-02-12 13:59:18 +01:00
|
|
|
find->options |= (DNS_ADBFIND_LAMEPRUNED |
|
|
|
|
DNS_ADBFIND_OVERQUOTA);
|
2015-07-08 22:53:39 -07:00
|
|
|
goto nextv4;
|
|
|
|
}
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
if (!FIND_RETURNLAME(find) &&
|
|
|
|
entry_is_lame(adb, entry, qname, qtype, now)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
find->options |= DNS_ADBFIND_LAMEPRUNED;
|
|
|
|
goto nextv4;
|
|
|
|
}
|
2021-04-22 18:58:01 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
addrinfo = new_adbaddrinfo(adb, entry, find->port);
|
2021-04-22 18:58:01 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Found a valid entry. Add it to the find's list.
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry_attach(entry, &(dns_adbentry_t *){ NULL });
|
2008-02-07 23:46:54 +00:00
|
|
|
ISC_LIST_APPEND(find->list, addrinfo, publink);
|
|
|
|
addrinfo = NULL;
|
|
|
|
nextv4:
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
|
|
|
ebucket = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
namehook = ISC_LIST_NEXT(namehook, plink);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-11 11:57:57 +02:00
|
|
|
if ((find->options & DNS_ADBFIND_INET6) != 0) {
|
2008-02-07 23:46:54 +00:00
|
|
|
namehook = ISC_LIST_HEAD(name->v6);
|
|
|
|
while (namehook != NULL) {
|
|
|
|
entry = namehook->entry;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = entry->bucket;
|
|
|
|
INSIST(ebucket != NULL);
|
|
|
|
LOCK(&ebucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2019-01-22 10:47:18 +01:00
|
|
|
if (dns_adbentry_overquota(entry)) {
|
2020-02-12 13:59:18 +01:00
|
|
|
find->options |= (DNS_ADBFIND_LAMEPRUNED |
|
|
|
|
DNS_ADBFIND_OVERQUOTA);
|
2015-07-08 22:53:39 -07:00
|
|
|
goto nextv6;
|
|
|
|
}
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
if (!FIND_RETURNLAME(find) &&
|
|
|
|
entry_is_lame(adb, entry, qname, qtype, now)) {
|
2008-10-17 03:23:13 +00:00
|
|
|
find->options |= DNS_ADBFIND_LAMEPRUNED;
|
2008-02-07 23:46:54 +00:00
|
|
|
goto nextv6;
|
2008-10-17 03:23:13 +00:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
addrinfo = new_adbaddrinfo(adb, entry, find->port);
|
2021-04-22 18:58:01 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Found a valid entry. Add it to the find's list.
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry_attach(entry, &(dns_adbentry_t *){ NULL });
|
2008-02-07 23:46:54 +00:00
|
|
|
ISC_LIST_APPEND(find->list, addrinfo, publink);
|
|
|
|
addrinfo = NULL;
|
|
|
|
nextv6:
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
|
|
|
ebucket = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
namehook = ISC_LIST_NEXT(namehook, plink);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ebucket != NULL) {
|
|
|
|
UNLOCK(&ebucket->lock);
|
|
|
|
}
|
1999-10-25 23:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-10-25 22:53:15 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* The name's bucket must be locked.
|
1999-10-25 22:53:15 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
|
|
|
maybe_expire_name(dns_adbname_t **namep, isc_stdtime_t now) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbname_t *name = NULL;
|
|
|
|
|
|
|
|
REQUIRE(namep != NULL && DNS_ADBNAME_VALID(*namep));
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
name = *namep;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/* Leave this name alone if it still has active namehooks... */
|
2020-02-13 21:48:23 +01:00
|
|
|
if (NAME_HAS_V4(name) || NAME_HAS_V6(name)) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
|
|
|
|
/* ...an active fetch in progres... */
|
2020-02-13 21:48:23 +01:00
|
|
|
if (NAME_FETCH(name)) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
|
|
|
|
/* ... or is not yet expired. */
|
|
|
|
if (!EXPIRE_OK(name->expire_v4, now) ||
|
|
|
|
!EXPIRE_OK(name->expire_v6, now) ||
|
|
|
|
!EXPIRE_OK(name->expire_target, now))
|
|
|
|
{
|
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
*namep = NULL;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
expire_name(&name, DNS_EVENT_ADBEXPIRED);
|
2007-10-19 17:15:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Examine the tail entry of the LRU list to see if it expires or is stale
|
|
|
|
* (unused for some period); if so, the name entry will be freed. If the ADB
|
|
|
|
* is in the overmem condition, the tail and the next to tail entries
|
|
|
|
* will be unconditionally removed (unless they have an outstanding fetch).
|
|
|
|
* We don't care about a race on 'overmem' at the risk of causing some
|
|
|
|
* collateral damage or a small delay in starting cleanup, so we don't bother
|
|
|
|
* to lock ADB (if it's not locked).
|
|
|
|
*
|
|
|
|
* Name bucket must be locked; adb may be locked; no other locks held.
|
|
|
|
*/
|
|
|
|
static void
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
purge_stale_names(dns_adb_t *adb, dns_adbnamebucket_t *nbucket,
|
|
|
|
isc_stdtime_t now) {
|
|
|
|
dns_adbname_t *adbname = NULL, *next_adbname = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
bool overmem = isc_mem_isovermem(adb->mctx);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
int max_removed = overmem ? 2 : 1;
|
|
|
|
int scans = 0, removed = 0;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(nbucket != NULL);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We limit the number of scanned entries to 10 (arbitrary choice)
|
|
|
|
* in order to avoid examining too many entries when there are many
|
|
|
|
* tail entries that have fetches (this should be rare, but could
|
|
|
|
* happen).
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
for (adbname = ISC_LIST_TAIL(nbucket->names);
|
|
|
|
adbname != NULL && removed < max_removed && scans < 10;
|
|
|
|
adbname = next_adbname)
|
2020-02-13 14:44:37 -08:00
|
|
|
{
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
INSIST(!NAME_DEAD(adbname));
|
|
|
|
|
|
|
|
next_adbname = ISC_LIST_PREV(adbname, plink);
|
2008-02-07 23:46:54 +00:00
|
|
|
scans++;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* Remove the name if it's expired or unused, has no
|
|
|
|
* address data, and there are no active fetches.
|
|
|
|
*/
|
|
|
|
maybe_expire_name(&adbname, now);
|
|
|
|
if (adbname == NULL) {
|
|
|
|
removed++;
|
|
|
|
if (overmem) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
2007-10-19 17:15:53 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (!NAME_FETCH(adbname) &&
|
|
|
|
(overmem || adbname->last_used + ADB_STALE_MARGIN <= now))
|
|
|
|
{
|
|
|
|
expire_name(&adbname, DNS_EVENT_ADBCANCELED);
|
|
|
|
removed++;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
1999-10-29 23:53:12 +00:00
|
|
|
}
|
|
|
|
|
2000-01-12 03:00:33 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* The entry's bucket must be locked.
|
2000-01-12 03:00:33 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
|
|
|
maybe_expire_entry(dns_adbentry_t **entryp, isc_stdtime_t now) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbentry_t *entry = NULL;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(entryp != NULL && DNS_ADBENTRY_VALID(*entryp));
|
2022-03-16 21:58:55 +01:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
entry = *entryp;
|
2003-10-16 05:46:19 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (isc_refcount_current(&entry->references) > 1) {
|
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-10-25 04:57:46 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (entry->expires == 0 || entry->expires > now) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-10-25 04:57:46 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* The entry is not in use. Delete it.
|
|
|
|
*/
|
2020-02-08 04:37:54 -08:00
|
|
|
*entryp = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
DP(DEF_LEVEL, "killing entry %p", entry);
|
|
|
|
INSIST(ISC_LINK_LINKED(entry, plink));
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
unlink_entry(entry);
|
|
|
|
entry_detach(&entry);
|
2000-01-12 03:00:33 +00:00
|
|
|
}
|
|
|
|
|
1999-10-29 23:53:12 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* A read lock must be held on adb->names_lock.
|
1999-10-29 23:53:12 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
|
|
|
cleanup_names(dns_adbnamebucket_t *nbucket, isc_stdtime_t now) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbname_t *name = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
DP(CLEAN_LEVEL, "cleaning name bucket %p", nbucket);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
LOCK(&nbucket->lock);
|
|
|
|
name = ISC_LIST_HEAD(nbucket->names);
|
2008-02-07 23:46:54 +00:00
|
|
|
while (name != NULL) {
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_adbname_t *next_name = ISC_LIST_NEXT(name, plink);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* Name hooks expire after the address record's TTL
|
|
|
|
* or 30 minutes, whichever is shorter. If after cleaning
|
|
|
|
* those up there are no name hooks left, and no active
|
|
|
|
* fetches, we can remove this name from the bucket.
|
|
|
|
*/
|
|
|
|
maybe_expire_namehooks(name, now);
|
|
|
|
maybe_expire_name(&name, now);
|
2008-02-07 23:46:54 +00:00
|
|
|
name = next_name;
|
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&nbucket->lock);
|
1999-10-25 22:53:15 +00:00
|
|
|
}
|
|
|
|
|
2000-01-12 03:00:33 +00:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* A read lock must be held on adb->entries_lock.
|
2000-01-12 03:00:33 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
static void
|
|
|
|
cleanup_entries(dns_adbentrybucket_t *ebucket, isc_stdtime_t now) {
|
|
|
|
dns_adbentry_t *entry = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
DP(CLEAN_LEVEL, "cleaning entry bucket %p", ebucket);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
LOCK(&ebucket->lock);
|
|
|
|
entry = ISC_LIST_HEAD(ebucket->entries);
|
2008-02-07 23:46:54 +00:00
|
|
|
while (entry != NULL) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentry_t *next = ISC_LIST_NEXT(entry, plink);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/* Address entries expire after 30 minutes. */
|
|
|
|
maybe_expire_entry(&entry, now);
|
|
|
|
entry = next;
|
|
|
|
}
|
|
|
|
UNLOCK(&ebucket->lock);
|
2000-01-12 03:00:33 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
static void
|
|
|
|
clean_hashes(dns_adb_t *adb, isc_stdtime_t now) {
|
|
|
|
isc_result_t result;
|
|
|
|
isc_ht_iter_t *it = NULL;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWLOCK(&adb->names_lock, isc_rwlocktype_read);
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_iter_create(adb->namebuckets, &it);
|
|
|
|
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
|
|
|
|
result = isc_ht_iter_next(it))
|
|
|
|
{
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
|
|
|
isc_ht_iter_current(it, (void **)&nbucket);
|
|
|
|
cleanup_names(nbucket, now);
|
2022-03-16 21:58:55 +01:00
|
|
|
}
|
|
|
|
isc_ht_iter_destroy(&it);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_read);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWLOCK(&adb->entries_lock, isc_rwlocktype_read);
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_iter_create(adb->entrybuckets, &it);
|
|
|
|
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
|
|
|
|
result = isc_ht_iter_next(it))
|
|
|
|
{
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
|
|
|
isc_ht_iter_current(it, (void **)&ebucket);
|
|
|
|
cleanup_entries(ebucket, now);
|
2022-03-16 21:58:55 +01:00
|
|
|
}
|
|
|
|
isc_ht_iter_destroy(&it);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_read);
|
2022-03-16 21:58:55 +01:00
|
|
|
}
|
|
|
|
|
1999-09-24 23:54:42 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
destroy(dns_adb_t *adb) {
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_result_t result;
|
|
|
|
isc_ht_iter_t *it = NULL;
|
|
|
|
|
2022-04-05 13:16:00 +01:00
|
|
|
DP(DEF_LEVEL, "destroying ADB %p", adb);
|
2022-03-24 15:58:26 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
adb->magic = 0;
|
2007-10-19 17:15:53 +00:00
|
|
|
|
2022-05-11 13:55:01 -07:00
|
|
|
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_ht_iter_create(adb->namebuckets, &it);
|
|
|
|
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
|
|
|
|
result = isc_ht_iter_delcurrent_next(it))
|
|
|
|
{
|
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
|
|
|
isc_ht_iter_current(it, (void **)&nbucket);
|
|
|
|
cleanup_names(nbucket, INT_MAX);
|
|
|
|
isc_mem_put(adb->mctx, nbucket, sizeof(*nbucket));
|
2022-03-16 21:58:55 +01:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_ht_iter_destroy(&it);
|
|
|
|
isc_ht_destroy(&adb->namebuckets);
|
2022-05-11 13:55:01 -07:00
|
|
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
|
|
|
|
isc_rwlock_destroy(&adb->names_lock);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
2022-05-11 13:55:01 -07:00
|
|
|
RWLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_ht_iter_create(adb->entrybuckets, &it);
|
|
|
|
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
|
|
|
|
result = isc_ht_iter_delcurrent_next(it))
|
|
|
|
{
|
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
|
|
|
isc_ht_iter_current(it, (void **)&ebucket);
|
|
|
|
cleanup_entries(ebucket, INT_MAX);
|
|
|
|
isc_mem_put(adb->mctx, ebucket, sizeof(*ebucket));
|
2022-03-16 21:58:55 +01:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_ht_iter_destroy(&it);
|
|
|
|
isc_ht_destroy(&adb->entrybuckets);
|
2022-05-11 13:55:01 -07:00
|
|
|
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_rwlock_destroy(&adb->entries_lock);
|
2022-05-11 13:55:01 -07:00
|
|
|
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&adb->lock);
|
1999-09-24 23:54:42 +00:00
|
|
|
|
2022-05-11 13:55:01 -07:00
|
|
|
isc_task_detach(&adb->task);
|
2022-05-11 15:38:54 -07:00
|
|
|
isc_stats_detach(&adb->stats);
|
2022-05-12 15:51:10 -07:00
|
|
|
dns_resolver_detach(&adb->res);
|
2022-05-11 13:55:01 -07:00
|
|
|
dns_view_weakdetach(&adb->view);
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
|
1999-09-24 23:54:42 +00:00
|
|
|
}
|
|
|
|
|
1999-09-22 00:26:20 +00:00
|
|
|
/*
|
|
|
|
* Public functions.
|
|
|
|
*/
|
|
|
|
|
1999-09-21 22:46:42 +00:00
|
|
|
isc_result_t
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_taskmgr_t *taskmgr,
|
|
|
|
dns_adb_t **newadb) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adb_t *adb = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_result_t result;
|
|
|
|
|
|
|
|
REQUIRE(mem != NULL);
|
|
|
|
REQUIRE(view != NULL);
|
|
|
|
REQUIRE(taskmgr != NULL);
|
|
|
|
REQUIRE(newadb != NULL && *newadb == NULL);
|
|
|
|
|
|
|
|
adb = isc_mem_get(mem, sizeof(dns_adb_t));
|
2022-03-16 21:58:55 +01:00
|
|
|
*adb = (dns_adb_t){
|
|
|
|
.taskmgr = taskmgr,
|
|
|
|
};
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize things here that cannot fail, and especially things
|
|
|
|
* that must be NULL for the error return to work properly.
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_refcount_init(&adb->references, 1);
|
2022-05-11 13:55:01 -07:00
|
|
|
dns_view_weakattach(view, &adb->view);
|
2022-05-12 15:51:10 -07:00
|
|
|
dns_resolver_attach(view->resolver, &adb->res);
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_mem_attach(mem, &adb->mctx);
|
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_init(&adb->namebuckets, adb->mctx, 1, ISC_HT_CASE_INSENSITIVE);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_rwlock_init(&adb->names_lock, 0, 0);
|
2010-12-21 03:11:42 +00:00
|
|
|
|
2022-04-06 18:52:18 +01:00
|
|
|
isc_ht_init(&adb->entrybuckets, adb->mctx, 1, ISC_HT_CASE_SENSITIVE);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_rwlock_init(&adb->entries_lock, 0, 0);
|
2018-11-19 10:31:09 +00:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_mutex_init(&adb->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
2008-05-01 18:23:07 +00:00
|
|
|
* Allocate an internal task.
|
2008-02-07 23:46:54 +00:00
|
|
|
*/
|
2022-05-19 11:20:21 +02:00
|
|
|
result = isc_task_create(adb->taskmgr, 0, &adb->task, 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
goto free_lock;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-07-19 23:00:21 +10:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_task_setname(adb->task, "ADB", adb);
|
2007-10-19 17:15:53 +00:00
|
|
|
|
2022-05-11 15:38:54 -07:00
|
|
|
result = isc_stats_create(adb->mctx, &adb->stats, dns_adbstats_max);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
goto free_task;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-07-19 23:00:21 +10:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
set_adbstat(adb, isc_ht_count(adb->namebuckets), dns_adbstats_nnames);
|
|
|
|
set_adbstat(adb, isc_ht_count(adb->entrybuckets),
|
|
|
|
dns_adbstats_nentries);
|
2012-05-14 10:06:05 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Normal return.
|
|
|
|
*/
|
|
|
|
adb->magic = DNS_ADB_MAGIC;
|
|
|
|
*newadb = adb;
|
|
|
|
return (ISC_R_SUCCESS);
|
1999-09-23 00:43:10 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
free_task:
|
|
|
|
isc_task_detach(&adb->task);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
free_lock:
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&adb->lock);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
|
|
|
|
isc_rwlock_destroy(&adb->entries_lock);
|
|
|
|
isc_ht_destroy(&adb->entrybuckets);
|
|
|
|
|
|
|
|
isc_rwlock_destroy(&adb->names_lock);
|
|
|
|
isc_ht_destroy(&adb->namebuckets);
|
|
|
|
|
2022-05-12 15:51:10 -07:00
|
|
|
dns_resolver_detach(&adb->res);
|
2022-05-11 13:55:01 -07:00
|
|
|
dns_view_weakdetach(&adb->view);
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
|
1999-09-23 00:43:10 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
return (result);
|
1999-09-21 22:46:42 +00:00
|
|
|
}
|
|
|
|
|
2000-04-18 08:18:52 +00:00
|
|
|
void
|
2022-03-24 15:58:26 -07:00
|
|
|
dns__adb_attach(dns_adb_t *adb, dns_adb_t **adbp, const char *func,
|
|
|
|
const char *file, unsigned int line) {
|
|
|
|
uint_fast32_t refs;
|
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(adbp != NULL && *adbp == NULL);
|
2000-04-18 08:18:52 +00:00
|
|
|
|
2022-03-24 15:58:26 -07:00
|
|
|
refs = isc_refcount_increment(&adb->references);
|
|
|
|
#ifdef ADB_TRACE
|
|
|
|
fprintf(stderr, "%s:%s:%u:%s(%p, %p) = %" PRIuFAST32 "\n", func, file,
|
|
|
|
line, __func__, adb, adbp, refs + 1);
|
|
|
|
#else
|
|
|
|
UNUSED(func);
|
|
|
|
UNUSED(file);
|
|
|
|
UNUSED(line);
|
|
|
|
UNUSED(refs);
|
|
|
|
#endif /* ADB_TRACE */
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
*adbp = adb;
|
2000-04-18 08:18:52 +00:00
|
|
|
}
|
|
|
|
|
1999-09-21 22:46:42 +00:00
|
|
|
void
|
2022-03-24 15:58:26 -07:00
|
|
|
dns__adb_detach(dns_adb_t **adbp, const char *func, const char *file,
|
|
|
|
unsigned int line) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adb_t *adb = NULL;
|
2022-03-24 15:58:26 -07:00
|
|
|
uint_fast32_t refs;
|
1999-09-23 00:43:10 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(adbp != NULL && DNS_ADB_VALID(*adbp));
|
1999-09-23 00:43:10 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
adb = *adbp;
|
|
|
|
*adbp = NULL;
|
1999-09-23 00:43:10 +00:00
|
|
|
|
2022-03-24 15:58:26 -07:00
|
|
|
refs = isc_refcount_decrement(&adb->references);
|
|
|
|
#ifdef ADB_TRACE
|
|
|
|
fprintf(stderr, "%s:%s:%u:%s(%p, %p), %" PRIuFAST32 "\n", func, file,
|
|
|
|
line, __func__, adb, adbp, refs - 1);
|
|
|
|
#else
|
|
|
|
UNUSED(func);
|
|
|
|
UNUSED(file);
|
|
|
|
UNUSED(line);
|
|
|
|
#endif /* ADB_TRACE */
|
|
|
|
|
|
|
|
if (refs == 1) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
destroy(adb);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
1999-11-22 19:57:58 +00:00
|
|
|
}
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
void
|
|
|
|
dns_adb_shutdown(dns_adb_t *adb) {
|
|
|
|
if (!atomic_compare_exchange_strong(&adb->exiting, &(bool){ false },
|
|
|
|
true)) {
|
|
|
|
return;
|
|
|
|
}
|
2014-07-31 11:38:11 +10:00
|
|
|
|
2022-04-05 13:16:00 +01:00
|
|
|
DP(DEF_LEVEL, "shutting down ADB %p", adb);
|
2022-03-24 15:58:26 -07:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_mem_clearwater(adb->mctx);
|
2014-07-31 11:38:11 +10:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
shutdown_names(adb);
|
|
|
|
shutdown_entries(adb);
|
1999-09-21 22:46:42 +00:00
|
|
|
}
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* Look up the name in our internal database.
|
|
|
|
*
|
|
|
|
* There are three possibilities. Note that these are not always exclusive.
|
|
|
|
*
|
|
|
|
* - No name found. In this case, allocate a new name header and
|
|
|
|
* an initial namehook or two.
|
|
|
|
*
|
|
|
|
* - Name found, valid addresses present. Allocate one addrinfo
|
|
|
|
* structure for each found and append it to the linked list
|
|
|
|
* of addresses for this header.
|
|
|
|
*
|
|
|
|
* - Name found, queries pending. In this case, if a task was
|
|
|
|
* passed in, allocate a job id, attach it to the name's job
|
|
|
|
* list and remember to tell the caller that there will be
|
|
|
|
* more info coming later.
|
|
|
|
*/
|
1999-09-21 22:46:42 +00:00
|
|
|
isc_result_t
|
1999-10-29 18:00:31 +00:00
|
|
|
dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
2016-12-30 15:45:08 +11:00
|
|
|
void *arg, const dns_name_t *name, const dns_name_t *qname,
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_rdatatype_t qtype, unsigned int options,
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_stdtime_t now, dns_name_t *target, in_port_t port,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int depth, isc_counter_t *qc,
|
|
|
|
dns_adbfind_t **findp) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_result_t result = ISC_R_UNEXPECTED;
|
2021-10-18 17:57:58 -07:00
|
|
|
dns_adbfind_t *find = NULL;
|
|
|
|
dns_adbname_t *adbname = NULL;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
2021-10-18 17:57:58 -07:00
|
|
|
bool want_event = true;
|
|
|
|
bool start_at_zone = false;
|
|
|
|
bool alias = false;
|
|
|
|
bool have_address = false;
|
|
|
|
unsigned int wanted_addresses = (options & DNS_ADBFIND_ADDRESSMASK);
|
|
|
|
unsigned int wanted_fetches = 0;
|
|
|
|
unsigned int query_pending = 0;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
char namebuf[DNS_NAME_FORMATSIZE] = { 0 };
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
if (task != NULL) {
|
|
|
|
REQUIRE(action != NULL);
|
|
|
|
}
|
|
|
|
REQUIRE(name != NULL);
|
|
|
|
REQUIRE(qname != NULL);
|
|
|
|
REQUIRE(findp != NULL && *findp == NULL);
|
|
|
|
REQUIRE(target == NULL || dns_name_hasbuffer(target));
|
|
|
|
|
|
|
|
REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0);
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (atomic_load(&adb->exiting)) {
|
2021-11-15 12:13:22 +01:00
|
|
|
DP(DEF_LEVEL, "dns_adb_createfind: returning "
|
|
|
|
"ISC_R_SHUTTINGDOWN");
|
|
|
|
|
|
|
|
return (ISC_R_SHUTTINGDOWN);
|
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (now == 0) {
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_stdtime_get(&now);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Remember what types of addresses we are interested in.
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
find = new_adbfind(adb, port);
|
2008-02-07 23:46:54 +00:00
|
|
|
find->options = options;
|
|
|
|
find->flags |= wanted_addresses;
|
|
|
|
if (FIND_WANTEVENT(find)) {
|
|
|
|
REQUIRE(task != NULL);
|
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (isc_log_wouldlog(dns_lctx, DEF_LEVEL)) {
|
2013-06-12 11:31:30 +10:00
|
|
|
dns_name_format(name, namebuf, sizeof(namebuf));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-06-12 11:31:30 +10:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Try to see if we know anything about this name at all.
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
get_namebucket(adb, name, &nbucket);
|
|
|
|
INSIST(nbucket != NULL);
|
|
|
|
LOCK(&nbucket->lock);
|
|
|
|
adbname = get_name(nbucket, name, find->options);
|
2008-02-07 23:46:54 +00:00
|
|
|
if (adbname == NULL) {
|
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Nothing found. Allocate a new adbname structure for
|
|
|
|
* this name. First, see if there are stale names at the
|
|
|
|
* end of the list, and purge them if so.
|
2008-02-07 23:46:54 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
purge_stale_names(adb, nbucket, now);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
adbname = new_adbname(adb, name);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
link_name(nbucket, adbname);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (FIND_HINTOK(find)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->flags |= NAME_HINT_OK;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (FIND_GLUEOK(find)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->flags |= NAME_GLUE_OK;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (FIND_STARTATZONE(find)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->flags |= NAME_STARTATZONE;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
} else {
|
|
|
|
/* Move this name forward in the LRU list */
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ISC_LIST_UNLINK(nbucket->names, adbname, plink);
|
|
|
|
ISC_LIST_PREPEND(nbucket->names, adbname, plink);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->last_used = now;
|
|
|
|
|
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Name hooks expire after the address record's TTL or 30 minutes,
|
|
|
|
* whichever is shorter. If there are expired name hooks, remove
|
|
|
|
* them so we'll send a new fetch.
|
2008-02-07 23:46:54 +00:00
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
maybe_expire_namehooks(adbname, now);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Do we know that the name is an alias?
|
|
|
|
*/
|
|
|
|
if (!EXPIRE_OK(adbname->expire_target, now)) {
|
|
|
|
/*
|
|
|
|
* Yes, it is.
|
|
|
|
*/
|
|
|
|
DP(DEF_LEVEL,
|
2013-06-12 11:31:30 +10:00
|
|
|
"dns_adb_createfind: name %s (%p) is an alias (cached)",
|
|
|
|
namebuf, adbname);
|
2018-04-17 08:29:14 -07:00
|
|
|
alias = true;
|
2008-02-07 23:46:54 +00:00
|
|
|
goto post_copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Try to populate the name from the database and/or
|
|
|
|
* start fetches. First try looking for an A record
|
|
|
|
* in the database.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
if (!NAME_HAS_V4(adbname) && EXPIRE_OK(adbname->expire_v4, now) &&
|
2020-02-13 14:44:37 -08:00
|
|
|
WANT_INET(wanted_addresses))
|
|
|
|
{
|
2008-02-07 23:46:54 +00:00
|
|
|
result = dbfind_name(adbname, now, dns_rdatatype_a);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
switch (result) {
|
|
|
|
case ISC_R_SUCCESS:
|
|
|
|
/* Found an A; now we proceed to check for AAAA */
|
2008-02-07 23:46:54 +00:00
|
|
|
DP(DEF_LEVEL,
|
2013-06-12 11:31:30 +10:00
|
|
|
"dns_adb_createfind: found A for name %s (%p) in db",
|
|
|
|
namebuf, adbname);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
break;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
case DNS_R_ALIAS:
|
|
|
|
/* Got a CNAME or DNAME. */
|
2008-02-07 23:46:54 +00:00
|
|
|
DP(DEF_LEVEL,
|
2013-06-12 11:31:30 +10:00
|
|
|
"dns_adb_createfind: name %s (%p) is an alias",
|
|
|
|
namebuf, adbname);
|
2018-04-17 08:29:14 -07:00
|
|
|
alias = true;
|
2008-02-07 23:46:54 +00:00
|
|
|
goto post_copy;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
case DNS_R_NXDOMAIN:
|
|
|
|
case DNS_R_NCACHENXDOMAIN:
|
|
|
|
/*
|
|
|
|
* If the name doesn't exist at all, don't bother with
|
|
|
|
* v6 queries; they won't work.
|
|
|
|
*/
|
2008-02-07 23:46:54 +00:00
|
|
|
goto fetch;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
case DNS_R_NXRRSET:
|
|
|
|
case DNS_R_NCACHENXRRSET:
|
|
|
|
case DNS_R_HINTNXRRSET:
|
|
|
|
/*
|
|
|
|
* The name does exist but we didn't get our data, go
|
|
|
|
* ahead and try AAAA.
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/*
|
|
|
|
* Any other result, start a fetch for A, then fall
|
|
|
|
* through to AAAA.
|
|
|
|
*/
|
|
|
|
if (!NAME_FETCH_A(adbname)) {
|
|
|
|
wanted_fetches |= DNS_ADBFIND_INET;
|
|
|
|
}
|
|
|
|
break;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
1999-10-26 01:12:20 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* Now look up or start fetches for AAAA.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
if (!NAME_HAS_V6(adbname) && EXPIRE_OK(adbname->expire_v6, now) &&
|
2020-02-13 14:44:37 -08:00
|
|
|
WANT_INET6(wanted_addresses))
|
|
|
|
{
|
2008-02-07 23:46:54 +00:00
|
|
|
result = dbfind_name(adbname, now, dns_rdatatype_aaaa);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
switch (result) {
|
|
|
|
case ISC_R_SUCCESS:
|
2008-02-07 23:46:54 +00:00
|
|
|
DP(DEF_LEVEL,
|
2013-06-12 11:31:30 +10:00
|
|
|
"dns_adb_createfind: found AAAA for name %s (%p)",
|
|
|
|
namebuf, adbname);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
break;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
case DNS_R_ALIAS:
|
|
|
|
/* Got a CNAME or DNAME. */
|
2008-02-07 23:46:54 +00:00
|
|
|
DP(DEF_LEVEL,
|
2013-06-12 11:31:30 +10:00
|
|
|
"dns_adb_createfind: name %s (%p) is an alias",
|
|
|
|
namebuf, adbname);
|
2018-04-17 08:29:14 -07:00
|
|
|
alias = true;
|
2008-02-07 23:46:54 +00:00
|
|
|
goto post_copy;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
case DNS_R_NXDOMAIN:
|
|
|
|
case DNS_R_NCACHENXDOMAIN:
|
|
|
|
case DNS_R_NXRRSET:
|
|
|
|
case DNS_R_NCACHENXRRSET:
|
|
|
|
/*
|
|
|
|
* Name doens't exist or was found in the negative
|
|
|
|
* cache to have no AAAA, don't bother fetching.
|
|
|
|
*/
|
|
|
|
break;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
default:
|
|
|
|
/*
|
|
|
|
* Any other result, start a fetch for AAAA.
|
|
|
|
*/
|
|
|
|
if (!NAME_FETCH_AAAA(adbname)) {
|
|
|
|
wanted_fetches |= DNS_ADBFIND_INET6;
|
|
|
|
}
|
|
|
|
break;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
1999-11-24 19:23:27 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
fetch:
|
2008-02-07 23:46:54 +00:00
|
|
|
if ((WANT_INET(wanted_addresses) && NAME_HAS_V4(adbname)) ||
|
2020-02-13 14:44:37 -08:00
|
|
|
(WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname)))
|
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
have_address = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2018-04-17 08:29:14 -07:00
|
|
|
have_address = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-06 17:19:10 +11:00
|
|
|
if (wanted_fetches != 0 && !(FIND_AVOIDFETCHES(find) && have_address) &&
|
|
|
|
!FIND_NOFETCH(find))
|
|
|
|
{
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* We're missing at least one address family. Either the
|
|
|
|
* caller hasn't instructed us to avoid fetches, or we don't
|
|
|
|
* know anything about any of the address families that would
|
|
|
|
* be acceptable so we have to launch fetches.
|
|
|
|
*/
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (FIND_STARTATZONE(find)) {
|
2018-04-17 08:29:14 -07:00
|
|
|
start_at_zone = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Start V4.
|
|
|
|
*/
|
|
|
|
if (WANT_INET(wanted_fetches) &&
|
2014-11-19 18:21:02 -08:00
|
|
|
fetch_name(adbname, start_at_zone, depth, qc,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdatatype_a) == ISC_R_SUCCESS)
|
|
|
|
{
|
2020-02-12 13:59:18 +01:00
|
|
|
DP(DEF_LEVEL,
|
|
|
|
"dns_adb_createfind: "
|
2013-06-12 11:31:30 +10:00
|
|
|
"started A fetch for name %s (%p)",
|
|
|
|
namebuf, adbname);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Start V6.
|
|
|
|
*/
|
|
|
|
if (WANT_INET6(wanted_fetches) &&
|
2014-11-19 18:21:02 -08:00
|
|
|
fetch_name(adbname, start_at_zone, depth, qc,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdatatype_aaaa) == ISC_R_SUCCESS)
|
|
|
|
{
|
2020-02-12 13:59:18 +01:00
|
|
|
DP(DEF_LEVEL,
|
|
|
|
"dns_adb_createfind: "
|
2013-06-12 11:31:30 +10:00
|
|
|
"started AAAA fetch for name %s (%p)",
|
|
|
|
namebuf, adbname);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Run through the name and copy out the bits we are
|
|
|
|
* interested in.
|
|
|
|
*/
|
|
|
|
copy_namehook_lists(adb, find, qname, qtype, adbname, now);
|
1999-10-21 01:37:57 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
post_copy:
|
2021-10-18 17:57:58 -07:00
|
|
|
if (NAME_FETCH_A(adbname)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
query_pending |= DNS_ADBFIND_INET;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2021-10-18 17:57:58 -07:00
|
|
|
if (NAME_FETCH_AAAA(adbname)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
query_pending |= DNS_ADBFIND_INET6;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-26 02:21:45 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Attach to the name's query list if there are queries
|
|
|
|
* already running, and we have been asked to.
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (!FIND_WANTEVENT(find)) {
|
2018-04-17 08:29:14 -07:00
|
|
|
want_event = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (FIND_WANTEMPTYEVENT(find) && FIND_HAS_ADDRS(find)) {
|
2018-04-17 08:29:14 -07:00
|
|
|
want_event = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if ((wanted_addresses & query_pending) == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
want_event = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (alias) {
|
2018-04-17 08:29:14 -07:00
|
|
|
want_event = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
if (want_event) {
|
2021-10-18 17:57:58 -07:00
|
|
|
bool empty;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
find->adbname = adbname;
|
2021-10-18 17:57:58 -07:00
|
|
|
empty = ISC_LIST_EMPTY(adbname->finds);
|
2008-02-07 23:46:54 +00:00
|
|
|
ISC_LIST_APPEND(adbname->finds, find, plink);
|
|
|
|
find->query_pending = (query_pending & wanted_addresses);
|
|
|
|
find->flags &= ~DNS_ADBFIND_ADDRESSMASK;
|
|
|
|
find->flags |= (find->query_pending & DNS_ADBFIND_ADDRESSMASK);
|
2021-10-18 17:57:58 -07:00
|
|
|
DP(DEF_LEVEL, "createfind: attaching find %p to adbname %p %d",
|
2018-09-28 16:51:55 +10:00
|
|
|
find, adbname, empty);
|
2008-02-07 23:46:54 +00:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Remove the flag so the caller knows there will never
|
|
|
|
* be an event, and set internal flags to fake that
|
|
|
|
* the event was sent and freed, so dns_adb_destroyfind() will
|
|
|
|
* do the right thing.
|
|
|
|
*/
|
|
|
|
find->query_pending = (query_pending & wanted_addresses);
|
|
|
|
find->options &= ~DNS_ADBFIND_WANTEVENT;
|
|
|
|
find->flags |= (FIND_EVENT_SENT | FIND_EVENT_FREED);
|
|
|
|
find->flags &= ~DNS_ADBFIND_ADDRESSMASK;
|
|
|
|
}
|
1999-10-08 23:12:21 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
find->partial_result |= (adbname->partial_result & wanted_addresses);
|
|
|
|
if (alias) {
|
|
|
|
if (target != NULL) {
|
2021-05-21 17:20:44 -07:00
|
|
|
dns_name_copy(&adbname->target, target);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
result = DNS_R_ALIAS;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
result = ISC_R_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-10-16 00:38:21 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Copy out error flags from the name structure into the find.
|
|
|
|
*/
|
|
|
|
find->result_v4 = find_err_map[adbname->fetch_err];
|
|
|
|
find->result_v6 = find_err_map[adbname->fetch6_err];
|
1999-10-16 00:38:21 +00:00
|
|
|
|
2022-04-06 12:54:08 +10:00
|
|
|
if (want_event) {
|
|
|
|
INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0);
|
|
|
|
isc_task_attach(task, &(isc_task_t *){ NULL });
|
|
|
|
find->event.ev_sender = task;
|
|
|
|
find->event.ev_action = action;
|
|
|
|
find->event.ev_arg = arg;
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
2022-04-06 12:54:08 +10:00
|
|
|
*findp = find;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&nbucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
return (result);
|
1999-09-25 01:56:10 +00:00
|
|
|
}
|
|
|
|
|
1999-09-21 22:46:42 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_destroyfind(dns_adbfind_t **findp) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbfind_t *find = NULL;
|
|
|
|
dns_adbaddrinfo_t *ai = NULL;
|
|
|
|
dns_adb_t *adb = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp));
|
2022-03-24 16:06:48 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
find = *findp;
|
|
|
|
*findp = NULL;
|
|
|
|
|
|
|
|
DP(DEF_LEVEL, "dns_adb_destroyfind on find %p", find);
|
|
|
|
|
|
|
|
adb = find->adb;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
LOCK(&find->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(FIND_EVENTFREED(find));
|
|
|
|
REQUIRE(find->adbname == NULL);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* Free the addrinfo objects on the find's list. Note that
|
|
|
|
* we also need to decrement the reference counter in the
|
|
|
|
* associated adbentry every time we remove one from the list.
|
2008-02-07 23:46:54 +00:00
|
|
|
*/
|
|
|
|
ai = ISC_LIST_HEAD(find->list);
|
|
|
|
while (ai != NULL) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
entry_detach(&(dns_adbentry_t *){ ai->entry });
|
2008-02-07 23:46:54 +00:00
|
|
|
ISC_LIST_UNLINK(find->list, ai, publink);
|
|
|
|
free_adbaddrinfo(adb, &ai);
|
|
|
|
ai = ISC_LIST_HEAD(find->list);
|
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&find->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
free_adbfind(&find);
|
1999-09-21 22:46:42 +00:00
|
|
|
}
|
1999-10-02 01:59:09 +00:00
|
|
|
|
2022-04-19 19:14:49 -07:00
|
|
|
/*
|
|
|
|
* Caller must hold find lock.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
find_sendevent(dns_adbfind_t *find) {
|
|
|
|
if (!FIND_EVENTSENT(find)) {
|
|
|
|
isc_event_t *ev = &find->event;
|
|
|
|
isc_task_t *task = ev->ev_sender;
|
|
|
|
|
|
|
|
ev->ev_sender = find;
|
|
|
|
ev->ev_type = DNS_EVENT_ADBCANCELED;
|
|
|
|
ev->ev_destroy = event_freefind;
|
|
|
|
ev->ev_destroy_arg = find;
|
|
|
|
find->result_v4 = ISC_R_CANCELED;
|
|
|
|
find->result_v6 = ISC_R_CANCELED;
|
|
|
|
|
|
|
|
DP(DEF_LEVEL, "sending event %p to task %p for find %p", ev,
|
|
|
|
task, find);
|
|
|
|
|
|
|
|
isc_task_sendanddetach(&task, (isc_event_t **)&ev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-29 18:00:31 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_cancelfind(dns_adbfind_t *find) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbname_t *adbname = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find);
|
|
|
|
|
2022-04-19 19:14:49 -07:00
|
|
|
REQUIRE(DNS_ADBFIND_VALID(find));
|
|
|
|
REQUIRE(DNS_ADB_VALID(find->adb));
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2022-04-19 19:14:49 -07:00
|
|
|
LOCK(&find->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
REQUIRE(!FIND_EVENTFREED(find));
|
|
|
|
REQUIRE(FIND_WANTEVENT(find));
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
adbname = find->adbname;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2022-04-19 19:14:49 -07:00
|
|
|
if (adbname == NULL) {
|
|
|
|
find_sendevent(find);
|
|
|
|
UNLOCK(&find->lock);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Release the find lock, then acquire the bucket and find
|
|
|
|
* locks in that order, to match locking hierarchy
|
|
|
|
* elsewhere.
|
|
|
|
*/
|
|
|
|
UNLOCK(&find->lock);
|
|
|
|
LOCK(&adbname->bucket->lock);
|
|
|
|
LOCK(&find->lock);
|
1999-10-29 18:00:31 +00:00
|
|
|
|
2022-04-19 19:14:49 -07:00
|
|
|
if (find->adbname != NULL) {
|
|
|
|
ISC_LIST_UNLINK(adbname->finds, find, plink);
|
|
|
|
find->adbname = NULL;
|
|
|
|
}
|
|
|
|
find_sendevent(find);
|
1999-10-29 18:00:31 +00:00
|
|
|
|
2022-04-19 19:14:49 -07:00
|
|
|
UNLOCK(&find->lock);
|
|
|
|
UNLOCK(&adbname->bucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
1999-10-29 18:00:31 +00:00
|
|
|
}
|
|
|
|
|
1999-10-02 01:59:09 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_dump(dns_adb_t *adb, FILE *f) {
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_stdtime_t now;
|
2004-11-10 22:33:18 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(f != NULL);
|
1999-10-02 01:59:09 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (atomic_load(&adb->exiting)) {
|
|
|
|
return;
|
|
|
|
}
|
1999-10-02 01:59:09 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_stdtime_get(&now);
|
2022-03-16 21:58:55 +01:00
|
|
|
clean_hashes(adb, now);
|
2018-04-17 08:29:14 -07:00
|
|
|
dump_adb(adb, f, false, now);
|
1999-10-27 19:36:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
dump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (value == INT_MAX) {
|
2008-02-07 23:46:54 +00:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2018-02-14 19:13:56 +11:00
|
|
|
fprintf(f, " [%s TTL %d]", legend, (int)(value - now));
|
2000-12-18 20:03:33 +00:00
|
|
|
}
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* Both rwlocks for the hash tables need to be held by the caller.
|
|
|
|
*/
|
2000-12-18 20:03:33 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_result_t result;
|
|
|
|
isc_ht_iter_t *it = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
fprintf(f, ";\n; Address database dump\n;\n");
|
2020-09-23 14:47:26 +02:00
|
|
|
fprintf(f, "; [edns success/timeout]\n");
|
2013-11-13 12:10:43 +11:00
|
|
|
fprintf(f, "; [plain success/timeout]\n;\n");
|
2019-11-19 13:49:28 +08:00
|
|
|
if (debug) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
fprintf(f, "; addr %p, references %" PRIuFAST32 "\n", adb,
|
|
|
|
isc_refcount_current(&adb->references));
|
2019-11-19 13:49:28 +08:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/*
|
|
|
|
* Ensure this operation is applied to both hash tables at once.
|
|
|
|
*/
|
|
|
|
RWLOCK(&adb->names_lock, isc_rwlocktype_read);
|
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_iter_create(adb->namebuckets, &it);
|
|
|
|
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
|
|
|
|
result = isc_ht_iter_next(it))
|
|
|
|
{
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_adbname_t *name = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_ht_iter_current(it, (void **)&nbucket);
|
|
|
|
LOCK(&nbucket->lock);
|
2019-01-22 10:47:18 +01:00
|
|
|
if (debug) {
|
2022-03-16 21:58:55 +01:00
|
|
|
static int n = 0;
|
|
|
|
fprintf(f, "; bucket %d\n", n);
|
|
|
|
n++;
|
2019-01-22 10:47:18 +01:00
|
|
|
}
|
2022-03-16 21:58:55 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Dump the names
|
|
|
|
*/
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
for (name = ISC_LIST_HEAD(nbucket->names); name != NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
name = ISC_LIST_NEXT(name, plink))
|
|
|
|
{
|
2019-01-22 10:47:18 +01:00
|
|
|
if (debug) {
|
2020-02-12 13:59:18 +01:00
|
|
|
fprintf(f, "; name %p (flags %08x)\n", name,
|
|
|
|
name->flags);
|
2019-01-22 10:47:18 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
fprintf(f, "; ");
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_name_print(&name->name, f);
|
2008-02-07 23:46:54 +00:00
|
|
|
if (dns_name_countlabels(&name->target) > 0) {
|
|
|
|
fprintf(f, " alias ");
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_name_print(&name->target, f);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
dump_ttl(f, "v4", name->expire_v4, now);
|
|
|
|
dump_ttl(f, "v6", name->expire_v6, now);
|
|
|
|
dump_ttl(f, "target", name->expire_target, now);
|
|
|
|
|
|
|
|
fprintf(f, " [v4 %s] [v6 %s]",
|
|
|
|
errnames[name->fetch_err],
|
|
|
|
errnames[name->fetch6_err]);
|
|
|
|
|
|
|
|
fprintf(f, "\n");
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
print_namehook_list(f, "v4", adb, &name->v4, debug,
|
|
|
|
now);
|
|
|
|
print_namehook_list(f, "v6", adb, &name->v6, debug,
|
|
|
|
now);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2017-09-13 09:50:51 +10:00
|
|
|
if (debug) {
|
2008-02-07 23:46:54 +00:00
|
|
|
print_fetch_list(f, name);
|
|
|
|
print_find_list(f, name);
|
2017-09-13 09:50:51 +10:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&nbucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_iter_destroy(&it);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_read);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
fprintf(f, ";\n; Unassociated entries\n;\n");
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWLOCK(&adb->entries_lock, isc_rwlocktype_read);
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_iter_create(adb->entrybuckets, &it);
|
|
|
|
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
|
|
|
|
result = isc_ht_iter_next(it))
|
|
|
|
{
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_adbentry_t *entry = NULL;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_ht_iter_current(it, (void **)&ebucket);
|
|
|
|
LOCK(&ebucket->lock);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
for (entry = ISC_LIST_HEAD(ebucket->entries); entry != NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
entry = ISC_LIST_NEXT(entry, plink))
|
|
|
|
{
|
2020-02-13 21:48:23 +01:00
|
|
|
if (entry->nh == 0) {
|
2015-07-08 22:53:39 -07:00
|
|
|
dump_entry(f, adb, entry, debug, now);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2019-01-22 10:47:18 +01:00
|
|
|
}
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_iter_destroy(&it);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
|
|
|
|
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_read);
|
1999-10-02 01:59:09 +00:00
|
|
|
}
|
|
|
|
|
2000-12-18 20:03:33 +00:00
|
|
|
static void
|
2020-02-12 13:59:18 +01:00
|
|
|
dump_entry(FILE *f, dns_adb_t *adb, dns_adbentry_t *entry, bool debug,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_stdtime_t now) {
|
|
|
|
char addrbuf[ISC_NETADDR_FORMATSIZE];
|
|
|
|
char typebuf[DNS_RDATATYPE_FORMATSIZE];
|
|
|
|
isc_netaddr_t netaddr;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adblameinfo_t *li = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
|
|
|
|
isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (debug) {
|
2022-03-16 21:58:55 +01:00
|
|
|
fprintf(f, ";\t%p: refcnt %" PRIuFAST32 "\n", entry,
|
|
|
|
isc_refcount_current(&entry->references));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
fprintf(f,
|
2020-09-23 14:47:26 +02:00
|
|
|
";\t%s [srtt %u] [flags %08x] [edns %u/%u] "
|
2020-02-12 13:59:18 +01:00
|
|
|
"[plain %u/%u]",
|
2020-09-23 14:47:26 +02:00
|
|
|
addrbuf, entry->srtt, entry->flags, entry->edns, entry->ednsto,
|
|
|
|
entry->plain, entry->plainto);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (entry->udpsize != 0U) {
|
2013-06-12 11:31:30 +10:00
|
|
|
fprintf(f, " [udpsize %u]", entry->udpsize);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-07-06 09:44:24 +10:00
|
|
|
if (entry->cookie != NULL) {
|
2014-02-19 12:53:42 +11:00
|
|
|
unsigned int i;
|
2015-07-06 09:44:24 +10:00
|
|
|
fprintf(f, " [cookie=");
|
2020-02-13 21:48:23 +01:00
|
|
|
for (i = 0; i < entry->cookielen; i++) {
|
2015-07-06 09:44:24 +10:00
|
|
|
fprintf(f, "%02x", entry->cookie[i]);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-02-19 12:53:42 +11:00
|
|
|
fprintf(f, "]");
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (entry->expires != 0) {
|
2018-02-14 19:20:38 +11:00
|
|
|
fprintf(f, " [ttl %d]", (int)(entry->expires - now));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-07-08 22:53:39 -07:00
|
|
|
|
|
|
|
if (adb != NULL && adb->quota != 0 && adb->atr_freq != 0) {
|
2020-04-15 12:36:12 +02:00
|
|
|
uint_fast32_t quota = atomic_load_relaxed(&entry->quota);
|
2020-02-12 13:59:18 +01:00
|
|
|
fprintf(f, " [atr %0.2f] [quota %" PRIuFAST32 "]", entry->atr,
|
2020-04-15 12:36:12 +02:00
|
|
|
quota);
|
2015-07-08 22:53:39 -07:00
|
|
|
}
|
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
fprintf(f, "\n");
|
2020-02-12 13:59:18 +01:00
|
|
|
for (li = ISC_LIST_HEAD(entry->lameinfo); li != NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
li = ISC_LIST_NEXT(li, plink))
|
|
|
|
{
|
2008-02-07 23:46:54 +00:00
|
|
|
fprintf(f, ";\t\t");
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_name_print(&li->qname, f);
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_rdatatype_format(li->qtype, typebuf, sizeof(typebuf));
|
|
|
|
fprintf(f, " %s [lame TTL %d]\n", typebuf,
|
2018-02-14 19:20:38 +11:00
|
|
|
(int)(li->lame_timer - now));
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
2000-12-18 20:03:33 +00:00
|
|
|
}
|
|
|
|
|
1999-10-16 00:38:21 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_dumpfind(dns_adbfind_t *find, FILE *f) {
|
|
|
|
char tmp[512];
|
2022-03-24 16:06:48 -07:00
|
|
|
const char *tmpp = NULL;
|
|
|
|
dns_adbaddrinfo_t *ai = NULL;
|
|
|
|
isc_sockaddr_t *sa = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Not used currently, in the API Just In Case we
|
|
|
|
* want to dump out the name and/or entries too.
|
|
|
|
*/
|
|
|
|
|
|
|
|
LOCK(&find->lock);
|
|
|
|
|
|
|
|
fprintf(f, ";Find %p\n", find);
|
|
|
|
fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n",
|
2020-02-12 13:59:18 +01:00
|
|
|
find->query_pending, find->partial_result, find->options,
|
|
|
|
find->flags);
|
2022-03-16 21:58:55 +01:00
|
|
|
fprintf(f, ";\tname bucket %p, name %p, event sender %p\n",
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
find->adbname->bucket, find->adbname, find->event.ev_sender);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
ai = ISC_LIST_HEAD(find->list);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ai != NULL) {
|
2008-02-07 23:46:54 +00:00
|
|
|
fprintf(f, "\tAddresses:\n");
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
while (ai != NULL) {
|
|
|
|
sa = &ai->sockaddr;
|
|
|
|
switch (sa->type.sa.sa_family) {
|
|
|
|
case AF_INET:
|
2020-02-12 13:59:18 +01:00
|
|
|
tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr, tmp,
|
|
|
|
sizeof(tmp));
|
2008-02-07 23:46:54 +00:00
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
tmpp = inet_ntop(AF_INET6, &sa->type.sin6.sin6_addr,
|
|
|
|
tmp, sizeof(tmp));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
tmpp = "UnkFamily";
|
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tmpp == NULL) {
|
2008-02-07 23:46:54 +00:00
|
|
|
tmpp = "BadAddress";
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
fprintf(f,
|
|
|
|
"\t\tentry %p, flags %08x"
|
2008-02-07 23:46:54 +00:00
|
|
|
" srtt %u addr %s\n",
|
|
|
|
ai->entry, ai->flags, ai->srtt, tmpp);
|
|
|
|
|
|
|
|
ai = ISC_LIST_NEXT(ai, publink);
|
|
|
|
}
|
|
|
|
|
|
|
|
UNLOCK(&find->lock);
|
1999-10-16 00:38:21 +00:00
|
|
|
}
|
|
|
|
|
1999-10-02 01:59:09 +00:00
|
|
|
static void
|
2020-02-12 13:59:18 +01:00
|
|
|
print_namehook_list(FILE *f, const char *legend, dns_adb_t *adb,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adbnamehooklist_t *list, bool debug,
|
|
|
|
isc_stdtime_t now) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbnamehook_t *nh = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
for (nh = ISC_LIST_HEAD(*list); nh != NULL;
|
|
|
|
nh = ISC_LIST_NEXT(nh, plink)) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (debug) {
|
2008-02-07 23:46:54 +00:00
|
|
|
fprintf(f, ";\tHook(%s) %p\n", legend, nh);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-07-08 22:53:39 -07:00
|
|
|
dump_entry(f, adb, nh->entry, debug, now);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
1999-10-02 01:59:09 +00:00
|
|
|
}
|
1999-10-16 00:38:21 +00:00
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
print_fetch(FILE *f, dns_adbfetch_t *ft, const char *type) {
|
2020-02-12 13:59:18 +01:00
|
|
|
fprintf(f, "\t\tFetch(%s): %p -> { fetch %p }\n", type, ft, ft->fetch);
|
1999-11-02 18:36:54 +00:00
|
|
|
}
|
|
|
|
|
1999-10-29 21:48:51 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
print_fetch_list(FILE *f, dns_adbname_t *n) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (NAME_FETCH_A(n)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
print_fetch(f, n->fetch_a, "A");
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (NAME_FETCH_AAAA(n)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
print_fetch(f, n->fetch_aaaa, "AAAA");
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-10-27 19:36:58 +00:00
|
|
|
}
|
|
|
|
|
1999-10-16 00:38:21 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
print_find_list(FILE *f, dns_adbname_t *name) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbfind_t *find = NULL;
|
1999-10-16 00:38:21 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
find = ISC_LIST_HEAD(name->finds);
|
|
|
|
while (find != NULL) {
|
|
|
|
dns_adb_dumpfind(find, f);
|
|
|
|
find = ISC_LIST_NEXT(find, plink);
|
|
|
|
}
|
1999-10-16 00:38:21 +00:00
|
|
|
}
|
1999-10-19 20:55:04 +00:00
|
|
|
|
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) {
|
|
|
|
isc_result_t result;
|
|
|
|
dns_rdataset_t rdataset;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adb_t *adb = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_fixedname_t foundname;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_name_t *fname = NULL;
|
|
|
|
|
|
|
|
REQUIRE(DNS_ADBNAME_VALID(adbname));
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
adb = adbname->adb;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2018-03-28 14:38:09 +02:00
|
|
|
fname = dns_fixedname_initname(&foundname);
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_rdataset_init(&rdataset);
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (rdtype == dns_rdatatype_a) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch_err = FIND_ERR_UNEXPECTED;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch6_err = FIND_ERR_UNEXPECTED;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2010-12-16 09:51:30 +00:00
|
|
|
/*
|
|
|
|
* We need to specify whether to search static-stub zones (if
|
|
|
|
* configured) depending on whether this is a "start at zone" lookup,
|
|
|
|
* i.e., whether it's a "bailiwick" glue. If it's bailiwick (in which
|
|
|
|
* case NAME_STARTATZONE is set) we need to stop the search at any
|
|
|
|
* matching static-stub zone without looking into the cache to honor
|
|
|
|
* the configuration on which server we should send queries to.
|
|
|
|
*/
|
2018-04-04 09:51:42 +02:00
|
|
|
result = dns_view_find(adb->view, &adbname->name, rdtype, now,
|
|
|
|
NAME_GLUEOK(adbname) ? DNS_DBFIND_GLUEOK : 0,
|
2018-04-17 08:29:14 -07:00
|
|
|
NAME_HINTOK(adbname),
|
2020-02-12 13:59:18 +01:00
|
|
|
((adbname->flags & NAME_STARTATZONE) != 0), NULL,
|
|
|
|
NULL, fname, &rdataset, NULL);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/* XXXVIX this switch statement is too sparse to gen a jump table. */
|
|
|
|
switch (result) {
|
|
|
|
case DNS_R_GLUE:
|
|
|
|
case DNS_R_HINT:
|
|
|
|
case ISC_R_SUCCESS:
|
|
|
|
/*
|
|
|
|
* Found in the database. Even if we can't copy out
|
|
|
|
* any information, return success, or else a fetch
|
|
|
|
* will be made, which will only make things worse.
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (rdtype == dns_rdatatype_a) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch_err = FIND_ERR_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch6_err = FIND_ERR_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
result = import_rdataset(adbname, &rdataset, now);
|
|
|
|
break;
|
|
|
|
case DNS_R_NXDOMAIN:
|
|
|
|
case DNS_R_NXRRSET:
|
|
|
|
/*
|
|
|
|
* We're authoritative and the data doesn't exist.
|
|
|
|
* Make up a negative cache entry so we don't ask again
|
|
|
|
* for a while.
|
|
|
|
*
|
|
|
|
* XXXRTH What time should we use? I'm putting in 30 seconds
|
|
|
|
* for now.
|
|
|
|
*/
|
|
|
|
if (rdtype == dns_rdatatype_a) {
|
|
|
|
adbname->expire_v4 = now + 30;
|
|
|
|
DP(NCACHE_LEVEL,
|
|
|
|
"adb name %p: Caching auth negative entry for A",
|
|
|
|
adbname);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == DNS_R_NXDOMAIN) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch_err = FIND_ERR_NXDOMAIN;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch_err = FIND_ERR_NXRRSET;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
} else {
|
|
|
|
DP(NCACHE_LEVEL,
|
|
|
|
"adb name %p: Caching auth negative entry for AAAA",
|
|
|
|
adbname);
|
|
|
|
adbname->expire_v6 = now + 30;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == DNS_R_NXDOMAIN) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch6_err = FIND_ERR_NXDOMAIN;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch6_err = FIND_ERR_NXRRSET;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DNS_R_NCACHENXDOMAIN:
|
|
|
|
case DNS_R_NCACHENXRRSET:
|
|
|
|
/*
|
|
|
|
* We found a negative cache entry. Pull the TTL from it
|
|
|
|
* so we won't ask again for a while.
|
|
|
|
*/
|
|
|
|
rdataset.ttl = ttlclamp(rdataset.ttl);
|
|
|
|
if (rdtype == dns_rdatatype_a) {
|
|
|
|
adbname->expire_v4 = rdataset.ttl + now;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == DNS_R_NCACHENXDOMAIN) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch_err = FIND_ERR_NXDOMAIN;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch_err = FIND_ERR_NXRRSET;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
DP(NCACHE_LEVEL,
|
2020-02-12 13:59:18 +01:00
|
|
|
"adb name %p: Caching negative entry for A (ttl %u)",
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname, rdataset.ttl);
|
|
|
|
} else {
|
|
|
|
DP(NCACHE_LEVEL,
|
2020-02-12 13:59:18 +01:00
|
|
|
"adb name %p: Caching negative entry for AAAA (ttl "
|
|
|
|
"%u)",
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname, rdataset.ttl);
|
|
|
|
adbname->expire_v6 = rdataset.ttl + now;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == DNS_R_NCACHENXDOMAIN) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch6_err = FIND_ERR_NXDOMAIN;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch6_err = FIND_ERR_NXRRSET;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DNS_R_CNAME:
|
|
|
|
case DNS_R_DNAME:
|
|
|
|
/*
|
|
|
|
* Clear the hint and glue flags, so this will match
|
|
|
|
* more often.
|
|
|
|
*/
|
|
|
|
adbname->flags &= ~(DNS_ADBFIND_GLUEOK | DNS_ADBFIND_HINTOK);
|
|
|
|
|
|
|
|
rdataset.ttl = ttlclamp(rdataset.ttl);
|
|
|
|
clean_target(adb, &adbname->target);
|
|
|
|
adbname->expire_target = INT_MAX;
|
|
|
|
result = set_target(adb, &adbname->name, fname, &rdataset,
|
|
|
|
&adbname->target);
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
result = DNS_R_ALIAS;
|
2020-02-12 13:59:18 +01:00
|
|
|
DP(NCACHE_LEVEL, "adb name %p: caching alias target",
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname);
|
|
|
|
adbname->expire_target = rdataset.ttl + now;
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (rdtype == dns_rdatatype_a) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch_err = FIND_ERR_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch6_err = FIND_ERR_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
break;
|
2021-10-04 17:14:53 +02:00
|
|
|
default:
|
|
|
|
break;
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dns_rdataset_isassociated(&rdataset)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_rdataset_disassociate(&rdataset);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
return (result);
|
1999-10-29 19:20:36 +00:00
|
|
|
}
|
|
|
|
|
1999-10-27 19:36:58 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
fetch_callback(isc_task_t *task, isc_event_t *ev) {
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_fetchevent_t *dev = (dns_fetchevent_t *)ev;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbname_t *name = NULL;
|
|
|
|
dns_adb_t *adb = NULL;
|
|
|
|
dns_adbfetch_t *fetch = NULL;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_eventtype_t ev_status;
|
|
|
|
isc_stdtime_t now;
|
|
|
|
isc_result_t result;
|
|
|
|
unsigned int address_type;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
UNUSED(task);
|
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(ev->ev_type == DNS_EVENT_FETCHDONE);
|
2008-02-07 23:46:54 +00:00
|
|
|
name = ev->ev_arg;
|
2022-03-24 16:06:48 -07:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADBNAME_VALID(name));
|
2022-05-11 13:55:01 -07:00
|
|
|
dns_adb_attach(name->adb, &adb);
|
2022-03-24 16:06:48 -07:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
nbucket = name->bucket;
|
|
|
|
LOCK(&nbucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
INSIST(NAME_FETCH_A(name) || NAME_FETCH_AAAA(name));
|
|
|
|
address_type = 0;
|
|
|
|
if (NAME_FETCH_A(name) && (name->fetch_a->fetch == dev->fetch)) {
|
|
|
|
address_type = DNS_ADBFIND_INET;
|
|
|
|
fetch = name->fetch_a;
|
|
|
|
name->fetch_a = NULL;
|
2020-02-12 13:59:18 +01:00
|
|
|
} else if (NAME_FETCH_AAAA(name) &&
|
|
|
|
(name->fetch_aaaa->fetch == dev->fetch)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
address_type = DNS_ADBFIND_INET6;
|
|
|
|
fetch = name->fetch_aaaa;
|
|
|
|
name->fetch_aaaa = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-10-15 04:22:30 +00:00
|
|
|
fetch = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-10-15 04:22:30 +00:00
|
|
|
|
|
|
|
INSIST(address_type != 0 && fetch != NULL);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
ev_status = DNS_EVENT_ADBNOMOREADDRESSES;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Cleanup things we don't care about.
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dev->node != NULL) {
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_db_detachnode(dev->db, &dev->node);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (dev->db != NULL) {
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_db_detach(&dev->db);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If this name is marked as dead, clean up, throwing away
|
|
|
|
* potentially good data.
|
|
|
|
*/
|
|
|
|
if (NAME_DEAD(name)) {
|
2022-05-11 13:55:01 -07:00
|
|
|
ev_status = DNS_EVENT_ADBCANCELED;
|
|
|
|
goto out;
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_stdtime_get(&now);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we got a negative cache response, remember it.
|
|
|
|
*/
|
|
|
|
if (NCACHE_RESULT(dev->result)) {
|
|
|
|
dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
|
|
|
|
if (address_type == DNS_ADBFIND_INET) {
|
2020-02-12 13:59:18 +01:00
|
|
|
DP(NCACHE_LEVEL,
|
|
|
|
"adb fetch name %p: "
|
2008-02-07 23:46:54 +00:00
|
|
|
"caching negative entry for A (ttl %u)",
|
|
|
|
name, dev->rdataset->ttl);
|
|
|
|
name->expire_v4 = ISC_MIN(name->expire_v4,
|
|
|
|
dev->rdataset->ttl + now);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dev->result == DNS_R_NCACHENXDOMAIN) {
|
2008-02-07 23:46:54 +00:00
|
|
|
name->fetch_err = FIND_ERR_NXDOMAIN;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
name->fetch_err = FIND_ERR_NXRRSET;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2022-05-11 15:38:54 -07:00
|
|
|
inc_resstats(adb, dns_resstatscounter_gluefetchv4fail);
|
2008-02-07 23:46:54 +00:00
|
|
|
} else {
|
2020-02-12 13:59:18 +01:00
|
|
|
DP(NCACHE_LEVEL,
|
|
|
|
"adb fetch name %p: "
|
2008-02-07 23:46:54 +00:00
|
|
|
"caching negative entry for AAAA (ttl %u)",
|
|
|
|
name, dev->rdataset->ttl);
|
|
|
|
name->expire_v6 = ISC_MIN(name->expire_v6,
|
|
|
|
dev->rdataset->ttl + now);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dev->result == DNS_R_NCACHENXDOMAIN) {
|
2008-02-07 23:46:54 +00:00
|
|
|
name->fetch6_err = FIND_ERR_NXDOMAIN;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
name->fetch6_err = FIND_ERR_NXRRSET;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2022-05-11 15:38:54 -07:00
|
|
|
inc_resstats(adb, dns_resstatscounter_gluefetchv6fail);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Handle CNAME/DNAME.
|
|
|
|
*/
|
|
|
|
if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) {
|
|
|
|
dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
|
|
|
|
clean_target(adb, &name->target);
|
|
|
|
name->expire_target = INT_MAX;
|
2021-04-22 18:58:01 -07:00
|
|
|
result = set_target(adb, &name->name, dev->foundname,
|
2020-02-12 13:59:18 +01:00
|
|
|
dev->rdataset, &name->target);
|
2008-02-07 23:46:54 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
DP(NCACHE_LEVEL,
|
2020-02-12 13:59:18 +01:00
|
|
|
"adb fetch name %p: caching alias target", name);
|
2008-02-07 23:46:54 +00:00
|
|
|
name->expire_target = dev->rdataset->ttl + now;
|
|
|
|
}
|
|
|
|
goto check_result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Did we get back junk? If so, and there are no more fetches
|
|
|
|
* sitting out there, tell all the finds about it.
|
|
|
|
*/
|
|
|
|
if (dev->result != ISC_R_SUCCESS) {
|
|
|
|
char buf[DNS_NAME_FORMATSIZE];
|
|
|
|
|
|
|
|
dns_name_format(&name->name, buf, sizeof(buf));
|
2020-02-12 13:59:18 +01:00
|
|
|
DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s", buf,
|
|
|
|
address_type == DNS_ADBFIND_INET ? "A" : "AAAA",
|
2021-10-04 17:14:53 +02:00
|
|
|
isc_result_totext(dev->result));
|
2014-11-17 23:24:44 -08:00
|
|
|
/*
|
|
|
|
* Don't record a failure unless this is the initial
|
|
|
|
* fetch of a chain.
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (fetch->depth > 1) {
|
2014-11-17 23:24:44 -08:00
|
|
|
goto out;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
/* XXXMLG Don't pound on bad servers. */
|
|
|
|
if (address_type == DNS_ADBFIND_INET) {
|
2014-12-15 22:28:06 -08:00
|
|
|
name->expire_v4 = ISC_MIN(name->expire_v4, now + 10);
|
2008-02-07 23:46:54 +00:00
|
|
|
name->fetch_err = FIND_ERR_FAILURE;
|
2022-05-11 15:38:54 -07:00
|
|
|
inc_resstats(adb, dns_resstatscounter_gluefetchv4fail);
|
2008-02-07 23:46:54 +00:00
|
|
|
} else {
|
2014-12-15 22:28:06 -08:00
|
|
|
name->expire_v6 = ISC_MIN(name->expire_v6, now + 10);
|
2008-02-07 23:46:54 +00:00
|
|
|
name->fetch6_err = FIND_ERR_FAILURE;
|
2022-05-11 15:38:54 -07:00
|
|
|
inc_resstats(adb, dns_resstatscounter_gluefetchv6fail);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We got something potentially useful.
|
|
|
|
*/
|
|
|
|
result = import_rdataset(name, &fetch->rdataset, now);
|
2000-01-21 02:50:27 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
check_result:
|
2008-02-07 23:46:54 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
ev_status = DNS_EVENT_ADBMOREADDRESSES;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (address_type == DNS_ADBFIND_INET) {
|
2008-02-07 23:46:54 +00:00
|
|
|
name->fetch_err = FIND_ERR_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
name->fetch6_err = FIND_ERR_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
1999-10-29 19:20:36 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
out:
|
2022-05-11 13:55:01 -07:00
|
|
|
dns_resolver_destroyfetch(&fetch->fetch);
|
2008-02-07 23:46:54 +00:00
|
|
|
free_adbfetch(adb, &fetch);
|
|
|
|
isc_event_free(&ev);
|
2022-05-11 13:55:01 -07:00
|
|
|
if (ev_status == DNS_EVENT_ADBCANCELED) {
|
|
|
|
expire_name(&name, ev_status);
|
|
|
|
} else {
|
|
|
|
clean_finds_at_name(name, ev_status, address_type);
|
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&nbucket->lock);
|
2022-05-11 13:55:01 -07:00
|
|
|
dns_adb_detach(&adb);
|
1999-10-27 19:36:58 +00:00
|
|
|
}
|
|
|
|
|
1999-10-26 01:12:20 +00:00
|
|
|
static isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_counter_t *qc, dns_rdatatype_t type) {
|
|
|
|
isc_result_t result;
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_adbfetch_t *fetch = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adb_t *adb = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_fixedname_t fixed;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_name_t *name = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdataset_t rdataset;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_rdataset_t *nameservers = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int options;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(DNS_ADBNAME_VALID(adbname));
|
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
adb = adbname->adb;
|
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
|
|
|
|
REQUIRE((type == dns_rdatatype_a && !NAME_FETCH_A(adbname)) ||
|
|
|
|
(type == dns_rdatatype_aaaa && !NAME_FETCH_AAAA(adbname)));
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
adbname->fetch_err = FIND_ERR_NOTFOUND;
|
|
|
|
|
|
|
|
dns_rdataset_init(&rdataset);
|
|
|
|
|
|
|
|
options = DNS_FETCHOPT_NOVALIDATE;
|
|
|
|
if (start_at_zone) {
|
2020-02-12 13:59:18 +01:00
|
|
|
DP(ENTER_LEVEL, "fetch_name: starting at zone for name %p",
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname);
|
2018-03-28 14:38:09 +02:00
|
|
|
name = dns_fixedname_initname(&fixed);
|
2018-04-04 09:51:42 +02:00
|
|
|
result = dns_view_findzonecut(adb->view, &adbname->name, name,
|
2018-06-13 09:29:40 +02:00
|
|
|
NULL, 0, 0, true, false,
|
2018-04-04 09:51:42 +02:00
|
|
|
&rdataset, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS && result != DNS_R_HINT) {
|
2008-02-07 23:46:54 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
nameservers = &rdataset;
|
|
|
|
options |= DNS_FETCHOPT_UNSHARED;
|
|
|
|
}
|
2018-05-18 13:07:31 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
fetch = new_adbfetch(adb);
|
2014-11-17 23:24:44 -08:00
|
|
|
fetch->depth = depth;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2018-06-13 09:29:40 +02:00
|
|
|
/*
|
|
|
|
* We're not minimizing this query, as nothing user-related should
|
|
|
|
* be leaked here.
|
|
|
|
* However, if we'd ever want to change it we'd have to modify
|
|
|
|
* createfetch to find deepest cached name when we're providing
|
|
|
|
* domain and nameservers.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_resolver_createfetch(
|
2022-05-12 15:51:10 -07:00
|
|
|
adb->res, &adbname->name, type, name, nameservers, NULL, NULL,
|
|
|
|
0, options, depth, qc, adb->task, fetch_callback, adbname,
|
|
|
|
&fetch->rdataset, NULL, &fetch->fetch);
|
2018-07-14 20:11:03 +02:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2020-02-12 13:59:18 +01:00
|
|
|
DP(ENTER_LEVEL, "fetch_name: createfetch failed with %s",
|
2018-07-14 20:11:03 +02:00
|
|
|
isc_result_totext(result));
|
2008-02-07 23:46:54 +00:00
|
|
|
goto cleanup;
|
2018-07-14 20:11:03 +02:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2008-04-03 06:09:05 +00:00
|
|
|
if (type == dns_rdatatype_a) {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch_a = fetch;
|
2022-05-11 15:38:54 -07:00
|
|
|
inc_resstats(adb, dns_resstatscounter_gluefetchv4);
|
2008-04-03 06:09:05 +00:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
adbname->fetch_aaaa = fetch;
|
2022-05-11 15:38:54 -07:00
|
|
|
inc_resstats(adb, dns_resstatscounter_gluefetchv6);
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
fetch = NULL; /* Keep us from cleaning this up below. */
|
1999-10-27 19:36:58 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (fetch != NULL) {
|
2008-02-07 23:46:54 +00:00
|
|
|
free_adbfetch(adb, &fetch);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (dns_rdataset_isassociated(&rdataset)) {
|
2008-02-07 23:46:54 +00:00
|
|
|
dns_rdataset_disassociate(&rdataset);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-10-30 02:26:03 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
return (result);
|
1999-10-30 02:26:03 +00:00
|
|
|
}
|
|
|
|
|
1999-10-19 21:10:29 +00:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
|
|
|
|
const dns_name_t *qname, dns_rdatatype_t qtype,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_stdtime_t expire_time) {
|
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_adblameinfo_t *li = NULL;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
REQUIRE(qname != NULL);
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
li = ISC_LIST_HEAD(addr->entry->lameinfo);
|
|
|
|
while (li != NULL &&
|
2020-02-13 21:48:23 +01:00
|
|
|
(li->qtype != qtype || !dns_name_equal(qname, &li->qname))) {
|
2008-02-07 23:46:54 +00:00
|
|
|
li = ISC_LIST_NEXT(li, plink);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
if (li != NULL) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (expire_time > li->lame_timer) {
|
2008-02-07 23:46:54 +00:00
|
|
|
li->lame_timer = expire_time;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
goto unlock;
|
|
|
|
}
|
|
|
|
li = new_adblameinfo(adb, qname, qtype);
|
|
|
|
li->lame_timer = expire_time;
|
|
|
|
|
|
|
|
ISC_LIST_PREPEND(addr->entry->lameinfo, li, plink);
|
1999-10-19 21:28:09 +00:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
unlock:
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
return (result);
|
1999-10-19 21:10:29 +00:00
|
|
|
}
|
1999-10-19 22:06:08 +00:00
|
|
|
|
1999-10-19 22:21:27 +00:00
|
|
|
void
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int rtt,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int factor) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2014-05-21 10:08:52 +10:00
|
|
|
isc_stdtime_t now = 0;
|
1999-10-19 22:21:27 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
REQUIRE(factor <= 10);
|
1999-10-19 22:21:27 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
1999-10-19 22:21:27 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (addr->entry->expires == 0 || factor == DNS_ADB_RTTADJAGE) {
|
2014-05-21 10:08:52 +10:00
|
|
|
isc_stdtime_get(&now);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-05-21 10:08:52 +10:00
|
|
|
adjustsrtt(addr, rtt, factor, now);
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2014-05-21 10:08:52 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_agesrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2014-05-21 10:08:52 +10:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
2014-05-21 10:08:52 +10:00
|
|
|
|
|
|
|
adjustsrtt(addr, 0, DNS_ADB_RTTADJAGE, now);
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2014-05-21 10:08:52 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-05-21 23:45:21 +00:00
|
|
|
adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_stdtime_t now) {
|
2018-03-28 14:19:37 +02:00
|
|
|
uint64_t new_srtt;
|
2013-06-12 11:31:30 +10:00
|
|
|
|
|
|
|
if (factor == DNS_ADB_RTTADJAGE) {
|
2014-05-21 10:08:52 +10:00
|
|
|
if (addr->entry->lastage != now) {
|
|
|
|
new_srtt = addr->entry->srtt;
|
|
|
|
new_srtt <<= 9;
|
|
|
|
new_srtt -= addr->entry->srtt;
|
|
|
|
new_srtt >>= 9;
|
|
|
|
addr->entry->lastage = now;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2014-05-21 10:08:52 +10:00
|
|
|
new_srtt = addr->entry->srtt;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
} else {
|
2020-02-12 13:59:18 +01:00
|
|
|
new_srtt = ((uint64_t)addr->entry->srtt / 10 * factor) +
|
|
|
|
((uint64_t)rtt / 10 * (10 - factor));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-11-19 00:30:13 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
addr->entry->srtt = (unsigned int)new_srtt;
|
|
|
|
addr->srtt = (unsigned int)new_srtt;
|
1999-10-19 22:21:27 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (addr->entry->expires == 0) {
|
2012-07-18 14:16:37 +10:00
|
|
|
addr->entry->expires = now + ADB_ENTRY_WINDOW;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-10-19 22:21:27 +00:00
|
|
|
}
|
1999-11-16 06:53:29 +00:00
|
|
|
|
|
|
|
void
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int mask) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2012-07-18 14:16:37 +10:00
|
|
|
isc_stdtime_t now;
|
1999-11-16 06:53:29 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
1999-11-16 06:53:29 +00:00
|
|
|
|
2014-04-28 10:24:39 -07:00
|
|
|
REQUIRE((bits & ENTRY_IS_DEAD) == 0);
|
|
|
|
REQUIRE((mask & ENTRY_IS_DEAD) == 0);
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
1999-11-16 06:53:29 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask);
|
2012-07-18 14:16:37 +10:00
|
|
|
if (addr->entry->expires == 0) {
|
|
|
|
isc_stdtime_get(&now);
|
|
|
|
addr->entry->expires = now + ADB_ENTRY_WINDOW;
|
|
|
|
}
|
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
/*
|
|
|
|
* Note that we do not update the other bits in addr->flags with
|
|
|
|
* the most recent values from addr->entry->flags.
|
|
|
|
*/
|
|
|
|
addr->flags = (addr->flags & ~mask) | (bits & mask);
|
1999-11-16 06:53:29 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
1999-11-16 06:53:29 +00:00
|
|
|
}
|
2000-01-12 03:00:33 +00:00
|
|
|
|
2015-07-08 22:53:39 -07:00
|
|
|
/*
|
2019-11-01 12:22:56 -05:00
|
|
|
* The polynomial backoff curve (10000 / ((10 + n) / 10)^(3/2)) <0..99> drops
|
|
|
|
* fairly aggressively at first, then slows down and tails off at around 2-3%.
|
|
|
|
*
|
2015-07-08 22:53:39 -07:00
|
|
|
* These will be used to make quota adjustments.
|
|
|
|
*/
|
|
|
|
static int quota_adj[] = {
|
2020-02-12 13:59:18 +01:00
|
|
|
10000, 8668, 7607, 6747, 6037, 5443, 4941, 4512, 4141, 3818, 3536,
|
|
|
|
3286, 3065, 2867, 2690, 2530, 2385, 2254, 2134, 2025, 1925, 1832,
|
|
|
|
1747, 1668, 1595, 1527, 1464, 1405, 1350, 1298, 1250, 1205, 1162,
|
|
|
|
1121, 1083, 1048, 1014, 981, 922, 894, 868, 843, 820, 797,
|
|
|
|
775, 755, 735, 716, 698, 680, 664, 648, 632, 618, 603,
|
|
|
|
590, 577, 564, 552, 540, 529, 518, 507, 497, 487, 477,
|
|
|
|
468, 459, 450, 442, 434, 426, 418, 411, 404, 397, 390,
|
|
|
|
383, 377, 370, 364, 358, 353, 347, 342, 336, 331, 326,
|
|
|
|
321, 316, 312, 307, 303, 298, 294, 290, 286, 282, 278
|
2015-07-08 22:53:39 -07:00
|
|
|
};
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#define QUOTA_ADJ_SIZE (sizeof(quota_adj) / sizeof(quota_adj[0]))
|
2017-09-13 09:50:51 +10:00
|
|
|
|
2015-07-08 22:53:39 -07:00
|
|
|
/*
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
* The adb entry associated with 'addr' must be locked.
|
2015-07-08 22:53:39 -07:00
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
maybe_adjust_quota(dns_adb_t *adb, dns_adbaddrinfo_t *addr, bool timeout) {
|
2015-07-08 22:53:39 -07:00
|
|
|
double tr;
|
|
|
|
|
|
|
|
UNUSED(adb);
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (adb->quota == 0 || adb->atr_freq == 0) {
|
2015-07-08 22:53:39 -07:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-07-08 22:53:39 -07:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (timeout) {
|
2015-07-08 22:53:39 -07:00
|
|
|
addr->entry->timeouts++;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-07-08 22:53:39 -07:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (addr->entry->completed++ <= adb->atr_freq) {
|
2015-07-08 22:53:39 -07:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-07-08 22:53:39 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Calculate an exponential rolling average of the timeout ratio
|
|
|
|
*
|
|
|
|
* XXX: Integer arithmetic might be better than floating point
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
tr = (double)addr->entry->timeouts / addr->entry->completed;
|
2015-07-08 22:53:39 -07:00
|
|
|
addr->entry->timeouts = addr->entry->completed = 0;
|
|
|
|
INSIST(addr->entry->atr >= 0.0);
|
|
|
|
INSIST(addr->entry->atr <= 1.0);
|
|
|
|
INSIST(adb->atr_discount >= 0.0);
|
|
|
|
INSIST(adb->atr_discount <= 1.0);
|
|
|
|
addr->entry->atr *= 1.0 - adb->atr_discount;
|
|
|
|
addr->entry->atr += tr * adb->atr_discount;
|
|
|
|
addr->entry->atr = ISC_CLAMP(addr->entry->atr, 0.0, 1.0);
|
|
|
|
|
|
|
|
if (addr->entry->atr < adb->atr_low && addr->entry->mode > 0) {
|
2019-01-22 10:47:18 +01:00
|
|
|
uint_fast32_t new_quota =
|
|
|
|
adb->quota * quota_adj[--addr->entry->mode] / 10000;
|
|
|
|
atomic_store_release(&addr->entry->quota,
|
2022-05-04 17:27:56 -07:00
|
|
|
ISC_MAX(1, new_quota));
|
2020-02-12 13:59:18 +01:00
|
|
|
log_quota(addr->entry,
|
|
|
|
"atr %0.2f, quota increased to %" PRIuFAST32,
|
|
|
|
addr->entry->atr, new_quota);
|
2017-09-13 09:50:51 +10:00
|
|
|
} else if (addr->entry->atr > adb->atr_high &&
|
2020-02-13 14:44:37 -08:00
|
|
|
addr->entry->mode < (QUOTA_ADJ_SIZE - 1))
|
|
|
|
{
|
2019-01-22 10:47:18 +01:00
|
|
|
uint_fast32_t new_quota =
|
|
|
|
adb->quota * quota_adj[++addr->entry->mode] / 10000;
|
|
|
|
atomic_store_release(&addr->entry->quota,
|
2022-05-04 17:27:56 -07:00
|
|
|
ISC_MAX(1, new_quota));
|
2020-02-12 13:59:18 +01:00
|
|
|
log_quota(addr->entry,
|
|
|
|
"atr %0.2f, quota decreased to %" PRIuFAST32,
|
|
|
|
addr->entry->atr, new_quota);
|
2015-07-08 22:53:39 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-12 11:31:30 +10:00
|
|
|
#define EDNSTOS 3U
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2013-06-12 11:31:30 +10:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
2014-02-19 12:53:42 +11:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
maybe_adjust_quota(adb, addr, false);
|
2015-07-08 22:53:39 -07:00
|
|
|
|
2013-06-12 11:31:30 +10:00
|
|
|
addr->entry->plain++;
|
|
|
|
if (addr->entry->plain == 0xff) {
|
|
|
|
addr->entry->edns >>= 1;
|
2020-09-23 14:47:26 +02:00
|
|
|
addr->entry->ednsto >>= 1;
|
2013-06-12 11:31:30 +10:00
|
|
|
addr->entry->plain >>= 1;
|
|
|
|
addr->entry->plainto >>= 1;
|
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2013-06-12 11:31:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2013-06-12 11:31:30 +10:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
2015-07-08 22:53:39 -07:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
maybe_adjust_quota(adb, addr, true);
|
2015-07-08 22:53:39 -07:00
|
|
|
|
2013-06-12 11:31:30 +10:00
|
|
|
addr->entry->plainto++;
|
|
|
|
if (addr->entry->plainto == 0xff) {
|
|
|
|
addr->entry->edns >>= 1;
|
2020-09-23 14:47:26 +02:00
|
|
|
addr->entry->ednsto >>= 1;
|
2013-06-12 11:31:30 +10:00
|
|
|
addr->entry->plain >>= 1;
|
|
|
|
addr->entry->plainto >>= 1;
|
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2013-06-12 11:31:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-09-23 14:47:26 +02:00
|
|
|
dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2013-06-12 11:31:30 +10:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
2013-06-12 11:31:30 +10:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
maybe_adjust_quota(adb, addr, true);
|
2015-07-08 22:53:39 -07:00
|
|
|
|
2020-09-23 14:47:26 +02:00
|
|
|
addr->entry->ednsto++;
|
|
|
|
if (addr->entry->ednsto == 0xff) {
|
2013-06-12 11:31:30 +10:00
|
|
|
addr->entry->edns >>= 1;
|
2020-09-23 14:47:26 +02:00
|
|
|
addr->entry->ednsto >>= 1;
|
2013-06-12 11:31:30 +10:00
|
|
|
addr->entry->plain >>= 1;
|
|
|
|
addr->entry->plainto >>= 1;
|
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2013-06-12 11:31:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2013-06-12 11:31:30 +10:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (size < 512U) {
|
2013-06-12 11:31:30 +10:00
|
|
|
size = 512U;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (size > addr->entry->udpsize) {
|
2013-06-12 11:31:30 +10:00
|
|
|
addr->entry->udpsize = size;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-07-08 22:53:39 -07:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
maybe_adjust_quota(adb, addr, false);
|
2015-07-08 22:53:39 -07:00
|
|
|
|
2013-06-12 11:31:30 +10:00
|
|
|
addr->entry->edns++;
|
|
|
|
if (addr->entry->edns == 0xff) {
|
|
|
|
addr->entry->edns >>= 1;
|
2020-09-23 14:47:26 +02:00
|
|
|
addr->entry->ednsto >>= 1;
|
2013-06-12 11:31:30 +10:00
|
|
|
addr->entry->plain >>= 1;
|
|
|
|
addr->entry->plainto >>= 1;
|
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2013-06-12 11:31:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2013-06-12 11:31:30 +10:00
|
|
|
unsigned int size;
|
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
2013-06-12 11:31:30 +10:00
|
|
|
size = addr->entry->udpsize;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2013-06-12 11:31:30 +10:00
|
|
|
|
|
|
|
return (size);
|
|
|
|
}
|
|
|
|
|
2014-02-19 12:53:42 +11:00
|
|
|
void
|
2015-07-06 09:44:24 +10:00
|
|
|
dns_adb_setcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
|
2020-02-13 14:44:37 -08:00
|
|
|
const unsigned char *cookie, size_t len) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2014-02-19 12:53:42 +11:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
2014-02-19 12:53:42 +11:00
|
|
|
|
2015-07-06 09:44:24 +10:00
|
|
|
if (addr->entry->cookie != NULL &&
|
2020-02-13 14:44:37 -08:00
|
|
|
(cookie == NULL || len != addr->entry->cookielen))
|
|
|
|
{
|
2015-07-06 09:44:24 +10:00
|
|
|
isc_mem_put(adb->mctx, addr->entry->cookie,
|
|
|
|
addr->entry->cookielen);
|
|
|
|
addr->entry->cookie = NULL;
|
|
|
|
addr->entry->cookielen = 0;
|
2014-02-19 12:53:42 +11:00
|
|
|
}
|
|
|
|
|
2015-07-06 09:44:24 +10:00
|
|
|
if (addr->entry->cookie == NULL && cookie != NULL && len != 0U) {
|
|
|
|
addr->entry->cookie = isc_mem_get(adb->mctx, len);
|
2019-07-16 15:52:14 +02:00
|
|
|
addr->entry->cookielen = (uint16_t)len;
|
2014-02-19 12:53:42 +11:00
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (addr->entry->cookie != NULL) {
|
2015-07-06 09:44:24 +10:00
|
|
|
memmove(addr->entry->cookie, cookie, len);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2014-02-19 12:53:42 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
2015-07-06 09:44:24 +10:00
|
|
|
dns_adb_getcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned char *cookie, size_t len) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2014-02-19 12:53:42 +11:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
ebucket = addr->entry->bucket;
|
|
|
|
LOCK(&ebucket->lock);
|
2015-07-06 09:44:24 +10:00
|
|
|
if (cookie != NULL && addr->entry->cookie != NULL &&
|
2020-02-13 14:44:37 -08:00
|
|
|
len >= addr->entry->cookielen)
|
|
|
|
{
|
2015-07-06 09:44:24 +10:00
|
|
|
memmove(cookie, addr->entry->cookie, addr->entry->cookielen);
|
|
|
|
len = addr->entry->cookielen;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2014-02-19 12:53:42 +11:00
|
|
|
len = 0;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2014-02-19 12:53:42 +11:00
|
|
|
|
|
|
|
return (len);
|
|
|
|
}
|
|
|
|
|
2000-01-12 03:00:33 +00:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_adb_findaddrinfo(dns_adb_t *adb, const isc_sockaddr_t *sa,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adbaddrinfo_t **addrp, isc_stdtime_t now) {
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbentrybucket_t *ebucket = NULL;
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbentry_t *entry = NULL;
|
|
|
|
dns_adbaddrinfo_t *addr = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
in_port_t port;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(addrp != NULL && *addrp == NULL);
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (atomic_load(&adb->exiting)) {
|
|
|
|
return (ISC_R_SHUTTINGDOWN);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
get_entrybucket(adb, sa, &ebucket);
|
|
|
|
INSIST(ebucket != NULL);
|
|
|
|
LOCK(&ebucket->lock);
|
|
|
|
|
|
|
|
entry = get_entry(ebucket, sa, now);
|
2008-02-07 23:46:54 +00:00
|
|
|
if (entry == NULL) {
|
|
|
|
/*
|
|
|
|
* We don't know anything about this address.
|
|
|
|
*/
|
|
|
|
entry = new_adbentry(adb);
|
|
|
|
entry->sockaddr = *sa;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
link_entry(ebucket, entry);
|
2008-02-07 23:46:54 +00:00
|
|
|
DP(ENTER_LEVEL, "findaddrinfo: new entry %p", entry);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
/* Move entry to the head of the LRU list */
|
|
|
|
ISC_LIST_UNLINK(ebucket->entries, entry, plink);
|
|
|
|
ISC_LIST_PREPEND(ebucket->entries, entry, plink);
|
2008-02-07 23:46:54 +00:00
|
|
|
DP(ENTER_LEVEL, "findaddrinfo: found entry %p", entry);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-02-07 23:46:54 +00:00
|
|
|
|
|
|
|
port = isc_sockaddr_getport(sa);
|
|
|
|
addr = new_adbaddrinfo(adb, entry, port);
|
2021-04-22 18:58:01 -07:00
|
|
|
*addrp = addr;
|
2000-01-12 03:00:33 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&ebucket->lock);
|
2008-02-07 23:46:54 +00:00
|
|
|
return (result);
|
2000-01-12 03:00:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbaddrinfo_t *addr = NULL;
|
|
|
|
dns_adbentry_t *entry = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_stdtime_t now;
|
2000-01-12 03:00:33 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(addrp != NULL);
|
2022-03-16 21:58:55 +01:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
addr = *addrp;
|
2020-02-08 04:37:54 -08:00
|
|
|
*addrp = NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
entry = addr->entry;
|
2000-01-12 03:00:33 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
REQUIRE(DNS_ADBENTRY_VALID(entry));
|
2000-01-12 03:00:33 +00:00
|
|
|
|
2012-07-18 14:16:37 +10:00
|
|
|
if (entry->expires == 0) {
|
|
|
|
isc_stdtime_get(&now);
|
|
|
|
entry->expires = now + ADB_ENTRY_WINDOW;
|
|
|
|
}
|
2000-01-12 03:00:33 +00:00
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
free_adbaddrinfo(adb, &addr);
|
2000-01-12 03:00:33 +00:00
|
|
|
}
|
2001-04-11 20:37:50 +00:00
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_flush(dns_adb_t *adb) {
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
2001-04-11 20:37:50 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (atomic_load(&adb->exiting)) {
|
|
|
|
return;
|
|
|
|
}
|
2001-04-11 20:37:50 +00:00
|
|
|
|
2022-03-16 21:58:55 +01:00
|
|
|
clean_hashes(adb, INT_MAX);
|
2001-04-11 20:37:50 +00:00
|
|
|
#ifdef DUMP_ADB_AFTER_CLEANING
|
2018-04-17 08:29:14 -07:00
|
|
|
dump_adb(adb, stdout, true, INT_MAX);
|
2020-02-13 21:48:23 +01:00
|
|
|
#endif /* ifdef DUMP_ADB_AFTER_CLEANING */
|
2001-04-11 20:37:50 +00:00
|
|
|
}
|
2001-10-25 04:57:46 +00:00
|
|
|
|
2001-11-27 03:00:50 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_flushname(dns_adb_t *adb, const dns_name_t *name) {
|
2022-03-24 16:06:48 -07:00
|
|
|
dns_adbname_t *adbname = NULL;
|
|
|
|
dns_adbname_t *nextname = NULL;
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_result_t result;
|
2008-02-07 23:46:54 +00:00
|
|
|
|
2013-06-26 14:59:32 -07:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(name != NULL);
|
2008-02-07 23:46:54 +00:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (atomic_load(&adb->exiting)) {
|
|
|
|
return;
|
|
|
|
}
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWLOCK(&adb->names_lock, isc_rwlocktype_read);
|
2022-03-16 21:58:55 +01:00
|
|
|
result = isc_ht_find(adb->namebuckets, name->ndata, name->length,
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
(void **)&nbucket);
|
2022-03-16 21:58:55 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_read);
|
2022-03-16 21:58:55 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
LOCK(&nbucket->lock);
|
|
|
|
adbname = ISC_LIST_HEAD(nbucket->names);
|
2008-02-07 23:46:54 +00:00
|
|
|
while (adbname != NULL) {
|
|
|
|
nextname = ISC_LIST_NEXT(adbname, plink);
|
2020-02-13 14:44:37 -08:00
|
|
|
if (!NAME_DEAD(adbname) && dns_name_equal(name, &adbname->name))
|
|
|
|
{
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
expire_name(&adbname, DNS_EVENT_ADBCANCELED);
|
2008-02-07 23:46:54 +00:00
|
|
|
}
|
|
|
|
adbname = nextname;
|
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&nbucket->lock);
|
|
|
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_read);
|
2001-11-27 03:00:50 +00:00
|
|
|
}
|
|
|
|
|
2013-06-26 14:59:32 -07:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name) {
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_result_t result;
|
|
|
|
isc_ht_iter_t *iter = NULL;
|
2013-06-26 14:59:32 -07:00
|
|
|
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(name != NULL);
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
if (atomic_load(&adb->exiting)) {
|
|
|
|
return;
|
|
|
|
}
|
2022-03-16 21:58:55 +01:00
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWLOCK(&adb->names_lock, isc_rwlocktype_read);
|
|
|
|
isc_ht_iter_create(adb->namebuckets, &iter);
|
2022-03-16 21:58:55 +01:00
|
|
|
for (result = isc_ht_iter_first(iter); result == ISC_R_SUCCESS;
|
|
|
|
result = isc_ht_iter_next(iter))
|
|
|
|
{
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
dns_adbnamebucket_t *nbucket = NULL;
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_adbname_t *adbname = NULL, *nextname = NULL;
|
|
|
|
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
isc_ht_iter_current(iter, (void **)&nbucket);
|
|
|
|
LOCK(&nbucket->lock);
|
|
|
|
adbname = ISC_LIST_HEAD(nbucket->names);
|
2013-06-26 14:59:32 -07:00
|
|
|
while (adbname != NULL) {
|
|
|
|
nextname = ISC_LIST_NEXT(adbname, plink);
|
|
|
|
if (!NAME_DEAD(adbname) &&
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_name_issubdomain(&adbname->name, name)) {
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
expire_name(&adbname, DNS_EVENT_ADBCANCELED);
|
2013-06-26 14:59:32 -07:00
|
|
|
}
|
|
|
|
adbname = nextname;
|
|
|
|
}
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
UNLOCK(&nbucket->lock);
|
2013-06-26 14:59:32 -07:00
|
|
|
}
|
2022-03-16 21:58:55 +01:00
|
|
|
isc_ht_iter_destroy(&iter);
|
Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.
It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.
The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward. Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero
In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry. Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.
Comments throughout the module have been improved.
2022-03-21 12:48:52 -07:00
|
|
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_read);
|
2013-06-26 14:59:32 -07:00
|
|
|
}
|
|
|
|
|
2001-10-25 04:57:46 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
water(void *arg, int mark) {
|
2022-03-16 21:58:55 +01:00
|
|
|
dns_adb_t *adb = arg;
|
|
|
|
bool overmem = (mark == ISC_MEM_HIWATER);
|
|
|
|
|
2010-08-11 22:54:58 +00:00
|
|
|
/*
|
|
|
|
* We're going to change the way to handle overmem condition: use
|
|
|
|
* isc_mem_isovermem() instead of storing the state via this callback,
|
|
|
|
* since the latter way tends to cause race conditions.
|
|
|
|
* To minimize the change, and in case we re-enable the callback
|
|
|
|
* approach, however, keep this function at the moment.
|
|
|
|
*/
|
|
|
|
|
2008-02-07 23:46:54 +00:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
2003-10-16 05:46:19 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
DP(ISC_LOG_DEBUG(1), "adb reached %s water mark",
|
|
|
|
overmem ? "high" : "low");
|
2001-10-25 04:57:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_setadbsize(dns_adb_t *adb, size_t size) {
|
2013-02-28 09:29:12 -08:00
|
|
|
size_t hiwater, lowater;
|
2001-10-25 04:57:46 +00:00
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
2001-10-25 04:57:46 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (size != 0U && size < DNS_ADB_MINADBSIZE) {
|
2008-02-07 23:46:54 +00:00
|
|
|
size = DNS_ADB_MINADBSIZE;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-10-25 04:57:46 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
hiwater = size - (size >> 3); /* Approximately 7/8ths. */
|
|
|
|
lowater = size - (size >> 2); /* Approximately 3/4ths. */
|
2001-10-25 04:57:46 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (size == 0U || hiwater == 0U || lowater == 0U) {
|
2021-07-22 06:14:32 +02:00
|
|
|
isc_mem_clearwater(adb->mctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2008-02-07 23:46:54 +00:00
|
|
|
isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-10-25 04:57:46 +00:00
|
|
|
}
|
2015-07-08 22:53:39 -07:00
|
|
|
|
|
|
|
void
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_adb_setquota(dns_adb_t *adb, uint32_t quota, uint32_t freq, double low,
|
2020-02-13 14:44:37 -08:00
|
|
|
double high, double discount) {
|
2015-07-08 22:53:39 -07:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
|
|
|
|
adb->quota = quota;
|
|
|
|
adb->atr_freq = freq;
|
|
|
|
adb->atr_low = low;
|
|
|
|
adb->atr_high = high;
|
|
|
|
adb->atr_discount = discount;
|
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adbentry_overquota(dns_adbentry_t *entry) {
|
2022-03-24 16:06:48 -07:00
|
|
|
uint_fast32_t quota, active;
|
|
|
|
|
2015-07-08 22:53:39 -07:00
|
|
|
REQUIRE(DNS_ADBENTRY_VALID(entry));
|
2019-01-22 10:47:18 +01:00
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
quota = atomic_load_relaxed(&entry->quota);
|
|
|
|
active = atomic_load_acquire(&entry->active);
|
2019-01-22 10:47:18 +01:00
|
|
|
|
|
|
|
return (quota != 0 && active >= quota);
|
2015-07-08 22:53:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
2015-07-08 22:53:39 -07:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(atomic_fetch_add_relaxed(&addr->entry->active, 1) !=
|
|
|
|
UINT32_MAX);
|
2015-07-08 22:53:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_adb_endudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
2015-07-08 22:53:39 -07:00
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
|
|
|
|
2022-03-24 16:06:48 -07:00
|
|
|
REQUIRE(atomic_fetch_sub_release(&addr->entry->active, 1) != 0);
|
2015-07-08 22:53:39 -07:00
|
|
|
}
|
2022-05-11 15:38:54 -07:00
|
|
|
|
|
|
|
isc_stats_t *
|
|
|
|
dns_adb_getstats(dns_adb_t *adb) {
|
|
|
|
REQUIRE(DNS_ADB_VALID(adb));
|
|
|
|
|
|
|
|
return (adb->stats);
|
|
|
|
}
|