summaryrefslogtreecommitdiff
path: root/src/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cache.c')
-rw-r--r--src/cache.c81
1 files changed, 55 insertions, 26 deletions
diff --git a/src/cache.c b/src/cache.c
index 09b6dbf..abaf25e 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -835,27 +835,42 @@ static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrl
Only insert each unique address once into this hashing structure.
This complexity avoids O(n^2) divergent CPU use whilst reading
- large (10000 entry) hosts files. */
-
- /* hash address */
- for (j = 0, i = 0; i < addrlen; i++)
- j = (j*2 +((unsigned char *)addr)[i]) % hashsz;
-
- for (lookup = rhash[j]; lookup; lookup = lookup->next)
- if ((lookup->flags & cache->flags & (F_IPV4 | F_IPV6)) &&
- memcmp(&lookup->addr.addr, addr, addrlen) == 0)
- {
- cache->flags &= ~F_REVERSE;
- break;
- }
+ large (10000 entry) hosts files.
+
+ Note that we only do this process when bulk-reading hosts files,
+ for incremental reads, rhash is NULL, and we use cache lookups
+ instead.
+ */
- /* maintain address hash chain, insert new unique address */
- if (!lookup)
+ if (rhash)
{
- cache->next = rhash[j];
- rhash[j] = cache;
+ /* hash address */
+ for (j = 0, i = 0; i < addrlen; i++)
+ j = (j*2 +((unsigned char *)addr)[i]) % hashsz;
+
+ for (lookup = rhash[j]; lookup; lookup = lookup->next)
+ if ((lookup->flags & cache->flags & (F_IPV4 | F_IPV6)) &&
+ memcmp(&lookup->addr.addr, addr, addrlen) == 0)
+ {
+ cache->flags &= ~F_REVERSE;
+ break;
+ }
+
+ /* maintain address hash chain, insert new unique address */
+ if (!lookup)
+ {
+ cache->next = rhash[j];
+ rhash[j] = cache;
+ }
}
-
+ else
+ {
+ /* incremental read, lookup in cache */
+ lookup = cache_find_by_addr(NULL, addr, 0, cache->flags & (F_IPV4 | F_IPV6));
+ if (lookup && lookup->flags & F_HOSTS)
+ cache->flags &= ~F_REVERSE;
+ }
+
cache->uid = index;
memcpy(&cache->addr.addr, addr, addrlen);
cache_hash(cache);
@@ -912,7 +927,7 @@ static int gettok(FILE *f, char *token)
}
}
-static int read_hostsfile(char *filename, unsigned int index, int cache_size, struct crec **rhash, int hashsz)
+int read_hostsfile(char *filename, unsigned int index, int cache_size, struct crec **rhash, int hashsz)
{
FILE *f = fopen(filename, "r");
char *token = daemon->namebuff, *domain_suffix = NULL;
@@ -958,7 +973,7 @@ static int read_hostsfile(char *filename, unsigned int index, int cache_size, st
addr_count++;
/* rehash every 1000 names. */
- if ((name_count - cache_size) > 1000)
+ if (rhash && ((name_count - cache_size) > 1000))
{
rehash(name_count);
cache_size = name_count;
@@ -1005,10 +1020,13 @@ static int read_hostsfile(char *filename, unsigned int index, int cache_size, st
}
fclose(f);
- rehash(name_count);
-
- my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
+ if (rhash)
+ {
+ rehash(name_count);
+ my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
+ }
+
return name_count;
}
@@ -1118,14 +1136,19 @@ void cache_reload(void)
my_syslog(LOG_INFO, _("cleared cache"));
return;
}
-
+
if (!option_bool(OPT_NO_HOSTS))
total_size = read_hostsfile(HOSTSFILE, SRC_HOSTS, total_size, (struct crec **)daemon->packet, revhashsz);
-
+
daemon->addn_hosts = expand_filelist(daemon->addn_hosts);
for (ah = daemon->addn_hosts; ah; ah = ah->next)
if (!(ah->flags & AH_INACTIVE))
total_size = read_hostsfile(ah->fname, ah->index, total_size, (struct crec **)daemon->packet, revhashsz);
+
+#ifdef HAVE_INOTIFY
+ set_dynamic_inotify(AH_HOSTS, total_size, (struct crec **)daemon->packet, revhashsz);
+#endif
+
}
#ifdef HAVE_DHCP
@@ -1505,7 +1528,13 @@ char *record_source(unsigned int index)
for (ah = daemon->addn_hosts; ah; ah = ah->next)
if (ah->index == index)
return ah->fname;
-
+
+#ifdef HAVE_INOTIFY
+ for (ah = daemon->dynamic_dirs; ah; ah = ah->next)
+ if (ah->index == index)
+ return ah->fname;
+#endif
+
return "<unknown>";
}