mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-19 05:38:00 +00:00
dnsmasq: backport latest pre2.81 patches
f52bb5b fix previous commit
18eac67 Fix entries in /etc/hosts disabling static leases.
f8c77ed Fix removal of DHCP_CLIENT_MAC options from DHCPv6 relay replies.
4bf62f6 Tidy cache_blockdata_free()
9c0d445 Fix e7bfd556c079c8b5e7425aed44abc35925b24043 to actually work.
2896e24 Check for not(DS or DNSKEY) in is_outdated_cname_pointer()
a90f09d Fix crash freeing negative SRV cache entries.
5b99eae Cache SRV records.
2daca52 Fix typo in ra-param man page section.
2c59473 File logic bug in cache-marshalling code. Introduced a couple of commits back.
cc921df Remove nested struct/union in cache records and all_addr.
ab194ed Futher address union tidying.
65a01b7
Tidy address-union handling: move class into explicit argument.
bde4647 Tidy all_addr union, merge log and rcode fields.
e7bfd55 Alter DHCP address selection after DECLINE in consec-addr mode. Avoid offering the same address after a recieving a DECLINE message to stop an infinite protocol loop. This has long been done in default address allocation mode: this adds similar behaviour when allocaing addresses consecutively.
The most relevant fix for openwrt is 18eac67 (& my own local f52bb5b
which fixes a missing bracket silly) To quote the patch:
It is possible for a config entry to have one address family specified by a
dhcp-host directive and the other added from /etc/hosts. This is especially
common on OpenWrt because it uses odhcpd for DHCPv6 and IPv6 leases are
imported into dnsmasq via a hosts file.
To handle this case there need to be separate *_HOSTS flags for IPv4 and IPv6.
Otherwise when the hosts file is reloaded it will clear the CONFIG_ADDR(6) flag
which was set by the dhcp-host directive.
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
This commit is contained in:
parent
63a2ed3ba5
commit
7541d30c9c
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dnsmasq
|
||||
PKG_VERSION:=2.80
|
||||
PKG_RELEASE:=5
|
||||
PKG_RELEASE:=6
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
|
||||
|
@ -1,7 +1,7 @@
|
||||
From a799ca0c6314ad73a97bc6c89382d2712a9c0b0e Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Thu, 18 Oct 2018 19:35:29 +0100
|
||||
Subject: [PATCH 01/11] Impove cache behaviour for TCP connections.
|
||||
Subject: [PATCH 01/30] Impove cache behaviour for TCP connections.
|
||||
|
||||
For ease of implementaion, dnsmasq has always forked a new process to
|
||||
handle each incoming TCP connection. A side-effect of this is that any
|
||||
|
@ -1,7 +1,7 @@
|
||||
From a220545c4277cba534be5ef4638b5076fc7d2cf4 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Mon, 22 Oct 2018 18:21:48 +0100
|
||||
Subject: [PATCH 02/11] Ensure that AD bit is reset on answers from
|
||||
Subject: [PATCH 02/30] Ensure that AD bit is reset on answers from
|
||||
--address=/<domain>/<address>.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
|
@ -1,7 +1,7 @@
|
||||
From ee8750451b49d27b180517a4e35b636be0fae575 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Tue, 23 Oct 2018 22:10:17 +0100
|
||||
Subject: [PATCH 03/11] Remove ability to compile without IPv6 support.
|
||||
Subject: [PATCH 03/30] Remove ability to compile without IPv6 support.
|
||||
|
||||
This was the source of a large number of #ifdefs, originally
|
||||
included for use with old embedded libc versions. I'm
|
||||
|
@ -1,7 +1,7 @@
|
||||
From cf5984367bc6a949e3803a576512c5a7bc48ebab Mon Sep 17 00:00:00 2001
|
||||
From: Vladislav Grishenko <themiron@mail.ru>
|
||||
Date: Thu, 18 Oct 2018 04:55:21 +0500
|
||||
Subject: [PATCH 04/11] Don't forward *.bind/*.server queries upstream
|
||||
Subject: [PATCH 04/30] Don't forward *.bind/*.server queries upstream
|
||||
|
||||
Chaos .bind and .server (RFC4892) zones are local, therefore
|
||||
don't forward queries upstream to avoid mixing with supported
|
||||
|
@ -1,7 +1,7 @@
|
||||
From cbb5b17ad8e03e08ade62376a4f6a2066e55960d Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Tue, 23 Oct 2018 23:45:57 +0100
|
||||
Subject: [PATCH 05/11] Fix logging in cf5984367bc6a949e3803a576512c5a7bc48ebab
|
||||
Subject: [PATCH 05/30] Fix logging in cf5984367bc6a949e3803a576512c5a7bc48ebab
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 6f7812d97bc8f87004c0a5069c6c94c64af78106 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Tue, 23 Oct 2018 23:54:44 +0100
|
||||
Subject: [PATCH 06/11] Fix spurious AD flags in some DNS replies from local
|
||||
Subject: [PATCH 06/30] Fix spurious AD flags in some DNS replies from local
|
||||
config.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 24b87607c1353e94689e8a2190571ab3f3b36f31 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||
Date: Wed, 24 Oct 2018 22:30:18 +0100
|
||||
Subject: [PATCH 07/11] Do not rely on dead code elimination, use array
|
||||
Subject: [PATCH 07/30] Do not rely on dead code elimination, use array
|
||||
instead. Make options bits derived from size and count. Use size of option
|
||||
bits and last supported bit in computation. No new change would be required
|
||||
when new options are added. Just change OPT_LAST constant.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 3a5a84cdd1488bad118eeac72d09a60299bca744 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Wed, 31 Oct 2018 21:30:13 +0000
|
||||
Subject: [PATCH 08/11] Fix Makefile lines generating UBUS linker config.
|
||||
Subject: [PATCH 08/30] Fix Makefile lines generating UBUS linker config.
|
||||
|
||||
If arg2 of pkg-wrapper is "--copy", then arg1 is NOT the name of
|
||||
the package manager (--copy doesn't invoke it) it's a secondary
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 122392e0b352507cabb9e982208d35d2e56902e0 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Wed, 31 Oct 2018 22:24:02 +0000
|
||||
Subject: [PATCH 09/11] Revert 68f6312d4bae30b78daafcd6f51dc441b8685b1e
|
||||
Subject: [PATCH 09/30] Revert 68f6312d4bae30b78daafcd6f51dc441b8685b1e
|
||||
|
||||
The above is intended to increase robustness, but actually does the
|
||||
opposite. The problem is that by ignoring SERVFAIL messages and hoping
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 48d12f14c9c0fc8cf943b52774c3892517dd72d4 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Fri, 2 Nov 2018 21:55:04 +0000
|
||||
Subject: [PATCH 10/11] Remove the NO_FORK compile-time option, and support for
|
||||
Subject: [PATCH 10/30] Remove the NO_FORK compile-time option, and support for
|
||||
uclinux.
|
||||
|
||||
In an era where everything has an MMU, this looks like
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 59e470381f84f2fdf0640c7bc67827f3f0c64784 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||
Date: Fri, 2 Nov 2018 22:39:39 +0000
|
||||
Subject: [PATCH 11/11] Free config file values on parsing errors.
|
||||
Subject: [PATCH 11/30] Free config file values on parsing errors.
|
||||
|
||||
This time I have a little bit more controversal patches. But I think
|
||||
still useful. They fixes memory leaks that might occur in some cases.
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 07e25da5bf26d46aad4f1d2eb19b260789182004 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Sun, 16 Dec 2018 18:21:58 +0000
|
||||
Subject: [PATCH 13/30] Treat DS and DNSKEY queries being forwarded the same as
|
||||
those locally originated.
|
||||
|
||||
The queries will not be forwarded to a server for a domain, unless
|
||||
there's a trust anchor provided for that domain. This allows, especially,
|
||||
suitable proof of non-existance for DS records to come from
|
||||
the parent domain for domains which are not signed.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/rfc1035.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/src/rfc1035.c
|
||||
+++ b/src/rfc1035.c
|
||||
@@ -916,6 +916,13 @@ unsigned int extract_request(struct dns_
|
||||
if (qtype == T_ANY)
|
||||
return F_IPV4 | F_IPV6;
|
||||
}
|
||||
+
|
||||
+ /* F_DNSSECOK as agument to search_servers() inhibits forwarding
|
||||
+ to servers for domains without a trust anchor. This make the
|
||||
+ behaviour for DS and DNSKEY queries we forward the same
|
||||
+ as for DS and DNSKEY queries we originate. */
|
||||
+ if (qtype == T_DS || qtype == T_DNSKEY)
|
||||
+ return F_DNSSECOK;
|
||||
|
||||
return F_QUERY;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
From 46de5d4954b470db155098001cffc357b51e50f4 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
Date: Wed, 12 Dec 2018 11:35:12 +0000
|
||||
Subject: [PATCH] ipset fix ternary order swap
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/ipset.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/src/ipset.c
|
||||
+++ b/src/ipset.c
|
||||
@@ -120,7 +120,7 @@ static int new_add_to_ipset(const char *
|
||||
struct my_nfgenmsg *nfg;
|
||||
struct my_nlattr *nested[2];
|
||||
uint8_t proto;
|
||||
- int addrsz = (af == AF_INET6) ? INADDRSZ : IN6ADDRSZ;
|
||||
+ int addrsz = (af == AF_INET6) ? IN6ADDRSZ : INADDRSZ;
|
||||
|
||||
if (strlen(setname) >= IPSET_MAXNAMELEN)
|
||||
{
|
@ -1,17 +1,19 @@
|
||||
From 668b45c29c38d440c8fce4bc994c56910adc3919 Mon Sep 17 00:00:00 2001
|
||||
From 137e9f878fafb38369eab7d9dfe84e4228ff5f89 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||
Date: Fri, 14 Dec 2018 17:03:08 +0100
|
||||
Subject: [PATCH] Fix required tags in few places
|
||||
Date: Sun, 16 Dec 2018 21:25:29 +0000
|
||||
Subject: [PATCH 14/30] Fix option parsing errors introduced in
|
||||
59e470381f84f2fdf0640c7bc67827f3f0c64784
|
||||
|
||||
Some locations were incorrectly changed to require always tags, else
|
||||
dnsmasq will not start. Fix dhcp-boot, dhcp-reply-delay and pxe-prompt.
|
||||
Thanks to Kevin Darbyshire-Bryant for spotting this.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/option.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/src/option.c
|
||||
+++ b/src/option.c
|
||||
@@ -3434,7 +3434,7 @@ static int one_opt(int option, char *arg
|
||||
@@ -3432,7 +3432,7 @@ static int one_opt(int option, char *arg
|
||||
{
|
||||
struct dhcp_netid *id = dhcp_tags(&arg);
|
||||
|
||||
@ -20,7 +22,7 @@ dnsmasq will not start. Fix dhcp-boot, dhcp-reply-delay and pxe-prompt.
|
||||
{
|
||||
ret_err(gen_err);
|
||||
}
|
||||
@@ -3485,7 +3485,7 @@ static int one_opt(int option, char *arg
|
||||
@@ -3483,7 +3483,7 @@ static int one_opt(int option, char *arg
|
||||
{
|
||||
struct dhcp_netid *id = dhcp_tags(&arg);
|
||||
|
||||
@ -29,7 +31,7 @@ dnsmasq will not start. Fix dhcp-boot, dhcp-reply-delay and pxe-prompt.
|
||||
{
|
||||
ret_err(gen_err);
|
||||
}
|
||||
@@ -3515,7 +3515,7 @@ static int one_opt(int option, char *arg
|
||||
@@ -3513,7 +3513,7 @@ static int one_opt(int option, char *arg
|
||||
new->opt = 10; /* PXE_MENU_PROMPT */
|
||||
new->netid = dhcp_tags(&arg);
|
||||
|
@ -0,0 +1,45 @@
|
||||
From 3becf468bad699bfdcb2d18d553bc72d4c79e23c Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
|
||||
Date: Wed, 12 Dec 2018 12:00:19 +0000
|
||||
Subject: [PATCH 15/30] fix ipv6 ipset bug in master
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Hi Simon,
|
||||
|
||||
Another one fallen out of the openwrt tree shake :-)
|
||||
|
||||
ipv6 ipset addresses weren’t being set correctly. patch attached
|
||||
|
||||
Cheers,
|
||||
|
||||
Kevin D-B
|
||||
|
||||
012C ACB2 28C6 C53E 9775 9123 B3A2 389B 9DE2 334A
|
||||
From b50fc0491e374186f982b019f293379955afd203 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
Date: Wed, 12 Dec 2018 11:35:12 +0000
|
||||
Subject: [PATCH] ipset fix ternary order swap
|
||||
|
||||
ee87504 Remove ability to compile without IPv6 support introduced a
|
||||
ternary operator for ip address size. Unfortunately the true/false
|
||||
order was incorrect which meant ipv6 ipset addresses were added
|
||||
incorrectly.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/ipset.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/src/ipset.c
|
||||
+++ b/src/ipset.c
|
||||
@@ -120,7 +120,7 @@ static int new_add_to_ipset(const char *
|
||||
struct my_nfgenmsg *nfg;
|
||||
struct my_nlattr *nested[2];
|
||||
uint8_t proto;
|
||||
- int addrsz = (af == AF_INET6) ? INADDRSZ : IN6ADDRSZ;
|
||||
+ int addrsz = (af == AF_INET6) ? IN6ADDRSZ : INADDRSZ;
|
||||
|
||||
if (strlen(setname) >= IPSET_MAXNAMELEN)
|
||||
{
|
@ -1,3 +1,26 @@
|
||||
From b683cf37f9f3dd3dc5d95d621ee75850d559b2e4 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
|
||||
Date: Mon, 10 Dec 2018 10:34:35 +0000
|
||||
Subject: [PATCH 16/30] build failure on master with NO_DHCPv6 and fix....
|
||||
|
||||
Hi Simon,
|
||||
|
||||
master has a build error when building without HAVE_DHCPv6
|
||||
|
||||
option.c: In function 'dhcp_context_free':
|
||||
option.c:1042:15: error: 'struct dhcp_context' has no member named 'template_interface'
|
||||
free(ctx->template_interface);
|
||||
|
||||
Sadly, need to put in a little conditional compilation ifdef'erey
|
||||
|
||||
Simplest patch in the world attached
|
||||
|
||||
Cheers,
|
||||
|
||||
Kevin D-B
|
||||
|
||||
012C ACB2 28C6 C53E 9775 9123 B3A2 389B 9DE2 334A
|
||||
|
||||
From 061eb8599636bb360e0b7fa5986935b86db39497 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
Date: Mon, 10 Dec 2018 10:07:33 +0000
|
@ -0,0 +1,57 @@
|
||||
From e7bfd556c079c8b5e7425aed44abc35925b24043 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Mon, 31 Dec 2018 20:51:15 +0000
|
||||
Subject: [PATCH 17/30] Alter DHCP address selection after DECLINE in
|
||||
consec-addr mode. Avoid offering the same address after a recieving a DECLINE
|
||||
message to stop an infinite protocol loop. This has long been done in default
|
||||
address allocation mode: this adds similar behaviour when allocaing addresses
|
||||
consecutively.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/dhcp.c | 13 +++++++++++++
|
||||
src/dhcp6.c | 11 +++++++++--
|
||||
2 files changed, 22 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/dhcp.c
|
||||
+++ b/src/dhcp.c
|
||||
@@ -754,6 +754,19 @@ int address_allocate(struct dhcp_context
|
||||
if (addr.s_addr == d->router.s_addr)
|
||||
break;
|
||||
|
||||
+ /* in consec-ip mode, skip addresses equal to
|
||||
+ the number of addresses rejected by clients. This
|
||||
+ should avoid the same client being offered the same
|
||||
+ address after it has rjected it. */
|
||||
+ if (option_bool(OPT_CONSEC_ADDR))
|
||||
+ {
|
||||
+ if (c->addr_epoch)
|
||||
+ {
|
||||
+ c->addr_epoch--;
|
||||
+ d = context; /* d non-NULL skips the address. */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Addresses which end in .255 and .0 are broken in Windows even when using
|
||||
supernetting. ie dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0
|
||||
then 192.168.0.255 is a valid IP address, but not for Windows as it's
|
||||
--- a/src/dhcp6.c
|
||||
+++ b/src/dhcp6.c
|
||||
@@ -431,8 +431,15 @@ struct dhcp_context *address6_allocate(s
|
||||
else
|
||||
{
|
||||
if (!temp_addr && option_bool(OPT_CONSEC_ADDR))
|
||||
- /* seed is largest extant lease addr in this context */
|
||||
- start = lease_find_max_addr6(c) + serial;
|
||||
+ {
|
||||
+ /* seed is largest extant lease addr in this context,
|
||||
+ skip addresses equal to the number of addresses rejected
|
||||
+ by clients. This should avoid the same client being offered the same
|
||||
+ address after it has rjected it. */
|
||||
+ start = lease_find_max_addr6(c) + serial + c->addr_epoch;
|
||||
+ if (c->addr_epoch)
|
||||
+ c->addr_epoch--;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
u64 range = 1 + addr6part(&c->end6) - addr6part(&c->start6);
|
@ -0,0 +1,80 @@
|
||||
From bde46476ee06c96e821653dfdb8fa11fe7326998 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Mon, 31 Dec 2018 23:28:24 +0000
|
||||
Subject: [PATCH 18/30] Tidy all_addr union, merge log and rcode fields.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/cache.c | 2 +-
|
||||
src/dnsmasq.h | 6 +-----
|
||||
src/forward.c | 2 +-
|
||||
src/rfc1035.c | 6 +++---
|
||||
4 files changed, 6 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -1926,7 +1926,7 @@ void log_query(unsigned int flags, char
|
||||
sprintf(daemon->addrbuff, arg, addr->addr.log.keytag, addr->addr.log.algo, addr->addr.log.digest);
|
||||
else if (flags & F_RCODE)
|
||||
{
|
||||
- unsigned int rcode = addr->addr.rcode.rcode;
|
||||
+ unsigned int rcode = addr->addr.log.rcode;
|
||||
|
||||
if (rcode == SERVFAIL)
|
||||
dest = "SERVFAIL";
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -279,12 +279,8 @@ struct all_addr {
|
||||
struct in6_addr addr6;
|
||||
/* for log_query */
|
||||
struct {
|
||||
- unsigned short keytag, algo, digest;
|
||||
+ unsigned short keytag, algo, digest, rcode;
|
||||
} log;
|
||||
- /* for log_query */
|
||||
- struct {
|
||||
- unsigned int rcode;
|
||||
- } rcode;
|
||||
/* for cache_insert of DNSKEY, DS */
|
||||
struct {
|
||||
unsigned short class, type;
|
||||
--- a/src/forward.c
|
||||
+++ b/src/forward.c
|
||||
@@ -658,7 +658,7 @@ static size_t process_reply(struct dns_h
|
||||
if (rcode != NOERROR && rcode != NXDOMAIN)
|
||||
{
|
||||
struct all_addr a;
|
||||
- a.addr.rcode.rcode = rcode;
|
||||
+ a.addr.log.rcode = rcode;
|
||||
log_query(F_UPSTREAM | F_RCODE, "error", &a, NULL);
|
||||
|
||||
return resize_packet(header, n, pheader, plen);
|
||||
--- a/src/rfc1035.c
|
||||
+++ b/src/rfc1035.c
|
||||
@@ -950,7 +950,7 @@ size_t setup_reply(struct dns_header *he
|
||||
else if (flags == F_SERVFAIL)
|
||||
{
|
||||
struct all_addr a;
|
||||
- a.addr.rcode.rcode = SERVFAIL;
|
||||
+ a.addr.log.rcode = SERVFAIL;
|
||||
log_query(F_CONFIG | F_RCODE, "error", &a, NULL);
|
||||
SET_RCODE(header, SERVFAIL);
|
||||
}
|
||||
@@ -975,7 +975,7 @@ size_t setup_reply(struct dns_header *he
|
||||
else /* nowhere to forward to */
|
||||
{
|
||||
struct all_addr a;
|
||||
- a.addr.rcode.rcode = REFUSED;
|
||||
+ a.addr.log.rcode = REFUSED;
|
||||
log_query(F_CONFIG | F_RCODE, "error", &a, NULL);
|
||||
SET_RCODE(header, REFUSED);
|
||||
}
|
||||
@@ -1374,7 +1374,7 @@ size_t answer_request(struct dns_header
|
||||
notimp = 1, auth = 0;
|
||||
if (!dryrun)
|
||||
{
|
||||
- addr.addr.rcode.rcode = NOTIMP;
|
||||
+ addr.addr.log.rcode = NOTIMP;
|
||||
log_query(F_CONFIG | F_RCODE, name, &addr, NULL);
|
||||
}
|
||||
ans = 1, sec_data = 0;
|
@ -0,0 +1,290 @@
|
||||
From 65a01b71bb433c9466e4c78a73a8d8ed218ed4e8 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Mon, 31 Dec 2018 23:56:33 +0000
|
||||
Subject: [PATCH 19/30] Tidy address-union handling: move class into explicit
|
||||
argument.
|
||||
|
||||
This moves the class argument to cache-insert into an argument,
|
||||
rather then overloading a union in the address argument. Note that
|
||||
tha class is NOT stored in the cache other than for DS/DNSKEY entries,
|
||||
so must always be C_IN except for these. The data-extraction code
|
||||
ensures this as it only attempts to cache C_IN class records.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/cache.c | 57 ++++++++++++++++++++++-----------------------------
|
||||
src/dnsmasq.h | 2 +-
|
||||
src/dnssec.c | 13 +++---------
|
||||
src/rfc1035.c | 12 +++++------
|
||||
4 files changed, 34 insertions(+), 50 deletions(-)
|
||||
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -26,7 +26,7 @@ static union bigname *big_free = NULL;
|
||||
static int bignames_left, hash_size;
|
||||
|
||||
static void make_non_terminals(struct crec *source);
|
||||
-static struct crec *really_insert(char *name, struct all_addr *addr,
|
||||
+static struct crec *really_insert(char *name, struct all_addr *addr, unsigned short class,
|
||||
time_t now, unsigned long ttl, unsigned short flags);
|
||||
|
||||
/* type->string mapping: this is also used by the name-hash function as a mixing table. */
|
||||
@@ -330,8 +330,8 @@ static int is_expired(time_t now, struct
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags,
|
||||
- struct crec **target_crec, unsigned int *target_uid)
|
||||
+static struct crec *cache_scan_free(char *name, struct all_addr *addr, unsigned short class, time_t now,
|
||||
+ unsigned short flags, struct crec **target_crec, unsigned int *target_uid)
|
||||
{
|
||||
/* Scan and remove old entries.
|
||||
If (flags & F_FORWARD) then remove any forward entries for name and any expired
|
||||
@@ -350,6 +350,8 @@ static struct crec *cache_scan_free(char
|
||||
This entry will get re-used with the same name, to preserve CNAMEs. */
|
||||
|
||||
struct crec *crecp, **up;
|
||||
+
|
||||
+ (void)class;
|
||||
|
||||
if (flags & F_FORWARD)
|
||||
{
|
||||
@@ -381,7 +383,7 @@ static struct crec *cache_scan_free(char
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
/* Deletion has to be class-sensitive for DS and DNSKEY */
|
||||
- if ((flags & crecp->flags & (F_DNSKEY | F_DS)) && crecp->uid == addr->addr.dnssec.class)
|
||||
+ if ((flags & crecp->flags & (F_DNSKEY | F_DS)) && crecp->uid == class)
|
||||
{
|
||||
if (crecp->flags & F_CONFIG)
|
||||
return crecp;
|
||||
@@ -464,7 +466,7 @@ void cache_start_insert(void)
|
||||
insert_error = 0;
|
||||
}
|
||||
|
||||
-struct crec *cache_insert(char *name, struct all_addr *addr,
|
||||
+struct crec *cache_insert(char *name, struct all_addr *addr, unsigned short class,
|
||||
time_t now, unsigned long ttl, unsigned short flags)
|
||||
{
|
||||
/* Don't log DNSSEC records here, done elsewhere */
|
||||
@@ -478,11 +480,11 @@ struct crec *cache_insert(char *name, st
|
||||
ttl = daemon->min_cache_ttl;
|
||||
}
|
||||
|
||||
- return really_insert(name, addr, now, ttl, flags);
|
||||
+ return really_insert(name, addr, class, now, ttl, flags);
|
||||
}
|
||||
|
||||
|
||||
-static struct crec *really_insert(char *name, struct all_addr *addr,
|
||||
+static struct crec *really_insert(char *name, struct all_addr *addr, unsigned short class,
|
||||
time_t now, unsigned long ttl, unsigned short flags)
|
||||
{
|
||||
struct crec *new, *target_crec = NULL;
|
||||
@@ -497,7 +499,7 @@ static struct crec *really_insert(char *
|
||||
|
||||
/* First remove any expired entries and entries for the name/address we
|
||||
are currently inserting. */
|
||||
- if ((new = cache_scan_free(name, addr, now, flags, &target_crec, &target_uid)))
|
||||
+ if ((new = cache_scan_free(name, addr, class, now, flags, &target_crec, &target_uid)))
|
||||
{
|
||||
/* We're trying to insert a record over one from
|
||||
/etc/hosts or DHCP, or other config. If the
|
||||
@@ -553,21 +555,14 @@ static struct crec *really_insert(char *
|
||||
|
||||
if (freed_all)
|
||||
{
|
||||
- struct all_addr free_addr = new->addr.addr;;
|
||||
-
|
||||
-#ifdef HAVE_DNSSEC
|
||||
- /* For DNSSEC records, addr holds class. */
|
||||
- if (new->flags & (F_DS | F_DNSKEY))
|
||||
- free_addr.addr.dnssec.class = new->uid;
|
||||
-#endif
|
||||
-
|
||||
+ /* For DNSSEC records, uid holds class. */
|
||||
free_avail = 1; /* Must be free space now. */
|
||||
- cache_scan_free(cache_get_name(new), &free_addr, now, new->flags, NULL, NULL);
|
||||
+ cache_scan_free(cache_get_name(new), &new->addr.addr, new->uid, now, new->flags, NULL, NULL);
|
||||
daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
- cache_scan_free(NULL, NULL, now, 0, NULL, NULL);
|
||||
+ cache_scan_free(NULL, NULL, class, now, 0, NULL, NULL);
|
||||
freed_all = 1;
|
||||
}
|
||||
}
|
||||
@@ -615,15 +610,13 @@ static struct crec *really_insert(char *
|
||||
else
|
||||
*cache_get_name(new) = 0;
|
||||
|
||||
- if (addr)
|
||||
- {
|
||||
#ifdef HAVE_DNSSEC
|
||||
- if (flags & (F_DS | F_DNSKEY))
|
||||
- new->uid = addr->addr.dnssec.class;
|
||||
- else
|
||||
+ if (flags & (F_DS | F_DNSKEY))
|
||||
+ new->uid = class;
|
||||
#endif
|
||||
- new->addr.addr = *addr;
|
||||
- }
|
||||
+
|
||||
+ if (addr)
|
||||
+ new->addr.addr = *addr;
|
||||
|
||||
new->ttd = now + (time_t)ttl;
|
||||
new->next = new_chain;
|
||||
@@ -747,11 +740,11 @@ int cache_recv_insert(time_t now, int fd
|
||||
{
|
||||
if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
|
||||
return 0;
|
||||
- crecp = really_insert(daemon->namebuff, &addr, now, ttl, flags);
|
||||
+ crecp = really_insert(daemon->namebuff, &addr, C_IN, now, ttl, flags);
|
||||
}
|
||||
else if (flags & F_CNAME)
|
||||
{
|
||||
- struct crec *newc = really_insert(daemon->namebuff, NULL, now, ttl, flags);
|
||||
+ struct crec *newc = really_insert(daemon->namebuff, NULL, C_IN, now, ttl, flags);
|
||||
/* This relies on the fact the the target of a CNAME immediately preceeds
|
||||
it because of the order of extraction in extract_addresses, and
|
||||
the order reversal on the new_chain. */
|
||||
@@ -780,10 +773,8 @@ int cache_recv_insert(time_t now, int fd
|
||||
|
||||
if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1))
|
||||
return 0;
|
||||
- /* Cache needs to known class for DNSSEC stuff */
|
||||
- addr.addr.dnssec.class = class;
|
||||
-
|
||||
- crecp = really_insert(daemon->namebuff, &addr, now, ttl, flags);
|
||||
+
|
||||
+ crecp = really_insert(daemon->namebuff, NULL, class, now, ttl, flags);
|
||||
|
||||
if (flags & F_DNSKEY)
|
||||
{
|
||||
@@ -1463,7 +1454,7 @@ void cache_add_dhcp_entry(char *host_nam
|
||||
}
|
||||
else if (!(crec->flags & F_DHCP))
|
||||
{
|
||||
- cache_scan_free(host_name, NULL, 0, crec->flags & (flags | F_CNAME | F_FORWARD), NULL, NULL);
|
||||
+ cache_scan_free(host_name, NULL, C_IN, 0, crec->flags & (flags | F_CNAME | F_FORWARD), NULL, NULL);
|
||||
/* scan_free deletes all addresses associated with name */
|
||||
break;
|
||||
}
|
||||
@@ -1490,7 +1481,7 @@ void cache_add_dhcp_entry(char *host_nam
|
||||
if (crec->flags & F_NEG)
|
||||
{
|
||||
flags |= F_REVERSE;
|
||||
- cache_scan_free(NULL, (struct all_addr *)host_address, 0, flags, NULL, NULL);
|
||||
+ cache_scan_free(NULL, (struct all_addr *)host_address, C_IN, 0, flags, NULL, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -1144,7 +1144,7 @@ struct crec *cache_find_by_name(struct c
|
||||
void cache_end_insert(void);
|
||||
void cache_start_insert(void);
|
||||
int cache_recv_insert(time_t now, int fd);
|
||||
-struct crec *cache_insert(char *name, struct all_addr *addr,
|
||||
+struct crec *cache_insert(char *name, struct all_addr *addr, unsigned short class,
|
||||
time_t now, unsigned long ttl, unsigned short flags);
|
||||
void cache_reload(void);
|
||||
void cache_add_dhcp_entry(char *host_name, int prot, struct all_addr *host_address, time_t ttd);
|
||||
--- a/src/dnssec.c
|
||||
+++ b/src/dnssec.c
|
||||
@@ -798,12 +798,9 @@ int dnssec_validate_by_ds(time_t now, st
|
||||
algo = *p++;
|
||||
keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
|
||||
|
||||
- /* Cache needs to known class for DNSSEC stuff */
|
||||
- a.addr.dnssec.class = class;
|
||||
-
|
||||
if ((key = blockdata_alloc((char*)p, rdlen - 4)))
|
||||
{
|
||||
- if (!(recp1 = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK)))
|
||||
+ if (!(recp1 = cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK)))
|
||||
{
|
||||
blockdata_free(key);
|
||||
return STAT_BOGUS;
|
||||
@@ -927,12 +924,9 @@ int dnssec_validate_ds(time_t now, struc
|
||||
algo = *p++;
|
||||
digest = *p++;
|
||||
|
||||
- /* Cache needs to known class for DNSSEC stuff */
|
||||
- a.addr.dnssec.class = class;
|
||||
-
|
||||
if ((key = blockdata_alloc((char*)p, rdlen - 4)))
|
||||
{
|
||||
- if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)))
|
||||
+ if (!(crecp = cache_insert(name, NULL, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)))
|
||||
{
|
||||
blockdata_free(key);
|
||||
return STAT_BOGUS;
|
||||
@@ -1021,8 +1015,7 @@ int dnssec_validate_ds(time_t now, struc
|
||||
{
|
||||
cache_start_insert();
|
||||
|
||||
- a.addr.dnssec.class = class;
|
||||
- if (!cache_insert(name, &a, now, ttl, flags))
|
||||
+ if (!cache_insert(name, NULL, class, now, ttl, flags))
|
||||
return STAT_BOGUS;
|
||||
|
||||
cache_end_insert();
|
||||
--- a/src/rfc1035.c
|
||||
+++ b/src/rfc1035.c
|
||||
@@ -701,7 +701,7 @@ int extract_addresses(struct dns_header
|
||||
goto cname_loop;
|
||||
}
|
||||
|
||||
- cache_insert(name, &addr, now, cttl, name_encoding | secflag | F_REVERSE);
|
||||
+ cache_insert(name, &addr, C_IN, now, cttl, name_encoding | secflag | F_REVERSE);
|
||||
found = 1;
|
||||
}
|
||||
|
||||
@@ -719,7 +719,7 @@ int extract_addresses(struct dns_header
|
||||
ttl = find_soa(header, qlen, NULL, doctored);
|
||||
}
|
||||
if (ttl)
|
||||
- cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | (secure ? F_DNSSECOK : 0));
|
||||
+ cache_insert(NULL, &addr, C_IN, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | (secure ? F_DNSSECOK : 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -773,7 +773,7 @@ int extract_addresses(struct dns_header
|
||||
{
|
||||
if (!cname_count--)
|
||||
return 0; /* looped CNAMES */
|
||||
- newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD | secflag);
|
||||
+ newc = cache_insert(name, NULL, C_IN, now, attl, F_CNAME | F_FORWARD | secflag);
|
||||
if (newc)
|
||||
{
|
||||
newc->addr.cname.target.cache = NULL;
|
||||
@@ -833,7 +833,7 @@ int extract_addresses(struct dns_header
|
||||
}
|
||||
#endif
|
||||
|
||||
- newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag);
|
||||
+ newc = cache_insert(name, &addr, C_IN, now, attl, flags | F_FORWARD | secflag);
|
||||
if (newc && cpp)
|
||||
{
|
||||
next_uid(newc);
|
||||
@@ -860,7 +860,7 @@ int extract_addresses(struct dns_header
|
||||
pointing at this, inherit its TTL */
|
||||
if (ttl || cpp)
|
||||
{
|
||||
- newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));
|
||||
+ newc = cache_insert(name, NULL, C_IN, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));
|
||||
if (newc && cpp)
|
||||
{
|
||||
next_uid(newc);
|
||||
@@ -1054,7 +1054,7 @@ int check_for_bogus_wildcard(struct dns_
|
||||
/* Found a bogus address. Insert that info here, since there no SOA record
|
||||
to get the ttl from in the normal processing */
|
||||
cache_start_insert();
|
||||
- cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
|
||||
+ cache_insert(name, NULL, C_IN, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
|
||||
cache_end_insert();
|
||||
|
||||
return 1;
|
@ -0,0 +1,363 @@
|
||||
From ab194ed7ca433e4e2e8b2ec338bfa4e6aa886a4b Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Tue, 1 Jan 2019 01:35:30 +0000
|
||||
Subject: [PATCH 20/30] Futher address union tidying.
|
||||
|
||||
Pass DNSKEY and DS data into cache_insert via the address argument,
|
||||
now these data types are included in struct all_addr.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/cache.c | 116 ++++++++++++++++----------------------------------
|
||||
src/dnsmasq.h | 26 +++++------
|
||||
src/dnssec.c | 53 +++++++++++------------
|
||||
3 files changed, 73 insertions(+), 122 deletions(-)
|
||||
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -202,9 +202,9 @@ static void cache_hash(struct crec *crec
|
||||
static void cache_blockdata_free(struct crec *crecp)
|
||||
{
|
||||
if (crecp->flags & F_DNSKEY)
|
||||
- blockdata_free(crecp->addr.key.keydata);
|
||||
+ blockdata_free(crecp->addr.addr.addr.key.keydata);
|
||||
else if ((crecp->flags & F_DS) && !(crecp->flags & F_NEG))
|
||||
- blockdata_free(crecp->addr.ds.keydata);
|
||||
+ blockdata_free(crecp->addr.addr.addr.ds.keydata);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -659,33 +659,22 @@ void cache_end_insert(void)
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->ttd, sizeof(new_chain->ttd), 0);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), 0);
|
||||
|
||||
- if (flags & (F_IPV4 | F_IPV6))
|
||||
+ if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS))
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0);
|
||||
#ifdef HAVE_DNSSEC
|
||||
- else if (flags & F_DNSKEY)
|
||||
+ if (flags & F_DNSKEY)
|
||||
{
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
|
||||
- read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.key.algo, sizeof(new_chain->addr.key.algo), 0);
|
||||
- read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.key.keytag, sizeof(new_chain->addr.key.keytag), 0);
|
||||
- read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.key.flags, sizeof(new_chain->addr.key.flags), 0);
|
||||
- read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.key.keylen, sizeof(new_chain->addr.key.keylen), 0);
|
||||
- blockdata_write(new_chain->addr.key.keydata, new_chain->addr.key.keylen, daemon->pipe_to_parent);
|
||||
+ blockdata_write(new_chain->addr.addr.addr.key.keydata, new_chain->addr.addr.addr.key.keylen, daemon->pipe_to_parent);
|
||||
}
|
||||
else if (flags & F_DS)
|
||||
{
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
|
||||
/* A negative DS entry is possible and has no data, obviously. */
|
||||
if (!(flags & F_NEG))
|
||||
- {
|
||||
- read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.ds.algo, sizeof(new_chain->addr.ds.algo), 0);
|
||||
- read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.ds.keytag, sizeof(new_chain->addr.ds.keytag), 0);
|
||||
- read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.ds.digest, sizeof(new_chain->addr.ds.digest), 0);
|
||||
- read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.ds.keylen, sizeof(new_chain->addr.ds.keylen), 0);
|
||||
- blockdata_write(new_chain->addr.ds.keydata, new_chain->addr.ds.keylen, daemon->pipe_to_parent);
|
||||
- }
|
||||
+ blockdata_write(new_chain->addr.addr.addr.ds.keydata, new_chain->addr.addr.addr.ds.keylen, daemon->pipe_to_parent);
|
||||
}
|
||||
#endif
|
||||
-
|
||||
}
|
||||
}
|
||||
|
||||
@@ -736,11 +725,30 @@ int cache_recv_insert(time_t now, int fd
|
||||
|
||||
ttl = difftime(ttd, now);
|
||||
|
||||
- if (flags & (F_IPV4 | F_IPV6))
|
||||
+ if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS))
|
||||
{
|
||||
+ unsigned short class = C_IN;
|
||||
+
|
||||
if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
|
||||
return 0;
|
||||
- crecp = really_insert(daemon->namebuff, &addr, C_IN, now, ttl, flags);
|
||||
+
|
||||
+#ifdef HAVE_DNSSEC
|
||||
+ if (flags & F_DNSKEY)
|
||||
+ {
|
||||
+ if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
|
||||
+ !(addr.addr.key.keydata = blockdata_read(fd, addr.addr.key.keylen)))
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else if (flags & F_DS)
|
||||
+ {
|
||||
+ if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
|
||||
+ (flags & F_NEG) ||
|
||||
+ !(addr.addr.key.keydata = blockdata_read(fd, addr.addr.key.keylen)))
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ crecp = really_insert(daemon->namebuff, &addr, class, now, ttl, flags);
|
||||
}
|
||||
else if (flags & F_CNAME)
|
||||
{
|
||||
@@ -764,58 +772,6 @@ int cache_recv_insert(time_t now, int fd
|
||||
}
|
||||
}
|
||||
}
|
||||
-#ifdef HAVE_DNSSEC
|
||||
- else if (flags & (F_DNSKEY | F_DS))
|
||||
- {
|
||||
- unsigned short class, keylen, keyflags, keytag;
|
||||
- unsigned char algo, digest;
|
||||
- struct blockdata *keydata;
|
||||
-
|
||||
- if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1))
|
||||
- return 0;
|
||||
-
|
||||
- crecp = really_insert(daemon->namebuff, NULL, class, now, ttl, flags);
|
||||
-
|
||||
- if (flags & F_DNSKEY)
|
||||
- {
|
||||
- if (!read_write(fd, (unsigned char *)&algo, sizeof(algo), 1) ||
|
||||
- !read_write(fd, (unsigned char *)&keytag, sizeof(keytag), 1) ||
|
||||
- !read_write(fd, (unsigned char *)&keyflags, sizeof(keyflags), 1) ||
|
||||
- !read_write(fd, (unsigned char *)&keylen, sizeof(keylen), 1) ||
|
||||
- !(keydata = blockdata_read(fd, keylen)))
|
||||
- return 0;
|
||||
- }
|
||||
- else if (!(flags & F_NEG))
|
||||
- {
|
||||
- if (!read_write(fd, (unsigned char *)&algo, sizeof(algo), 1) ||
|
||||
- !read_write(fd, (unsigned char *)&keytag, sizeof(keytag), 1) ||
|
||||
- !read_write(fd, (unsigned char *)&digest, sizeof(digest), 1) ||
|
||||
- !read_write(fd, (unsigned char *)&keylen, sizeof(keylen), 1) ||
|
||||
- !(keydata = blockdata_read(fd, keylen)))
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- if (crecp)
|
||||
- {
|
||||
- if (flags & F_DNSKEY)
|
||||
- {
|
||||
- crecp->addr.key.algo = algo;
|
||||
- crecp->addr.key.keytag = keytag;
|
||||
- crecp->addr.key.flags = flags;
|
||||
- crecp->addr.key.keylen = keylen;
|
||||
- crecp->addr.key.keydata = keydata;
|
||||
- }
|
||||
- else if (!(flags & F_NEG))
|
||||
- {
|
||||
- crecp->addr.ds.algo = algo;
|
||||
- crecp->addr.ds.keytag = keytag;
|
||||
- crecp->addr.ds.digest = digest;
|
||||
- crecp->addr.ds.keylen = keylen;
|
||||
- crecp->addr.ds.keydata = keydata;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1290,15 +1246,15 @@ void cache_reload(void)
|
||||
#ifdef HAVE_DNSSEC
|
||||
for (ds = daemon->ds; ds; ds = ds->next)
|
||||
if ((cache = whine_malloc(SIZEOF_POINTER_CREC)) &&
|
||||
- (cache->addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
|
||||
+ (cache->addr.addr.addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
|
||||
{
|
||||
cache->flags = F_FORWARD | F_IMMORTAL | F_DS | F_CONFIG | F_NAMEP;
|
||||
cache->ttd = daemon->local_ttl;
|
||||
cache->name.namep = ds->name;
|
||||
- cache->addr.ds.keylen = ds->digestlen;
|
||||
- cache->addr.ds.algo = ds->algo;
|
||||
- cache->addr.ds.keytag = ds->keytag;
|
||||
- cache->addr.ds.digest = ds->digest_type;
|
||||
+ cache->addr.addr.addr.ds.keylen = ds->digestlen;
|
||||
+ cache->addr.addr.addr.ds.algo = ds->algo;
|
||||
+ cache->addr.addr.addr.ds.keytag = ds->keytag;
|
||||
+ cache->addr.addr.addr.ds.digest = ds->digest_type;
|
||||
cache->uid = ds->class;
|
||||
cache_hash(cache);
|
||||
make_non_terminals(cache);
|
||||
@@ -1775,12 +1731,12 @@ void dump_cache(time_t now)
|
||||
else if (cache->flags & F_DS)
|
||||
{
|
||||
if (!(cache->flags & F_NEG))
|
||||
- sprintf(a, "%5u %3u %3u", cache->addr.ds.keytag,
|
||||
- cache->addr.ds.algo, cache->addr.ds.digest);
|
||||
+ sprintf(a, "%5u %3u %3u", cache->addr.addr.addr.ds.keytag,
|
||||
+ cache->addr.addr.addr.ds.algo, cache->addr.addr.addr.ds.digest);
|
||||
}
|
||||
else if (cache->flags & F_DNSKEY)
|
||||
- sprintf(a, "%5u %3u %3u", cache->addr.key.keytag,
|
||||
- cache->addr.key.algo, cache->addr.key.flags);
|
||||
+ sprintf(a, "%5u %3u %3u", cache->addr.addr.addr.key.keytag,
|
||||
+ cache->addr.addr.addr.key.algo, cache->addr.addr.addr.key.flags);
|
||||
#endif
|
||||
else if (!(cache->flags & F_NEG) || !(cache->flags & F_FORWARD))
|
||||
{
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -277,14 +277,21 @@ struct all_addr {
|
||||
union {
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
+ struct {
|
||||
+ struct blockdata *keydata;
|
||||
+ unsigned short keylen, flags, keytag;
|
||||
+ unsigned char algo;
|
||||
+ } key;
|
||||
+ struct {
|
||||
+ struct blockdata *keydata;
|
||||
+ unsigned short keylen, keytag;
|
||||
+ unsigned char algo;
|
||||
+ unsigned char digest;
|
||||
+ } ds;
|
||||
/* for log_query */
|
||||
struct {
|
||||
unsigned short keytag, algo, digest, rcode;
|
||||
} log;
|
||||
- /* for cache_insert of DNSKEY, DS */
|
||||
- struct {
|
||||
- unsigned short class, type;
|
||||
- } dnssec;
|
||||
} addr;
|
||||
};
|
||||
|
||||
@@ -414,17 +421,6 @@ struct crec {
|
||||
} target;
|
||||
unsigned int uid; /* 0 if union is interface-name */
|
||||
} cname;
|
||||
- struct {
|
||||
- struct blockdata *keydata;
|
||||
- unsigned short keylen, flags, keytag;
|
||||
- unsigned char algo;
|
||||
- } key;
|
||||
- struct {
|
||||
- struct blockdata *keydata;
|
||||
- unsigned short keylen, keytag;
|
||||
- unsigned char algo;
|
||||
- unsigned char digest;
|
||||
- } ds;
|
||||
} addr;
|
||||
time_t ttd; /* time to die */
|
||||
/* used as class if DNSKEY/DS, index to source for F_HOSTS */
|
||||
--- a/src/dnssec.c
|
||||
+++ b/src/dnssec.c
|
||||
@@ -628,10 +628,10 @@ static int validate_rrset(time_t now, st
|
||||
{
|
||||
/* iterate through all possible keys 4035 5.3.1 */
|
||||
for (; crecp; crecp = cache_find_by_name(crecp, keyname, now, F_DNSKEY))
|
||||
- if (crecp->addr.key.algo == algo &&
|
||||
- crecp->addr.key.keytag == key_tag &&
|
||||
+ if (crecp->addr.addr.addr.key.algo == algo &&
|
||||
+ crecp->addr.addr.addr.key.keytag == key_tag &&
|
||||
crecp->uid == (unsigned int)class &&
|
||||
- verify(crecp->addr.key.keydata, crecp->addr.key.keylen, sig, sig_len, digest, hash->digest_size, algo))
|
||||
+ verify(crecp->addr.addr.addr.key.keydata, crecp->addr.addr.addr.key.keylen, sig, sig_len, digest, hash->digest_size, algo))
|
||||
return (labels < name_labels) ? STAT_SECURE_WILDCARD : STAT_SECURE;
|
||||
}
|
||||
}
|
||||
@@ -728,10 +728,10 @@ int dnssec_validate_by_ds(time_t now, st
|
||||
const struct nettle_hash *hash;
|
||||
int sigcnt, rrcnt;
|
||||
|
||||
- if (recp1->addr.ds.algo == algo &&
|
||||
- recp1->addr.ds.keytag == keytag &&
|
||||
+ if (recp1->addr.addr.addr.ds.algo == algo &&
|
||||
+ recp1->addr.addr.addr.ds.keytag == keytag &&
|
||||
recp1->uid == (unsigned int)class &&
|
||||
- (hash = hash_find(ds_digest_name(recp1->addr.ds.digest))) &&
|
||||
+ (hash = hash_find(ds_digest_name(recp1->addr.addr.addr.ds.digest))) &&
|
||||
hash_init(hash, &ctx, &digest))
|
||||
|
||||
{
|
||||
@@ -746,9 +746,9 @@ int dnssec_validate_by_ds(time_t now, st
|
||||
from_wire(name);
|
||||
|
||||
if (!(recp1->flags & F_NEG) &&
|
||||
- recp1->addr.ds.keylen == (int)hash->digest_size &&
|
||||
- (ds_digest = blockdata_retrieve(recp1->addr.key.keydata, recp1->addr.ds.keylen, NULL)) &&
|
||||
- memcmp(ds_digest, digest, recp1->addr.ds.keylen) == 0 &&
|
||||
+ recp1->addr.addr.addr.ds.keylen == (int)hash->digest_size &&
|
||||
+ (ds_digest = blockdata_retrieve(recp1->addr.addr.addr.ds.keydata, recp1->addr.addr.addr.ds.keylen, NULL)) &&
|
||||
+ memcmp(ds_digest, digest, recp1->addr.addr.addr.ds.keylen) == 0 &&
|
||||
explore_rrset(header, plen, class, T_DNSKEY, name, keyname, &sigcnt, &rrcnt) &&
|
||||
sigcnt != 0 && rrcnt != 0 &&
|
||||
validate_rrset(now, header, plen, class, T_DNSKEY, sigcnt, rrcnt, name, keyname,
|
||||
@@ -800,7 +800,13 @@ int dnssec_validate_by_ds(time_t now, st
|
||||
|
||||
if ((key = blockdata_alloc((char*)p, rdlen - 4)))
|
||||
{
|
||||
- if (!(recp1 = cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK)))
|
||||
+ a.addr.key.keylen = rdlen - 4;
|
||||
+ a.addr.key.keydata = key;
|
||||
+ a.addr.key.algo = algo;
|
||||
+ a.addr.key.keytag = keytag;
|
||||
+ a.addr.key.flags = flags;
|
||||
+
|
||||
+ if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK))
|
||||
{
|
||||
blockdata_free(key);
|
||||
return STAT_BOGUS;
|
||||
@@ -813,12 +819,6 @@ int dnssec_validate_by_ds(time_t now, st
|
||||
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu");
|
||||
else
|
||||
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu (not supported)");
|
||||
-
|
||||
- recp1->addr.key.keylen = rdlen - 4;
|
||||
- recp1->addr.key.keydata = key;
|
||||
- recp1->addr.key.algo = algo;
|
||||
- recp1->addr.key.keytag = keytag;
|
||||
- recp1->addr.key.flags = flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -915,8 +915,7 @@ int dnssec_validate_ds(time_t now, struc
|
||||
int algo, digest, keytag;
|
||||
unsigned char *psave = p;
|
||||
struct blockdata *key;
|
||||
- struct crec *crecp;
|
||||
-
|
||||
+
|
||||
if (rdlen < 4)
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
@@ -926,7 +925,13 @@ int dnssec_validate_ds(time_t now, struc
|
||||
|
||||
if ((key = blockdata_alloc((char*)p, rdlen - 4)))
|
||||
{
|
||||
- if (!(crecp = cache_insert(name, NULL, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)))
|
||||
+ a.addr.ds.digest = digest;
|
||||
+ a.addr.ds.keydata = key;
|
||||
+ a.addr.ds.algo = algo;
|
||||
+ a.addr.ds.keytag = keytag;
|
||||
+ a.addr.ds.keylen = rdlen - 4;
|
||||
+
|
||||
+ if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK))
|
||||
{
|
||||
blockdata_free(key);
|
||||
return STAT_BOGUS;
|
||||
@@ -940,12 +945,6 @@ int dnssec_validate_ds(time_t now, struc
|
||||
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu");
|
||||
else
|
||||
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)");
|
||||
-
|
||||
- crecp->addr.ds.digest = digest;
|
||||
- crecp->addr.ds.keydata = key;
|
||||
- crecp->addr.ds.algo = algo;
|
||||
- crecp->addr.ds.keytag = keytag;
|
||||
- crecp->addr.ds.keylen = rdlen - 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1711,8 +1710,8 @@ static int zone_status(char *name, int c
|
||||
do
|
||||
{
|
||||
if (crecp->uid == (unsigned int)class &&
|
||||
- ds_digest_name(crecp->addr.ds.digest) &&
|
||||
- algo_digest_name(crecp->addr.ds.algo))
|
||||
+ ds_digest_name(crecp->addr.addr.addr.ds.digest) &&
|
||||
+ algo_digest_name(crecp->addr.addr.addr.ds.algo))
|
||||
break;
|
||||
}
|
||||
while ((crecp = cache_find_by_name(crecp, keyname, now, F_DS)));
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,23 @@
|
||||
From 2c594732eb7391e7cfa817598e33e61cab71131f Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Thu, 3 Jan 2019 13:42:03 +0000
|
||||
Subject: [PATCH 22/30] File logic bug in cache-marshalling code. Introduced a
|
||||
couple of commits back.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/cache.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -742,8 +742,7 @@ int cache_recv_insert(time_t now, int fd
|
||||
else if (flags & F_DS)
|
||||
{
|
||||
if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
|
||||
- (flags & F_NEG) ||
|
||||
- !(addr.key.keydata = blockdata_read(fd, addr.key.keylen)))
|
||||
+ (!(flags & F_NEG) && !(addr.key.keydata = blockdata_read(fd, addr.key.keylen))))
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -0,0 +1,33 @@
|
||||
From 2daca52b80afdc92e7c976629a2bf8182335a626 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Weiske <cweiske@cweiske.de>
|
||||
Date: Thu, 3 Jan 2019 20:10:14 +0000
|
||||
Subject: [PATCH 23/30] Fix typo in ra-param man page section.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
man/dnsmasq.8 | 2 +-
|
||||
man/fr/dnsmasq.8 | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/man/dnsmasq.8
|
||||
+++ b/man/dnsmasq.8
|
||||
@@ -1829,7 +1829,7 @@ The interval between router advertisemen
|
||||
.B --ra-param=eth0,60.
|
||||
The lifetime of the route may be changed or set to zero, which allows
|
||||
a router to advertise prefixes but not a route via itself.
|
||||
-.B --ra-parm=eth0,0,0
|
||||
+.B --ra-param=eth0,0,0
|
||||
(A value of zero for the interval means the default value.) All four parameters may be set at once.
|
||||
.B --ra-param=eth0,mtu:1280,low,60,1200
|
||||
|
||||
--- a/man/fr/dnsmasq.8
|
||||
+++ b/man/fr/dnsmasq.8
|
||||
@@ -1774,7 +1774,7 @@ Un intervalle (en secondes) entre les an
|
||||
.B --ra-param=eth0,60.
|
||||
La durée de vie de la route peut être changée ou mise à zéro, auquel cas
|
||||
le routeur peut annoncer les préfixes mais pas de route :
|
||||
-.B --ra-parm=eth0,0,0
|
||||
+.B --ra-param=eth0,0,0
|
||||
(une valeur de zéro pour l'intervalle signifie qu'il garde la valeur par défaut).
|
||||
Ces quatre paramètres peuvent être configurés en une fois :
|
||||
.B --ra-param=eth0,mtu:1280,low,60,1200
|
@ -0,0 +1,523 @@
|
||||
From 5b99eae59d59a8e34a7e512059b98bbd803312f2 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Sun, 6 Jan 2019 23:09:50 +0000
|
||||
Subject: [PATCH 24/30] Cache SRV records.
|
||||
|
||||
Inpsired by a patch from Jeremy Allison, but completely re-rolled
|
||||
by srk. All bugs are mine.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/auth.c | 2 +-
|
||||
src/blockdata.c | 12 ++---
|
||||
src/cache.c | 64 ++++++++++++++--------
|
||||
src/dnsmasq.c | 2 -
|
||||
src/dnsmasq.h | 11 ++--
|
||||
src/rfc1035.c | 141 ++++++++++++++++++++++++++++++++++++++----------
|
||||
6 files changed, 166 insertions(+), 66 deletions(-)
|
||||
|
||||
--- a/src/auth.c
|
||||
+++ b/src/auth.c
|
||||
@@ -129,7 +129,7 @@ size_t answer_auth(struct dns_header *he
|
||||
|
||||
for (q = ntohs(header->qdcount); q != 0; q--)
|
||||
{
|
||||
- unsigned short flag = 0;
|
||||
+ unsigned int flag = 0;
|
||||
int found = 0;
|
||||
int cname_wildcard = 0;
|
||||
|
||||
--- a/src/blockdata.c
|
||||
+++ b/src/blockdata.c
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
-#ifdef HAVE_DNSSEC
|
||||
-
|
||||
static struct blockdata *keyblock_free;
|
||||
static unsigned int blockdata_count, blockdata_hwm, blockdata_alloced;
|
||||
|
||||
@@ -54,11 +52,10 @@ void blockdata_init(void)
|
||||
|
||||
void blockdata_report(void)
|
||||
{
|
||||
- if (option_bool(OPT_DNSSEC_VALID))
|
||||
- my_syslog(LOG_INFO, _("DNSSEC memory in use %u, max %u, allocated %u"),
|
||||
- blockdata_count * sizeof(struct blockdata),
|
||||
- blockdata_hwm * sizeof(struct blockdata),
|
||||
- blockdata_alloced * sizeof(struct blockdata));
|
||||
+ my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"),
|
||||
+ blockdata_count * sizeof(struct blockdata),
|
||||
+ blockdata_hwm * sizeof(struct blockdata),
|
||||
+ blockdata_alloced * sizeof(struct blockdata));
|
||||
}
|
||||
|
||||
static struct blockdata *blockdata_alloc_real(int fd, char *data, size_t len)
|
||||
@@ -178,4 +175,3 @@ struct blockdata *blockdata_read(int fd,
|
||||
return blockdata_alloc_real(fd, NULL, len);
|
||||
}
|
||||
|
||||
-#endif
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -27,7 +27,7 @@ static int bignames_left, hash_size;
|
||||
|
||||
static void make_non_terminals(struct crec *source);
|
||||
static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,
|
||||
- time_t now, unsigned long ttl, unsigned short flags);
|
||||
+ time_t now, unsigned long ttl, unsigned int flags);
|
||||
|
||||
/* type->string mapping: this is also used by the name-hash function as a mixing table. */
|
||||
static const struct {
|
||||
@@ -198,15 +198,17 @@ static void cache_hash(struct crec *crec
|
||||
*up = crecp;
|
||||
}
|
||||
|
||||
-#ifdef HAVE_DNSSEC
|
||||
static void cache_blockdata_free(struct crec *crecp)
|
||||
{
|
||||
- if (crecp->flags & F_DNSKEY)
|
||||
+ if (crecp->flags & F_SRV)
|
||||
+ blockdata_free(crecp->addr.srv.target);
|
||||
+#ifdef HAVE_DNSSEC
|
||||
+ else if (crecp->flags & F_DNSKEY)
|
||||
blockdata_free(crecp->addr.key.keydata);
|
||||
else if ((crecp->flags & F_DS) && !(crecp->flags & F_NEG))
|
||||
blockdata_free(crecp->addr.ds.keydata);
|
||||
-}
|
||||
#endif
|
||||
+}
|
||||
|
||||
static void cache_free(struct crec *crecp)
|
||||
{
|
||||
@@ -230,9 +232,7 @@ static void cache_free(struct crec *crec
|
||||
crecp->flags &= ~F_BIGNAME;
|
||||
}
|
||||
|
||||
-#ifdef HAVE_DNSSEC
|
||||
cache_blockdata_free(crecp);
|
||||
-#endif
|
||||
}
|
||||
|
||||
/* insert a new cache entry at the head of the list (youngest entry) */
|
||||
@@ -331,7 +331,7 @@ static int is_expired(time_t now, struct
|
||||
}
|
||||
|
||||
static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned short class, time_t now,
|
||||
- unsigned short flags, struct crec **target_crec, unsigned int *target_uid)
|
||||
+ unsigned int flags, struct crec **target_crec, unsigned int *target_uid)
|
||||
{
|
||||
/* Scan and remove old entries.
|
||||
If (flags & F_FORWARD) then remove any forward entries for name and any expired
|
||||
@@ -360,7 +360,7 @@ static struct crec *cache_scan_free(char
|
||||
if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name))
|
||||
{
|
||||
/* Don't delete DNSSEC in favour of a CNAME, they can co-exist */
|
||||
- if ((flags & crecp->flags & (F_IPV4 | F_IPV6)) ||
|
||||
+ if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_SRV)) ||
|
||||
(((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))
|
||||
{
|
||||
if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
|
||||
@@ -467,10 +467,10 @@ void cache_start_insert(void)
|
||||
}
|
||||
|
||||
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
|
||||
- time_t now, unsigned long ttl, unsigned short flags)
|
||||
+ time_t now, unsigned long ttl, unsigned int flags)
|
||||
{
|
||||
/* Don't log DNSSEC records here, done elsewhere */
|
||||
- if (flags & (F_IPV4 | F_IPV6 | F_CNAME))
|
||||
+ if (flags & (F_IPV4 | F_IPV6 | F_CNAME | F_SRV))
|
||||
{
|
||||
log_query(flags | F_UPSTREAM, name, addr, NULL);
|
||||
/* Don't mess with TTL for DNSSEC records. */
|
||||
@@ -485,7 +485,7 @@ struct crec *cache_insert(char *name, un
|
||||
|
||||
|
||||
static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,
|
||||
- time_t now, unsigned long ttl, unsigned short flags)
|
||||
+ time_t now, unsigned long ttl, unsigned int flags)
|
||||
{
|
||||
struct crec *new, *target_crec = NULL;
|
||||
union bigname *big_name = NULL;
|
||||
@@ -649,7 +649,7 @@ void cache_end_insert(void)
|
||||
{
|
||||
char *name = cache_get_name(new_chain);
|
||||
ssize_t m = strlen(name);
|
||||
- unsigned short flags = new_chain->flags;
|
||||
+ unsigned int flags = new_chain->flags;
|
||||
#ifdef HAVE_DNSSEC
|
||||
u16 class = new_chain->uid;
|
||||
#endif
|
||||
@@ -659,8 +659,10 @@ void cache_end_insert(void)
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->ttd, sizeof(new_chain->ttd), 0);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), 0);
|
||||
|
||||
- if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS))
|
||||
+ if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV))
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0);
|
||||
+ if (flags & F_SRV)
|
||||
+ blockdata_write(new_chain->addr.srv.target, new_chain->addr.srv.targetlen, daemon->pipe_to_parent);
|
||||
#ifdef HAVE_DNSSEC
|
||||
if (flags & F_DNSKEY)
|
||||
{
|
||||
@@ -699,7 +701,7 @@ int cache_recv_insert(time_t now, int fd
|
||||
union all_addr addr;
|
||||
unsigned long ttl;
|
||||
time_t ttd;
|
||||
- unsigned short flags;
|
||||
+ unsigned int flags;
|
||||
struct crec *crecp = NULL;
|
||||
|
||||
cache_start_insert();
|
||||
@@ -725,13 +727,16 @@ int cache_recv_insert(time_t now, int fd
|
||||
|
||||
ttl = difftime(ttd, now);
|
||||
|
||||
- if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS))
|
||||
+ if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV))
|
||||
{
|
||||
unsigned short class = C_IN;
|
||||
|
||||
if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
|
||||
return 0;
|
||||
-
|
||||
+
|
||||
+ if (flags & F_SRV && !(addr.srv.target = blockdata_read(fd, addr.srv.targetlen)))
|
||||
+ return 0;
|
||||
+
|
||||
#ifdef HAVE_DNSSEC
|
||||
if (flags & F_DNSKEY)
|
||||
{
|
||||
@@ -802,7 +807,7 @@ struct crec *cache_find_by_name(struct c
|
||||
/* first search, look for relevant entries and push to top of list
|
||||
also free anything which has expired */
|
||||
struct crec *next, **up, **insert = NULL, **chainp = &ans;
|
||||
- unsigned short ins_flags = 0;
|
||||
+ unsigned int ins_flags = 0;
|
||||
|
||||
for (up = hash_bucket(name), crecp = *up; crecp; crecp = next)
|
||||
{
|
||||
@@ -1086,7 +1091,7 @@ int read_hostsfile(char *filename, unsig
|
||||
FILE *f = fopen(filename, "r");
|
||||
char *token = daemon->namebuff, *domain_suffix = NULL;
|
||||
int addr_count = 0, name_count = cache_size, lineno = 0;
|
||||
- unsigned short flags = 0;
|
||||
+ unsigned int flags = 0;
|
||||
union all_addr addr;
|
||||
int atnl, addrlen = 0;
|
||||
|
||||
@@ -1201,9 +1206,8 @@ void cache_reload(void)
|
||||
for (i=0; i<hash_size; i++)
|
||||
for (cache = hash_table[i], up = &hash_table[i]; cache; cache = tmp)
|
||||
{
|
||||
-#ifdef HAVE_DNSSEC
|
||||
cache_blockdata_free(cache);
|
||||
-#endif
|
||||
+
|
||||
tmp = cache->hash_next;
|
||||
if (cache->flags & (F_HOSTS | F_CONFIG))
|
||||
{
|
||||
@@ -1381,7 +1385,7 @@ void cache_add_dhcp_entry(char *host_nam
|
||||
union all_addr *host_address, time_t ttd)
|
||||
{
|
||||
struct crec *crec = NULL, *fail_crec = NULL;
|
||||
- unsigned short flags = F_IPV4;
|
||||
+ unsigned int flags = F_IPV4;
|
||||
int in_hosts = 0;
|
||||
size_t addrlen = sizeof(struct in_addr);
|
||||
|
||||
@@ -1682,9 +1686,8 @@ void dump_cache(time_t now)
|
||||
#ifdef HAVE_AUTH
|
||||
my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->metrics[METRIC_DNS_AUTH_ANSWERED]);
|
||||
#endif
|
||||
-#ifdef HAVE_DNSSEC
|
||||
+
|
||||
blockdata_report();
|
||||
-#endif
|
||||
|
||||
/* sum counts from different records for same server */
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
@@ -1726,6 +1729,17 @@ void dump_cache(time_t now)
|
||||
p += sprintf(p, "%-30.30s ", sanitise(n));
|
||||
if ((cache->flags & F_CNAME) && !is_outdated_cname_pointer(cache))
|
||||
a = sanitise(cache_get_cname_target(cache));
|
||||
+ else if ((cache->flags & F_SRV) && !(cache->flags & F_NEG))
|
||||
+ {
|
||||
+ int targetlen = cache->addr.srv.targetlen;
|
||||
+ ssize_t len = sprintf(a, "%u %u %u ", cache->addr.srv.priority,
|
||||
+ cache->addr.srv.weight, cache->addr.srv.srvport);
|
||||
+
|
||||
+ if (targetlen > (40 - len))
|
||||
+ targetlen = 40 - len;
|
||||
+ blockdata_retrieve(cache->addr.srv.target, targetlen, a + len);
|
||||
+ a[len + targetlen] = 0;
|
||||
+ }
|
||||
#ifdef HAVE_DNSSEC
|
||||
else if (cache->flags & F_DS)
|
||||
{
|
||||
@@ -1752,6 +1766,8 @@ void dump_cache(time_t now)
|
||||
t = "6";
|
||||
else if (cache->flags & F_CNAME)
|
||||
t = "C";
|
||||
+ else if (cache->flags & F_SRV)
|
||||
+ t = "V";
|
||||
#ifdef HAVE_DNSSEC
|
||||
else if (cache->flags & F_DS)
|
||||
t = "S";
|
||||
@@ -1913,6 +1929,8 @@ void log_query(unsigned int flags, char
|
||||
}
|
||||
else if (flags & F_CNAME)
|
||||
dest = "<CNAME>";
|
||||
+ else if (flags & F_SRV)
|
||||
+ dest = "<SRV>";
|
||||
else if (flags & F_RRNAME)
|
||||
dest = arg;
|
||||
|
||||
--- a/src/dnsmasq.c
|
||||
+++ b/src/dnsmasq.c
|
||||
@@ -366,9 +366,7 @@ int main (int argc, char **argv)
|
||||
{
|
||||
cache_init();
|
||||
|
||||
-#ifdef HAVE_DNSSEC
|
||||
blockdata_init();
|
||||
-#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -299,6 +299,10 @@ union all_addr {
|
||||
unsigned char algo;
|
||||
unsigned char digest;
|
||||
} ds;
|
||||
+ struct {
|
||||
+ struct blockdata *target;
|
||||
+ unsigned short targetlen, srvport, priority, weight;
|
||||
+ } srv;
|
||||
/* for log_query */
|
||||
struct {
|
||||
unsigned short keytag, algo, digest, rcode;
|
||||
@@ -426,7 +430,7 @@ struct crec {
|
||||
time_t ttd; /* time to die */
|
||||
/* used as class if DNSKEY/DS, index to source for F_HOSTS */
|
||||
unsigned int uid;
|
||||
- unsigned short flags;
|
||||
+ unsigned int flags;
|
||||
union {
|
||||
char sname[SMALLDNAME];
|
||||
union bigname *bname;
|
||||
@@ -470,6 +474,7 @@ struct crec {
|
||||
#define F_NOEXTRA (1u<<27)
|
||||
#define F_SERVFAIL (1u<<28)
|
||||
#define F_RCODE (1u<<29)
|
||||
+#define F_SRV (1u<<30)
|
||||
|
||||
#define UID_NONE 0
|
||||
/* Values of uid in crecs with F_CONFIG bit set. */
|
||||
@@ -1142,7 +1147,7 @@ void cache_end_insert(void);
|
||||
void cache_start_insert(void);
|
||||
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 short flags);
|
||||
+ time_t now, unsigned long ttl, unsigned int flags);
|
||||
void cache_reload(void);
|
||||
void cache_add_dhcp_entry(char *host_name, int prot, union all_addr *host_address, time_t ttd);
|
||||
struct in_addr a_record_from_hosts(char *name, time_t now);
|
||||
@@ -1158,7 +1163,6 @@ int read_hostsfile(char *filename, unsig
|
||||
struct crec **rhash, int hashsz);
|
||||
|
||||
/* blockdata.c */
|
||||
-#ifdef HAVE_DNSSEC
|
||||
void blockdata_init(void);
|
||||
void blockdata_report(void);
|
||||
struct blockdata *blockdata_alloc(char *data, size_t len);
|
||||
@@ -1166,7 +1170,6 @@ void *blockdata_retrieve(struct blockdat
|
||||
struct blockdata *blockdata_read(int fd, size_t len);
|
||||
void blockdata_write(struct blockdata *block, size_t len, int fd);
|
||||
void blockdata_free(struct blockdata *blocks);
|
||||
-#endif
|
||||
|
||||
/* domain.c */
|
||||
char *get_domain(struct in_addr addr);
|
||||
--- a/src/rfc1035.c
|
||||
+++ b/src/rfc1035.c
|
||||
@@ -726,7 +726,7 @@ int extract_addresses(struct dns_header
|
||||
{
|
||||
/* everything other than PTR */
|
||||
struct crec *newc;
|
||||
- int addrlen;
|
||||
+ int addrlen = 0;
|
||||
|
||||
if (qtype == T_A)
|
||||
{
|
||||
@@ -738,7 +738,9 @@ int extract_addresses(struct dns_header
|
||||
addrlen = IN6ADDRSZ;
|
||||
flags |= F_IPV6;
|
||||
}
|
||||
- else
|
||||
+ else if (qtype == T_SRV)
|
||||
+ flags |= F_SRV;
|
||||
+ else
|
||||
continue;
|
||||
|
||||
cname_loop1:
|
||||
@@ -799,39 +801,61 @@ int extract_addresses(struct dns_header
|
||||
{
|
||||
found = 1;
|
||||
|
||||
- /* copy address into aligned storage */
|
||||
- if (!CHECK_LEN(header, p1, qlen, addrlen))
|
||||
- return 0; /* bad packet */
|
||||
- memcpy(&addr, p1, addrlen);
|
||||
-
|
||||
- /* check for returned address in private space */
|
||||
- if (check_rebind)
|
||||
+ if (flags & F_SRV)
|
||||
{
|
||||
- if ((flags & F_IPV4) &&
|
||||
- private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
|
||||
- return 1;
|
||||
-
|
||||
- if ((flags & F_IPV6) &&
|
||||
- IN6_IS_ADDR_V4MAPPED(&addr.addr6))
|
||||
+ unsigned char *tmp = namep;
|
||||
+
|
||||
+ if (!CHECK_LEN(header, p1, qlen, 6))
|
||||
+ return 0; /* bad packet */
|
||||
+ GETSHORT(addr.srv.priority, p1);
|
||||
+ GETSHORT(addr.srv.weight, p1);
|
||||
+ GETSHORT(addr.srv.srvport, p1);
|
||||
+ if (!extract_name(header, qlen, &p1, name, 1, 0))
|
||||
+ return 0;
|
||||
+ addr.srv.targetlen = strlen(name) + 1; /* include terminating zero */
|
||||
+ if (!(addr.srv.target = blockdata_alloc(name, addr.srv.targetlen)))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* we overwrote the original name, so get it back here. */
|
||||
+ if (!extract_name(header, qlen, &tmp, name, 1, 0))
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* copy address into aligned storage */
|
||||
+ if (!CHECK_LEN(header, p1, qlen, addrlen))
|
||||
+ return 0; /* bad packet */
|
||||
+ memcpy(&addr, p1, addrlen);
|
||||
+
|
||||
+ /* check for returned address in private space */
|
||||
+ if (check_rebind)
|
||||
{
|
||||
- struct in_addr v4;
|
||||
- v4.s_addr = ((const uint32_t *) (&addr.addr6))[3];
|
||||
- if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
|
||||
+ if ((flags & F_IPV4) &&
|
||||
+ private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
|
||||
return 1;
|
||||
+
|
||||
+ if ((flags & F_IPV6) &&
|
||||
+ IN6_IS_ADDR_V4MAPPED(&addr.addr6))
|
||||
+ {
|
||||
+ struct in_addr v4;
|
||||
+ v4.s_addr = ((const uint32_t *) (&addr.addr6))[3];
|
||||
+ if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
|
||||
+ return 1;
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
-
|
||||
+
|
||||
#ifdef HAVE_IPSET
|
||||
- if (ipsets && (flags & (F_IPV4 | F_IPV6)))
|
||||
- {
|
||||
- ipsets_cur = ipsets;
|
||||
- while (*ipsets_cur)
|
||||
+ if (ipsets && (flags & (F_IPV4 | F_IPV6)))
|
||||
{
|
||||
- log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
|
||||
- add_to_ipset(*ipsets_cur++, &addr, flags, 0);
|
||||
+ ipsets_cur = ipsets;
|
||||
+ while (*ipsets_cur)
|
||||
+ {
|
||||
+ log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
|
||||
+ add_to_ipset(*ipsets_cur++, &addr, flags, 0);
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
#endif
|
||||
+ }
|
||||
|
||||
newc = cache_insert(name, &addr, C_IN, now, attl, flags | F_FORWARD | secflag);
|
||||
if (newc && cpp)
|
||||
@@ -1844,7 +1868,68 @@ size_t answer_request(struct dns_header
|
||||
*up = move;
|
||||
move->next = NULL;
|
||||
}
|
||||
-
|
||||
+
|
||||
+ if (!found)
|
||||
+ {
|
||||
+ cname_srv_restart:
|
||||
+ if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME | F_SRV | (dryrun ? F_NO_RR : 0))) &&
|
||||
+ (!do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))))
|
||||
+ {
|
||||
+ if (!(crecp->flags & F_DNSSECOK))
|
||||
+ sec_data = 0;
|
||||
+
|
||||
+ auth = 0;
|
||||
+ found = ans = 1;
|
||||
+
|
||||
+ do {
|
||||
+ if (crecp->flags & F_CNAME)
|
||||
+ {
|
||||
+ char *cname_target = cache_get_cname_target(crecp);
|
||||
+
|
||||
+ if (!dryrun)
|
||||
+ {
|
||||
+ log_query(crecp->flags, name, NULL, record_source(crecp->uid));
|
||||
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
+ crec_ttl(crecp, now), &nameoffset,
|
||||
+ T_CNAME, C_IN, "d", cname_target))
|
||||
+ anscount++;
|
||||
+ }
|
||||
+
|
||||
+ strcpy(name, cname_target);
|
||||
+ goto cname_srv_restart;
|
||||
+ }
|
||||
+ else if (crecp->flags & F_NEG)
|
||||
+ {
|
||||
+ if (crecp->flags & F_NXDOMAIN)
|
||||
+ nxdomain = 1;
|
||||
+ if (!dryrun)
|
||||
+ log_query(crecp->flags, name, NULL, NULL);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ unsigned char *p1 = ((unsigned char *)header) + nameoffset;
|
||||
+
|
||||
+ if (!dryrun)
|
||||
+ {
|
||||
+ log_query(crecp->flags, name, NULL, 0);
|
||||
+
|
||||
+ blockdata_retrieve(crecp->addr.srv.target, crecp->addr.srv.targetlen, name);
|
||||
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
+ crec_ttl(crecp, now), NULL, T_SRV, C_IN, "sssd",
|
||||
+ crecp->addr.srv.priority, crecp->addr.srv.weight, crecp->addr.srv.srvport,
|
||||
+ name))
|
||||
+ anscount++;
|
||||
+
|
||||
+
|
||||
+ /* restore name we overwrote */
|
||||
+ if (!extract_name(header, qlen, &p1, name, 1, 0))
|
||||
+ return 0; /* bad packet */
|
||||
+ }
|
||||
+ }
|
||||
+ } while ((crecp = cache_find_by_name(crecp, name, now, F_SRV | F_CNAME)));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
|
||||
{
|
||||
ans = 1;
|
@ -0,0 +1,23 @@
|
||||
From a90f09db4cc635941a32b973b57e58c662569625 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Wed, 9 Jan 2019 15:08:16 +0000
|
||||
Subject: [PATCH 25/30] Fix crash freeing negative SRV cache entries.
|
||||
|
||||
Thanks to Daniel for finding this one.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/cache.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -200,7 +200,7 @@ static void cache_hash(struct crec *crec
|
||||
|
||||
static void cache_blockdata_free(struct crec *crecp)
|
||||
{
|
||||
- if (crecp->flags & F_SRV)
|
||||
+ if (crecp->flags & F_SRV && !(crecp->flags & F_NEG))
|
||||
blockdata_free(crecp->addr.srv.target);
|
||||
#ifdef HAVE_DNSSEC
|
||||
else if (crecp->flags & F_DNSKEY)
|
@ -0,0 +1,24 @@
|
||||
From 2896e2485e44c04e73a0b7c9f7cbc9c8515d0800 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Wed, 9 Jan 2019 15:12:34 +0000
|
||||
Subject: [PATCH 26/30] Check for not(DS or DNSKEY) in
|
||||
is_outdated_cname_pointer()
|
||||
|
||||
Previous check was _for_ IPV4, IPv6 CNAME, and I missed adding SRV.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/cache.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -312,7 +312,7 @@ static int is_outdated_cname_pointer(str
|
||||
/* NB. record may be reused as DS or DNSKEY, where uid is
|
||||
overloaded for something completely different */
|
||||
if (crecp->addr.cname.target.cache &&
|
||||
- (crecp->addr.cname.target.cache->flags & (F_IPV4 | F_IPV6 | F_CNAME)) &&
|
||||
+ !(crecp->addr.cname.target.cache->flags & (F_DNSKEY | F_DS)) &&
|
||||
crecp->addr.cname.uid == crecp->addr.cname.target.cache->uid)
|
||||
return 0;
|
||||
|
@ -0,0 +1,95 @@
|
||||
From 9c0d445ef4abffa2b9342ad65e85ef425c1f83bb Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Wed, 9 Jan 2019 17:57:56 +0000
|
||||
Subject: [PATCH 27/30] Fix e7bfd556c079c8b5e7425aed44abc35925b24043 to
|
||||
actually work.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/dhcp.c | 54 +++++++++++++++++++++++++----------------------------
|
||||
src/dhcp6.c | 2 +-
|
||||
2 files changed, 26 insertions(+), 30 deletions(-)
|
||||
|
||||
--- a/src/dhcp.c
|
||||
+++ b/src/dhcp.c
|
||||
@@ -754,19 +754,6 @@ int address_allocate(struct dhcp_context
|
||||
if (addr.s_addr == d->router.s_addr)
|
||||
break;
|
||||
|
||||
- /* in consec-ip mode, skip addresses equal to
|
||||
- the number of addresses rejected by clients. This
|
||||
- should avoid the same client being offered the same
|
||||
- address after it has rjected it. */
|
||||
- if (option_bool(OPT_CONSEC_ADDR))
|
||||
- {
|
||||
- if (c->addr_epoch)
|
||||
- {
|
||||
- c->addr_epoch--;
|
||||
- d = context; /* d non-NULL skips the address. */
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* Addresses which end in .255 and .0 are broken in Windows even when using
|
||||
supernetting. ie dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0
|
||||
then 192.168.0.255 is a valid IP address, but not for Windows as it's
|
||||
@@ -778,24 +765,33 @@ int address_allocate(struct dhcp_context
|
||||
(!IN_CLASSC(ntohl(addr.s_addr)) ||
|
||||
((ntohl(addr.s_addr) & 0xff) != 0xff && ((ntohl(addr.s_addr) & 0xff) != 0x0))))
|
||||
{
|
||||
- struct ping_result *r;
|
||||
-
|
||||
- if ((r = do_icmp_ping(now, addr, j, loopback)))
|
||||
- {
|
||||
- /* consec-ip mode: we offered this address for another client
|
||||
- (different hash) recently, don't offer it to this one. */
|
||||
- if (!option_bool(OPT_CONSEC_ADDR) || r->hash == j)
|
||||
- {
|
||||
- *addrp = addr;
|
||||
- return 1;
|
||||
- }
|
||||
- }
|
||||
+ /* in consec-ip mode, skip addresses equal to
|
||||
+ the number of addresses rejected by clients. This
|
||||
+ should avoid the same client being offered the same
|
||||
+ address after it has rjected it. */
|
||||
+ if (option_bool(OPT_CONSEC_ADDR) && c->addr_epoch)
|
||||
+ c->addr_epoch--;
|
||||
else
|
||||
{
|
||||
- /* address in use: perturb address selection so that we are
|
||||
- less likely to try this address again. */
|
||||
- if (!option_bool(OPT_CONSEC_ADDR))
|
||||
- c->addr_epoch++;
|
||||
+ struct ping_result *r;
|
||||
+
|
||||
+ if ((r = do_icmp_ping(now, addr, j, loopback)))
|
||||
+ {
|
||||
+ /* consec-ip mode: we offered this address for another client
|
||||
+ (different hash) recently, don't offer it to this one. */
|
||||
+ if (!option_bool(OPT_CONSEC_ADDR) || r->hash == j)
|
||||
+ {
|
||||
+ *addrp = addr;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* address in use: perturb address selection so that we are
|
||||
+ less likely to try this address again. */
|
||||
+ if (!option_bool(OPT_CONSEC_ADDR))
|
||||
+ c->addr_epoch++;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--- a/src/dhcp6.c
|
||||
+++ b/src/dhcp6.c
|
||||
@@ -436,7 +436,7 @@ struct dhcp_context *address6_allocate(s
|
||||
skip addresses equal to the number of addresses rejected
|
||||
by clients. This should avoid the same client being offered the same
|
||||
address after it has rjected it. */
|
||||
- start = lease_find_max_addr6(c) + serial + c->addr_epoch;
|
||||
+ start = lease_find_max_addr6(c) + 1 + serial + c->addr_epoch;
|
||||
if (c->addr_epoch)
|
||||
c->addr_epoch--;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
From 4bf62f616b82fad7a7f91195b0204dd64d79a35c Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Thu, 10 Jan 2019 21:54:22 +0000
|
||||
Subject: [PATCH 28/30] Tidy cache_blockdata_free()
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/cache.c | 15 +++++++++------
|
||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -200,14 +200,17 @@ static void cache_hash(struct crec *crec
|
||||
|
||||
static void cache_blockdata_free(struct crec *crecp)
|
||||
{
|
||||
- if (crecp->flags & F_SRV && !(crecp->flags & F_NEG))
|
||||
- blockdata_free(crecp->addr.srv.target);
|
||||
+ if (!(crecp->flags & F_NEG))
|
||||
+ {
|
||||
+ if (crecp->flags & F_SRV)
|
||||
+ blockdata_free(crecp->addr.srv.target);
|
||||
#ifdef HAVE_DNSSEC
|
||||
- else if (crecp->flags & F_DNSKEY)
|
||||
- blockdata_free(crecp->addr.key.keydata);
|
||||
- else if ((crecp->flags & F_DS) && !(crecp->flags & F_NEG))
|
||||
- blockdata_free(crecp->addr.ds.keydata);
|
||||
+ else if (crecp->flags & F_DNSKEY)
|
||||
+ blockdata_free(crecp->addr.key.keydata);
|
||||
+ else if (crecp->flags & F_DS)
|
||||
+ blockdata_free(crecp->addr.ds.keydata);
|
||||
#endif
|
||||
+ }
|
||||
}
|
||||
|
||||
static void cache_free(struct crec *crecp)
|
@ -0,0 +1,52 @@
|
||||
From f8c77edbdffb8ada7753ea9fa104f0f6da70cfe3 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Thu, 10 Jan 2019 21:58:18 +0000
|
||||
Subject: [PATCH 29/30] Fix removal of DHCP_CLIENT_MAC options from DHCPv6
|
||||
relay replies.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/rfc3315.c | 30 +++++++++++++++++-------------
|
||||
1 file changed, 17 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/src/rfc3315.c
|
||||
+++ b/src/rfc3315.c
|
||||
@@ -219,21 +219,25 @@ static int dhcp6_maybe_relay(struct stat
|
||||
if (opt6_ptr(opt, 0) + opt6_len(opt) > end)
|
||||
return 0;
|
||||
|
||||
- int o = new_opt6(opt6_type(opt));
|
||||
- if (opt6_type(opt) == OPTION6_RELAY_MSG)
|
||||
+ /* Don't copy MAC address into reply. */
|
||||
+ if (opt6_type(opt) != OPTION6_CLIENT_MAC)
|
||||
{
|
||||
- struct in6_addr align;
|
||||
- /* the packet data is unaligned, copy to aligned storage */
|
||||
- memcpy(&align, inbuff + 2, IN6ADDRSZ);
|
||||
- state->link_address = &align;
|
||||
- /* zero is_unicast since that is now known to refer to the
|
||||
- relayed packet, not the original sent by the client */
|
||||
- if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, 0, now))
|
||||
- return 0;
|
||||
+ int o = new_opt6(opt6_type(opt));
|
||||
+ if (opt6_type(opt) == OPTION6_RELAY_MSG)
|
||||
+ {
|
||||
+ struct in6_addr align;
|
||||
+ /* the packet data is unaligned, copy to aligned storage */
|
||||
+ memcpy(&align, inbuff + 2, IN6ADDRSZ);
|
||||
+ state->link_address = &align;
|
||||
+ /* zero is_unicast since that is now known to refer to the
|
||||
+ relayed packet, not the original sent by the client */
|
||||
+ if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, 0, now))
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
|
||||
+ end_opt6(o);
|
||||
}
|
||||
- else if (opt6_type(opt) != OPTION6_CLIENT_MAC)
|
||||
- put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
|
||||
- end_opt6(o);
|
||||
}
|
||||
|
||||
return 1;
|
@ -0,0 +1,54 @@
|
||||
From 18eac67c0a15b673c8d27002c248651b308093e4 Mon Sep 17 00:00:00 2001
|
||||
From: Steven Siloti <ssiloti@gmail.com>
|
||||
Date: Sun, 13 Jan 2019 22:56:36 +0000
|
||||
Subject: [PATCH 30/30] Fix entries in /etc/hosts disabling static leases.
|
||||
|
||||
It is possible for a config entry to have one address family specified by a
|
||||
dhcp-host directive and the other added from /etc/hosts. This is especially
|
||||
common on OpenWrt because it uses odhcpd for DHCPv6 and IPv6 leases are
|
||||
imported into dnsmasq via a hosts file.
|
||||
|
||||
To handle this case there need to be separate *_HOSTS flags for IPv4 and IPv6.
|
||||
Otherwise when the hosts file is reloaded it will clear the CONFIG_ADDR(6) flag
|
||||
which was set by the dhcp-host directive.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/dhcp-common.c | 8 ++++++--
|
||||
src/dnsmasq.h | 1 +
|
||||
2 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/dhcp-common.c
|
||||
+++ b/src/dhcp-common.c
|
||||
@@ -372,7 +372,11 @@ void dhcp_update_configs(struct dhcp_con
|
||||
|
||||
for (config = configs; config; config = config->next)
|
||||
if (config->flags & CONFIG_ADDR_HOSTS)
|
||||
- config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR6 | CONFIG_ADDR_HOSTS);
|
||||
+ config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR_HOSTS);
|
||||
+#ifdef HAVE_DHCP6
|
||||
+ if (config->flags & CONFIG_ADDR6_HOSTS)
|
||||
+ config->flags &= ~(CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS);
|
||||
+#endif
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
again:
|
||||
@@ -421,7 +425,7 @@ void dhcp_update_configs(struct dhcp_con
|
||||
(!(conf_tmp = config_find_by_address6(configs, &crec->addr.addr6, 128, 0)) || conf_tmp == config))
|
||||
{
|
||||
memcpy(&config->addr6, &crec->addr.addr6, IN6ADDRSZ);
|
||||
- config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS;
|
||||
+ config->flags |= CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -789,6 +789,7 @@ struct dhcp_config {
|
||||
#define CONFIG_BANK 2048 /* from dhcp hosts file */
|
||||
#define CONFIG_ADDR6 4096
|
||||
#define CONFIG_WILDCARD 8192
|
||||
+#define CONFIG_ADDR6_HOSTS 16384 /* address added by from /etc/hosts */
|
||||
|
||||
struct dhcp_opt {
|
||||
int opt, len, flags;
|
@ -0,0 +1,27 @@
|
||||
From f52bb5be437ab33d7cd10f0ff1cdf0bb86857cf7 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
Date: Wed, 16 Jan 2019 09:48:07 +0000
|
||||
Subject: [PATCH 31/31] fix previous commit
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/dhcp-common.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/src/dhcp-common.c
|
||||
+++ b/src/dhcp-common.c
|
||||
@@ -371,12 +371,14 @@ void dhcp_update_configs(struct dhcp_con
|
||||
int prot = AF_INET;
|
||||
|
||||
for (config = configs; config; config = config->next)
|
||||
+ {
|
||||
if (config->flags & CONFIG_ADDR_HOSTS)
|
||||
config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR_HOSTS);
|
||||
#ifdef HAVE_DHCP6
|
||||
if (config->flags & CONFIG_ADDR6_HOSTS)
|
||||
config->flags &= ~(CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS);
|
||||
#endif
|
||||
+ }
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
again:
|
Loading…
Reference in New Issue
Block a user