]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/dnsmasq/0018-Make-caching-work-for-CNAMEs-pointing-to-A-AAAA-reco.patch
Merge remote-tracking branch 'mfischer/slang' into next
[people/pmueller/ipfire-2.x.git] / src / patches / dnsmasq / 0018-Make-caching-work-for-CNAMEs-pointing-to-A-AAAA-reco.patch
1 From cbc652423403e3cef00e00240f6beef713142246 Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Sun, 21 Dec 2014 21:21:53 +0000
4 Subject: [PATCH 18/98] Make caching work for CNAMEs pointing to A/AAAA records
5 shadowed in /etc/hosts
6
7 If the answer to an upstream query is a CNAME which points to an
8 A/AAAA record which also exists in /etc/hosts and friends, then
9 caching is suppressed, to avoid inconsistent answers. This is
10 now modified to allow caching when the upstream and local A/AAAA
11 records have the same value.
12 ---
13 src/cache.c | 34 +++++++++++++++++++++++++---------
14 1 file changed, 25 insertions(+), 9 deletions(-)
15
16 diff --git a/src/cache.c b/src/cache.c
17 index f9e1d31e8c99..ff1ca6f1c352 100644
18 --- a/src/cache.c
19 +++ b/src/cache.c
20 @@ -322,7 +322,7 @@ static int is_expired(time_t now, struct crec *crecp)
21 return 1;
22 }
23
24 -static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
25 +static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
26 {
27 /* Scan and remove old entries.
28 If (flags & F_FORWARD) then remove any forward entries for name and any expired
29 @@ -331,8 +331,8 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
30 entries in the whole cache.
31 If (flags == 0) remove any expired entries in the whole cache.
32
33 - In the flags & F_FORWARD case, the return code is valid, and returns zero if the
34 - name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
35 + In the flags & F_FORWARD case, the return code is valid, and returns a non-NULL pointer
36 + to a cache entry if the name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
37
38 We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal>
39 so that when we hit an entry which isn't reverse and is immortal, we're done. */
40 @@ -361,7 +361,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
41 (((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))
42 {
43 if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
44 - return 0;
45 + return crecp;
46 *up = crecp->hash_next;
47 cache_unlink(crecp);
48 cache_free(crecp);
49 @@ -378,7 +378,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
50 crecp->addr.sig.type_covered == addr->addr.dnssec.type))
51 {
52 if (crecp->flags & F_CONFIG)
53 - return 0;
54 + return crecp;
55 *up = crecp->hash_next;
56 cache_unlink(crecp);
57 cache_free(crecp);
58 @@ -423,7 +423,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
59 up = &crecp->hash_next;
60 }
61
62 - return 1;
63 + return NULL;
64 }
65
66 /* Note: The normal calling sequence is
67 @@ -471,10 +471,26 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
68 return NULL;
69
70 /* First remove any expired entries and entries for the name/address we
71 - are currently inserting. Fail if we attempt to delete a name from
72 - /etc/hosts or DHCP. */
73 - if (!cache_scan_free(name, addr, now, flags))
74 + are currently inserting. */
75 + if ((new = cache_scan_free(name, addr, now, flags)))
76 {
77 + /* We're trying to insert a record over one from
78 + /etc/hosts or DHCP, or other config. If the
79 + existing record is for an A or AAAA and
80 + the record we're trying to insert is the same,
81 + just drop the insert, but don't error the whole process. */
82 + if ((flags & (F_IPV4 | F_IPV6)) && (flags & F_FORWARD))
83 + {
84 + if ((flags & F_IPV4) && (new->flags & F_IPV4) &&
85 + new->addr.addr.addr.addr4.s_addr == addr->addr.addr4.s_addr)
86 + return new;
87 +#ifdef HAVE_IPV6
88 + else if ((flags & F_IPV6) && (new->flags & F_IPV6) &&
89 + IN6_ARE_ADDR_EQUAL(&new->addr.addr.addr.addr6, &addr->addr.addr6))
90 + return new;
91 +#endif
92 + }
93 +
94 insert_error = 1;
95 return NULL;
96 }
97 --
98 2.1.0
99