diff --git a/src/dns_cache.c b/src/dns_cache.c index d558072..6d81107 100644 --- a/src/dns_cache.c +++ b/src/dns_cache.c @@ -412,7 +412,37 @@ int dns_cache_get_ttl(struct dns_cache *dns_cache) return ttl; } -int dns_cache_is_soa(struct dns_cache *dns_cache) { +int dns_cache_get_cname_ttl(struct dns_cache *dns_cache) +{ + time_t now; + int ttl = 0; + time(&now); + + struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache_get_data(dns_cache); + + if (cache_addr->head.cache_type != CACHE_TYPE_ADDR) { + return 0; + } + + ttl = dns_cache->info.insert_time + cache_addr->addr_data.cname_ttl - now; + if (ttl < 0) { + return 0; + } + + int addr_ttl = dns_cache_get_ttl(dns_cache); + if (ttl < addr_ttl) { + return addr_ttl; + } + + if (ttl < 0) { + return 0; + } + + return ttl; +} + +int dns_cache_is_soa(struct dns_cache *dns_cache) +{ if (dns_cache == NULL) { return 0; } diff --git a/src/dns_cache.h b/src/dns_cache.h index d6443dd..1f66122 100644 --- a/src/dns_cache.h +++ b/src/dns_cache.h @@ -143,6 +143,8 @@ void dns_cache_invalidate(dns_cache_preinvalid_callback callback, int ttl_pre); int dns_cache_get_ttl(struct dns_cache *dns_cache); +int dns_cache_get_cname_ttl(struct dns_cache *dns_cache); + int dns_cache_is_soa(struct dns_cache *dns_cache); struct dns_cache_data *dns_cache_new_data(void); diff --git a/src/dns_server.c b/src/dns_server.c index 1fe7682..c4b9d5c 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -2349,6 +2349,17 @@ static int _dns_server_get_expired_ttl_reply(struct dns_cache *dns_cache) return dns_conf_serve_expired_reply_ttl; } + +static int _dns_server_get_expired_cname_ttl_reply(struct dns_cache *dns_cache) +{ + int ttl = dns_cache_get_cname_ttl(dns_cache); + if (ttl > 0) { + return ttl; + } + + return dns_conf_serve_expired_reply_ttl; +} + static int _dns_server_process_cache_addr(struct dns_request *request, struct dns_cache *dns_cache) { struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache_get_data(dns_cache); @@ -2376,7 +2387,7 @@ static int _dns_server_process_cache_addr(struct dns_request *request, struct dn if (cache_addr->addr_data.cname[0] != 0) { safe_strncpy(request->cname, cache_addr->addr_data.cname, DNS_MAX_CNAME_LEN); request->has_cname = 1; - request->ttl_cname = cache_addr->addr_data.cname_ttl; + request->ttl_cname = _dns_server_get_expired_cname_ttl_reply(dns_cache); } request->rcode = DNS_RC_NOERROR;