#define SIZE_AS_PERCENT ((size_t)-2)
#endif /* ifndef SIZE_AS_PERCENT */
-#define RESOLVER_NTASKS 523
-
/* RFC7828 defines timeout as 16-bit value specified in units of 100
* milliseconds, so the maximum and minimum advertised and keepalive
* timeouts are capped by the data type (it's ~109 minutes)
nzf_append(dns_view_t *view, const cfg_obj_t *zconfig);
#endif /* ifdef HAVE_LMDB */
+static const uint32_t primes[] = {
+ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
+ 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89,
+ 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
+ 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223,
+ 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
+ 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359,
+ 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433,
+ 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
+ 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593,
+ 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
+ 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743,
+ 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827,
+ 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
+ 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,
+ 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
+ 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
+ 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249,
+ 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321,
+ 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439,
+ 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
+ 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601,
+ 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
+ 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783,
+ 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877,
+ 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,
+ 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069,
+ 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143,
+ 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267,
+ 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347,
+ 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
+ 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543,
+ 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657,
+ 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713,
+ 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801,
+ 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903,
+ 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011,
+ 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119,
+ 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221,
+ 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323,
+ 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
+ 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527,
+ 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607,
+ 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697,
+ 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797,
+ 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907,
+ 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003,
+ 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093,
+ 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211,
+ 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283,
+ 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,
+ 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513,
+ 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621,
+ 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721,
+ 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813,
+ 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937,
+ 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011,
+ 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113,
+ 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233,
+ 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351,
+ 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,
+ 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531,
+ 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653,
+ 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743,
+ 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849,
+ 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939,
+ 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073,
+ 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173,
+ 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271,
+ 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359,
+ 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,
+ 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581,
+ 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701,
+ 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803,
+ 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907,
+ 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997,
+ 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121,
+ 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229,
+ 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349,
+ 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487,
+ 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,
+ 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669,
+ 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757,
+ 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879,
+ 7883, 7901, 7907, 7919,
+};
+
+static uint32_t
+closest_prime(uint32_t n) {
+ for (size_t i = 0; i < ARRAY_SIZE(primes); i++) {
+ if (primes[i] >= n) {
+ return primes[i];
+ }
+ }
+
+ return primes[ARRAY_SIZE(primes) - 1];
+}
+
/*%
* Configure a single view ACL at '*aclp'. Get its configuration from
* 'vconfig' (for per-view configuration) and maybe from 'config'
named_cache_t *nsc;
bool zero_no_soattl;
dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL;
- unsigned int query_timeout, ndisp;
+ unsigned int query_timeout, ndisp, ntasks;
bool old_rpz_ok = false;
dns_dyndbctx_t *dctx = NULL;
unsigned int resolver_param;
}
dns_view_setresquerystats(view, resquerystats);
+ ntasks = closest_prime(2 * named_g_cpus);
ndisp = 4 * ISC_MIN(named_g_udpdisp, MAX_UDP_DISPATCH);
- CHECK(dns_view_createresolver(view, named_g_taskmgr, RESOLVER_NTASKS,
- ndisp, named_g_netmgr, named_g_timermgr,
- resopts, named_g_dispatchmgr, dispatch4,
+ CHECK(dns_view_createresolver(view, named_g_taskmgr, ntasks, ndisp,
+ named_g_netmgr, named_g_timermgr, resopts,
+ named_g_dispatchmgr, dispatch4,
dispatch6));
/*
#include <isc/atomic.h>
#include <isc/counter.h>
+#include <isc/hash.h>
+#include <isc/ht.h>
#include <isc/log.h>
#include <isc/print.h>
#include <isc/random.h>
unsigned int options;
unsigned int bucketnum;
unsigned int dbucketnum;
+ bool hashed;
char *info;
isc_mem_t *mctx;
isc_stdtime_t now;
bool cloned;
bool spilled;
isc_event_t control_event;
- ISC_LINK(struct fetchctx) link;
ISC_LIST(dns_fetchevent_t) events;
/*% Locked by task event serialization. */
#define DNS_FETCH_MAGIC ISC_MAGIC('F', 't', 'c', 'h')
#define DNS_FETCH_VALID(fetch) ISC_MAGIC_VALID(fetch, DNS_FETCH_MAGIC)
+#define DNS_FCTX_KEYSIZE \
+ (DNS_NAME_MAXWIRE + sizeof(dns_rdatatype_t) + sizeof(unsigned int))
+
typedef struct fctxbucket {
isc_task_t *task;
isc_mutex_t lock;
- ISC_LIST(fetchctx_t) fctxs;
+ isc_refcount_t nfctxs;
+ isc_ht_t *fctxs;
atomic_bool exiting;
} fctxbucket_t;
uint32_t allowed;
uint32_t dropped;
isc_stdtime_t logged;
- ISC_LINK(fctxcount_t) link;
};
typedef struct zonebucket {
isc_mutex_t lock;
- ISC_LIST(fctxcount_t) list;
+ isc_ht_t *counters;
} zonebucket_t;
typedef struct alternate {
/* Locked by primelock. */
dns_fetch_t *primefetch;
-
- /* Atomic. */
- atomic_uint_fast32_t nfctx;
};
#define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!')
counter->logged = now;
}
+static void
+fcount_makekey(const dns_name_t *name, uint8_t *key, size_t *keysizep) {
+ REQUIRE(*keysizep >= name->length);
+
+ size_t keysize = 0;
+ isc_buffer_t buffer;
+ dns_name_t downname;
+ isc_result_t result;
+
+ DNS_NAME_INIT(&downname, NULL);
+ isc_buffer_init(&buffer, key, *keysizep);
+
+ result = dns_name_downcase(name, &downname, &buffer);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ keysize += isc_buffer_usedlength(&buffer);
+
+ *keysizep = keysize;
+}
+
static isc_result_t
fcount_incr(fetchctx_t *fctx, bool force) {
isc_result_t result = ISC_R_SUCCESS;
fctxcount_t *counter = NULL;
uint32_t hashval;
uint32_t dbucketnum;
+ uint8_t key[DNS_NAME_MAXWIRE];
+ size_t keysize = sizeof(key);
+ uint_fast32_t spill;
REQUIRE(fctx != NULL);
REQUIRE(fctx->res != NULL);
dbucket = &fctx->res->dbuckets[dbucketnum];
LOCK(&dbucket->lock);
- for (counter = ISC_LIST_HEAD(dbucket->list); counter != NULL;
- counter = ISC_LIST_NEXT(counter, link))
- {
- if (dns_name_equal(counter->domain, fctx->domain)) {
- break;
- }
- }
- if (counter == NULL) {
+ fcount_makekey(fctx->domain, key, &keysize);
+
+ result = isc_ht_find(dbucket->counters, key, keysize,
+ (void **)&counter);
+
+ switch (result) {
+ case ISC_R_NOTFOUND:
counter = isc_mem_get(fctx->res->mctx, sizeof(*counter));
*counter = (fctxcount_t){
.count = 1,
};
counter->domain = dns_fixedname_initname(&counter->dfname);
- ISC_LINK_INIT(counter, link);
dns_name_copy(fctx->domain, counter->domain);
- ISC_LIST_APPEND(dbucket->list, counter, link);
- } else {
- uint_fast32_t spill = atomic_load_acquire(&fctx->res->zspill);
+ result = isc_ht_add(dbucket->counters, key, keysize, counter);
+ break;
+ case ISC_R_SUCCESS:
+ spill = atomic_load_acquire(&fctx->res->zspill);
if (!force && spill != 0 && counter->count >= spill) {
counter->dropped++;
fcount_logspill(fctx, counter, false);
counter->count++;
counter->allowed++;
}
+ break;
+ default:
+ UNREACHABLE();
}
UNLOCK(&dbucket->lock);
fcount_decr(fetchctx_t *fctx) {
zonebucket_t *dbucket = NULL;
fctxcount_t *counter = NULL;
+ uint8_t key[DNS_NAME_MAXWIRE];
+ size_t keysize = sizeof(key);
+ isc_result_t result;
REQUIRE(fctx != NULL);
dbucket = &fctx->res->dbuckets[fctx->dbucketnum];
LOCK(&dbucket->lock);
- for (counter = ISC_LIST_HEAD(dbucket->list); counter != NULL;
- counter = ISC_LIST_NEXT(counter, link))
- {
- if (dns_name_equal(counter->domain, fctx->domain)) {
- break;
- }
- }
- if (counter != NULL) {
- INSIST(counter->count != 0);
- counter->count--;
- fctx->dbucketnum = RES_NOBUCKET;
+ fcount_makekey(fctx->domain, key, &keysize);
- if (counter->count == 0) {
- fcount_logspill(fctx, counter, true);
- ISC_LIST_UNLINK(dbucket->list, counter, link);
- isc_mem_put(fctx->res->mctx, counter, sizeof(*counter));
- }
+ result = isc_ht_find(dbucket->counters, key, keysize,
+ (void **)&counter);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ INSIST(counter->count != 0);
+ counter->count--;
+ fctx->dbucketnum = RES_NOBUCKET;
+
+ if (counter->count == 0) {
+ fcount_logspill(fctx, counter, true);
+ result = isc_ht_delete(dbucket->counters, key, keysize);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ isc_mem_put(fctx->res->mctx, counter, sizeof(*counter));
}
UNLOCK(&dbucket->lock);
}
}
+static void
+fctx_makekey(const dns_name_t *name, dns_rdatatype_t type, unsigned int options,
+ uint8_t *key, size_t *keysizep) {
+ REQUIRE(*keysizep >= name->length + sizeof(type) + sizeof(options));
+
+ size_t keysize = 0;
+ isc_buffer_t buffer;
+ dns_name_t downname;
+ isc_result_t result;
+
+ DNS_NAME_INIT(&downname, NULL);
+ isc_buffer_init(&buffer, key, *keysizep);
+
+ result = dns_name_downcase(name, &downname, &buffer);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ keysize += isc_buffer_usedlength(&buffer);
+
+ memmove(&key[keysize], &type, sizeof(type));
+ keysize += sizeof(type);
+
+ memmove(&key[keysize], &options, sizeof(options));
+ keysize += sizeof(options);
+
+ *keysizep = keysize;
+}
+
+static void
+fctx_unhash(fetchctx_t *fctx) {
+ dns_resolver_t *res = fctx->res;
+ unsigned int bucketnum = fctx->bucketnum;
+ uint8_t key[DNS_FCTX_KEYSIZE] = { 0 };
+ size_t keysize = sizeof(key);
+ isc_result_t result;
+
+ if (!fctx->hashed) {
+ return;
+ }
+
+ fctx_makekey(fctx->name, fctx->type, fctx->options, key, &keysize);
+
+ result = isc_ht_delete(res->buckets[bucketnum].fctxs, key, keysize);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ fctx->hashed = false;
+}
+
+static void
+fctx_hash(fetchctx_t *fctx) {
+ dns_resolver_t *res = fctx->res;
+ unsigned int bucketnum = fctx->bucketnum;
+ uint8_t key[DNS_FCTX_KEYSIZE] = { 0 };
+ size_t keysize = sizeof(key);
+ isc_result_t result;
+ bool unshared = ((fctx->options & DNS_FETCHOPT_UNSHARED) != 0);
+
+ if (unshared) {
+ return;
+ }
+
+ fctx_makekey(fctx->name, fctx->type, fctx->options, key, &keysize);
+
+ result = isc_ht_add(res->buckets[bucketnum].fctxs, key, keysize, fctx);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ fctx->hashed = true;
+}
+
static void
fctx__done_detach(fetchctx_t **fctxp, isc_result_t result, const char *file,
unsigned int line, const char *func) {
LOCK(&res->buckets[fctx->bucketnum].lock);
INSIST(fctx->state != fetchstate_done);
fctx->state = fetchstate_done;
+ fctx_unhash(fctx);
UNLOCK(&res->buckets[fctx->bucketnum].lock);
if (result == ISC_R_SUCCESS) {
event->result = ISC_R_TIMEDOUT;
isc_task_sendanddetach(&sender, ISC_EVENT_PTR(&event));
}
+
+ if (ISC_LIST_EMPTY(fctx->events)) {
+ fctx_unhash(fctx);
+ }
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
/*
struct tried *tried = NULL;
unsigned int bucketnum;
bool bucket_empty = false;
- uint_fast32_t nfctx;
REQUIRE(VALID_FCTX(fctx));
REQUIRE(ISC_LIST_EMPTY(fctx->events));
LOCK(&res->buckets[bucketnum].lock);
REQUIRE(fctx->state != fetchstate_active);
- ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link);
-
- nfctx = atomic_fetch_sub_release(&res->nfctx, 1);
- INSIST(nfctx > 0);
+ fctx_unhash(fctx);
- dec_stats(res, dns_resstatscounter_nfetch);
+ INSIST(res->buckets[bucketnum].nfctxs > 0);
+ res->buckets[bucketnum].nfctxs--;
if (atomic_load_acquire(&res->buckets[bucketnum].exiting) &&
- ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs))
+ res->buckets[bucketnum].nfctxs == 0)
{
bucket_empty = true;
}
+
+ dec_stats(res, dns_resstatscounter_nfetch);
+
UNLOCK(&res->buckets[bucketnum].lock);
if (bucket_empty && exiting &&
if (fctx->state == fetchstate_active) {
fctx->state = fetchstate_done;
+ fctx_unhash(fctx);
fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__);
isc_interval_t interval;
unsigned int findoptions = 0;
char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + 1];
- uint_fast32_t nfctx;
size_t p;
/*
isc_mem_attach(res->mctx, &fctx->mctx);
ISC_LIST_INIT(fctx->events);
- ISC_LINK_INIT(fctx, link);
fctx->magic = FCTX_MAGIC;
/*
fctx_minimize_qname(fctx);
}
- ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link);
+ fctx_hash(fctx);
- nfctx = atomic_fetch_add_relaxed(&res->nfctx, 1);
- INSIST(nfctx < UINT32_MAX);
+ res->buckets[bucketnum].nfctxs++;
inc_stats(res, dns_resstatscounter_nfetch);
* Caller must be holding the appropriate lock.
*/
+ fctx_unhash(fctx);
fctx->cloned = true;
for (event = ISC_LIST_HEAD(fctx->events); event != NULL;
RTRACE("destroy");
- REQUIRE(atomic_load_acquire(&res->nfctx) == 0);
-
isc_mutex_destroy(&res->primelock);
isc_mutex_destroy(&res->lock);
for (i = 0; i < res->nbuckets; i++) {
- INSIST(ISC_LIST_EMPTY(res->buckets[i].fctxs));
+ INSIST(res->buckets[i].nfctxs == 0);
+ INSIST(isc_ht_count(res->buckets[i].fctxs) == 0);
+ isc_ht_destroy(&res->buckets[i].fctxs);
isc_task_shutdown(res->buckets[i].task);
isc_task_detach(&res->buckets[i].task);
isc_mutex_destroy(&res->buckets[i].lock);
isc_mem_put(res->mctx, res->buckets,
res->nbuckets * sizeof(fctxbucket_t));
for (i = 0; i < HASHSIZE(res->dhashbits); i++) {
- INSIST(ISC_LIST_EMPTY(res->dbuckets[i].list));
+ INSIST(isc_ht_count(res->dbuckets[i].counters) == 0);
+ isc_ht_destroy(&res->dbuckets[i].counters);
isc_mutex_destroy(&res->dbuckets[i].lock);
}
isc_mem_put(res->mctx, res->dbuckets,
atomic_init(&res->exiting, false);
atomic_init(&res->priming, false);
atomic_init(&res->zspill, 0);
- atomic_init(&res->nfctx, 0);
ISC_LIST_INIT(res->whenshutdown);
ISC_LIST_INIT(res->alternates);
snprintf(name, sizeof(name), "res%" PRIu32, i);
isc_task_setname(res->buckets[i].task, name, res);
- ISC_LIST_INIT(res->buckets[i].fctxs);
+ isc_ht_init(&res->buckets[i].fctxs, res->mctx, 8,
+ ISC_HT_CASE_SENSITIVE);
atomic_init(&res->buckets[i].exiting, false);
}
HASHSIZE(res->dhashbits) *
sizeof(res->dbuckets[0]));
for (size_t i = 0; i < HASHSIZE(res->dhashbits); i++) {
- res->dbuckets[i] = (zonebucket_t){ .list = { 0 } };
- ISC_LIST_INIT(res->dbuckets[i].list);
+ res->dbuckets[i] = (zonebucket_t){ 0 };
+ isc_ht_init(&res->dbuckets[i].counters, res->mctx, 8,
+ ISC_HT_CASE_SENSITIVE);
+
isc_mutex_init(&res->dbuckets[i].lock);
}
void
dns_resolver_shutdown(dns_resolver_t *res) {
unsigned int i;
- fetchctx_t *fctx;
isc_result_t result;
- bool is_false = false;
bool is_done = false;
REQUIRE(VALID_RESOLVER(res));
RTRACE("shutdown");
- if (atomic_compare_exchange_strong(&res->exiting, &is_false, true)) {
+ if (atomic_compare_exchange_strong(&res->exiting, &(bool){ false },
+ true))
+ {
RTRACE("exiting");
for (i = 0; i < res->nbuckets; i++) {
LOCK(&res->buckets[i].lock);
- for (fctx = ISC_LIST_HEAD(res->buckets[i].fctxs);
- fctx != NULL; fctx = ISC_LIST_NEXT(fctx, link))
+ isc_ht_iter_t *it = NULL;
+
+ isc_ht_iter_create(res->buckets[i].fctxs, &it);
+
+ for (result = isc_ht_iter_first(it);
+ result == ISC_R_SUCCESS;
+ result = isc_ht_iter_next(it))
{
+ fetchctx_t *fctx = NULL;
+ isc_ht_iter_current(it, (void **)&fctx);
fctx_shutdown(fctx);
}
+
+ isc_ht_iter_destroy(&it);
+
atomic_store(&res->buckets[i].exiting, true);
- if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) {
+
+ if (res->buckets[i].nfctxs == 0) {
if (isc_refcount_decrement(
&res->activebuckets) == 1)
{
is_done = true;
}
}
+
UNLOCK(&res->buckets[i].lock);
}
if (is_done) {
}
}
-static bool
-fctx_match(fetchctx_t *fctx, const dns_name_t *name, dns_rdatatype_t type,
- unsigned int options) {
- /*
- * Don't match fetch contexts that are shutting down.
- */
- if (fctx->cloned || fctx->state == fetchstate_done ||
- ISC_LIST_EMPTY(fctx->events))
- {
- return false;
- }
-
- if (fctx->type != type || fctx->options != options) {
- return false;
- }
- return dns_name_equal(fctx->name, name);
-}
-
static void
log_fetch(const dns_name_t *name, dns_rdatatype_t type) {
char namebuf[DNS_NAME_FORMATSIZE];
}
if ((options & DNS_FETCHOPT_UNSHARED) == 0) {
- for (fctx = ISC_LIST_HEAD(res->buckets[bucketnum].fctxs);
- fctx != NULL; fctx = ISC_LIST_NEXT(fctx, link))
- {
- if (fctx_match(fctx, name, type, options)) {
- break;
- }
- }
+ uint8_t key[DNS_FCTX_KEYSIZE];
+ size_t keysize = sizeof(key);
+
+ fctx_makekey(name, type, options, key, &keysize);
+
+ (void)isc_ht_find(res->buckets[bucketnum].fctxs, key, keysize,
+ (void **)&fctx);
}
/*
}
}
}
+
/*
* The "trystale" event must be sent before the "fetchdone" event,
* because the latter clears the "recursing" query attribute, which is
REQUIRE(format == isc_statsformat_file);
for (size_t i = 0; i < HASHSIZE(resolver->dhashbits); i++) {
- fctxcount_t *fc;
LOCK(&resolver->dbuckets[i].lock);
- for (fc = ISC_LIST_HEAD(resolver->dbuckets[i].list); fc != NULL;
- fc = ISC_LIST_NEXT(fc, link))
+ isc_ht_iter_t *it = NULL;
+ isc_result_t result;
+
+ isc_ht_iter_create(resolver->dbuckets[i].counters, &it);
+ for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
+ result = isc_ht_iter_next(it))
{
- dns_name_print(fc->domain, fp);
+ fctxcount_t *counter = NULL;
+ isc_ht_iter_current(it, (void **)&counter);
+ dns_name_print(counter->domain, fp);
fprintf(fp,
": %u active (%u spilled, %u "
"allowed)\n",
- fc->count, fc->dropped, fc->allowed);
+ counter->count, counter->dropped,
+ counter->allowed);
}
+ isc_ht_iter_destroy(&it);
UNLOCK(&resolver->dbuckets[i].lock);
}
}