2014-09-03 23:28:14 -07:00
|
|
|
/*
|
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
2021-06-03 08:37:05 +02:00
|
|
|
*
|
2014-09-03 23:28:14 -07: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
|
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
2014-09-03 23:28:14 -07:00
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
2016-03-04 11:12:23 +05:30
|
|
|
* information regarding copyright ownership.
|
2014-09-03 23:28:14 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*! \file */
|
|
|
|
|
2018-03-28 14:56:40 +02:00
|
|
|
#include <inttypes.h>
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
2018-03-28 14:56:40 +02:00
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
#include <isc/async.h>
|
2014-09-03 23:28:14 -07:00
|
|
|
#include <isc/buffer.h>
|
|
|
|
#include <isc/hash.h>
|
|
|
|
#include <isc/log.h>
|
2024-11-14 19:51:29 +01:00
|
|
|
#include <isc/loop.h>
|
2014-09-03 23:28:14 -07:00
|
|
|
#include <isc/mem.h>
|
|
|
|
#include <isc/mutex.h>
|
2020-02-17 10:37:39 +01:00
|
|
|
#include <isc/rwlock.h>
|
2023-06-19 15:43:02 +02:00
|
|
|
#include <isc/spinlock.h>
|
|
|
|
#include <isc/stdtime.h>
|
2014-09-03 23:28:14 -07:00
|
|
|
#include <isc/string.h>
|
2023-06-19 15:43:02 +02:00
|
|
|
#include <isc/thread.h>
|
2014-09-03 23:28:14 -07:00
|
|
|
#include <isc/time.h>
|
2023-06-19 15:43:02 +02:00
|
|
|
#include <isc/urcu.h>
|
2014-09-03 23:28:14 -07:00
|
|
|
#include <isc/util.h>
|
|
|
|
|
|
|
|
#include <dns/badcache.h>
|
2021-05-21 17:10:59 -07:00
|
|
|
#include <dns/fixedname.h>
|
2014-09-03 23:28:14 -07:00
|
|
|
#include <dns/name.h>
|
|
|
|
#include <dns/rdatatype.h>
|
|
|
|
#include <dns/types.h>
|
|
|
|
|
|
|
|
typedef struct dns_bcentry dns_bcentry_t;
|
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
typedef struct dns_bckey {
|
|
|
|
const dns_name_t *name;
|
|
|
|
dns_rdatatype_t type;
|
|
|
|
} dns__bckey_t;
|
|
|
|
|
2014-09-03 23:28:14 -07:00
|
|
|
struct dns_badcache {
|
|
|
|
unsigned int magic;
|
|
|
|
isc_mem_t *mctx;
|
2023-06-19 15:43:02 +02:00
|
|
|
struct cds_lfht *ht;
|
2024-11-14 19:51:29 +01:00
|
|
|
struct cds_list_head *lru;
|
|
|
|
uint32_t nloops;
|
2014-09-03 23:28:14 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
#define BADCACHE_MAGIC ISC_MAGIC('B', 'd', 'C', 'a')
|
|
|
|
#define VALID_BADCACHE(m) ISC_MAGIC_VALID(m, BADCACHE_MAGIC)
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
#define BADCACHE_INIT_SIZE (1 << 10) /* Must be power of 2 */
|
|
|
|
#define BADCACHE_MIN_SIZE (1 << 8) /* Must be power of 2 */
|
|
|
|
|
2014-09-03 23:28:14 -07:00
|
|
|
struct dns_bcentry {
|
2024-11-14 19:51:29 +01:00
|
|
|
isc_loop_t *loop;
|
|
|
|
isc_stdtime_t expire;
|
|
|
|
uint32_t flags;
|
2023-06-19 15:43:02 +02:00
|
|
|
|
|
|
|
struct cds_lfht_node ht_node;
|
|
|
|
struct rcu_head rcu_head;
|
2024-11-14 19:51:29 +01:00
|
|
|
struct cds_list_head lru_head;
|
|
|
|
|
|
|
|
dns_name_t name;
|
|
|
|
dns_rdatatype_t type;
|
2014-09-03 23:28:14 -07:00
|
|
|
};
|
|
|
|
|
2020-02-17 10:37:39 +01:00
|
|
|
static void
|
2023-06-19 15:43:02 +02:00
|
|
|
bcentry_print(dns_bcentry_t *bad, isc_stdtime_t now, FILE *fp);
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
static void
|
|
|
|
bcentry_destroy(struct rcu_head *rcu_head);
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
static bool
|
|
|
|
bcentry_alive(struct cds_lfht *ht, dns_bcentry_t *bad, isc_stdtime_t now);
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
dns_badcache_t *
|
2025-07-14 10:50:21 +02:00
|
|
|
dns_badcache_new(isc_mem_t *mctx) {
|
|
|
|
uint32_t nloops = isc_loopmgr_nloops();
|
2023-06-19 15:43:02 +02:00
|
|
|
dns_badcache_t *bc = isc_mem_get(mctx, sizeof(*bc));
|
2022-08-26 11:58:51 +02:00
|
|
|
*bc = (dns_badcache_t){
|
2023-06-19 15:43:02 +02:00
|
|
|
.magic = BADCACHE_MAGIC,
|
2024-11-14 19:51:29 +01:00
|
|
|
.nloops = nloops,
|
2022-08-26 11:58:51 +02:00
|
|
|
};
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
bc->ht = cds_lfht_new(BADCACHE_INIT_SIZE, BADCACHE_MIN_SIZE, 0,
|
|
|
|
CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
|
|
|
|
INSIST(bc->ht != NULL);
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
bc->lru = isc_mem_cget(mctx, bc->nloops, sizeof(bc->lru[0]));
|
|
|
|
for (size_t i = 0; i < bc->nloops; i++) {
|
|
|
|
CDS_INIT_LIST_HEAD(&bc->lru[i]);
|
|
|
|
}
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
isc_mem_attach(mctx, &bc->mctx);
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
return bc;
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_badcache_destroy(dns_badcache_t **bcp) {
|
|
|
|
REQUIRE(bcp != NULL && *bcp != NULL);
|
2023-06-19 15:43:02 +02:00
|
|
|
REQUIRE(VALID_BADCACHE(*bcp));
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
dns_badcache_t *bc = *bcp;
|
|
|
|
*bcp = NULL;
|
2014-09-03 23:28:14 -07:00
|
|
|
bc->magic = 0;
|
2023-06-19 15:43:02 +02:00
|
|
|
|
|
|
|
dns_bcentry_t *bad = NULL;
|
|
|
|
struct cds_lfht_iter iter;
|
|
|
|
cds_lfht_for_each_entry(bc->ht, &iter, bad, ht_node) {
|
|
|
|
INSIST(!cds_lfht_del(bc->ht, &bad->ht_node));
|
|
|
|
bcentry_destroy(&bad->rcu_head);
|
2020-02-17 10:37:39 +01:00
|
|
|
}
|
2023-06-19 15:43:02 +02:00
|
|
|
RUNTIME_CHECK(!cds_lfht_destroy(bc->ht, NULL));
|
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
isc_mem_cput(bc->mctx, bc->lru, bc->nloops, sizeof(bc->lru[0]));
|
|
|
|
|
2014-09-03 23:28:14 -07:00
|
|
|
isc_mem_putanddetach(&bc->mctx, bc, sizeof(dns_badcache_t));
|
|
|
|
}
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
static int
|
2024-11-14 19:51:29 +01:00
|
|
|
bcentry_match(struct cds_lfht_node *ht_node, const void *key0) {
|
|
|
|
const dns__bckey_t *key = key0;
|
2023-06-19 15:43:02 +02:00
|
|
|
dns_bcentry_t *bad = caa_container_of(ht_node, dns_bcentry_t, ht_node);
|
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
return (bad->type == key->type) &&
|
|
|
|
dns_name_equal(&bad->name, key->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t
|
|
|
|
bcentry_hash(const dns__bckey_t *key) {
|
|
|
|
isc_hash32_t state;
|
|
|
|
isc_hash32_init(&state);
|
|
|
|
isc_hash32_hash(&state, key->name->ndata, key->name->length, false);
|
|
|
|
isc_hash32_hash(&state, &key->type, sizeof(key->type), true);
|
|
|
|
return isc_hash32_finalize(&state);
|
|
|
|
}
|
|
|
|
|
|
|
|
static dns_bcentry_t *
|
|
|
|
bcentry_lookup(struct cds_lfht *ht, uint32_t hashval, dns__bckey_t *key) {
|
|
|
|
struct cds_lfht_iter iter;
|
|
|
|
|
|
|
|
cds_lfht_lookup(ht, hashval, bcentry_match, key, &iter);
|
|
|
|
|
|
|
|
return cds_lfht_entry(cds_lfht_iter_get_node(&iter), dns_bcentry_t,
|
|
|
|
ht_node);
|
2023-06-19 15:43:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static dns_bcentry_t *
|
2024-11-14 19:51:29 +01:00
|
|
|
bcentry_new(isc_loop_t *loop, const dns_name_t *name,
|
2023-06-19 15:43:02 +02:00
|
|
|
const dns_rdatatype_t type, const uint32_t flags,
|
|
|
|
const isc_stdtime_t expire) {
|
2024-11-14 19:51:29 +01:00
|
|
|
isc_mem_t *mctx = isc_loop_getmctx(loop);
|
|
|
|
dns_bcentry_t *bad = isc_mem_get(mctx, sizeof(*bad));
|
2023-06-19 15:43:02 +02:00
|
|
|
*bad = (dns_bcentry_t){
|
|
|
|
.type = type,
|
|
|
|
.flags = flags,
|
|
|
|
.expire = expire,
|
2024-11-14 19:51:29 +01:00
|
|
|
.loop = isc_loop_ref(loop),
|
|
|
|
.lru_head = CDS_LIST_HEAD_INIT(bad->lru_head),
|
2023-06-19 15:43:02 +02:00
|
|
|
};
|
|
|
|
|
2025-02-21 12:09:39 +01:00
|
|
|
dns_name_init(&bad->name);
|
2024-11-14 19:51:29 +01:00
|
|
|
dns_name_dup(name, mctx, &bad->name);
|
2023-06-19 15:43:02 +02:00
|
|
|
|
|
|
|
return bad;
|
|
|
|
}
|
|
|
|
|
2020-02-17 10:37:39 +01:00
|
|
|
static void
|
2023-06-19 15:43:02 +02:00
|
|
|
bcentry_destroy(struct rcu_head *rcu_head) {
|
|
|
|
dns_bcentry_t *bad = caa_container_of(rcu_head, dns_bcentry_t,
|
|
|
|
rcu_head);
|
2024-11-14 19:51:29 +01:00
|
|
|
isc_loop_t *loop = bad->loop;
|
|
|
|
isc_mem_t *mctx = isc_loop_getmctx(loop);
|
2020-02-17 10:37:39 +01:00
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
dns_name_free(&bad->name, mctx);
|
|
|
|
isc_mem_put(mctx, bad, sizeof(*bad));
|
|
|
|
|
|
|
|
isc_loop_unref(loop);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bcentry_evict_async(void *arg) {
|
|
|
|
dns_bcentry_t *bad = arg;
|
|
|
|
|
|
|
|
RUNTIME_CHECK(bad->loop == isc_loop());
|
|
|
|
|
|
|
|
cds_list_del(&bad->lru_head);
|
|
|
|
call_rcu(&bad->rcu_head, bcentry_destroy);
|
2023-06-19 15:43:02 +02:00
|
|
|
}
|
2020-02-17 10:37:39 +01:00
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
static void
|
|
|
|
bcentry_evict(struct cds_lfht *ht, dns_bcentry_t *bad) {
|
|
|
|
if (!cds_lfht_del(ht, &bad->ht_node)) {
|
2024-11-14 19:51:29 +01:00
|
|
|
if (bad->loop == isc_loop()) {
|
|
|
|
bcentry_evict_async(bad);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_async_run(bad->loop, bcentry_evict_async, bad);
|
2020-02-17 10:37:39 +01:00
|
|
|
}
|
2023-06-19 15:43:02 +02:00
|
|
|
}
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
static bool
|
|
|
|
bcentry_alive(struct cds_lfht *ht, dns_bcentry_t *bad, isc_stdtime_t now) {
|
|
|
|
if (cds_lfht_is_node_deleted(&bad->ht_node)) {
|
|
|
|
return false;
|
2024-11-14 19:51:29 +01:00
|
|
|
} else if (bad->expire < now) {
|
2023-06-19 15:43:02 +02:00
|
|
|
bcentry_evict(ht, bad);
|
|
|
|
return false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
return true;
|
|
|
|
}
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
#define cds_lfht_for_each_entry_next(ht, iter, pos, member) \
|
|
|
|
for (cds_lfht_next(ht, iter), \
|
|
|
|
pos = cds_lfht_entry(cds_lfht_iter_get_node(iter), \
|
|
|
|
__typeof__(*(pos)), member); \
|
|
|
|
pos != NULL; /**/ \
|
|
|
|
cds_lfht_next(ht, iter), \
|
|
|
|
pos = cds_lfht_entry(cds_lfht_iter_get_node(iter), \
|
|
|
|
__typeof__(*(pos)), member))
|
2020-02-17 10:37:39 +01:00
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
static void
|
2024-11-14 19:51:29 +01:00
|
|
|
bcentry_purge(struct cds_lfht *ht, struct cds_list_head *lru,
|
|
|
|
isc_stdtime_t now) {
|
2023-06-19 15:43:02 +02:00
|
|
|
size_t count = 10;
|
|
|
|
dns_bcentry_t *bad;
|
2024-11-14 19:51:29 +01:00
|
|
|
cds_list_for_each_entry_rcu(bad, lru, lru_head) {
|
|
|
|
if (bcentry_alive(ht, bad, now)) {
|
2023-06-19 15:43:02 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (--count == 0) {
|
|
|
|
break;
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_badcache_add(dns_badcache_t *bc, const dns_name_t *name,
|
2024-11-14 19:51:29 +01:00
|
|
|
dns_rdatatype_t type, uint32_t flags, isc_stdtime_t expire) {
|
2014-09-03 23:28:14 -07:00
|
|
|
REQUIRE(VALID_BADCACHE(bc));
|
|
|
|
REQUIRE(name != NULL);
|
2023-06-19 15:43:02 +02:00
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
isc_loop_t *loop = isc_loop();
|
2025-06-04 17:54:20 +02:00
|
|
|
isc_tid_t tid = isc_tid();
|
2024-11-14 19:51:29 +01:00
|
|
|
struct cds_list_head *lru = &bc->lru[tid];
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
isc_stdtime_t now = isc_stdtime_now();
|
|
|
|
if (expire < now) {
|
|
|
|
expire = now;
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
rcu_read_lock();
|
|
|
|
struct cds_lfht *ht = rcu_dereference(bc->ht);
|
|
|
|
INSIST(ht != NULL);
|
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
dns__bckey_t key = {
|
|
|
|
.name = name,
|
|
|
|
.type = type,
|
|
|
|
};
|
|
|
|
uint32_t hashval = bcentry_hash(&key);
|
|
|
|
|
|
|
|
/* struct cds_lfht_iter iter; */
|
|
|
|
dns_bcentry_t *bad = bcentry_new(loop, name, type, flags, expire);
|
|
|
|
struct cds_lfht_node *ht_node;
|
|
|
|
do {
|
|
|
|
ht_node = cds_lfht_add_unique(ht, hashval, bcentry_match, &key,
|
|
|
|
&bad->ht_node);
|
|
|
|
if (ht_node != &bad->ht_node) {
|
|
|
|
dns_bcentry_t *found = caa_container_of(
|
|
|
|
ht_node, dns_bcentry_t, ht_node);
|
|
|
|
bcentry_evict(ht, found);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2024-11-14 19:51:29 +01:00
|
|
|
} while (ht_node != &bad->ht_node);
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
/* No locking, instead we are using per-thread lists */
|
|
|
|
cds_list_add_tail_rcu(&bad->lru_head, lru);
|
|
|
|
|
|
|
|
bcentry_purge(ht, lru, now);
|
2023-06-19 15:43:02 +02:00
|
|
|
|
|
|
|
rcu_read_unlock();
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_badcache_find(dns_badcache_t *bc, const dns_name_t *name,
|
2023-06-19 15:43:02 +02:00
|
|
|
dns_rdatatype_t type, uint32_t *flagp, isc_stdtime_t now) {
|
2014-09-03 23:28:14 -07:00
|
|
|
REQUIRE(VALID_BADCACHE(bc));
|
|
|
|
REQUIRE(name != NULL);
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
isc_result_t result = ISC_R_NOTFOUND;
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
rcu_read_lock();
|
|
|
|
struct cds_lfht *ht = rcu_dereference(bc->ht);
|
|
|
|
INSIST(ht != NULL);
|
2016-03-04 11:12:23 +05:30
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
dns__bckey_t key = {
|
|
|
|
.name = name,
|
|
|
|
.type = type,
|
|
|
|
};
|
|
|
|
uint32_t hashval = bcentry_hash(&key);
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
dns_bcentry_t *found = bcentry_lookup(ht, hashval, &key);
|
2014-09-03 23:28:14 -07:00
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
if (found != NULL && bcentry_alive(ht, found, now)) {
|
2023-06-19 15:43:02 +02:00
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
if (flagp != NULL) {
|
2024-11-14 19:51:29 +01:00
|
|
|
*flagp = found->flags;
|
2020-02-17 10:37:39 +01:00
|
|
|
}
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
|
2025-06-04 17:54:20 +02:00
|
|
|
isc_tid_t tid = isc_tid();
|
2024-11-14 19:51:29 +01:00
|
|
|
struct cds_list_head *lru = &bc->lru[tid];
|
|
|
|
bcentry_purge(ht, lru, now);
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
rcu_read_unlock();
|
|
|
|
|
|
|
|
return result;
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_badcache_flush(dns_badcache_t *bc) {
|
|
|
|
REQUIRE(VALID_BADCACHE(bc));
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
rcu_read_lock();
|
2024-11-14 19:51:29 +01:00
|
|
|
struct cds_lfht *ht = rcu_dereference(bc->ht);
|
|
|
|
INSIST(ht != NULL);
|
2023-06-19 15:43:02 +02:00
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
/* Flush the hash table */
|
|
|
|
dns_bcentry_t *bad;
|
2023-06-19 15:43:02 +02:00
|
|
|
struct cds_lfht_iter iter;
|
|
|
|
cds_lfht_for_each_entry(ht, &iter, bad, ht_node) {
|
2024-11-14 19:51:29 +01:00
|
|
|
bcentry_evict(ht, bad);
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
2024-11-14 19:51:29 +01:00
|
|
|
|
|
|
|
rcu_read_unlock();
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_badcache_flushname(dns_badcache_t *bc, const dns_name_t *name) {
|
2014-09-03 23:28:14 -07:00
|
|
|
REQUIRE(VALID_BADCACHE(bc));
|
|
|
|
REQUIRE(name != NULL);
|
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
isc_stdtime_t now = isc_stdtime_now();
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
rcu_read_lock();
|
|
|
|
struct cds_lfht *ht = rcu_dereference(bc->ht);
|
|
|
|
INSIST(ht != NULL);
|
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
dns_bcentry_t *bad;
|
2023-06-19 15:43:02 +02:00
|
|
|
struct cds_lfht_iter iter;
|
2024-11-14 19:51:29 +01:00
|
|
|
cds_lfht_for_each_entry(ht, &iter, bad, ht_node) {
|
|
|
|
if (dns_name_equal(&bad->name, name)) {
|
|
|
|
bcentry_evict(ht, bad);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Flush all the expired entries */
|
|
|
|
(void)bcentry_alive(ht, bad, now);
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
rcu_read_unlock();
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_badcache_flushtree(dns_badcache_t *bc, const dns_name_t *name) {
|
2014-09-03 23:28:14 -07:00
|
|
|
REQUIRE(VALID_BADCACHE(bc));
|
|
|
|
REQUIRE(name != NULL);
|
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
isc_stdtime_t now = isc_stdtime_now();
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
rcu_read_lock();
|
|
|
|
struct cds_lfht *ht = rcu_dereference(bc->ht);
|
|
|
|
INSIST(ht != NULL);
|
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
dns_bcentry_t *bad;
|
2023-06-19 15:43:02 +02:00
|
|
|
struct cds_lfht_iter iter;
|
|
|
|
cds_lfht_for_each_entry(ht, &iter, bad, ht_node) {
|
2024-11-14 19:51:29 +01:00
|
|
|
if (dns_name_issubdomain(&bad->name, name)) {
|
2023-06-19 15:43:02 +02:00
|
|
|
bcentry_evict(ht, bad);
|
2024-11-14 19:51:29 +01:00
|
|
|
continue;
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
2024-11-14 19:51:29 +01:00
|
|
|
|
|
|
|
/* Flush all the expired entries */
|
|
|
|
(void)bcentry_alive(ht, bad, now);
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
rcu_read_unlock();
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
static void
|
|
|
|
bcentry_print(dns_bcentry_t *bad, isc_stdtime_t now, FILE *fp) {
|
2014-09-03 23:28:14 -07:00
|
|
|
char namebuf[DNS_NAME_FORMATSIZE];
|
|
|
|
char typebuf[DNS_RDATATYPE_FORMATSIZE];
|
2023-06-19 15:43:02 +02:00
|
|
|
|
2024-11-14 19:51:29 +01:00
|
|
|
dns_name_format(&bad->name, namebuf, sizeof(namebuf));
|
2023-06-19 15:43:02 +02:00
|
|
|
dns_rdatatype_format(bad->type, typebuf, sizeof(typebuf));
|
|
|
|
fprintf(fp, "; %s/%s [ttl %" PRIu32 "]\n", namebuf, typebuf,
|
2024-11-14 19:51:29 +01:00
|
|
|
bad->expire - now);
|
2023-06-19 15:43:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_badcache_print(dns_badcache_t *bc, const char *cachename, FILE *fp) {
|
|
|
|
dns_bcentry_t *bad;
|
|
|
|
isc_stdtime_t now = isc_stdtime_now();
|
2014-09-03 23:28:14 -07:00
|
|
|
|
|
|
|
REQUIRE(VALID_BADCACHE(bc));
|
|
|
|
REQUIRE(fp != NULL);
|
|
|
|
|
|
|
|
fprintf(fp, ";\n; %s\n;\n", cachename);
|
|
|
|
|
2023-06-19 15:43:02 +02:00
|
|
|
rcu_read_lock();
|
|
|
|
struct cds_lfht *ht = rcu_dereference(bc->ht);
|
|
|
|
INSIST(ht != NULL);
|
|
|
|
|
|
|
|
struct cds_lfht_iter iter;
|
|
|
|
cds_lfht_for_each_entry(ht, &iter, bad, ht_node) {
|
|
|
|
if (bcentry_alive(ht, bad, now)) {
|
|
|
|
bcentry_print(bad, now, fp);
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|
|
|
|
}
|
2023-06-19 15:43:02 +02:00
|
|
|
|
|
|
|
rcu_read_unlock();
|
2014-09-03 23:28:14 -07:00
|
|
|
}
|