diff --git a/bin/tests/adb_test.c b/bin/tests/adb_test.c index 3c52a69df8..48a4376f5c 100644 --- a/bin/tests/adb_test.c +++ b/bin/tests/adb_test.c @@ -78,8 +78,8 @@ static inline void CLOCK(void); static inline void CUNLOCK(void); void clean_dead_client_list(void); -void lookup(char *name); -void insert(char *target, char *addr); +void lookup(char *); +void insert(char *, char *, dns_ttl_t, isc_stdtime_t); static void check_result(isc_result_t result, char *format, ...) @@ -314,7 +314,7 @@ destroy_view(void) } void -insert(char *target, char *addr) +insert(char *target, char *addr, dns_ttl_t ttl, isc_stdtime_t now) { isc_sockaddr_t sockaddr; struct in_addr ina; @@ -336,7 +336,7 @@ insert(char *target, char *addr) ina.s_addr = inet_addr(addr); isc_sockaddr_fromin(&sockaddr, &ina, 53); - result = dns_adb_insert(adb, &name, &sockaddr); + result = dns_adb_insert(adb, &name, &sockaddr, ttl, now); check_result(result, "dns_adb_insert %s -> %s", target, addr); printf("Added %s -> %s\n", target, addr); } @@ -446,11 +446,11 @@ main(int argc, char **argv) /* * Store this address for this name. */ - insert("kechara.flame.org.", "204.152.184.79"); - insert("moghedien.flame.org.", "204.152.184.97"); - insert("mailrelay.flame.org.", "204.152.184.79"); - insert("mailrelay.flame.org.", "204.152.184.97"); - insert("blackhole.flame.org.", "127.0.0.1"); + insert("kechara.flame.org.", "204.152.184.79", 10, now); + insert("moghedien.flame.org.", "204.152.184.97", 10, now); + insert("mailrelay.flame.org.", "204.152.184.79", 10, now); + insert("mailrelay.flame.org.", "204.152.184.97", 5, now); + insert("blackhole.flame.org.", "127.0.0.1", 0, now); /* * Lock the entire client list here. This will cause all events diff --git a/lib/dns/adb.c b/lib/dns/adb.c index 35f9811665..30f692b6d0 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -1313,6 +1313,18 @@ dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, goto fail; } + /* + * Give us a chance to expire this name. + */ + if (adbname != NULL) { + if (adbname->expire_time < now) { + printf("Should kill name!\n"); + } + } + + /* + * Still there? + */ if (adbname != NULL) goto found; /* goodness, I hate goto's. */ @@ -1477,7 +1489,8 @@ dns_adb_deletename(dns_adb_t *adb, dns_name_t *host) } isc_result_t -dns_adb_insert(dns_adb_t *adb, dns_name_t *host, isc_sockaddr_t *addr) +dns_adb_insert(dns_adb_t *adb, dns_name_t *host, isc_sockaddr_t *addr, + dns_ttl_t ttl, isc_stdtime_t now) { dns_adbname_t *name; isc_boolean_t free_name; @@ -1487,11 +1500,20 @@ dns_adb_insert(dns_adb_t *adb, dns_name_t *host, isc_sockaddr_t *addr) isc_boolean_t free_namehook; int name_bucket, addr_bucket; /* unlock if != DNS_ADB_INVALIDBUCKET */ isc_result_t result; + isc_stdtime_t expire_time; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(host != NULL); REQUIRE(addr != NULL); + if (now == 0) { + result = isc_stdtime_get(&now); + if (result != ISC_R_SUCCESS) + return (result); + } + + expire_time = now + ttl; + name = NULL; free_name = ISC_FALSE; entry = NULL; @@ -1515,6 +1537,7 @@ dns_adb_insert(dns_adb_t *adb, dns_name_t *host, isc_sockaddr_t *addr) goto out; } free_name = ISC_TRUE; + name->expire_time = expire_time; } /* @@ -1576,6 +1599,10 @@ dns_adb_insert(dns_adb_t *adb, dns_name_t *host, isc_sockaddr_t *addr) } if (!ISC_LINK_LINKED(entry, link)) ISC_LIST_PREPEND(adb->entries[addr_bucket], entry, link); + + if (name->expire_time > expire_time) + name->expire_time = expire_time; + UNLOCK(&adb->namelocks[name_bucket]); name_bucket = DNS_ADB_INVALIDBUCKET; UNLOCK(&adb->entrylocks[addr_bucket]); @@ -1707,7 +1734,7 @@ dns_adb_dump(dns_adb_t *adb, FILE *f) fprintf(f, "name %p\n", name); if (!DNS_ADBNAME_VALID(name)) fprintf(f, "\tMAGIC %08x\n", name->magic); - fprintf(f, "\t"); + fprintf(f, "\texpiry %u ", name->expire_time); print_dns_name(f, &name->name); fprintf(f, "\n"); print_namehook_list(f, name); @@ -1889,6 +1916,7 @@ construct_name(dns_adb_t *adb, dns_adbhandle_t *handle, dns_name_t *name, struct in_addr ina; isc_sockaddr_t sockaddr; dns_adbentry_t *foundentry; /* NO CLEAN UP! */ + isc_stdtime_t expire_time; INSIST(DNS_ADB_VALID(adb)); INSIST(DNS_ADBHANDLE_VALID(handle)); @@ -1902,6 +1930,7 @@ construct_name(dns_adb_t *adb, dns_adbhandle_t *handle, dns_name_t *name, result = ISC_R_UNEXPECTED; addr_bucket = DNS_ADB_INVALIDBUCKET; return_success = ISC_FALSE; + expire_time = INT_MAX; nh = NULL; use_hints = dns_name_equal(zone, dns_rootname); @@ -1923,6 +1952,10 @@ construct_name(dns_adb_t *adb, dns_adbhandle_t *handle, dns_name_t *name, result = ISC_R_NOMEMORY; goto fail; } + + if (now + rdataset.ttl < expire_time) + expire_time = now + rdataset.ttl; + dns_rdataset_current(&rdataset, &rdata); INSIST(rdata.length == 4); memcpy(&ina.s_addr, rdata.data, 4); @@ -1972,6 +2005,8 @@ construct_name(dns_adb_t *adb, dns_adbhandle_t *handle, dns_name_t *name, if (addr_bucket != DNS_ADB_INVALIDBUCKET) UNLOCK(&adb->entrylocks[addr_bucket]); + adbname->expire_time = expire_time; + if (return_success) return (ISC_R_SUCCESS); return (result); diff --git a/lib/dns/include/dns/adb.h b/lib/dns/include/dns/adb.h index f4bf1176f1..b370641492 100644 --- a/lib/dns/include/dns/adb.h +++ b/lib/dns/include/dns/adb.h @@ -306,7 +306,8 @@ dns_adb_deletename(dns_adb_t *adb, dns_name_t *host); isc_result_t -dns_adb_insert(dns_adb_t *adb, dns_name_t *host, isc_sockaddr_t *addr); +dns_adb_insert(dns_adb_t *adb, dns_name_t *host, isc_sockaddr_t *addr, + dns_ttl_t ttl, isc_stdtime_t now); /* * Insert a host name and address into the database. A new (blank, no * badness) record is inserted.