diff --git a/FTL.h b/FTL.h index 892ba2fb..4bbeabc3 100644 --- a/FTL.h +++ b/FTL.h @@ -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]; diff --git a/api.c b/api.c index ce33d70c..5b6f5521 100644 --- a/api.c +++ b/api.c @@ -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; } } diff --git a/database.c b/database.c index db27dfa6..260a3452 100644 --- a/database.c +++ b/database.c @@ -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 diff --git a/datastructure.c b/datastructure.c index ea9f884e..f83acc36 100644 --- a/datastructure.c +++ b/datastructure.c @@ -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++; diff --git a/dnsmasq/cache.c b/dnsmasq/cache.c index ba2d305d..6aefe187 100644 --- a/dnsmasq/cache.c +++ b/dnsmasq/cache.c @@ -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. */ diff --git a/dnsmasq/forward.c b/dnsmasq/forward.c index c1a547cf..8e2e0a7c 100644 --- a/dnsmasq/forward.c +++ b/dnsmasq/forward.c @@ -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) { diff --git a/dnsmasq/rfc1035.c b/dnsmasq/rfc1035.c index d824fc9b..9e281836 100644 --- a/dnsmasq/rfc1035.c +++ b/dnsmasq/rfc1035.c @@ -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, ""); - FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "", daemon->local_ttl, daemon->log_display_id); + FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "", 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, ""); - FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "", daemon->local_ttl, daemon->log_display_id); + FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "", 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, ""); - FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "", daemon->local_ttl, daemon->log_display_id); + FTL_cache(F_CONFIG | F_RRNAME, name, NULL, "", 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, ""); - FTL_cache(F_CONFIG | F_NEG, name, NULL, "", daemon->local_ttl, daemon->log_display_id); + FTL_cache(F_CONFIG | F_NEG, name, NULL, "", 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); } } } diff --git a/dnsmasq_interface.c b/dnsmasq_interface.c index 4342c5d1..ffd1b2b3 100644 --- a/dnsmasq_interface.c +++ b/dnsmasq_interface.c @@ -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 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 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) { // - 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; +} diff --git a/dnsmasq_interface.h b/dnsmasq_interface.h index c25142aa..5718d709 100644 --- a/dnsmasq_interface.h +++ b/dnsmasq_interface.h @@ -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); diff --git a/gc.c b/gc.c index 67e7a5dc..246dd15e 100644 --- a/gc.c +++ b/gc.c @@ -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: // - counters.reply_CNAME--; - break; + case REPLY_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)