mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
Merge pull request #251 from pi-hole/FTLDNS-improvements
Several FTLDNS improvements
This commit is contained in:
@@ -149,8 +149,9 @@ typedef struct {
|
||||
int id;
|
||||
bool complete;
|
||||
bool private;
|
||||
unsigned long ttl;
|
||||
unsigned long response; // saved in units of 1/10 milliseconds (1 = 0.1ms, 2 = 0.2ms, 2500 = 250.0ms, etc.)
|
||||
unsigned char reply;
|
||||
unsigned char dnssec;
|
||||
} queriesDataStruct;
|
||||
|
||||
typedef struct {
|
||||
@@ -172,10 +173,6 @@ typedef struct {
|
||||
int blockedcount;
|
||||
char *domain;
|
||||
bool wildcard;
|
||||
unsigned char dnssec;
|
||||
char *IPv4;
|
||||
char *IPv6;
|
||||
unsigned char reply[2];
|
||||
} domainsDataStruct;
|
||||
|
||||
typedef struct {
|
||||
@@ -184,6 +181,7 @@ typedef struct {
|
||||
int total;
|
||||
int blocked;
|
||||
int cached;
|
||||
int forwarded;
|
||||
int clientnum;
|
||||
int *clientdata;
|
||||
int querytypedata[7];
|
||||
|
||||
@@ -688,8 +688,6 @@ void getAllQueries(char *client_message, int *sock)
|
||||
char *domain = domains[queries[i].domainID].domain;
|
||||
char *client = clients[queries[i].clientID].ip;
|
||||
|
||||
unsigned char reply = domains[queries[i].domainID].reply[queries[i].type == TYPE_A ? 0 : 1];
|
||||
|
||||
unsigned long delay = queries[i].response;
|
||||
// Check if received (delay should be smaller than 30min)
|
||||
if(delay > 1.8e7)
|
||||
@@ -697,7 +695,7 @@ void getAllQueries(char *client_message, int *sock)
|
||||
|
||||
if(istelnet[*sock])
|
||||
{
|
||||
ssend(*sock,"%i %s %s %s %i %i %i %lu\n",queries[i].timestamp,qtype,domain,client,queries[i].status,domains[queries[i].domainID].dnssec,reply,delay);
|
||||
ssend(*sock,"%i %s %s %s %i %i %i %lu\n",queries[i].timestamp,qtype,domain,client,queries[i].status,queries[i].dnssec,queries[i].reply,delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -712,7 +710,7 @@ void getAllQueries(char *client_message, int *sock)
|
||||
return;
|
||||
|
||||
pack_uint8(*sock, queries[i].status);
|
||||
pack_uint8(*sock, domains[queries[i].domainID].dnssec);
|
||||
pack_uint8(*sock, queries[i].dnssec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1139,30 +1137,6 @@ void getDomainDetails(char *client_message, int *sock)
|
||||
ssend(*sock,"Total: %i\n", domains[i].count);
|
||||
ssend(*sock,"Blocked: %i\n", domains[i].blockedcount);
|
||||
ssend(*sock,"Wildcard blocked: %s\n", domains[i].wildcard ? "true" : "false");
|
||||
ssend(*sock,"DNSSEC status: %u\n", domains[i].dnssec);
|
||||
int j;
|
||||
for(j = 0; j < 2; j++) // 0 = IPv4, 1 = IPv6
|
||||
{
|
||||
ssend(*sock, "IPv%i reply: ", j == 0 ? 4 : 6);
|
||||
switch(domains[i].reply[j])
|
||||
{
|
||||
case REPLY_UNKNOWN:
|
||||
ssend(*sock, "Unknown\n");
|
||||
break;
|
||||
case REPLY_NODATA:
|
||||
ssend(*sock, "NODATA\n");
|
||||
break;
|
||||
case REPLY_NXDOMAIN:
|
||||
ssend(*sock, "NXDOMAIN\n");
|
||||
break;
|
||||
case REPLY_CNAME:
|
||||
ssend(*sock, "CNAME\n");
|
||||
break;
|
||||
case REPLY_IP:
|
||||
ssend(*sock, "%s\n", domains[i].IPv4 == NULL ? "N/A" : domains[i].IPv4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -704,7 +704,7 @@ void read_data_from_DB(void)
|
||||
queries[queryID].db = true; // Mark this as already present in the database
|
||||
queries[queryID].id = 0; // This is dnsmasq's internal ID. We don't store it in the database
|
||||
queries[queryID].complete = true; // Mark as all information is avaiable
|
||||
queries[queryID].ttl = 0;
|
||||
queries[queryID].response = 0;
|
||||
lastDBimportedtimestamp = queryTimeStamp;
|
||||
|
||||
// Handle type counters
|
||||
|
||||
@@ -152,14 +152,6 @@ int findDomainID(const char *domain)
|
||||
// Store domain name - no need to check for NULL here as it doesn't harm
|
||||
domains[domainID].domain = strdup(domain);
|
||||
memory.domainnames += (strlen(domain) + 1) * sizeof(char);
|
||||
// Store DNSSEC result for this domain
|
||||
domains[domainID].dnssec = DNSSEC_UNSPECIFIED;
|
||||
// Set reply points to uninitialized
|
||||
domains[domainID].IPv4 = NULL;
|
||||
domains[domainID].IPv6 = NULL;
|
||||
// Initialize reply type
|
||||
domains[domainID].reply[0] = REPLY_UNKNOWN;
|
||||
domains[domainID].reply[1] = REPLY_UNKNOWN;
|
||||
// Increase counter by one
|
||||
counters.domains++;
|
||||
|
||||
|
||||
+1
-1
@@ -462,7 +462,7 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
|
||||
ttl = daemon->max_cache_ttl;
|
||||
if (daemon->min_cache_ttl != 0 && daemon->min_cache_ttl > ttl)
|
||||
ttl = daemon->min_cache_ttl;
|
||||
FTL_reply(flags, name, addr, ttl, daemon->log_display_id);
|
||||
FTL_reply(flags, name, addr, daemon->log_display_id);
|
||||
}
|
||||
|
||||
/* if previous insertion failed give up now. */
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
|
||||
if (flags == F_NXDOMAIN || flags == F_NOERR)
|
||||
logflags = F_NEG | qtype;
|
||||
log_query(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, NULL);
|
||||
FTL_reply(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, 0, daemon->log_display_id);
|
||||
FTL_reply(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, daemon->log_display_id);
|
||||
}
|
||||
else if ((*type) & SERV_USE_RESOLV)
|
||||
{
|
||||
|
||||
+10
-10
@@ -1696,7 +1696,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
if (!dryrun)
|
||||
{
|
||||
log_query(crecp->flags, name, NULL, NULL);
|
||||
FTL_cache(crecp->flags, name, NULL, NULL, 0, daemon->log_display_id);
|
||||
FTL_cache(crecp->flags, name, NULL, NULL, daemon->log_display_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1717,7 +1717,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
|
||||
record_source(crecp->uid));
|
||||
FTL_cache(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
|
||||
record_source(crecp->uid), crec_ttl(crecp, now),
|
||||
record_source(crecp->uid),
|
||||
daemon->log_display_id);
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
@@ -1734,7 +1734,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
if (!dryrun)
|
||||
{
|
||||
log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
|
||||
FTL_cache(F_FORWARD | F_CONFIG | flag, name, &addr, NULL, daemon->local_ttl, daemon->log_display_id);
|
||||
FTL_cache(F_FORWARD | F_CONFIG | flag, name, &addr, NULL, daemon->log_display_id);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->local_ttl, NULL, type, C_IN, type == T_A ? "4" : "6", &addr))
|
||||
anscount++;
|
||||
@@ -1756,7 +1756,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
{
|
||||
log_query(crecp->flags, name, NULL, record_source(crecp->uid));
|
||||
FTL_cache(crecp->flags, name, NULL, record_source(crecp->uid),
|
||||
crec_ttl(crecp, now), daemon->log_display_id);
|
||||
daemon->log_display_id);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
crec_ttl(crecp, now), &nameoffset,
|
||||
T_CNAME, C_IN, "d", cache_get_cname_target(crecp)))
|
||||
@@ -1776,7 +1776,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
{
|
||||
int offset;
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
|
||||
FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "<MX>", daemon->local_ttl, daemon->log_display_id);
|
||||
FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "<MX>", daemon->log_display_id);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
|
||||
&offset, T_MX, C_IN, "sd", rec->weight, rec->target))
|
||||
{
|
||||
@@ -1794,7 +1794,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
if (!dryrun)
|
||||
{
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
|
||||
FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "<MX>", daemon->local_ttl, daemon->log_display_id);
|
||||
FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "<MX>", daemon->log_display_id);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
|
||||
T_MX, C_IN, "sd", 1,
|
||||
option_bool(OPT_SELFMX) ? name : daemon->mxtarget))
|
||||
@@ -1816,7 +1816,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
{
|
||||
int offset;
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
|
||||
FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "<SRV>", daemon->local_ttl, daemon->log_display_id);
|
||||
FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "<SRV>", daemon->log_display_id);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
|
||||
&offset, T_SRV, C_IN, "sssd",
|
||||
rec->priority, rec->weight, rec->srvport, rec->target))
|
||||
@@ -1852,7 +1852,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
if (!dryrun)
|
||||
{
|
||||
log_query(F_CONFIG | F_NEG, name, NULL, NULL);
|
||||
FTL_cache(F_CONFIG | F_NEG, name, NULL, NULL, 0, daemon->log_display_id);
|
||||
FTL_cache(F_CONFIG | F_NEG, name, NULL, NULL, daemon->log_display_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1867,7 +1867,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
if (!dryrun)
|
||||
{
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
|
||||
FTL_cache(F_CONFIG | F_NEG, name, NULL, "<NAPTR>", daemon->local_ttl, daemon->log_display_id);
|
||||
FTL_cache(F_CONFIG | F_NEG, name, NULL, "<NAPTR>", daemon->log_display_id);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
|
||||
NULL, T_NAPTR, C_IN, "sszzzd",
|
||||
na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
|
||||
@@ -1885,7 +1885,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
if (!dryrun)
|
||||
{
|
||||
log_query(F_CONFIG | F_NEG, name, &addr, NULL);
|
||||
FTL_cache(F_CONFIG | F_NEG, name, NULL, NULL, 0, daemon->log_display_id);
|
||||
FTL_cache(F_CONFIG | F_NEG, name, NULL, NULL, daemon->log_display_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+89
-133
@@ -14,8 +14,8 @@
|
||||
#include "dnsmasq_interface.h"
|
||||
|
||||
void print_flags(unsigned int flags);
|
||||
void storeIP(int i, char *ip);
|
||||
void save_reply_type(unsigned int flags, int queryID);
|
||||
void save_reply_type(unsigned int flags, int queryID, struct timeval response);
|
||||
unsigned long converttimeval(struct timeval time);
|
||||
|
||||
char flagnames[28][12] = {"F_IMMORTAL ", "F_NAMEP ", "F_REVERSE ", "F_FORWARD ", "F_DHCP ", "F_NEG ", "F_HOSTS ", "F_IPV4 ", "F_IPV6 ", "F_BIGNAME ", "F_NXDOMAIN ", "F_CNAME ", "F_DNSKEY ", "F_CONFIG ", "F_DS ", "F_DNSSECOK ", "F_UPSTREAM ", "F_RRNAME ", "F_SERVER ", "F_QUERY ", "F_NOERR ", "F_AUTH ", "F_DNSSEC ", "F_KEYTAG ", "F_SECSTAT ", "F_NO_RR ", "F_IPSET ", "F_NOEXTRA "};
|
||||
|
||||
@@ -143,8 +143,11 @@ void FTL_new_query(unsigned int flags, char *name, struct all_addr *addr, char *
|
||||
queries[queryID].id = id;
|
||||
queries[queryID].complete = false;
|
||||
queries[queryID].private = (config.privacylevel == PRIVACY_MAXIMUM);
|
||||
queries[queryID].ttl = 0;
|
||||
queries[queryID].response = request.tv_sec*10000 + request.tv_usec/100;
|
||||
queries[queryID].response = converttimeval(request);
|
||||
// Initialize reply type
|
||||
queries[queryID].reply = REPLY_UNKNOWN;
|
||||
// Store DNSSEC result for this domain
|
||||
queries[queryID].dnssec = DNSSEC_UNSPECIFIED;
|
||||
|
||||
// Increase DNS queries counter
|
||||
counters.queries++;
|
||||
@@ -188,19 +191,6 @@ void FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int id
|
||||
// Check UUID of this query
|
||||
if(queries[i].id == id)
|
||||
{
|
||||
// Detect if we cached the <CNAME> but need to ask the upstream
|
||||
// servers for the actual IPs now
|
||||
if(queries[i].status == QUERY_CACHE)
|
||||
{
|
||||
// Fix counters
|
||||
counters.cached--;
|
||||
validate_access("overTime", queries[i].timeidx, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
overTime[queries[i].timeidx].cached--;
|
||||
|
||||
// Mark this query again as (temporarily) unknown
|
||||
counters.unknown++;
|
||||
queries[i].complete = false;
|
||||
}
|
||||
queries[i].status = QUERY_FORWARDED;
|
||||
found = true;
|
||||
break;
|
||||
@@ -215,8 +205,13 @@ void FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int id
|
||||
return;
|
||||
}
|
||||
|
||||
// Count only if current query has not been counted so far
|
||||
if(queries[i].complete)
|
||||
// Proceed only if
|
||||
// - current query has not been marked as replied to so far
|
||||
// (it could be that answers from multiple forward
|
||||
// destionations are coimg in for the same query)
|
||||
// - the query was formally known as cached but had to be forwarded
|
||||
// (this is a special case further described below)
|
||||
if(queries[i].complete && queries[i].status != QUERY_CACHE)
|
||||
{
|
||||
free(forward);
|
||||
disable_thread_lock();
|
||||
@@ -230,12 +225,51 @@ void FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int id
|
||||
|
||||
if(!queries[i].complete)
|
||||
{
|
||||
// This query is no longer unknown ...
|
||||
counters.unknown--;
|
||||
// ... but got forwarded
|
||||
int j = queries[i].timeidx;
|
||||
validate_access("overTime", j, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
if(queries[i].status == QUERY_CACHE)
|
||||
{
|
||||
// Detect if we cached the <CNAME> but need to ask the upstream
|
||||
// servers for the actual IPs now, we remove this query from the
|
||||
// counters for cache replied queries as we had to forward a
|
||||
// request for it. Example:
|
||||
// Assume a domain a.com is a CNAME which is cached and has a very
|
||||
// long TTL. It point to another domain server.a.com which has an
|
||||
// A record but this has a much lower TTL.
|
||||
// If you now query a.com and then again after some time, you end
|
||||
// up in a situation where dnsmasq can answer the first level of
|
||||
// the DNS result (the CNAME) from cache, hence the status of this
|
||||
// query is marked as "answered from cache" in FTLDNS. However, for
|
||||
// server.a.com wit the much shorter TTL, we still have to forward
|
||||
// something and ask the upstream server for the final IP address.
|
||||
// This code section acknowledges this by removing one entry from
|
||||
// the cached counters as we will re-brand this query as having been
|
||||
// forwarded in the following.
|
||||
counters.cached--;
|
||||
// Also correct overTime data
|
||||
overTime[j].cached--;
|
||||
|
||||
// Correct reply timer
|
||||
struct timeval response;
|
||||
gettimeofday(&response, 0);
|
||||
// Reset timer, shift slightly into the past to acknowledge the time
|
||||
// FTLDNS needed to look up the CNAME in its cache
|
||||
queries[i].response = converttimeval(response) - queries[i].response;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal cache reply
|
||||
// Query is no longer unknown
|
||||
counters.unknown--;
|
||||
// Hereby, this query is now fully determined
|
||||
queries[i].complete = true;
|
||||
}
|
||||
// Update overTime data
|
||||
overTime[j].forwarded++;
|
||||
|
||||
// Update couter for forwarded queries
|
||||
counters.forwardedqueries++;
|
||||
// Hereby, this query is now fully determined
|
||||
queries[i].complete = true;
|
||||
}
|
||||
|
||||
// Release allocated memory
|
||||
@@ -251,7 +285,7 @@ void FTL_dnsmasq_reload(void)
|
||||
readGravityFiles();
|
||||
}
|
||||
|
||||
void FTL_reply(unsigned short flags, char *name, struct all_addr *addr, unsigned long ttl, int id)
|
||||
void FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id)
|
||||
{
|
||||
// Interpret hosts files that have been read by dnsmasq
|
||||
enable_thread_lock();
|
||||
@@ -272,7 +306,7 @@ void FTL_reply(unsigned short flags, char *name, struct all_addr *addr, unsigned
|
||||
else if(flags & F_NEG)
|
||||
answer = "(NODATA)";
|
||||
|
||||
logg("**** got reply %s is %s (TTL %lu, ID %i)", name, answer, ttl, id);
|
||||
logg("**** got reply %s is %s (ID %i)", name, answer, id);
|
||||
print_flags(flags);
|
||||
}
|
||||
|
||||
@@ -354,26 +388,10 @@ void FTL_reply(unsigned short flags, char *name, struct all_addr *addr, unsigned
|
||||
}
|
||||
|
||||
// Save reply type and update individual reply counters
|
||||
save_reply_type(flags, i);
|
||||
|
||||
// Save returned IP
|
||||
// but only if we have an exact match (there will be no exact match for a CNAME)
|
||||
// on this else-branch this is not a negative match (NXDOMAIN, NODATA)
|
||||
if(!(flags & F_NEG) && !(flags & F_CNAME) &&
|
||||
strlen(dest) > 2 &&
|
||||
strcmp(domains[domainID].domain, name) == 0)
|
||||
{
|
||||
storeIP(i, dest);
|
||||
}
|
||||
|
||||
// Store TTL
|
||||
queries[i].ttl = ttl;
|
||||
save_reply_type(flags, i, response);
|
||||
|
||||
// Hereby, this query is now fully determined
|
||||
queries[i].complete = true;
|
||||
|
||||
// Save response time (relative time)
|
||||
queries[i].response = response.tv_sec*10000 + response.tv_usec/100 - queries[i].response;
|
||||
}
|
||||
|
||||
// We are done here
|
||||
@@ -410,29 +428,14 @@ void FTL_reply(unsigned short flags, char *name, struct all_addr *addr, unsigned
|
||||
{
|
||||
|
||||
// Save reply type and update individual reply counters
|
||||
save_reply_type(flags, i);
|
||||
|
||||
// Save returned IP
|
||||
// but only if we have an exact match (there will be no exact match for a CNAME)
|
||||
// on this else-branch this is not a negative match (NXDOMAIN, NODATA)
|
||||
if(!(flags & F_NEG) && !(flags & F_CNAME) &&
|
||||
strlen(dest) > 2)
|
||||
{
|
||||
storeIP(i, dest);
|
||||
}
|
||||
|
||||
// Store TTL
|
||||
queries[i].ttl = ttl;
|
||||
|
||||
// Save response time (relative time)
|
||||
queries[i].response = response.tv_sec*10000 + response.tv_usec/100 - queries[i].response;
|
||||
save_reply_type(flags, i, response);
|
||||
}
|
||||
}
|
||||
else if((flags & F_REVERSE) && debug)
|
||||
{
|
||||
logg("Skipping result of PTR query");
|
||||
}
|
||||
else if(debug)
|
||||
else
|
||||
{
|
||||
logg("*************************** unknown REPLY ***************************");
|
||||
print_flags(flags);
|
||||
@@ -441,7 +444,7 @@ void FTL_reply(unsigned short flags, char *name, struct all_addr *addr, unsigned
|
||||
disable_thread_lock();
|
||||
}
|
||||
|
||||
void FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg, unsigned long ttl, int id)
|
||||
void FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg, int id)
|
||||
{
|
||||
// Save that this query got answered from cache
|
||||
enable_thread_lock();
|
||||
@@ -464,7 +467,7 @@ void FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg,
|
||||
}
|
||||
free(domain);
|
||||
|
||||
if(debug) logg("**** got cache answer for %s / %s / %s (TTL %lu, ID %i)", name, dest, arg, ttl, id);
|
||||
if(debug) logg("**** got cache answer for %s / %s / %s (ID %i)", name, dest, arg, id);
|
||||
if(debug) print_flags(flags);
|
||||
|
||||
// Get response time
|
||||
@@ -494,7 +497,7 @@ void FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg,
|
||||
requesttype = QUERY_CACHE;
|
||||
else if(flags & F_FORWARD) // cached answer to previously forwarded request
|
||||
requesttype = QUERY_CACHE;
|
||||
else if(debug)
|
||||
else
|
||||
{
|
||||
logg("*************************** unknown CACHE reply (1) ***************************");
|
||||
print_flags(flags);
|
||||
@@ -550,29 +553,13 @@ void FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg,
|
||||
}
|
||||
|
||||
// Save reply type and update individual reply counters
|
||||
save_reply_type(flags, i);
|
||||
|
||||
// Save returned IP
|
||||
// but only if we have an exact match (there will be no exact match for a CNAME)
|
||||
// on this else-branch this is not a negative match (NXDOMAIN, NODATA)
|
||||
if(!(flags & F_NEG) && !(flags & F_CNAME) &&
|
||||
strlen(dest) > 2 &&
|
||||
strcmp(domains[domainID].domain, name) == 0)
|
||||
{
|
||||
storeIP(i, dest);
|
||||
}
|
||||
|
||||
// Store TTL
|
||||
queries[i].ttl = ttl;
|
||||
save_reply_type(flags, i, response);
|
||||
|
||||
// Hereby, this query is now fully determined
|
||||
queries[i].complete = true;
|
||||
|
||||
// Save response time (relative time)
|
||||
queries[i].response = response.tv_sec*10000 + response.tv_usec/100 - queries[i].response;
|
||||
}
|
||||
}
|
||||
else if(debug)
|
||||
else
|
||||
{
|
||||
logg("*************************** unknown CACHE reply (2) ***************************");
|
||||
print_flags(flags);
|
||||
@@ -580,45 +567,6 @@ void FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg,
|
||||
disable_thread_lock();
|
||||
}
|
||||
|
||||
void storeIP(int i, char *ip)
|
||||
{
|
||||
validate_access("queries", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
int domainID = queries[i].domainID;
|
||||
validate_access("domains", domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
if(queries[i].type == TYPE_A) // IPv4 query
|
||||
{
|
||||
// First check if entry is already set
|
||||
if(domains[domainID].IPv4 != NULL)
|
||||
{
|
||||
if(strcmp(domains[domainID].IPv4, ip) != 0)
|
||||
{
|
||||
free(domains[domainID].IPv4);
|
||||
domains[domainID].IPv4 = strdup(ip);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
domains[domainID].IPv4 = strdup(ip);
|
||||
}
|
||||
}
|
||||
else if(queries[i].type == TYPE_AAAA) // IPv6 query
|
||||
{
|
||||
// First check if entry is already set
|
||||
if(domains[domainID].IPv6 != NULL)
|
||||
{
|
||||
if(strcmp(domains[domainID].IPv6, ip) != 0)
|
||||
{
|
||||
free(domains[domainID].IPv6);
|
||||
domains[domainID].IPv6 = strdup(ip);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
domains[domainID].IPv6 = strdup(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FTL_dnssec(int status, int id)
|
||||
{
|
||||
// Process DNSSEC result for a domain
|
||||
@@ -647,11 +595,11 @@ void FTL_dnssec(int status, int id)
|
||||
|
||||
// Iterate through possible values
|
||||
if(status == STAT_SECURE)
|
||||
domains[queries[i].domainID].dnssec = DNSSEC_SECURE;
|
||||
queries[i].dnssec = DNSSEC_SECURE;
|
||||
else if(status == STAT_INSECURE)
|
||||
domains[queries[i].domainID].dnssec = DNSSEC_INSECURE;
|
||||
queries[i].dnssec = DNSSEC_INSECURE;
|
||||
else
|
||||
domains[queries[i].domainID].dnssec = DNSSEC_BOGUS;
|
||||
queries[i].dnssec = DNSSEC_BOGUS;
|
||||
|
||||
disable_thread_lock();
|
||||
}
|
||||
@@ -667,40 +615,41 @@ void print_flags(unsigned int flags)
|
||||
free(flagstr);
|
||||
}
|
||||
|
||||
void save_reply_type(unsigned int flags, int queryID)
|
||||
void save_reply_type(unsigned int flags, int queryID, struct timeval response)
|
||||
{
|
||||
// Iterate through possible values
|
||||
validate_access("queries", queryID, false, __LINE__, __FUNCTION__, __FILE__);
|
||||
int domainID = queries[queryID].domainID;
|
||||
validate_access("domains", domainID, false, __LINE__, __FUNCTION__, __FILE__);
|
||||
int replyID = queries[queryID].type == TYPE_A ? 0 : 1;
|
||||
if(flags & F_NEG)
|
||||
{
|
||||
if(flags & F_NXDOMAIN)
|
||||
{
|
||||
// NXDOMAIN
|
||||
domains[domainID].reply[replyID] = REPLY_NXDOMAIN;
|
||||
queries[queryID].reply = REPLY_NXDOMAIN;
|
||||
counters.reply_NXDOMAIN++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NODATA(-IPv6)
|
||||
domains[domainID].reply[replyID] = REPLY_NODATA;
|
||||
queries[queryID].reply = REPLY_NODATA;
|
||||
counters.reply_NODATA++;
|
||||
}
|
||||
}
|
||||
else if(flags & F_CNAME)
|
||||
{
|
||||
// <CNAME>
|
||||
domains[domainID].reply[replyID] = REPLY_CNAME;
|
||||
queries[queryID].reply = REPLY_CNAME;
|
||||
counters.reply_CNAME++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Valid IP
|
||||
domains[domainID].reply[replyID] = REPLY_IP;
|
||||
queries[queryID].reply = REPLY_IP;
|
||||
counters.reply_IP++;
|
||||
}
|
||||
|
||||
// Save response time (relative time)
|
||||
queries[queryID].response = converttimeval(response) -
|
||||
queries[queryID].response;
|
||||
}
|
||||
|
||||
pthread_t telnet_listenthreadv4;
|
||||
@@ -763,7 +712,7 @@ void FTL_fork_and_bind_sockets(void)
|
||||
}
|
||||
}
|
||||
|
||||
// defined in dnsmasq/cache.c
|
||||
// int cache_inserted, cache_live_freed are defined in dnsmasq/cache.c
|
||||
extern int cache_inserted, cache_live_freed;
|
||||
void getCacheInformation(int *sock)
|
||||
{
|
||||
@@ -781,7 +730,7 @@ void getCacheInformation(int *sock)
|
||||
|
||||
void FTL_forwarding_failed(struct server *server)
|
||||
{
|
||||
// Save that this query got forwarded to an updtream server
|
||||
// Save that this query got forwarded to an upstream server
|
||||
enable_thread_lock();
|
||||
char dest[ADDRSTRLEN];
|
||||
if(server->addr.sa.sa_family == AF_INET)
|
||||
@@ -802,3 +751,10 @@ void FTL_forwarding_failed(struct server *server)
|
||||
disable_thread_lock();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long converttimeval(struct timeval time)
|
||||
{
|
||||
// Convert time from struct timeval into units
|
||||
// of 10*milliseconds
|
||||
return time.tv_sec*10000 + time.tv_usec/100;
|
||||
}
|
||||
|
||||
+2
-2
@@ -11,8 +11,8 @@ extern int socketfd, telnetfd4, telnetfd6;
|
||||
|
||||
void FTL_new_query(unsigned int flags, char *name, struct all_addr *addr, char *types, int id);
|
||||
void FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int id);
|
||||
void FTL_reply(unsigned short flags, char *name, struct all_addr *addr, unsigned long ttl, int id);
|
||||
void FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char * arg, unsigned long ttl, int id);
|
||||
void FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id);
|
||||
void FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char * arg, int id);
|
||||
void FTL_dnssec(int status, int id);
|
||||
void FTL_dnsmasq_reload(void);
|
||||
void FTL_fork_and_bind_sockets(void);
|
||||
|
||||
@@ -66,6 +66,12 @@ void *GC_thread(void *val)
|
||||
validate_access("domains", queries[i].domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
domains[queries[i].domainID].count--;
|
||||
|
||||
// Get indices and validate memory access
|
||||
int timeidx = queries[i].timeidx;
|
||||
validate_access("overTime", timeidx, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
int domainID = queries[i].domainID;
|
||||
validate_access("domains", domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
// Change other counters according to status of this query
|
||||
switch(queries[i].status)
|
||||
{
|
||||
@@ -76,38 +82,31 @@ void *GC_thread(void *val)
|
||||
case QUERY_GRAVITY:
|
||||
// Blocked by Pi-hole's blocking lists
|
||||
counters.blocked--;
|
||||
validate_access("overTime", queries[i].timeidx, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
overTime[queries[i].timeidx].blocked--;
|
||||
validate_access("domains", queries[i].domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
domains[queries[i].domainID].blockedcount--;
|
||||
overTime[timeidx].blocked--;
|
||||
domains[domainID].blockedcount--;
|
||||
break;
|
||||
case QUERY_FORWARDED:
|
||||
// Forwarded to an upstream DNS server
|
||||
counters.forwardedqueries--;
|
||||
overTime[timeidx].forwarded--;
|
||||
validate_access("forwarded", queries[i].forwardID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
forwarded[queries[i].forwardID].count--;
|
||||
// Maybe we have to adjust total counters depending on the reply type
|
||||
break;
|
||||
case QUERY_CACHE:
|
||||
// Answered from local cache _or_ local config
|
||||
counters.cached--;
|
||||
validate_access("overTime", queries[i].timeidx, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
overTime[queries[i].timeidx].cached--;
|
||||
overTime[timeidx].cached--;
|
||||
break;
|
||||
case QUERY_WILDCARD:
|
||||
counters.wildcardblocked--;
|
||||
validate_access("overTime", queries[i].timeidx, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
overTime[queries[i].timeidx].blocked--;
|
||||
validate_access("domains", queries[i].domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
domains[queries[i].domainID].blockedcount--;
|
||||
overTime[timeidx].blocked--;
|
||||
domains[domainID].blockedcount--;
|
||||
break;
|
||||
case QUERY_BLACKLIST:
|
||||
// Blocked by user's black list
|
||||
counters.blocked--;
|
||||
validate_access("overTime", queries[i].timeidx, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
overTime[queries[i].timeidx].blocked--;
|
||||
validate_access("domains", queries[i].domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
domains[queries[i].domainID].blockedcount--;
|
||||
overTime[timeidx].blocked--;
|
||||
domains[domainID].blockedcount--;
|
||||
break;
|
||||
default:
|
||||
/* That cannot happen */
|
||||
@@ -115,29 +114,27 @@ void *GC_thread(void *val)
|
||||
}
|
||||
|
||||
// Update reply counters
|
||||
int j;
|
||||
for(j = 0; j < 2; j++) // 0 = IPv4, 1 = IPv6
|
||||
switch(domains[queries[i].domainID].reply[j])
|
||||
{
|
||||
case REPLY_NODATA: // NODATA(-IPv6)
|
||||
counters.reply_NODATA--;
|
||||
break;
|
||||
switch(queries[i].reply)
|
||||
{
|
||||
case REPLY_NODATA: // NODATA(-IPv6)
|
||||
counters.reply_NODATA--;
|
||||
break;
|
||||
|
||||
case REPLY_NXDOMAIN: // NXDOMAIN
|
||||
counters.reply_NXDOMAIN--;
|
||||
break;
|
||||
case REPLY_NXDOMAIN: // NXDOMAIN
|
||||
counters.reply_NXDOMAIN--;
|
||||
break;
|
||||
|
||||
case REPLY_CNAME: // <CNAME>
|
||||
counters.reply_CNAME--;
|
||||
break;
|
||||
case REPLY_CNAME: // <CNAME>
|
||||
counters.reply_CNAME--;
|
||||
break;
|
||||
|
||||
case REPLY_IP: // valid IP
|
||||
counters.reply_IP--;
|
||||
break;
|
||||
case REPLY_IP: // valid IP
|
||||
counters.reply_IP--;
|
||||
break;
|
||||
|
||||
default: // Incomplete query, do nothing
|
||||
break;
|
||||
}
|
||||
default: // Incomplete query, do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
// Update type counters
|
||||
if(queries[i].type >= TYPE_A && queries[i].type < TYPE_MAX)
|
||||
|
||||
Reference in New Issue
Block a user