*
* This value must be coordinated with CLEAN_SECONDS (below).
*/
-#define NBUCKETS 101 /* how many buckets for names/addrs */
+#define NBUCKETS 1009 /* how many buckets for names/addrs */
+
+/*
+ * For type 3 negative cache entries, we will remember that the address is
+ * broken for this long.
+ */
+#define ADB_NCACHE_MINIMUM 600 /* seconds */
/*
* Clean one bucket every CLEAN_SECONDS.
*/
#define CLEAN_SECONDS (300 / NBUCKETS)
+#if CLEAN_SECONDS < 1
+#undef CLEAN_SECONDS
+#define CLEAN_SECONDS 1
+#endif
#define FREE_ITEMS 16 /* free count for memory pools */
#define FILL_COUNT 8 /* fill count for memory pools */
#define EXIT_LEVEL ENTER_LEVEL
#define CLEAN_LEVEL 100
#define DEF_LEVEL 5
+#define NCACHE_LEVEL 20
#define NCACHE_RESULT(r) ((r) == DNS_R_NCACHENXDOMAIN || \
(r) == DNS_R_NCACHENXRRSET)
addr_bucket = DNS_ADB_INVALIDBUCKET;
new_addresses_added = ISC_FALSE;
+ nh = NULL;
result = dns_rdataset_first(rdataset);
while (result == ISC_R_SUCCESS) {
- nh = new_adbnamehook(adb, NULL);
- if (nh == NULL) {
- adbname->partial_result |= findoptions;
- result = ISC_R_NOMEMORY;
- goto fail;
- }
-
dns_rdataset_current(rdataset, &rdata);
if (rdtype == dns_rdatatype_a) {
INSIST(rdata.length == 4);
isc_sockaddr_fromin6(&sockaddr, &in6a, 53);
}
+ if (IN6_IS_ADDR_V4MAPPED(&sockaddr.type.sin6.sin6_addr)
+ || IN6_IS_ADDR_V4COMPAT(&sockaddr.type.sin6.sin6_addr)) {
+ DP(1, "Ignoring IPv6 mapped IPv4 address");
+ goto next;
+ }
+
+ INSIST(nh == NULL);
+ nh = new_adbnamehook(adb, NULL);
+ if (nh == NULL) {
+ adbname->partial_result |= findoptions;
+ result = ISC_R_NOMEMORY;
+ goto fail;
+ }
+
foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket);
if (foundentry == NULL) {
dns_adbentry_t *entry;
ISC_LIST_APPEND(adbname->v6, nh, plink);
nh = NULL;
+ next:
+
result = dns_rdataset_next(rdataset);
}
if (addr_bucket != DNS_ADB_INVALIDBUCKET)
UNLOCK(&adb->entrylocks[addr_bucket]);
- if (new_addresses_added) {
- if (rdtype == dns_rdatatype_a) {
- DP(1, "expire_v4 set to MIN(%u,%u) import_rdataset",
- adbname->expire_v4, now + rdataset->ttl);
- adbname->expire_v4 = ISC_MIN(adbname->expire_v4,
- now + rdataset->ttl);
- } else {
- DP(1, "expire_v6 set to MIN(%u,%u) import_rdataset",
- adbname->expire_v6, now + rdataset->ttl);
- adbname->expire_v6 = ISC_MIN(adbname->expire_v6,
- now + rdataset->ttl);
- }
+ if (rdataset->ttl == 0)
+ rdataset->ttl = ADB_NCACHE_MINIMUM;
+ if (rdtype == dns_rdatatype_a) {
+ DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
+ adbname->expire_v4, now + rdataset->ttl);
+ adbname->expire_v4 = ISC_MIN(adbname->expire_v4,
+ now + rdataset->ttl);
+ } else {
+ DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
+ adbname->expire_v6, now + rdataset->ttl);
+ adbname->expire_v6 = ISC_MIN(adbname->expire_v6,
+ now + rdataset->ttl);
+ }
+ 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.
isc_sockaddr_fromin6(&sockaddr, &a6ctx->in6addr, 53);
+ if (IN6_IS_ADDR_V4MAPPED(&sockaddr.type.sin6.sin6_addr)
+ || IN6_IS_ADDR_V4COMPAT(&sockaddr.type.sin6.sin6_addr)) {
+ DP(1, "Ignoring IPv6 mapped IPv4 address");
+ goto fail;
+ }
+
foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket);
if (foundentry == NULL) {
dns_adbentry_t *entry;
ISC_LIST_APPEND(name->v6, nh, plink);
nh = NULL;
- DP(1, "expire_v6 set to MIN(%u,%u) in import_v6",
+ fail:
+ DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) in import_v6",
name->expire_v6, a6ctx->expiration);
name->expire_v6 = ISC_MIN(name->expire_v6, a6ctx->expiration);
name->flags |= NAME_NEEDS_POKE;
- fail:
if (nh != NULL)
free_adbnamehook(adb, &nh);
result = isc_task_create(adb->taskmgr, adb->mctx, 0, &adb->task);
if (result != ISC_R_SUCCESS)
goto fail3;
+ /*
+ * XXXMLG When this is changed to be a config file option,
+ */
isc_interval_set(&adb->tick_interval, CLEAN_SECONDS, 0);
result = isc_timer_create(adb->timermgr, isc_timertype_once,
NULL, &adb->tick_interval, adb->task,
* We found a negative cache entry. Pull the TTL from it
* so we won't ask again for a while.
*/
+ if (rdataset.ttl == 0)
+ rdataset.ttl = ADB_NCACHE_MINIMUM;
if (rdtype == dns_rdatatype_a) {
adbname->expire_v4 = rdataset.ttl + now;
- DP(1, "adb name %p: Caching negative entry for A (ttl %u)",
+ DP(NCACHE_LEVEL, "adb name %p: Caching negative entry for A (ttl %u)",
adbname, rdataset.ttl);
} else {
- DP(1, "adb name %p: Caching negative entry for AAAA (ttl %u)",
+ DP(NCACHE_LEVEL, "adb name %p: Caching negative entry for AAAA (ttl %u)",
adbname, rdataset.ttl);
adbname->expire_v6 = rdataset.ttl + now;
}
* We found a negative cache entry. Pull the TTL from it
* so we won't ask again for a while.
*/
- DP(1, "adb name %p: Caching negative entry for A6 (ttl %u)",
+ DP(NCACHE_LEVEL, "adb name %p: Caching negative entry for A6 (ttl %u)",
adbname, rdataset.ttl);
adbname->expire_v6 = ISC_MIN(rdataset.ttl + now,
adbname->expire_v6);
*/
if (NCACHE_RESULT(dev->result)) {
if (address_type == DNS_ADBFIND_INET) {
- DP(1, "adb fetch name %p: "
+ DP(NCACHE_LEVEL, "adb fetch name %p: "
"Caching negative entry for A (ttl %u)",
name, dev->rdataset->ttl);
name->expire_v4 = ISC_MIN(name->expire_v4,
dev->rdataset->ttl + now);
} else {
- DP(1, "adb fetch name %p: "
+ DP(NCACHE_LEVEL, "adb fetch name %p: "
"Caching negative entry for AAAA (ttl %u)",
name, dev->rdataset->ttl);
name->expire_v6 = ISC_MIN(name->expire_v6,
* If we got a negative cache response, remember it.
*/
if (NCACHE_RESULT(dev->result)) {
- DP(1, "adb fetch name %p: "
+ DP(NCACHE_LEVEL, "adb fetch name %p: "
"Caching negative entry for A6 (ttl %u)",
name, dev->rdataset->ttl);
name->expire_v6 = ISC_MIN(name->expire_v6,