mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-28 11:43:25 +02:00
100 lines
3.9 KiB
Diff
100 lines
3.9 KiB
Diff
From cbc652423403e3cef00e00240f6beef713142246 Mon Sep 17 00:00:00 2001
|
|
From: Simon Kelley <simon@thekelleys.org.uk>
|
|
Date: Sun, 21 Dec 2014 21:21:53 +0000
|
|
Subject: [PATCH] Make caching work for CNAMEs pointing to A/AAAA records
|
|
shadowed in /etc/hosts
|
|
|
|
If the answer to an upstream query is a CNAME which points to an
|
|
A/AAAA record which also exists in /etc/hosts and friends, then
|
|
caching is suppressed, to avoid inconsistent answers. This is
|
|
now modified to allow caching when the upstream and local A/AAAA
|
|
records have the same value.
|
|
---
|
|
src/cache.c | 34 +++++++++++++++++++++++++---------
|
|
1 file changed, 25 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/src/cache.c b/src/cache.c
|
|
index f9e1d31..ff1ca6f 100644
|
|
--- a/src/cache.c
|
|
+++ b/src/cache.c
|
|
@@ -322,7 +322,7 @@ static int is_expired(time_t now, struct crec *crecp)
|
|
return 1;
|
|
}
|
|
|
|
-static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
|
|
+static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
|
|
{
|
|
/* Scan and remove old entries.
|
|
If (flags & F_FORWARD) then remove any forward entries for name and any expired
|
|
@@ -331,8 +331,8 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
|
entries in the whole cache.
|
|
If (flags == 0) remove any expired entries in the whole cache.
|
|
|
|
- In the flags & F_FORWARD case, the return code is valid, and returns zero if the
|
|
- name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
|
|
+ In the flags & F_FORWARD case, the return code is valid, and returns a non-NULL pointer
|
|
+ to a cache entry if the name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
|
|
|
|
We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal>
|
|
so that when we hit an entry which isn't reverse and is immortal, we're done. */
|
|
@@ -361,7 +361,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
|
(((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))
|
|
{
|
|
if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
|
|
- return 0;
|
|
+ return crecp;
|
|
*up = crecp->hash_next;
|
|
cache_unlink(crecp);
|
|
cache_free(crecp);
|
|
@@ -378,7 +378,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
|
crecp->addr.sig.type_covered == addr->addr.dnssec.type))
|
|
{
|
|
if (crecp->flags & F_CONFIG)
|
|
- return 0;
|
|
+ return crecp;
|
|
*up = crecp->hash_next;
|
|
cache_unlink(crecp);
|
|
cache_free(crecp);
|
|
@@ -423,7 +423,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
|
up = &crecp->hash_next;
|
|
}
|
|
|
|
- return 1;
|
|
+ return NULL;
|
|
}
|
|
|
|
/* Note: The normal calling sequence is
|
|
@@ -471,10 +471,26 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
|
|
return NULL;
|
|
|
|
/* First remove any expired entries and entries for the name/address we
|
|
- are currently inserting. Fail if we attempt to delete a name from
|
|
- /etc/hosts or DHCP. */
|
|
- if (!cache_scan_free(name, addr, now, flags))
|
|
+ are currently inserting. */
|
|
+ if ((new = cache_scan_free(name, addr, now, flags)))
|
|
{
|
|
+ /* We're trying to insert a record over one from
|
|
+ /etc/hosts or DHCP, or other config. If the
|
|
+ existing record is for an A or AAAA and
|
|
+ the record we're trying to insert is the same,
|
|
+ just drop the insert, but don't error the whole process. */
|
|
+ if ((flags & (F_IPV4 | F_IPV6)) && (flags & F_FORWARD))
|
|
+ {
|
|
+ if ((flags & F_IPV4) && (new->flags & F_IPV4) &&
|
|
+ new->addr.addr.addr.addr4.s_addr == addr->addr.addr4.s_addr)
|
|
+ return new;
|
|
+#ifdef HAVE_IPV6
|
|
+ else if ((flags & F_IPV6) && (new->flags & F_IPV6) &&
|
|
+ IN6_ARE_ADDR_EQUAL(&new->addr.addr.addr.addr6, &addr->addr.addr6))
|
|
+ return new;
|
|
+#endif
|
|
+ }
|
|
+
|
|
insert_error = 1;
|
|
return NULL;
|
|
}
|
|
--
|
|
1.7.10.4
|
|
|