diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index d179ccec49..3c800e1f30 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -63,6 +63,7 @@ public: protected: char* host; // if non-nil, this is a host request uint32 addr; + uint32 ttl; int request_pending; }; @@ -82,8 +83,8 @@ int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns) class DNS_Mapping { public: - DNS_Mapping(const char* host, struct hostent* h); - DNS_Mapping(uint32 addr, struct hostent* h); + DNS_Mapping(const char* host, struct hostent* h, uint32 ttl); + DNS_Mapping(uint32 addr, struct hostent* h, uint32 ttl); DNS_Mapping(FILE* f); int NoMapping() const { return no_mapping; } @@ -108,6 +109,9 @@ public: int Failed() const { return failed; } int Valid() const { return ! failed; } + bool Expired() const + { return current_time() > (creation_time + req_ttl); } + protected: friend class DNS_Mgr; @@ -119,6 +123,7 @@ protected: char* req_host; uint32 req_addr; + uint32 req_ttl; int num_names; char** names; @@ -146,21 +151,23 @@ static TableVal* empty_addr_set() return new TableVal(s); } -DNS_Mapping::DNS_Mapping(const char* host, struct hostent* h) +DNS_Mapping::DNS_Mapping(const char* host, struct hostent* h, uint32 ttl) { Init(h); req_host = copy_string(host); req_addr = 0; + req_ttl = ttl; if ( names && ! names[0] ) names[0] = copy_string(host); } -DNS_Mapping::DNS_Mapping(uint32 addr, struct hostent* h) +DNS_Mapping::DNS_Mapping(uint32 addr, struct hostent* h, uint32 ttl) { Init(h); req_addr = addr; req_host = 0; + req_ttl = ttl; } DNS_Mapping::DNS_Mapping(FILE* f) @@ -663,6 +670,7 @@ Val* DNS_Mgr::BuildMappingVal(DNS_Mapping* dm) void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) { struct hostent* h = (r && r->host_errno == 0) ? r->hostent : 0; + u_int32_t ttl = r->ttl; DNS_Mapping* new_dm; DNS_Mapping* prev_dm; @@ -670,7 +678,7 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) if ( dr->ReqHost() ) { - new_dm = new DNS_Mapping(dr->ReqHost(), h); + new_dm = new DNS_Mapping(dr->ReqHost(), h, ttl); prev_dm = host_mappings.Insert(dr->ReqHost(), new_dm); if ( new_dm->Failed() && prev_dm && prev_dm->Valid() ) @@ -683,7 +691,7 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) } else { - new_dm = new DNS_Mapping(dr->ReqAddr(), h); + new_dm = new DNS_Mapping(dr->ReqAddr(), h, ttl); uint32 tmp_addr = dr->ReqAddr(); HashKey k(&tmp_addr, 1); prev_dm = addr_mappings.Insert(&k, new_dm); @@ -833,9 +841,16 @@ const char* DNS_Mgr::LookupAddrInCache(dns_mgr_addr_type addr) { HashKey h(&addr, 1); DNS_Mapping* d = dns_mgr->addr_mappings.Lookup(&h); + if ( ! d ) return 0; + if ( d->Expired() ) + { + dns_mgr->addr_mappings.Remove(&h); + return 0; + } + // The escapes in the following strings are to avoid having it // interpreted as a trigraph sequence. return d->names ? d->names[0] : "<\?\?\?>"; @@ -844,9 +859,17 @@ const char* DNS_Mgr::LookupAddrInCache(dns_mgr_addr_type addr) TableVal* DNS_Mgr::LookupNameInCache(string name) { DNS_Mapping* d = dns_mgr->host_mappings.Lookup(name.c_str()); + if ( ! d || ! d->names ) return 0; + if ( d->Expired() ) + { + HashKey h(name.c_str()); + dns_mgr->host_mappings.Remove(&h); + return 0; + } + return d->AddrsSet(); } diff --git a/src/nb_dns.c b/src/nb_dns.c index 5033aadad4..225eb984cf 100644 --- a/src/nb_dns.c +++ b/src/nb_dns.c @@ -438,6 +438,7 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr) register char **ap, **hap; register u_int16_t id; register const u_char *rdata; + register u_int32_t rttl; register struct hostent *he; register size_t rdlen; ns_msg handle; @@ -557,6 +558,7 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr) rdata = ns_rr_rdata(rr); rdlen = ns_rr_rdlen(rr); + rttl = ns_rr_ttl(rr); switch (atype) { case T_A: @@ -603,10 +605,12 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr) /* "Find first satisfactory answer" */ nr->hostent = he; + nr->ttl = rttl; return (1); } } nr->hostent = he; + nr->ttl = rttl; return (1); } diff --git a/src/nb_dns.h b/src/nb_dns.h index 41b5946e48..5787a3fdb0 100644 --- a/src/nb_dns.h +++ b/src/nb_dns.h @@ -11,6 +11,7 @@ struct nb_dns_result { void *cookie; int host_errno; struct hostent *hostent; + uint32_t ttl; }; typedef unsigned int nb_uint32_t;