summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Derigs <dl6er@dl6er.de>2022-10-16 22:08:45 +0100
committerSimon Kelley <simon@thekelleys.org.uk>2022-10-16 22:10:48 +0100
commit0017dd74d519d6d963fb8c0b4f07e69e55a46a13 (patch)
treeaaa96f8b0ce38921bba2bb7180a6e47b1d55cab6
parent0ba25a05122e86e14c3b00e54fa76ea9421eeeab (diff)
downloaddnsmasq-0017dd74d519d6d963fb8c0b4f07e69e55a46a13.tar.gz
Enhance --hostdir so that records are automatically removed when re-reading.
Initial patch from Dominik Derigs, re-written by Simon Kelley.
-rw-r--r--CHANGELOG4
-rw-r--r--man/dnsmasq.83
-rw-r--r--src/cache.c21
-rw-r--r--src/dnsmasq.h1
-rw-r--r--src/inotify.c6
5 files changed, 33 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 1d2391e..fd4994d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,6 +18,10 @@ version 2.88
flushed when its TTL expires, so the cache becomes
strictly least-recently-used.
+ Make --hostsdir (but NOT --dhcp-hostsdir and --dhcp-optsdir)
+ handle removal of whole files or entries within files.
+ Thanks to Dominik Derigs for the initial patches for this.
+
version 2.87
Allow arbitrary prefix lengths in --rev-server and
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index 3ae3000..c7b6ee5 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -60,7 +60,8 @@ in alphabetical order.
.TP
.B --hostsdir=<path>
Read all the hosts files contained in the directory. New or changed files
-are read automatically. See \fB--dhcp-hostsdir\fP for details.
+are read automatically and modified and deleted files have removed records
+automatically deleted.
.TP
.B \-E, --expand-hosts
Add the domain to simple names (without a period) in /etc/hosts
diff --git a/src/cache.c b/src/cache.c
index 6da742c..7cb5221 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -388,6 +388,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)
{
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index f1dc4a9..de5ef32 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1304,6 +1304,7 @@ struct crec *cache_find_by_name(struct crec *crecp,
char *name, time_t now, unsigned int prot);
void cache_end_insert(void);
void cache_start_insert(void);
+unsigned int cache_remove_uid(const unsigned int uid);
int cache_recv_insert(time_t now, int fd);
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
time_t now, unsigned long ttl, unsigned int flags);
diff --git a/src/inotify.c b/src/inotify.c
index 6e1ba18..e257ec4 100644
--- a/src/inotify.c
+++ b/src/inotify.c
@@ -294,12 +294,16 @@ int inotify_check(time_t now)
strcat(path, "/");
strcat(path, in->name);
- my_syslog(LOG_INFO, _("inotify, new or changed file %s"), path);
+ my_syslog(LOG_INFO, _("inotify: new, removed or changed file %s"), path);
if (dd->flags & AH_HOSTS)
{
if ((ah = dyndir_addhosts(dd, path)))
{
+ const unsigned int removed = cache_remove_uid(ah->index);
+ if (removed > 0)
+ my_syslog(LOG_INFO, _("flushed %u outdated entries"), removed);
+
read_hostsfile(path, ah->index, 0, NULL, 0);
#ifdef HAVE_DHCP
if (daemon->dhcp || daemon->doing_dhcp6)