Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update embedded dnsmasq to v2.88test3 #1469

Merged
merged 46 commits into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
f3bf548
Add --port-limit option.
simonkelley Aug 17, 2022
c7a4c2d
Add --fast-dns-retry option.
simonkelley Aug 21, 2022
cf06741
Add --use-stale-cache option.
simonkelley Aug 29, 2022
00f7c4e
Remove fast-retry development logging.
simonkelley Sep 6, 2022
d4065af
Fix namebuff overwrite leading to wrong log after socket bind warning.
simonkelley Sep 9, 2022
281063a
Second try at port-limit option.
simonkelley Sep 9, 2022
10dcef3
Further optimisation of --port-limit.
simonkelley Sep 9, 2022
7fe84ae
Add GetServerMetrics method to DBus interface.
simonkelley Sep 12, 2022
8f2d7b5
Add stale cache replies to metrics.
simonkelley Sep 12, 2022
11119f7
Return EDE_STALE extended error when returning stale data from cache.
simonkelley Sep 12, 2022
ee80725
Remove unused vars.
simonkelley Sep 13, 2022
039e2b3
Make fast-retry more configurable and do exponential backoff.
simonkelley Sep 14, 2022
85fdfb0
Add metric for queries which never see an answer.
simonkelley Sep 15, 2022
3d5b4e2
Count NXDOMAIN replies from each server.
simonkelley Sep 15, 2022
7cae4bd
Combine server stats from all records for the same server in DBUS met…
simonkelley Sep 15, 2022
b9957e4
Keep a per-DNS-server moving average of query latency.
simonkelley Sep 15, 2022
861f529
Tweak server-selection logic in the fast-retry case.
simonkelley Sep 15, 2022
a599278
Split failed queries in retries in stat counting.
simonkelley Sep 15, 2022
5935160
Initialise modified-moving-average latency calc better.
simonkelley Sep 15, 2022
0fd2a13
Don't exclude stale-cache answers from "local answered" metric.
simonkelley Sep 16, 2022
f4e3592
Optimise cache code when stale caching in use.
simonkelley Sep 16, 2022
976e932
Add ClearMetrics Dbus method.
simonkelley Sep 16, 2022
5929989
Fix bug in --dynamic-host when interface has /16 IPv4 address.
simonkelley Oct 13, 2022
d398298
Update embedded dnsmasq to v2.88test1
DL6ER Oct 14, 2022
0dc0533
Locally blocked queries are not stale
DL6ER Oct 14, 2022
652c1e8
Improve logging of DNS record source from --hostsdir files.
DL6ER Oct 16, 2022
e8d19f7
Enhance --hostdir so that records are automatically removed when re-r…
DL6ER Oct 16, 2022
a1b66e8
Handle multiple addresses when removing duplicates in host files.
DL6ER Oct 16, 2022
4cfb84a
Fix loss of DNS servers on config reload.
simonkelley Oct 17, 2022
cdf9d9d
Add --no-round-robin option.
simonkelley Oct 18, 2022
3a6dd32
Fix in dhcpv4 rapid-commit code.
simonkelley Oct 27, 2022
779ba10
Do not (try to) re-read deleted files inside a --hostsdir.
DL6ER Oct 27, 2022
8aba33f
Inotify: make "flushed" log message more understandable.
simonkelley Oct 27, 2022
2bf2863
Reconcile "names" and "address" counts when reading hostfiles.
simonkelley Oct 30, 2022
703ee7e
Allow domain names as well is IP addresses in --server options.
DL6ER Nov 5, 2022
1b2612c
Fix breakage of --local=/domain.name/1.2.3.4 in immediately previous …
simonkelley Nov 6, 2022
891acaa
Extend specifying DNS servers by domain-name to --rev-server
simonkelley Nov 6, 2022
801f034
Add dnsmasq tag v2.88test2
DL6ER Nov 7, 2022
42c7105
Add support for dnsmasq flags F_SRV and F_STALE
DL6ER Nov 7, 2022
7ecd358
Allow FTL to analyze stale cache replies. They are assigned to a new …
DL6ER Nov 7, 2022
0ae86d2
Call freeaddrinfo() in domain_rev[46]()
simonkelley Nov 7, 2022
ed8d37b
Make specifying nameservers by name work for DBus API.
simonkelley Nov 7, 2022
1449829
Fix --server with multiple domains.
simonkelley Nov 7, 2022
2a94aef
Fix --server=/domain/#
simonkelley Nov 7, 2022
5556dd5
Add dnsmasq tag v2.88test3
DL6ER Nov 8, 2022
4b798e8
Fix incorrect three-way merge happened when importing the stale-cache…
DL6ER Nov 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
cmake_minimum_required(VERSION 2.8.12)
project(PIHOLE_FTL C)

set(DNSMASQ_VERSION pi-hole-v2.87)
set(DNSMASQ_VERSION pi-hole-v2.88test3)

add_subdirectory(src)
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
93 changes: 72 additions & 21 deletions src/dnsmasq/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ void rehash(int size)
else if (new_size <= hash_size || !(new = whine_malloc(new_size * sizeof(struct crec *))))
return;

for(i = 0; i < new_size; i++)
for (i = 0; i < new_size; i++)
new[i] = NULL;

old = hash_table;
Expand Down Expand Up @@ -234,7 +234,8 @@ static void cache_hash(struct crec *crecp)
immortal entries are at the end of the hash-chain.
This allows reverse searches and garbage collection to be optimised */

struct crec **up = hash_bucket(cache_get_name(crecp));
char *name = cache_get_name(crecp);
struct crec **up = hash_bucket(name);

if (!(crecp->flags & F_REVERSE))
{
Expand All @@ -245,6 +246,11 @@ static void cache_hash(struct crec *crecp)
while (*up && !((*up)->flags & F_IMMORTAL))
up = &((*up)->hash_next);
}

/* Preserve order when inserting the same name multiple times. */
while (*up && hostname_isequal(cache_get_name(*up), name))
up = &((*up)->hash_next);

crecp->hash_next = *up;
*up = crecp;
}
Expand Down Expand Up @@ -375,6 +381,11 @@ static int is_outdated_cname_pointer(struct crec *crecp)

static int is_expired(time_t now, struct crec *crecp)
{
/* Don't dump expired entries if we're using them, cache becomes strictly LRU in that case.
Never use expired DS or DNSKEY entries. */
if (option_bool(OPT_STALE_CACHE) && !(crecp->flags & (F_DS | F_DNSKEY)))
return 0;

if (crecp->flags & F_IMMORTAL)
return 0;

Expand All @@ -384,6 +395,27 @@ static int is_expired(time_t now, struct crec *crecp)
return 1;
}

/* Remove entries with a given UID from the cache */
unsigned int cache_remove_uid(const unsigned int uid)
{
int i;
unsigned int removed = 0;
struct crec *crecp, **up;

for (i = 0; i < hash_size; i++)
for (crecp = hash_table[i], up = &hash_table[i]; crecp; crecp = crecp->hash_next)
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && crecp->uid == uid)
{
*up = crecp->hash_next;
free(crecp);
removed++;
}
else
up = &crecp->hash_next;

return removed;
}

static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned short class, time_t now,
unsigned int flags, struct crec **target_crec, unsigned int *target_uid)
{
Expand Down Expand Up @@ -554,7 +586,7 @@ static struct crec *really_insert(char *name, union all_addr *addr, unsigned sho
{
struct crec *new, *target_crec = NULL;
union bigname *big_name = NULL;
int freed_all = flags & F_REVERSE;
int freed_all = (flags & F_REVERSE);
int free_avail = 0;
unsigned int target_uid;

Expand Down Expand Up @@ -629,8 +661,12 @@ static struct crec *really_insert(char *name, union all_addr *addr, unsigned sho
{
/* For DNSSEC records, uid holds class. */
free_avail = 1; /* Must be free space now. */

/* condition valid when stale-caching */
if (difftime(now, new->ttd) < 0)
daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++;

cache_scan_free(cache_get_name(new), &new->addr, new->uid, now, new->flags, NULL, NULL);
daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++;
}
else
{
Expand Down Expand Up @@ -693,7 +729,7 @@ static struct crec *really_insert(char *name, union all_addr *addr, unsigned sho
new->ttd = now + (time_t)ttl;
new->next = new_chain;
new_chain = new;

return new;
}

Expand Down Expand Up @@ -871,7 +907,7 @@ int cache_find_non_terminal(char *name, time_t now)
struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned int prot)
{
struct crec *ans;
int no_rr = prot & F_NO_RR;
int no_rr = (prot & F_NO_RR) || option_bool(OPT_NORR);

prot &= ~F_NO_RR;

Expand Down Expand Up @@ -1019,16 +1055,17 @@ struct crec *cache_find_by_addr(struct crec *crecp, union all_addr *addr,
void add_hosts_entry(struct crec *cache, union all_addr *addr, int addrlen,
unsigned int index, struct crec **rhash, int hashsz)
{
struct crec *lookup = cache_find_by_name(NULL, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6));
int i;
unsigned int j;
struct crec *lookup = NULL;

/* Remove duplicates in hosts files. */
if (lookup && (lookup->flags & F_HOSTS) && memcmp(&lookup->addr, addr, addrlen) == 0)
{
free(cache);
return;
}
while ((lookup = cache_find_by_name(lookup, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6))))
if ((lookup->flags & F_HOSTS) && memcmp(&lookup->addr, addr, addrlen) == 0)
{
free(cache);
return;
}

/* Ensure there is only one address -> name mapping (first one trumps)
We do this by steam here, The entries are kept in hash chains, linked
Expand Down Expand Up @@ -1133,7 +1170,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
{
FILE *f = fopen(filename, "r");
char *token = daemon->namebuff, *domain_suffix = NULL;
int addr_count = 0, name_count = cache_size, lineno = 1;
int names_done = 0, name_count = cache_size, lineno = 1;
unsigned int flags = 0;
union all_addr addr;
int atnl, addrlen = 0;
Expand Down Expand Up @@ -1169,8 +1206,6 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
continue;
}

addr_count++;

/* rehash every 1000 names. */
if (rhash && ((name_count - cache_size) > 1000))
{
Expand Down Expand Up @@ -1202,6 +1237,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
cache->ttd = daemon->local_ttl;
add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
name_count++;
names_done++;
}
if ((cache = whine_malloc(SIZEOF_BARE_CREC + strlen(canon) + 1)))
{
Expand All @@ -1210,6 +1246,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
cache->ttd = daemon->local_ttl;
add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
name_count++;
names_done++;
}
free(canon);

Expand All @@ -1226,7 +1263,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
if (rhash)
rehash(name_count);

my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
my_syslog(LOG_INFO, _("read %s - %d names"), filename, names_done);

return name_count;
}
Expand Down Expand Up @@ -1765,6 +1802,8 @@ void dump_cache(time_t now)
daemon->cachesize, daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED], daemon->metrics[METRIC_DNS_CACHE_INSERTED]);
my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"),
daemon->metrics[METRIC_DNS_QUERIES_FORWARDED], daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]);
if (option_bool(OPT_STALE_CACHE))
my_syslog(LOG_INFO, _("queries answered from stale cache %u"), daemon->metrics[METRIC_DNS_STALE_ANSWERED]);
#ifdef HAVE_AUTH
my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->metrics[METRIC_DNS_AUTH_ANSWERED]);
#endif
Expand All @@ -1779,16 +1818,23 @@ void dump_cache(time_t now)
if (!(serv->flags & SERV_MARK))
{
int port;
unsigned int queries = 0, failed_queries = 0;
unsigned int queries = 0, failed_queries = 0, nxdomain_replies = 0, retrys = 0;
unsigned int sigma_latency = 0, count_latency = 0;

for (serv1 = serv; serv1; serv1 = serv1->next)
if (!(serv1->flags & SERV_MARK) && sockaddr_isequal(&serv->addr, &serv1->addr))
{
serv1->flags |= SERV_MARK;
queries += serv1->queries;
failed_queries += serv1->failed_queries;
nxdomain_replies += serv1->nxdomain_replies;
retrys += serv1->retrys;
sigma_latency += serv1->query_latency;
count_latency++;
}
port = prettyprint_addr(&serv->addr, daemon->addrbuff);
my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried or failed %u"), daemon->addrbuff, port, queries, failed_queries);
my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried %u, failed %u, nxdomain replies %u, avg. latency %ums"),
daemon->addrbuff, port, queries, retrys, failed_queries, nxdomain_replies, sigma_latency/count_latency);
}

if (option_bool(OPT_DEBUG) || option_bool(OPT_LOG))
Expand Down Expand Up @@ -1883,6 +1929,7 @@ void dump_cache(time_t now)
char *record_source(unsigned int index)
{
struct hostsfile *ah;
struct dyndir *dd;

if (index == SRC_CONFIG)
return "config";
Expand All @@ -1894,9 +1941,11 @@ char *record_source(unsigned int index)
return ah->fname;

#ifdef HAVE_INOTIFY
for (ah = daemon->dynamic_dirs; ah; ah = ah->next)
if (ah->index == index)
return ah->fname;
/* Dynamic directories contain multiple files */
for (dd = daemon->dynamic_dirs; dd; dd = dd->next)
for (ah = dd->files; ah; ah = ah->next)
if (ah->index == index)
return ah->fname;
#endif

return "<unknown>";
Expand Down Expand Up @@ -2124,6 +2173,8 @@ void _log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
name = arg;
verb = daemon->addrbuff;
}
else if (flags & F_STALE)
source = "cached-stale";
else
source = "cached";

Expand Down
2 changes: 2 additions & 0 deletions src/dnsmasq/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define KEYBLOCK_LEN 40 /* choose to minimise fragmentation when storing DNSSEC keys */
#define DNSSEC_WORK 50 /* Max number of queries to validate one question */
#define TIMEOUT 10 /* drop UDP queries after TIMEOUT seconds */
#define SMALL_PORT_RANGE 30 /* If DNS port range is smaller than this, use different allocation. */
#define FORWARD_TEST 1000 /* try all servers every 1000 queries */
#define FORWARD_TIME 600 /* or 10 minutes */
#define UDP_TEST_TIME 60 /* How often to reset our idea of max packet size. */
Expand Down Expand Up @@ -60,6 +61,7 @@
#define SOA_EXPIRY 1209600 /* SOA expiry default */
#define LOOP_TEST_DOMAIN "test" /* domain for loop testing, "test" is reserved by RFC 2606 and won't therefore clash */
#define LOOP_TEST_TYPE T_TXT
#define DEFAULT_FAST_RETRY 1000 /* ms, default delay before fast retry */

/* compile-time options: uncomment below to enable or do eg.
make COPTS=-DHAVE_BROKEN_RTC
Expand Down
Loading