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:
		| @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk | |||||||
|  |  | ||||||
| PKG_NAME:=dnsmasq | PKG_NAME:=dnsmasq | ||||||
| PKG_VERSION:=2.80 | PKG_VERSION:=2.80 | ||||||
| PKG_RELEASE:=5 | PKG_RELEASE:=6 | ||||||
|  |  | ||||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz | ||||||
| PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq | PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| From a799ca0c6314ad73a97bc6c89382d2712a9c0b0e Mon Sep 17 00:00:00 2001 | From a799ca0c6314ad73a97bc6c89382d2712a9c0b0e Mon Sep 17 00:00:00 2001 | ||||||
| From: Simon Kelley <simon@thekelleys.org.uk> | From: Simon Kelley <simon@thekelleys.org.uk> | ||||||
| Date: Thu, 18 Oct 2018 19:35:29 +0100 | 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 | 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 | 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 a220545c4277cba534be5ef4638b5076fc7d2cf4 Mon Sep 17 00:00:00 2001 | ||||||
| From: Simon Kelley <simon@thekelleys.org.uk> | From: Simon Kelley <simon@thekelleys.org.uk> | ||||||
| Date: Mon, 22 Oct 2018 18:21:48 +0100 | 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>. |  --address=/<domain>/<address>. | ||||||
|  |  | ||||||
| Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | 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 ee8750451b49d27b180517a4e35b636be0fae575 Mon Sep 17 00:00:00 2001 | ||||||
| From: Simon Kelley <simon@thekelleys.org.uk> | From: Simon Kelley <simon@thekelleys.org.uk> | ||||||
| Date: Tue, 23 Oct 2018 22:10:17 +0100 | 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 | This was the source of a large number of #ifdefs, originally | ||||||
| included for use with old embedded libc versions. I'm | included for use with old embedded libc versions. I'm | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| From cf5984367bc6a949e3803a576512c5a7bc48ebab Mon Sep 17 00:00:00 2001 | From cf5984367bc6a949e3803a576512c5a7bc48ebab Mon Sep 17 00:00:00 2001 | ||||||
| From: Vladislav Grishenko <themiron@mail.ru> | From: Vladislav Grishenko <themiron@mail.ru> | ||||||
| Date: Thu, 18 Oct 2018 04:55:21 +0500 | 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 | Chaos .bind and .server (RFC4892) zones are local, therefore | ||||||
| don't forward queries upstream to avoid mixing with supported | don't forward queries upstream to avoid mixing with supported | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| From cbb5b17ad8e03e08ade62376a4f6a2066e55960d Mon Sep 17 00:00:00 2001 | From cbb5b17ad8e03e08ade62376a4f6a2066e55960d Mon Sep 17 00:00:00 2001 | ||||||
| From: Simon Kelley <simon@thekelleys.org.uk> | From: Simon Kelley <simon@thekelleys.org.uk> | ||||||
| Date: Tue, 23 Oct 2018 23:45:57 +0100 | 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> | 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 6f7812d97bc8f87004c0a5069c6c94c64af78106 Mon Sep 17 00:00:00 2001 | ||||||
| From: Simon Kelley <simon@thekelleys.org.uk> | From: Simon Kelley <simon@thekelleys.org.uk> | ||||||
| Date: Tue, 23 Oct 2018 23:54:44 +0100 | 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. |  config. | ||||||
|  |  | ||||||
| Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | 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 24b87607c1353e94689e8a2190571ab3f3b36f31 Mon Sep 17 00:00:00 2001 | ||||||
| From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com> | From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com> | ||||||
| Date: Wed, 24 Oct 2018 22:30:18 +0100 | 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 |  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 |  bits and last supported bit in computation. No new change would be required | ||||||
|  when new options are added. Just change OPT_LAST constant. |  when new options are added. Just change OPT_LAST constant. | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| From 3a5a84cdd1488bad118eeac72d09a60299bca744 Mon Sep 17 00:00:00 2001 | From 3a5a84cdd1488bad118eeac72d09a60299bca744 Mon Sep 17 00:00:00 2001 | ||||||
| From: Simon Kelley <simon@thekelleys.org.uk> | From: Simon Kelley <simon@thekelleys.org.uk> | ||||||
| Date: Wed, 31 Oct 2018 21:30:13 +0000 | 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 | 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 | 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 122392e0b352507cabb9e982208d35d2e56902e0 Mon Sep 17 00:00:00 2001 | ||||||
| From: Simon Kelley <simon@thekelleys.org.uk> | From: Simon Kelley <simon@thekelleys.org.uk> | ||||||
| Date: Wed, 31 Oct 2018 22:24:02 +0000 | 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 | The above is intended to increase robustness, but actually does the | ||||||
| opposite. The problem is that by ignoring SERVFAIL messages and hoping | 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 48d12f14c9c0fc8cf943b52774c3892517dd72d4 Mon Sep 17 00:00:00 2001 | ||||||
| From: Simon Kelley <simon@thekelleys.org.uk> | From: Simon Kelley <simon@thekelleys.org.uk> | ||||||
| Date: Fri, 2 Nov 2018 21:55:04 +0000 | 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. |  uclinux. | ||||||
|  |  | ||||||
| In an era where everything has an MMU, this looks like | 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 59e470381f84f2fdf0640c7bc67827f3f0c64784 Mon Sep 17 00:00:00 2001 | ||||||
| From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com> | From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com> | ||||||
| Date: Fri, 2 Nov 2018 22:39:39 +0000 | 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 | 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. | 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> | From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com> | ||||||
| Date: Fri, 14 Dec 2018 17:03:08 +0100 | Date: Sun, 16 Dec 2018 21:25:29 +0000 | ||||||
| Subject: [PATCH] Fix required tags in few places | Subject: [PATCH 14/30] Fix option parsing errors introduced in | ||||||
|  |  59e470381f84f2fdf0640c7bc67827f3f0c64784 | ||||||
| 
 | 
 | ||||||
| Some locations were incorrectly changed to require always tags, else | Thanks to Kevin Darbyshire-Bryant for spotting this. | ||||||
| dnsmasq will not start. Fix dhcp-boot, dhcp-reply-delay and pxe-prompt. | 
 | ||||||
|  | Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | ||||||
| ---
 | ---
 | ||||||
|  src/option.c | 6 +++--- |  src/option.c | 6 +++--- | ||||||
|  1 file changed, 3 insertions(+), 3 deletions(-) |  1 file changed, 3 insertions(+), 3 deletions(-) | ||||||
| 
 | 
 | ||||||
| --- a/src/option.c
 | --- a/src/option.c
 | ||||||
| +++ b/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); |  	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); |  	    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); |  	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); |  	    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->opt = 10; /* PXE_MENU_PROMPT */ | ||||||
|  	 new->netid = dhcp_tags(&arg); |  	 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 061eb8599636bb360e0b7fa5986935b86db39497 Mon Sep 17 00:00:00 2001 | ||||||
| From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | ||||||
| Date: Mon, 10 Dec 2018 10:07:33 +0000 | 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:   | ||||||
		Reference in New Issue
	
	Block a user
	 Kevin Darbyshire-Bryant
					Kevin Darbyshire-Bryant