diff --git a/src/database/query-table.c b/src/database/query-table.c index ed5320660..bf2bdaafa 100644 --- a/src/database/query-table.c +++ b/src/database/query-table.c @@ -988,6 +988,7 @@ void DB_read_queries(void) break; case QUERY_CACHE: // Cached or local config + case QUERY_CACHE_STALE: // Nothing to be done here break; diff --git a/src/datastructure.c b/src/datastructure.c index 9a69b35c8..a2bf2a2f5 100644 --- a/src/datastructure.c +++ b/src/datastructure.c @@ -530,6 +530,7 @@ bool __attribute__ ((const)) is_blocked(const enum query_status status) case QUERY_RETRIED: case QUERY_RETRIED_DNSSEC: case QUERY_IN_PROGRESS: + case QUERY_CACHE_STALE: case QUERY_STATUS_MAX: default: return false; @@ -549,32 +550,58 @@ bool __attribute__ ((const)) is_blocked(const enum query_status status) } } -static const char *query_status_str[QUERY_STATUS_MAX] = { - "UNKNOWN", - "GRAVITY", - "FORWARDED", - "CACHE", - "REGEX", - "BLACKLIST", - "EXTERNAL_BLOCKED_IP", - "EXTERNAL_BLOCKED_NULL", - "EXTERNAL_BLOCKED_NXRA", - "GRAVITY_CNAME", - "REGEX_CNAME", - "BLACKLIST_CNAME", - "RETRIED", - "RETRIED_DNSSEC", - "IN_PROGRESS", - "DBBUSY", - "SPECIAL_DOMAIN" -}; +static const char* __attribute__ ((const)) query_status_str(const enum query_status status) +{ + switch (status) + { + case QUERY_UNKNOWN: + return "UNKNOWN"; + case QUERY_GRAVITY: + return "GRAVITY"; + case QUERY_FORWARDED: + return "FORWARDED"; + case QUERY_CACHE: + return "CACHE"; + case QUERY_REGEX: + return "REGEX"; + case QUERY_BLACKLIST: + return "BLACKLIST"; + case QUERY_EXTERNAL_BLOCKED_IP: + return "EXTERNAL_BLOCKED_IP"; + case QUERY_EXTERNAL_BLOCKED_NULL: + return "EXTERNAL_BLOCKED_NULL"; + case QUERY_EXTERNAL_BLOCKED_NXRA: + return "EXTERNAL_BLOCKED_NXRA"; + case QUERY_GRAVITY_CNAME: + return "GRAVITY_CNAME"; + case QUERY_REGEX_CNAME: + return "REGEX_CNAME"; + case QUERY_BLACKLIST_CNAME: + return "BLACKLIST_CNAME"; + case QUERY_RETRIED: + return "RETRIED"; + case QUERY_RETRIED_DNSSEC: + return "RETRIED_DNSSEC"; + case QUERY_IN_PROGRESS: + return "IN_PROGRESS"; + case QUERY_DBBUSY: + return "DBBUSY"; + case QUERY_SPECIAL_DOMAIN: + return "SPECIAL_DOMAIN"; + case QUERY_CACHE_STALE: + return "CACHE_STALE"; + case QUERY_STATUS_MAX: + return NULL; + } + return NULL; +} void _query_set_status(queriesData *query, const enum query_status new_status, const char *func, const int line, const char *file) { // Debug logging if(config.debug & DEBUG_STATUS) { - const char *oldstr = query->status < QUERY_STATUS_MAX ? query_status_str[query->status] : "INVALID"; + const char *oldstr = query->status < QUERY_STATUS_MAX ? query_status_str(query->status) : "INVALID"; if(query->status == new_status) { logg("Query %i: status unchanged: %s (%d) in %s() (%s:%i)", @@ -582,7 +609,7 @@ void _query_set_status(queriesData *query, const enum query_status new_status, c } else { - const char *newstr = new_status < QUERY_STATUS_MAX ? query_status_str[new_status] : "INVALID"; + const char *newstr = new_status < QUERY_STATUS_MAX ? query_status_str(new_status) : "INVALID"; logg("Query %i: status changed: %s (%d) -> %s (%d) in %s() (%s:%i)", query->id, oldstr, query->status, newstr, new_status, func, short_path(file), line); } diff --git a/src/dnsmasq_interface.c b/src/dnsmasq_interface.c index c1791cd8d..a90dabd1e 100644 --- a/src/dnsmasq_interface.c +++ b/src/dnsmasq_interface.c @@ -1932,6 +1932,9 @@ static void FTL_reply(const unsigned int flags, const char *name, const union al logg("***** Unknown cache query"); } + // Is this a stale reply? + const bool stale = flags & F_STALE; + // Possible debugging output if(config.debug & DEBUG_QUERIES) { @@ -1983,16 +1986,18 @@ static void FTL_reply(const unsigned int flags, const char *name, const union al if(cached || last_server.sa.sa_family == 0) // Log cache or upstream reply from unknown source - logg("**** got %s reply: %s is %s (ID %i, %s:%i)", - cached ? "cache" : "upstream", dispname, answer, id, file, line); + logg("**** got %s%s reply: %s is %s (ID %i, %s:%i)", + stale ? "stale ": "", cached ? "cache" : "upstream", + dispname, answer, id, file, line); else { char ip[ADDRSTRLEN+1] = { 0 }; in_port_t port = 0; mysockaddr_extract_ip_port(&last_server, ip, &port); // Log server which replied to our request - logg("**** got %s reply from %s#%d: %s is %s (ID %i, %s:%i)", - cached ? "cache" : "upstream", ip, port, dispname, answer, id, file, line); + logg("**** got %s%s reply from %s#%d: %s is %s (ID %i, %s:%i)", + stale ? "stale ": "", cached ? "cache" : "upstream", + ip, port, dispname, answer, id, file, line); } } @@ -2042,13 +2047,16 @@ static void FTL_reply(const unsigned int flags, const char *name, const union al return; } + // Determing query status (live or stale data?) + const enum query_status qs = stale ? QUERY_CACHE_STALE : QUERY_CACHE; + // This is either a reply served from cache or a blocked query (which appear // to be from cache because of flags containing F_HOSTS) if(cached) { // Set status of this query only if this is not a blocked query if(!is_blocked(query->status)) - query_set_status(query, QUERY_CACHE); + query_set_status(query, qs); // Detect if returned IP indicates that this query was blocked const enum query_status new_status = detect_blocked_IP(flags, addr, query, domain); @@ -2089,7 +2097,7 @@ static void FTL_reply(const unsigned int flags, const char *name, const union al // Answered from a custom (user provided) cache file or because // we're the authoritative DNS server (e.g. DHCP server and this // is our own domain) - query_set_status(query, QUERY_CACHE); + query_set_status(query, qs); // Save reply type and update individual reply counters query_set_reply(flags, 0, addr, query, response); diff --git a/src/enums.h b/src/enums.h index cd4dd3fde..9ec7dc9d4 100644 --- a/src/enums.h +++ b/src/enums.h @@ -46,6 +46,7 @@ enum query_status { QUERY_IN_PROGRESS, QUERY_DBBUSY, QUERY_SPECIAL_DOMAIN, + QUERY_CACHE_STALE, QUERY_STATUS_MAX } __attribute__ ((packed)); diff --git a/src/gc.c b/src/gc.c index c10c5d60c..47734c110 100644 --- a/src/gc.c +++ b/src/gc.c @@ -215,6 +215,7 @@ void *GC_thread(void *val) // Adjusting counters is done below in moveOverTimeMemory() break; case QUERY_CACHE: + case QUERY_CACHE_STALE: // Answered from local cache _or_ local config break; case QUERY_GRAVITY: // Blocked by Pi-hole's blocking lists (fall through)