CHECK(ns_interfacemgr_create(mctx, sctx, loopmgr, netmgr, dispatchmgr,
NULL, &interfacemgr));
- CHECK(dns_view_create(mctx, dispatchmgr, dns_rdataclass_in, "_default",
- &view));
+ CHECK(dns_view_create(mctx, loopmgr, dispatchmgr, dns_rdataclass_in,
+ "_default", &view));
CHECK(dns_cache_create(loopmgr, dns_rdataclass_in, "", mctx, &cache));
dns_view_setcache(view, cache, false);
dns_cache_detach(&cache);
}
INSIST(view == NULL);
- result = dns_view_create(named_g_mctx, named_g_dispatchmgr, viewclass,
- viewname, &view);
+ result = dns_view_create(named_g_mctx, named_g_loopmgr,
+ named_g_dispatchmgr, viewclass, viewname,
+ &view);
if (result != ISC_R_SUCCESS) {
return result;
}
RUNCHECK(dns_requestmgr_create(mctx, loopmgr, dispatchmgr, dispatchv4,
NULL, &requestmgr));
- RUNCHECK(dns_view_create(mctx, NULL, 0, "_test", &view));
+ RUNCHECK(dns_view_create(mctx, loopmgr, NULL, 0, "_test", &view));
isc_loopmgr_setup(loopmgr, sendqueries, NULL);
isc_loopmgr_teardown(loopmgr, teardown_view, view);
mctx, loopmgr, dispatchmgr, have_ipv4 ? dispatchvx : NULL,
have_ipv6 ? dispatchvx : NULL, &requestmgr));
- RUNCHECK(dns_view_create(mctx, NULL, 0, "_mdig", &view));
+ RUNCHECK(dns_view_create(mctx, loopmgr, NULL, 0, "_mdig", &view));
}
/*% Main processing routine for mdig */
isc_loopmgr_create(mctx, 1, &loopmgr);
- result = dns_view_create(mctx, NULL, dns_rdataclass_in, "view", &view);
+ result = dns_view_create(mctx, loopmgr, NULL, dns_rdataclass_in, "view",
+ &view);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "dns_view_create failed: %s\n",
isc_result_totext(result));
#include <inttypes.h>
#include <stdbool.h>
-#include <isc/atomic.h>
+#include <isc/async.h>
#include <isc/buffer.h>
#include <isc/hash.h>
#include <isc/log.h>
+#include <isc/loop.h>
#include <isc/mem.h>
#include <isc/mutex.h>
-#include <isc/refcount.h>
#include <isc/rwlock.h>
#include <isc/spinlock.h>
#include <isc/stdtime.h>
typedef struct dns_bcentry dns_bcentry_t;
+typedef struct dns_bckey {
+ const dns_name_t *name;
+ dns_rdatatype_t type;
+} dns__bckey_t;
+
struct dns_badcache {
unsigned int magic;
isc_mem_t *mctx;
struct cds_lfht *ht;
- atomic_bool purge_in_progress;
+ struct cds_list_head *lru;
+ uint32_t nloops;
};
#define BADCACHE_MAGIC ISC_MAGIC('B', 'd', 'C', 'a')
#define BADCACHE_MIN_SIZE (1 << 8) /* Must be power of 2 */
struct dns_bcentry {
- isc_mem_t *mctx;
- dns_rdatatype_t type;
- _Atomic(isc_stdtime_t) expire;
- atomic_uint_fast32_t flags;
- dns_fixedname_t fname;
- dns_name_t *name;
+ isc_loop_t *loop;
+ isc_stdtime_t expire;
+ uint32_t flags;
struct cds_lfht_node ht_node;
struct rcu_head rcu_head;
+ struct cds_list_head lru_head;
+
+ dns_name_t name;
+ dns_rdatatype_t type;
};
static void
static void
bcentry_destroy(struct rcu_head *rcu_head);
+static bool
+bcentry_alive(struct cds_lfht *ht, dns_bcentry_t *bad, isc_stdtime_t now);
+
dns_badcache_t *
-dns_badcache_new(isc_mem_t *mctx) {
- REQUIRE(mctx != NULL);
+dns_badcache_new(isc_mem_t *mctx, isc_loopmgr_t *loopmgr) {
+ REQUIRE(loopmgr != NULL);
+ uint32_t nloops = isc_loopmgr_nloops(loopmgr);
dns_badcache_t *bc = isc_mem_get(mctx, sizeof(*bc));
*bc = (dns_badcache_t){
.magic = BADCACHE_MAGIC,
+ .nloops = nloops,
};
bc->ht = cds_lfht_new(BADCACHE_INIT_SIZE, BADCACHE_MIN_SIZE, 0,
CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
INSIST(bc->ht != NULL);
+ 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]);
+ }
+
isc_mem_attach(mctx, &bc->mctx);
return bc;
}
RUNTIME_CHECK(!cds_lfht_destroy(bc->ht, NULL));
+ isc_mem_cput(bc->mctx, bc->lru, bc->nloops, sizeof(bc->lru[0]));
+
isc_mem_putanddetach(&bc->mctx, bc, sizeof(dns_badcache_t));
}
static int
-bcentry_match(struct cds_lfht_node *ht_node, const void *key) {
- const dns_name_t *name = key;
+bcentry_match(struct cds_lfht_node *ht_node, const void *key0) {
+ const dns__bckey_t *key = key0;
dns_bcentry_t *bad = caa_container_of(ht_node, dns_bcentry_t, ht_node);
- return dns_name_equal(bad->name, name);
+ 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);
}
static dns_bcentry_t *
-bcentry_new(dns_badcache_t *bc, const dns_name_t *name,
+bcentry_new(isc_loop_t *loop, const dns_name_t *name,
const dns_rdatatype_t type, const uint32_t flags,
const isc_stdtime_t expire) {
- dns_bcentry_t *bad = isc_mem_get(bc->mctx, sizeof(*bad));
+ isc_mem_t *mctx = isc_loop_getmctx(loop);
+ dns_bcentry_t *bad = isc_mem_get(mctx, sizeof(*bad));
*bad = (dns_bcentry_t){
.type = type,
.flags = flags,
.expire = expire,
+ .loop = isc_loop_ref(loop),
+ .lru_head = CDS_LIST_HEAD_INIT(bad->lru_head),
};
- isc_mem_attach(bc->mctx, &bad->mctx);
- bad->name = dns_fixedname_initname(&bad->fname);
- dns_name_copy(name, bad->name);
+ dns_name_init(&bad->name, NULL);
+ dns_name_dup(name, mctx, &bad->name);
return bad;
}
bcentry_destroy(struct rcu_head *rcu_head) {
dns_bcentry_t *bad = caa_container_of(rcu_head, dns_bcentry_t,
rcu_head);
+ isc_loop_t *loop = bad->loop;
+ isc_mem_t *mctx = isc_loop_getmctx(loop);
- isc_mem_putanddetach(&bad->mctx, bad, sizeof(*bad));
+ 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);
}
static void
bcentry_evict(struct cds_lfht *ht, dns_bcentry_t *bad) {
- /*
- * The hashtable isn't locked in a traditional sense, so multiple
- * threads can lookup and evict the same record at the same time.
- *
- * This is amplified by the bcentry_purge_next() that walks a few more
- * records in the hashtable and evicts them if they are expired.
- *
- * We need to destroy the bcentry only once - from the thread that has
- * deleted the entry from the hashtable, all other calls to this
- * function were redundant.
- */
if (!cds_lfht_del(ht, &bad->ht_node)) {
- call_rcu(&bad->rcu_head, bcentry_destroy);
+ if (bad->loop == isc_loop()) {
+ bcentry_evict_async(bad);
+ return;
+ }
+
+ isc_async_run(bad->loop, bcentry_evict_async, bad);
}
}
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;
- } else if (atomic_load_relaxed(&bad->expire) < now) {
+ } else if (bad->expire < now) {
bcentry_evict(ht, bad);
return false;
}
__typeof__(*(pos)), member))
static void
-bcentry_purge_next(struct cds_lfht *ht, struct cds_lfht_iter *iter,
- isc_stdtime_t now) {
- /* Lazy-purge the table */
+bcentry_purge(struct cds_lfht *ht, struct cds_list_head *lru,
+ isc_stdtime_t now) {
size_t count = 10;
dns_bcentry_t *bad;
- cds_lfht_for_each_entry_next(ht, iter, bad, ht_node) {
- if (!bcentry_alive(ht, bad, now)) {
+ cds_list_for_each_entry_rcu(bad, lru, lru_head) {
+ if (bcentry_alive(ht, bad, now)) {
break;
}
if (--count == 0) {
void
dns_badcache_add(dns_badcache_t *bc, const dns_name_t *name,
- dns_rdatatype_t type, bool update, uint32_t flags,
- isc_stdtime_t expire) {
+ dns_rdatatype_t type, uint32_t flags, isc_stdtime_t expire) {
REQUIRE(VALID_BADCACHE(bc));
REQUIRE(name != NULL);
+ isc_loop_t *loop = isc_loop();
+ uint32_t tid = isc_tid();
+ struct cds_list_head *lru = &bc->lru[tid];
+
isc_stdtime_t now = isc_stdtime_now();
if (expire < now) {
expire = now;
struct cds_lfht *ht = rcu_dereference(bc->ht);
INSIST(ht != NULL);
- dns_bcentry_t *bad = NULL;
- uint32_t hashval = dns_name_hash(name);
-
- struct cds_lfht_iter iter;
- dns_bcentry_t *found = NULL;
- cds_lfht_for_each_entry_duplicate(ht, hashval, bcentry_match, name,
- &iter, bad, ht_node) {
- if (bcentry_alive(ht, bad, now) && bad->type == type) {
- found = bad;
- /*
- * We could bail-out on first match, but:
- * 1. there could be duplicate .type entries
- * 2. we want to check expire for all entries
- */
+ 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);
}
- }
+ } while (ht_node != &bad->ht_node);
- if (found == NULL) {
- /*
- * In theory, this could result in multiple entries for the same
- * type, but we don't care much, as they are going to be roughly
- * the same, and the last will always trump and the former
- * entries will expire (see above).
- */
- bad = bcentry_new(bc, name, type, flags, expire);
- cds_lfht_add(ht, hashval, &bad->ht_node);
- } else if (update) {
- atomic_store_relaxed(&found->expire, expire);
- atomic_store_relaxed(&found->flags, flags);
- }
+ /* No locking, instead we are using per-thread lists */
+ cds_list_add_tail_rcu(&bad->lru_head, lru);
+
+ bcentry_purge(ht, lru, now);
rcu_read_unlock();
}
struct cds_lfht *ht = rcu_dereference(bc->ht);
INSIST(ht != NULL);
- dns_bcentry_t *bad = NULL;
- uint32_t hashval = dns_name_hash(name);
+ dns__bckey_t key = {
+ .name = name,
+ .type = type,
+ };
+ uint32_t hashval = bcentry_hash(&key);
- struct cds_lfht_iter iter;
- dns_bcentry_t *found = NULL;
- cds_lfht_for_each_entry_duplicate(ht, hashval, bcentry_match, name,
- &iter, bad, ht_node) {
- if (bad->type == type && bcentry_alive(ht, bad, now)) {
- found = bad;
- }
- }
+ dns_bcentry_t *found = bcentry_lookup(ht, hashval, &key);
- if (found) {
+ if (found != NULL && bcentry_alive(ht, found, now)) {
result = ISC_R_SUCCESS;
if (flagp != NULL) {
- *flagp = atomic_load_relaxed(&found->flags);
+ *flagp = found->flags;
}
-
- bcentry_purge_next(ht, &iter, now);
}
+ uint32_t tid = isc_tid();
+ struct cds_list_head *lru = &bc->lru[tid];
+ bcentry_purge(ht, lru, now);
+
rcu_read_unlock();
return result;
dns_badcache_flush(dns_badcache_t *bc) {
REQUIRE(VALID_BADCACHE(bc));
- struct cds_lfht *ht =
- cds_lfht_new(BADCACHE_INIT_SIZE, BADCACHE_MIN_SIZE, 0,
- CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
- INSIST(ht != NULL);
-
- /* First swap the hashtables */
rcu_read_lock();
- ht = rcu_xchg_pointer(&bc->ht, ht);
- rcu_read_unlock();
-
- /* Make sure nobody is using the old hash table */
- synchronize_rcu();
+ struct cds_lfht *ht = rcu_dereference(bc->ht);
+ INSIST(ht != NULL);
- /* Flush the old hash table */
- dns_bcentry_t *bad = NULL;
+ /* Flush the hash table */
+ dns_bcentry_t *bad;
struct cds_lfht_iter iter;
cds_lfht_for_each_entry(ht, &iter, bad, ht_node) {
- INSIST(!cds_lfht_del(ht, &bad->ht_node));
- bcentry_destroy(&bad->rcu_head);
+ bcentry_evict(ht, bad);
}
- RUNTIME_CHECK(!cds_lfht_destroy(ht, NULL));
+
+ rcu_read_unlock();
}
void
REQUIRE(VALID_BADCACHE(bc));
REQUIRE(name != NULL);
+ isc_stdtime_t now = isc_stdtime_now();
+
rcu_read_lock();
struct cds_lfht *ht = rcu_dereference(bc->ht);
INSIST(ht != NULL);
- dns_bcentry_t *bad = NULL;
- uint32_t hashval = dns_name_hash(name);
-
+ dns_bcentry_t *bad;
struct cds_lfht_iter iter;
- cds_lfht_for_each_entry_duplicate(ht, hashval, bcentry_match, name,
- &iter, bad, ht_node) {
- bcentry_evict(ht, bad);
+ 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);
}
rcu_read_unlock();
void
dns_badcache_flushtree(dns_badcache_t *bc, const dns_name_t *name) {
- dns_bcentry_t *bad;
- isc_stdtime_t now = isc_stdtime_now();
-
REQUIRE(VALID_BADCACHE(bc));
REQUIRE(name != NULL);
+ isc_stdtime_t now = isc_stdtime_now();
+
rcu_read_lock();
struct cds_lfht *ht = rcu_dereference(bc->ht);
INSIST(ht != NULL);
+ dns_bcentry_t *bad;
struct cds_lfht_iter iter;
cds_lfht_for_each_entry(ht, &iter, bad, ht_node) {
- if (dns_name_issubdomain(bad->name, name)) {
+ if (dns_name_issubdomain(&bad->name, name)) {
bcentry_evict(ht, bad);
- } else if (!bcentry_alive(ht, bad, now)) {
- /* Flush all the expired entries */
+ continue;
}
+
+ /* Flush all the expired entries */
+ (void)bcentry_alive(ht, bad, now);
}
rcu_read_unlock();
char namebuf[DNS_NAME_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
- dns_name_format(bad->name, namebuf, sizeof(namebuf));
+ dns_name_format(&bad->name, namebuf, sizeof(namebuf));
dns_rdatatype_format(bad->type, typebuf, sizeof(typebuf));
fprintf(fp, "; %s/%s [ttl %" PRIu32 "]\n", namebuf, typebuf,
- atomic_load_relaxed(&bad->expire) - now);
+ bad->expire - now);
}
void
#include <isc/async.h>
#include <isc/buffer.h>
+#include <isc/loop.h>
#include <isc/md.h>
#include <isc/mem.h>
#include <isc/mutex.h>
static isc_result_t
createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_nm_t *nm,
- isc_tlsctx_cache_t *tlsctx_client_cache,
+ isc_tlsctx_cache_t *tlsctx_client_cache, isc_loopmgr_t *loopmgr,
dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4,
dns_dispatch_t *dispatchv6, dns_view_t **viewp) {
isc_result_t result;
dns_view_t *view = NULL;
- result = dns_view_create(mctx, dispatchmgr, rdclass,
+ result = dns_view_create(mctx, loopmgr, dispatchmgr, rdclass,
DNS_CLIENTVIEW_NAME, &view);
if (result != ISC_R_SUCCESS) {
return result;
/* Create the default view for class IN */
result = createview(mctx, dns_rdataclass_in, nm, tlsctx_client_cache,
+ isc_loop_getloopmgr(client->loop),
client->dispatchmgr, dispatchv4, dispatchv6, &view);
if (result != ISC_R_SUCCESS) {
goto cleanup_references;
#include <inttypes.h>
#include <stdbool.h>
+#include <isc/loop.h>
#include <isc/mem.h>
#include <isc/stdtime.h>
***/
dns_badcache_t *
-dns_badcache_new(isc_mem_t *mctx);
+dns_badcache_new(isc_mem_t *mctx, isc_loopmgr_t *loopmgr);
/*%
* Allocate and initialize a badcache and store it in '*bcp'.
*
void
dns_badcache_add(dns_badcache_t *bc, const dns_name_t *name,
- dns_rdatatype_t type, bool update, uint32_t flags,
- isc_stdtime_t expire);
+ dns_rdatatype_t type, uint32_t flags, isc_stdtime_t expire);
/*%
- * Adds a badcache entry to the badcache 'bc' for name 'name' and
- * type 'type'. If an entry already exists, then it will be updated if
- * 'update' is true. The entry will be stored with flags 'flags'
- * and expiration date 'expire'.
+ * Adds a badcache entry to the badcache 'bc' for name 'name' and type 'type'.
+ * If an entry already exists, then it will be updated. The entry will be
+ * stored with flags 'flags' and expiration date 'expire'.
*
* Requires:
* \li bc to be a valid badcache.
* \li name != NULL
- * \li expire != NULL
*/
isc_result_t
#endif /* HAVE_LMDB */
isc_result_t
-dns_view_create(isc_mem_t *mctx, dns_dispatchmgr_t *dispmgr,
- dns_rdataclass_t rdclass, const char *name, dns_view_t **viewp);
+dns_view_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
+ dns_dispatchmgr_t *dispmgr, dns_rdataclass_t rdclass,
+ const char *name, dns_view_t **viewp);
/*%<
* Create a view.
*
#endif
isc_refcount_init(&res->references, 1);
- res->badcache = dns_badcache_new(res->mctx);
+ res->badcache = dns_badcache_new(res->mctx, res->loopmgr);
isc_hashmap_create(view->mctx, RES_DOMAIN_HASH_BITS, &res->fctxs);
isc_rwlock_init(&res->fctxs_lock);
dns_resolver_addbadcache(dns_resolver_t *resolver, const dns_name_t *name,
dns_rdatatype_t type, isc_time_t *expire) {
#ifdef ENABLE_AFL
- if (!dns_fuzzing_resolver)
-#endif /* ifdef ENABLE_AFL */
- {
- dns_badcache_add(resolver->badcache, name, type, false, 0,
- isc_time_seconds(expire));
+ if (dns_fuzzing_resolver) {
+ return;
}
+#endif /* ifdef ENABLE_AFL */
+
+ dns_badcache_add(resolver->badcache, name, type, 0,
+ isc_time_seconds(expire));
}
isc_result_t
#define DEFAULT_EDNS_BUFSIZE 1232
isc_result_t
-dns_view_create(isc_mem_t *mctx, dns_dispatchmgr_t *dispatchmgr,
- dns_rdataclass_t rdclass, const char *name,
- dns_view_t **viewp) {
+dns_view_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
+ dns_dispatchmgr_t *dispatchmgr, dns_rdataclass_t rdclass,
+ const char *name, dns_view_t **viewp) {
dns_view_t *view = NULL;
isc_result_t result;
char buffer[1024];
dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
- view->failcache = dns_badcache_new(view->mctx);
+ view->failcache = dns_badcache_new(view->mctx, loopmgr);
isc_mutex_init(&view->new_zone_lock);
if (result == ISC_R_SUCCESS) {
dns_badcache_add(client->view->failcache,
client->query.qname,
- client->query.qtype, true, flags,
+ client->query.qtype, flags,
isc_time_seconds(&expire));
}
}
dns_name_fromstring(name, "example.com.", NULL, 0, NULL);
- bc = dns_badcache_new(mctx);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now + 60);
+ bc = dns_badcache_new(mctx, loopmgr);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now + 60);
flags = 0;
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags, now);
dns_name_fromstring(name, "example.com.", NULL, 0, NULL);
- bc = dns_badcache_new(mctx);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now + 60);
- dns_badcache_add(bc, name, dns_rdatatype_a, false, flags, now + 60);
+ bc = dns_badcache_new(mctx, loopmgr);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now + 60);
+ dns_badcache_add(bc, name, dns_rdatatype_a, flags, now + 60);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags, now);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_NOTFOUND);
result = dns_badcache_find(bc, name, dns_rdatatype_a, &flags, now);
- assert_int_equal(result, ISC_R_SUCCESS);
- assert_int_equal(flags, BADCACHE_TEST_FLAG);
+ assert_int_equal(result, ISC_R_NOTFOUND);
- dns_badcache_add(bc, name, dns_rdatatype_a, true, flags, now + 120);
+ dns_badcache_add(bc, name, dns_rdatatype_a, flags, now + 120);
result = dns_badcache_find(bc, name, dns_rdatatype_a, &flags, now + 61);
assert_int_equal(result, ISC_R_SUCCESS);
size_t len;
char *pos;
char *endptr;
- const char *part1 = ";\n; badcache\n;\n; example.com/A [ttl ";
- const char *part2 = "]\n; example.com/AAAA [ttl ";
- const char *part3 = "]\n";
+ const char *header_part = ";\n; badcache\n;\n";
+ const char *bol_part = "; ";
+ const char *name_part = "example.com/";
+ const char *ttl_part = " [ttl ";
+ const char *eol_part = "]\n";
+ size_t num_a = 0;
+ bool seen_a = false, seen_aaaa = false;
long ttl;
dns_name_fromstring(name, "example.com.", NULL, 0, NULL);
- bc = dns_badcache_new(mctx);
- dns_badcache_add(bc, name, dns_rdatatype_a, false, flags, expire);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, expire);
+ bc = dns_badcache_new(mctx, loopmgr);
+ dns_badcache_add(bc, name, dns_rdatatype_a, flags, expire);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, expire);
file = fopen("./badcache.out", "w");
dns_badcache_print(bc, "badcache", file);
fclose(file);
pos = buf;
- assert_memory_equal(pos, part1, strlen(part1));
- pos += strlen(part1);
+ assert_memory_equal(pos, header_part, strlen(header_part));
+ pos += strlen(header_part);
+
+line:
+ /* There's no fixed order for A and AAAA types in the hash table */
+ assert_memory_equal(pos, bol_part, strlen(bol_part));
+ pos += strlen(bol_part);
+
+ assert_memory_equal(pos, name_part, strlen(name_part));
+ pos += strlen(name_part);
+
+ num_a = 0;
+ while (*pos == 'A') {
+ num_a++;
+ pos++;
+ }
+ switch (num_a) {
+ case 1:
+ seen_a = true;
+ break;
+ case 4:
+ seen_aaaa = true;
+ break;
+ default:
+ assert_true(num_a == 1 || num_a == 4);
+ }
+
+ assert_memory_equal(pos, ttl_part, strlen(ttl_part));
+ pos += strlen(ttl_part);
ttl = strtol(pos, &endptr, 0);
assert_ptr_not_equal(pos, endptr);
assert_true(ttl >= 0 && ttl <= 60);
pos = endptr;
- assert_memory_equal(pos, part2, strlen(part2));
- pos += strlen(part2);
-
- ttl = strtol(pos, &endptr, 0);
- assert_ptr_not_equal(pos, endptr);
- assert_true(ttl >= 0 && ttl <= 60);
- pos = endptr;
+ assert_memory_equal(pos, eol_part, strlen(eol_part));
+ pos += strlen(eol_part);
- assert_memory_equal(pos, part3, strlen(part3));
- pos += strlen(part3);
+ if (!seen_a || !seen_aaaa) {
+ goto line;
+ }
assert_int_equal(pos - buf, len);
dns_name_fromstring(name, "example.com.", NULL, 0, NULL);
- bc = dns_badcache_new(mctx);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now + 60);
+ bc = dns_badcache_new(mctx, loopmgr);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now + 60);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags, now);
assert_int_equal(result, ISC_R_SUCCESS);
isc_result_t result;
uint32_t flags = BADCACHE_TEST_FLAG;
- bc = dns_badcache_new(mctx);
+ bc = dns_badcache_new(mctx, loopmgr);
dns_name_fromstring(name, "example.com.", NULL, 0, NULL);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now + 60);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now + 60);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags, now);
assert_int_equal(result, ISC_R_SUCCESS);
dns_name_fromstring(name, "sub.example.com.", NULL, 0, NULL);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now + 60);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now + 60);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags, now);
assert_int_equal(result, ISC_R_SUCCESS);
dns_name_fromstring(name, "sub.sub.example.com.", NULL, 0, NULL);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now + 60);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now + 60);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags, now);
assert_int_equal(result, ISC_R_SUCCESS);
isc_result_t result;
uint32_t flags = BADCACHE_TEST_FLAG;
- bc = dns_badcache_new(mctx);
+ bc = dns_badcache_new(mctx, loopmgr);
dns_name_fromstring(name, "example.com.", NULL, 0, NULL);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now + 60);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now + 60);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags, now);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(flags, BADCACHE_TEST_FLAG);
dns_name_fromstring(name, "sub.example.com.", NULL, 0, NULL);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now + 60);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now + 60);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags, now);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(flags, BADCACHE_TEST_FLAG);
dns_name_fromstring(name, "sub.sub.example.com.", NULL, 0, NULL);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now + 60);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now + 60);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags, now);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(flags, BADCACHE_TEST_FLAG);
isc_result_t result;
uint32_t flags = BADCACHE_TEST_FLAG;
- bc = dns_badcache_new(mctx);
+ bc = dns_badcache_new(mctx, loopmgr);
dns_name_fromstring(name, "example.com.", NULL, 0, NULL);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags,
now - 60);
assert_int_equal(result, ISC_R_SUCCESS);
dns_name_fromstring(name, "sub.example.com.", NULL, 0, NULL);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags,
now - 60);
assert_int_equal(result, ISC_R_SUCCESS);
dns_name_fromstring(name, "sub.sub.example.com.", NULL, 0, NULL);
- dns_badcache_add(bc, name, dns_rdatatype_aaaa, false, flags, now);
+ dns_badcache_add(bc, name, dns_rdatatype_aaaa, flags, now);
result = dns_badcache_find(bc, name, dns_rdatatype_aaaa, &flags,
now - 60);
assert_int_equal(result, ISC_R_SUCCESS);
#define TAPSAVED TESTS_DIR "/testdata/dnstap/dnstap.saved"
#define TAPTEXT TESTS_DIR "/testdata/dnstap/dnstap.text"
-static int
+static void
cleanup(void **state ISC_ATTR_UNUSED) {
(void)isc_file_remove(TAPFILE);
(void)isc_file_remove(TAPSOCK);
-
- return 0;
}
static int
* the testdata was originally generated.
*/
setenv("TZ", "PDT8", 1);
+
+ setup_loopmgr(state);
+
+ return 0;
+}
+
+static int
+teardown(void **state) {
+ cleanup(state);
+
+ teardown_loopmgr(state);
+
return 0;
}
/* set up dnstap environment */
-ISC_RUN_TEST_IMPL(dns_dt_create) {
+ISC_LOOP_TEST_IMPL(dns_dt_create) {
isc_result_t result;
dns_dtenv_t *dtenv = NULL;
struct fstrm_iothr_options *fopt;
if (fopt != NULL) {
fstrm_iothr_options_destroy(&fopt);
}
+
+ isc_loopmgr_shutdown(loopmgr);
}
/* send dnstap messages */
-ISC_RUN_TEST_IMPL(dns_dt_send) {
+ISC_LOOP_TEST_IMPL(dns_dt_send) {
isc_result_t result;
dns_dtenv_t *dtenv = NULL;
dns_dthandle_t *handle = NULL;
if (handle != NULL) {
dns_dt_close(&handle);
}
+
+ isc_loopmgr_shutdown(loopmgr);
}
/* dnstap message to text */
-ISC_RUN_TEST_IMPL(dns_dt_totext) {
+ISC_LOOP_TEST_IMPL(dns_dt_totext) {
isc_result_t result;
dns_dthandle_t *handle = NULL;
uint8_t *data;
size_t dsize;
FILE *fp = NULL;
- UNUSED(state);
-
result = dns_dt_open(TAPSAVED, dns_dtmode_file, mctx, &handle);
assert_int_equal(result, ISC_R_SUCCESS);
if (handle != NULL) {
dns_dt_close(&handle);
}
+ isc_loopmgr_shutdown(loopmgr);
}
ISC_TEST_LIST_START
-ISC_TEST_ENTRY_CUSTOM(dns_dt_create, setup, cleanup)
-ISC_TEST_ENTRY_CUSTOM(dns_dt_send, setup, cleanup)
-ISC_TEST_ENTRY_CUSTOM(dns_dt_totext, setup, cleanup)
+ISC_TEST_ENTRY_CUSTOM(dns_dt_create, setup, teardown)
+ISC_TEST_ENTRY_CUSTOM(dns_dt_send, setup, teardown)
+ISC_TEST_ENTRY_CUSTOM(dns_dt_totext, setup, teardown)
ISC_TEST_LIST_END
}
}
- result = dns_view_create(mctx, dispatchmgr, dns_rdataclass_in, name,
- &view);
+ result = dns_view_create(mctx, loopmgr, dispatchmgr, dns_rdataclass_in,
+ name, &view);
if (dispatchmgr != NULL) {
dns_dispatchmgr_detach(&dispatchmgr);
assert_int_equal(result, ISC_R_SUCCESS);
dns_badcache_add(qctx->client->view->failcache, dns_rootname,
- dns_rdatatype_ns, true,
- test->cache_entry_flags,
+ dns_rdatatype_ns, test->cache_entry_flags,
isc_time_seconds(&expire));
}