Skip to content

Commit

Permalink
Allow FTL to analyze stale cache replies. They are assigned to a new …
Browse files Browse the repository at this point in the history
…query type (17)

Signed-off-by: DL6ER <dl6er@dl6er.de>
  • Loading branch information
DL6ER committed Nov 7, 2022
1 parent 89fc9b4 commit fdb6522
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 27 deletions.
1 change: 1 addition & 0 deletions src/database/query-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
69 changes: 48 additions & 21 deletions src/datastructure.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -549,40 +550,66 @@ 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)",
query->id, oldstr, query->status, func, short_path(file), line);
}
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);
}
Expand Down
20 changes: 14 additions & 6 deletions src/dnsmasq_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ enum query_status {
QUERY_IN_PROGRESS,
QUERY_DBBUSY,
QUERY_SPECIAL_DOMAIN,
QUERY_CACHE_STALE,
QUERY_STATUS_MAX
} __attribute__ ((packed));

Expand Down
1 change: 1 addition & 0 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit fdb6522

Please sign in to comment.