dnsmasq: backport latest patches
authorKevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Sat, 9 Mar 2019 08:40:57 +0000 (08:40 +0000)
committerKevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Thu, 25 Jul 2019 11:23:46 +0000 (12:23 +0100)
Backport upstream patches pre 2.81rc for testing purposes.

Let's see what falls out!

Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
52 files changed:
package/network/services/dnsmasq/Makefile
package/network/services/dnsmasq/patches/0001-Impove-cache-behaviour-for-TCP-connections.patch
package/network/services/dnsmasq/patches/0002-Ensure-that-AD-bit-is-reset-on-answers-from-address-.patch
package/network/services/dnsmasq/patches/0003-Remove-ability-to-compile-without-IPv6-support.patch
package/network/services/dnsmasq/patches/0004-Don-t-forward-.bind-.server-queries-upstream.patch
package/network/services/dnsmasq/patches/0005-Fix-logging-in-cf5984367bc6a949e3803a576512c5a7bc48e.patch
package/network/services/dnsmasq/patches/0006-Fix-spurious-AD-flags-in-some-DNS-replies-from-local.patch
package/network/services/dnsmasq/patches/0007-Do-not-rely-on-dead-code-elimination-use-array-inste.patch
package/network/services/dnsmasq/patches/0008-Fix-Makefile-lines-generating-UBUS-linker-config.patch
package/network/services/dnsmasq/patches/0009-Revert-68f6312d4bae30b78daafcd6f51dc441b8685b1e.patch
package/network/services/dnsmasq/patches/0010-Remove-the-NO_FORK-compile-time-option-and-support-f.patch
package/network/services/dnsmasq/patches/0011-Free-config-file-values-on-parsing-errors.patch
package/network/services/dnsmasq/patches/0013-Treat-DS-and-DNSKEY-queries-being-forwarded-the-same.patch
package/network/services/dnsmasq/patches/0014-Fix-option-parsing-errors-introduced-in-59e470381f84.patch
package/network/services/dnsmasq/patches/0015-fix-ipv6-ipset-bug-in-master.patch
package/network/services/dnsmasq/patches/0016-build-failure-on-master-with-NO_DHCPv6-and-fix.patch
package/network/services/dnsmasq/patches/0017-Alter-DHCP-address-selection-after-DECLINE-in-consec.patch
package/network/services/dnsmasq/patches/0018-Tidy-all_addr-union-merge-log-and-rcode-fields.patch
package/network/services/dnsmasq/patches/0019-Tidy-address-union-handling-move-class-into-explicit.patch
package/network/services/dnsmasq/patches/0020-Futher-address-union-tidying.patch
package/network/services/dnsmasq/patches/0021-Remove-nested-struct-union-in-cache-records-and-all_.patch
package/network/services/dnsmasq/patches/0022-File-logic-bug-in-cache-marshalling-code.-Introduced.patch
package/network/services/dnsmasq/patches/0023-Fix-typo-in-ra-param-man-page-section.patch
package/network/services/dnsmasq/patches/0024-Cache-SRV-records.patch
package/network/services/dnsmasq/patches/0025-Fix-crash-freeing-negative-SRV-cache-entries.patch
package/network/services/dnsmasq/patches/0026-Check-for-not-DS-or-DNSKEY-in-is_outdated_cname_poin.patch
package/network/services/dnsmasq/patches/0027-Fix-e7bfd556c079c8b5e7425aed44abc35925b24043-to-actu.patch
package/network/services/dnsmasq/patches/0028-Tidy-cache_blockdata_free.patch
package/network/services/dnsmasq/patches/0029-Fix-removal-of-DHCP_CLIENT_MAC-options-from-DHCPv6-r.patch
package/network/services/dnsmasq/patches/0030-Fix-entries-in-etc-hosts-disabling-static-leases.patch
package/network/services/dnsmasq/patches/0031-Fix-missing-braces-in-8eac67c0a15b673c8d27002c248651.patch
package/network/services/dnsmasq/patches/0032-Change-read_leases-to-skip-invalid-entries.patch
package/network/services/dnsmasq/patches/0033-Fix-line-counting-when-reading-etc-hosts.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0034-Fix-bug-added-in-2.80-non-terminal-code-which-return.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0035-lease-prune-lease-as-soon-as-expired.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0036-More-etc-hosts-linecount-fixing.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0037-Small-error-message-tweak-for-clarity.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0038-Fix-to-credits-in-162e5e0062ce923c494cc64282f293f0ed.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0041-Don-t-attempt-to-parse-a-sequence-of-hex-digits-with.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0042-Remove-unclear-gcc-ism-in-conditional-expression.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0043-Remove-redundant-prototypes-from-dnsmasq.h.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0044-Support-TCP-fastopen-on-incoming-and-outgoing-connec.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0045-Improve-kernel-capability-manipulation-code-under-Li.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0046-Add-shared-network-DHCP-configuration.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0047-CHANGELOG-typo-fix.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0048-Fix-cmsg-3-API-usage-on-OpenBSD.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0049-Apply-fix-from-c6cc455dd191fbea56ee14a0ef88a7d655a6f.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0050-Don-t-retry-close-syscalls-after-an-EINTR-errors.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0051-Allow-more-then-one-conf-file-on-the-command-line.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0052-Improved-UBus-supported.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0056-Fix-wrong-return-code-from-explore_rrset-with-some-e.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0057-Fix-build-after-y2038-changes-in-glib.patch [new file with mode: 0644]

index c04d96f..dc20ada 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=dnsmasq
 PKG_UPSTREAM_VERSION:=2.80
 PKG_VERSION:=$(subst test,~~test,$(subst rc,~rc,$(PKG_UPSTREAM_VERSION)))
-PKG_RELEASE:=13
+PKG_RELEASE:=14
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_UPSTREAM_VERSION).tar.xz
 PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
index c801f25..bd2d3cb 100644 (file)
@@ -1,7 +1,7 @@
 From a799ca0c6314ad73a97bc6c89382d2712a9c0b0e Mon Sep 17 00:00:00 2001
 From: Simon Kelley <simon@thekelleys.org.uk>
 Date: Thu, 18 Oct 2018 19:35:29 +0100
-Subject: [PATCH 01/32] Impove cache behaviour for TCP connections.
+Subject: [PATCH 01/57] Impove cache behaviour for TCP connections.
 
 For ease of implementaion, dnsmasq has always forked a new process to
 handle each incoming TCP connection. A side-effect of this is that any
index 0a115fe..2cded82 100644 (file)
@@ -1,7 +1,7 @@
 From a220545c4277cba534be5ef4638b5076fc7d2cf4 Mon Sep 17 00:00:00 2001
 From: Simon Kelley <simon@thekelleys.org.uk>
 Date: Mon, 22 Oct 2018 18:21:48 +0100
-Subject: [PATCH 02/32] Ensure that AD bit is reset on answers from
+Subject: [PATCH 02/57] Ensure that AD bit is reset on answers from
  --address=/<domain>/<address>.
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
index 527a38d..bc18c0d 100644 (file)
@@ -1,7 +1,7 @@
 From ee8750451b49d27b180517a4e35b636be0fae575 Mon Sep 17 00:00:00 2001
 From: Simon Kelley <simon@thekelleys.org.uk>
 Date: Tue, 23 Oct 2018 22:10:17 +0100
-Subject: [PATCH 03/32] Remove ability to compile without IPv6 support.
+Subject: [PATCH 03/57] Remove ability to compile without IPv6 support.
 
 This was the source of a large number of #ifdefs, originally
 included for use with old embedded libc versions. I'm
index cbf211a..dd47128 100644 (file)
@@ -1,7 +1,7 @@
 From cf5984367bc6a949e3803a576512c5a7bc48ebab Mon Sep 17 00:00:00 2001
 From: Vladislav Grishenko <themiron@mail.ru>
 Date: Thu, 18 Oct 2018 04:55:21 +0500
-Subject: [PATCH 04/32] Don't forward *.bind/*.server queries upstream
+Subject: [PATCH 04/57] Don't forward *.bind/*.server queries upstream
 
 Chaos .bind and .server (RFC4892) zones are local, therefore
 don't forward queries upstream to avoid mixing with supported
index 473297b..80689e4 100644 (file)
@@ -1,7 +1,7 @@
 From cbb5b17ad8e03e08ade62376a4f6a2066e55960d Mon Sep 17 00:00:00 2001
 From: Simon Kelley <simon@thekelleys.org.uk>
 Date: Tue, 23 Oct 2018 23:45:57 +0100
-Subject: [PATCH 05/32] Fix logging in cf5984367bc6a949e3803a576512c5a7bc48ebab
+Subject: [PATCH 05/57] Fix logging in cf5984367bc6a949e3803a576512c5a7bc48ebab
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
 ---
index bebc7ba..3641ffc 100644 (file)
@@ -1,7 +1,7 @@
 From 6f7812d97bc8f87004c0a5069c6c94c64af78106 Mon Sep 17 00:00:00 2001
 From: Simon Kelley <simon@thekelleys.org.uk>
 Date: Tue, 23 Oct 2018 23:54:44 +0100
-Subject: [PATCH 06/32] Fix spurious AD flags in some DNS replies from local
+Subject: [PATCH 06/57] Fix spurious AD flags in some DNS replies from local
  config.
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
index 7934792..828773a 100644 (file)
@@ -1,7 +1,7 @@
 From 24b87607c1353e94689e8a2190571ab3f3b36f31 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
 Date: Wed, 24 Oct 2018 22:30:18 +0100
-Subject: [PATCH 07/32] Do not rely on dead code elimination, use array
+Subject: [PATCH 07/57] Do not rely on dead code elimination, use array
  instead. Make options bits derived from size and count. Use size of option
  bits and last supported bit in computation. No new change would be required
  when new options are added. Just change OPT_LAST constant.
index 766aad2..2a34847 100644 (file)
@@ -1,7 +1,7 @@
 From 3a5a84cdd1488bad118eeac72d09a60299bca744 Mon Sep 17 00:00:00 2001
 From: Simon Kelley <simon@thekelleys.org.uk>
 Date: Wed, 31 Oct 2018 21:30:13 +0000
-Subject: [PATCH 08/32] Fix Makefile lines generating UBUS linker config.
+Subject: [PATCH 08/57] Fix Makefile lines generating UBUS linker config.
 
 If arg2 of pkg-wrapper is "--copy", then arg1 is NOT the name of
 the package manager (--copy doesn't invoke it) it's a secondary
index 32468ae..aba1fb3 100644 (file)
@@ -1,7 +1,7 @@
 From 122392e0b352507cabb9e982208d35d2e56902e0 Mon Sep 17 00:00:00 2001
 From: Simon Kelley <simon@thekelleys.org.uk>
 Date: Wed, 31 Oct 2018 22:24:02 +0000
-Subject: [PATCH 09/32] Revert 68f6312d4bae30b78daafcd6f51dc441b8685b1e
+Subject: [PATCH 09/57] Revert 68f6312d4bae30b78daafcd6f51dc441b8685b1e
 
 The above is intended to increase robustness, but actually does the
 opposite. The problem is that by ignoring SERVFAIL messages and hoping
index 78f31d0..120180a 100644 (file)
@@ -1,7 +1,7 @@
 From 48d12f14c9c0fc8cf943b52774c3892517dd72d4 Mon Sep 17 00:00:00 2001
 From: Simon Kelley <simon@thekelleys.org.uk>
 Date: Fri, 2 Nov 2018 21:55:04 +0000
-Subject: [PATCH 10/32] Remove the NO_FORK compile-time option, and support for
+Subject: [PATCH 10/57] Remove the NO_FORK compile-time option, and support for
  uclinux.
 
 In an era where everything has an MMU, this looks like
index 0b53b30..e113d30 100644 (file)
@@ -1,7 +1,7 @@
 From 59e470381f84f2fdf0640c7bc67827f3f0c64784 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
 Date: Fri, 2 Nov 2018 22:39:39 +0000
-Subject: [PATCH 11/32] Free config file values on parsing errors.
+Subject: [PATCH 11/57] Free config file values on parsing errors.
 
 This time I have a little bit more controversal patches. But I think
 still useful. They fixes memory leaks that might occur in some cases.
index 7053d03..4fa3319 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Treat DS and DNSKEY queries being forwarded the same as
+Subject: [PATCH 13/57] 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
index 2aaf382..eca8417 100644 (file)
@@ -1,7 +1,7 @@
 From 137e9f878fafb38369eab7d9dfe84e4228ff5f89 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
 Date: Sun, 16 Dec 2018 21:25:29 +0000
-Subject: [PATCH 14/32] Fix option parsing errors introduced in
+Subject: [PATCH 14/57] Fix option parsing errors introduced in
  59e470381f84f2fdf0640c7bc67827f3f0c64784
 
 Thanks to Kevin Darbyshire-Bryant for spotting this.
index 920cf75..0a7b6f4 100644 (file)
@@ -1,7 +1,7 @@
 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/32] fix ipv6 ipset bug in master
+Subject: [PATCH 15/57] fix ipv6 ipset bug in master
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
index e4e363b..f89b52a 100644 (file)
@@ -1,7 +1,7 @@
 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/32] build failure on master with NO_DHCPv6 and fix....
+Subject: [PATCH 16/57] build failure on master with NO_DHCPv6 and fix....
 
 Hi Simon,
 
index 1a3b341..1bbfe3f 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Alter DHCP address selection after DECLINE in
+Subject: [PATCH 17/57] 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
index e6b456f..7b770cd 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Tidy all_addr union, merge log and rcode fields.
+Subject: [PATCH 18/57] Tidy all_addr union, merge log and rcode fields.
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
 ---
index 4854617..1a1cd0b 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Tidy address-union handling: move class into explicit
+Subject: [PATCH 19/57] Tidy address-union handling: move class into explicit
  argument.
 
 This moves the class argument to cache-insert into an argument,
index deda82f..74fe46b 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Futher address union tidying.
+Subject: [PATCH 20/57] 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.
index 360e8a4..6fc85e2 100644 (file)
@@ -1,7 +1,7 @@
 From cc921df9ceac79acf9f1c477d015a3d88275422d Mon Sep 17 00:00:00 2001
 From: Simon Kelley <simon@thekelleys.org.uk>
 Date: Wed, 2 Jan 2019 22:48:59 +0000
-Subject: [PATCH 21/32] Remove nested struct/union in cache records and
+Subject: [PATCH 21/57] Remove nested struct/union in cache records and
  all_addr.
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
index 32a02cd..593150c 100644 (file)
@@ -1,7 +1,7 @@
 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/32] File logic bug in cache-marshalling code. Introduced a
+Subject: [PATCH 22/57] File logic bug in cache-marshalling code. Introduced a
  couple of commits back.
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
index 48343af..7b7cbca 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Fix typo in ra-param man page section.
+Subject: [PATCH 23/57] Fix typo in ra-param man page section.
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
 ---
index d38d30e..351a3c2 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Cache SRV records.
+Subject: [PATCH 24/57] Cache SRV records.
 
 Inpsired by a patch from Jeremy Allison, but completely re-rolled
 by srk. All bugs are mine.
index 424574b..e94223d 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Fix crash freeing negative SRV cache entries.
+Subject: [PATCH 25/57] Fix crash freeing negative SRV cache entries.
 
 Thanks to Daniel for finding this one.
 
index 4ca0be4..9ded9eb 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Check for not(DS or DNSKEY) in
+Subject: [PATCH 26/57] Check for not(DS or DNSKEY) in
  is_outdated_cname_pointer()
 
 Previous check was _for_ IPV4, IPv6 CNAME, and I missed adding SRV.
index 63d5baa..fb6580a 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Fix e7bfd556c079c8b5e7425aed44abc35925b24043 to
+Subject: [PATCH 27/57] Fix e7bfd556c079c8b5e7425aed44abc35925b24043 to
  actually work.
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
index 8aa69a7..f93b232 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Tidy cache_blockdata_free()
+Subject: [PATCH 28/57] Tidy cache_blockdata_free()
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
 ---
index e02bd11..d05c2b8 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Fix removal of DHCP_CLIENT_MAC options from DHCPv6
+Subject: [PATCH 29/57] Fix removal of DHCP_CLIENT_MAC options from DHCPv6
  relay replies.
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
index 00f2102..3b8e47f 100644 (file)
@@ -1,7 +1,7 @@
 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/32] Fix entries in /etc/hosts disabling static leases.
+Subject: [PATCH 30/57] 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
index 928c6ee..6f74394 100644 (file)
@@ -1,7 +1,7 @@
 From d2d49907435433001ab00698a3e9ca2a7b5b3236 Mon Sep 17 00:00:00 2001
 From: Steven Siloti <ssiloti@gmail.com>
 Date: Thu, 17 Jan 2019 22:52:13 +0000
-Subject: [PATCH 31/32] Fix missing braces in
+Subject: [PATCH 31/57] Fix missing braces in
  8eac67c0a15b673c8d27002c248651b308093e4
 
 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
index bbaed87..8f21c1a 100644 (file)
@@ -1,7 +1,7 @@
 From 28cfe36e1eee9d2c234e0256ad459956b415a3bb Mon Sep 17 00:00:00 2001
 From: Brian Haley <haleyb.dev@gmail.com>
 Date: Thu, 17 Jan 2019 23:21:23 +0000
-Subject: [PATCH 32/32] Change read_leases() to skip invalid entries.
+Subject: [PATCH 32/57] Change read_leases() to skip invalid entries.
 
 There's no reason to stop reading the existing lease file
 when dnsmasq is started and an invalid entry is found, it
diff --git a/package/network/services/dnsmasq/patches/0033-Fix-line-counting-when-reading-etc-hosts.patch b/package/network/services/dnsmasq/patches/0033-Fix-line-counting-when-reading-etc-hosts.patch
new file mode 100644 (file)
index 0000000..18b1768
--- /dev/null
@@ -0,0 +1,86 @@
+From 4219adeeef8a3d5447af4c9bd1e4e7c05b3112fd Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Wed, 27 Feb 2019 20:30:21 +0000
+Subject: [PATCH 33/57] Fix line counting when reading /etc/hosts.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ CHANGELOG   |  4 ++++
+ src/cache.c | 16 ++++++++--------
+ 2 files changed, 12 insertions(+), 8 deletions(-)
+
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -17,6 +17,10 @@ version 2.81
+       combinatorial explosion of compile-time options. Thanks to
+       Kevin Darbyshire-Bryant for the patch.
++      Fix line-counting when reading /etc/hosts and friends; for
++      correct error messages. Thanks to Christian Rosentreter
++      for reporting this.
++
+ version 2.80
+       Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -1062,7 +1062,7 @@ static int eatspace(FILE *f)
+       }
+       if (c == '\n')
+-      nl = 1;
++      nl++;
+     }
+ }
+        
+@@ -1073,7 +1073,7 @@ static int gettok(FILE *f, char *token)
+   while (1)
+     {
+       if ((c = getc(f)) == EOF)
+-      return (count == 0) ? EOF : 1;
++      return (count == 0) ? -1 : 1;
+       if (isspace(c) || c == '#')
+       {
+@@ -1093,7 +1093,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;
++  int addr_count = 0, name_count = cache_size, lineno = 1;
+   unsigned int flags = 0;
+   union all_addr addr;
+   int atnl, addrlen = 0;
+@@ -1104,12 +1104,10 @@ int read_hostsfile(char *filename, unsig
+       return cache_size;
+     }
+   
+-  eatspace(f);
++  lineno += eatspace(f);
+   
+-  while ((atnl = gettok(f, token)) != EOF)
++  while ((atnl = gettok(f, token)) != -1)
+     {
+-      lineno++;
+-      
+       if (inet_pton(AF_INET, token, &addr) > 0)
+       {
+         flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
+@@ -1145,7 +1143,7 @@ int read_hostsfile(char *filename, unsig
+         int fqdn, nomem;
+         char *canon;
+         
+-        if ((atnl = gettok(f, token)) == EOF)
++        if ((atnl = gettok(f, token)) == -1)
+           break;
+         fqdn = !!strchr(token, '.');
+@@ -1178,6 +1176,8 @@ int read_hostsfile(char *filename, unsig
+         else if (!nomem)
+           my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno); 
+       }
++
++      lineno += atnl;
+     } 
+   fclose(f);
diff --git a/package/network/services/dnsmasq/patches/0034-Fix-bug-added-in-2.80-non-terminal-code-which-return.patch b/package/network/services/dnsmasq/patches/0034-Fix-bug-added-in-2.80-non-terminal-code-which-return.patch
new file mode 100644 (file)
index 0000000..6ae67e6
--- /dev/null
@@ -0,0 +1,42 @@
+From 162e5e0062ce923c494cc64282f293f0ed64fc10 Mon Sep 17 00:00:00 2001
+From: Sven Mueller <smu@google.com>
+Date: Wed, 27 Feb 2019 21:17:37 +0000
+Subject: [PATCH 34/57] Fix bug added in 2.80 non-terminal code which returns
+ NODATA instead of NXDOMAIN.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Thanks to Sven Muleller and Maciej Żenczykowski for work on this.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1674067 refers.
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ CHANGELOG   | 5 +++++
+ src/cache.c | 1 +
+ 2 files changed, 6 insertions(+)
+
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -21,6 +21,11 @@ version 2.81
+       correct error messages. Thanks to Christian Rosentreter
+       for reporting this.
++      Fix bug in DNS non-terminal code, added in 2.80, which could
++      sometimes cause a NODATA rather than an NXDOMAIN reply.
++      Thanks to Sven Mueller and Maciej Żenczykowski for spotting
++      and diagnosing the bug and providing patches.
++
+ version 2.80
+       Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -790,6 +790,7 @@ int cache_find_non_terminal(char *name,
+     if (!is_outdated_cname_pointer(crecp) &&
+       !is_expired(now, crecp) &&
+       (crecp->flags & F_FORWARD) &&
++      !(crecp->flags & F_NXDOMAIN) && 
+       hostname_isequal(name, cache_get_name(crecp)))
+       return 1;
diff --git a/package/network/services/dnsmasq/patches/0035-lease-prune-lease-as-soon-as-expired.patch b/package/network/services/dnsmasq/patches/0035-lease-prune-lease-as-soon-as-expired.patch
new file mode 100644 (file)
index 0000000..e1cfde8
--- /dev/null
@@ -0,0 +1,42 @@
+From df6636bff61aa53ed7ad4b34d940805193c0bc74 Mon Sep 17 00:00:00 2001
+From: Florent Fourcot <florent.fourcot@wifirst.fr>
+Date: Mon, 11 Feb 2019 17:04:44 +0100
+Subject: [PATCH 35/57] lease: prune lease as soon as expired
+
+We detected a performance issue on a dnsmasq running many dhcp sessions
+(more than 10 000). At the end of the day, the server was only releasing
+old DHCP leases but was consuming a lot of CPU.
+
+It looks like curent dhcp pruning:
+ 1) it's pruning old sessions (iterate on all current leases). It's
+ important to note that it's only pruning session expired since more
+ than one second
+ 2) it's looking for next lease to expire (iterate on all current leases
+ again)
+ 3) it launchs an alarm to catch next expiration found in step 2). This
+ value can be zero for leases just expired (but not pruned).
+
+So, for a second, dnsmasq could fall in a "prune loop" by doing:
+ * Not pruning anything, since difftime() is not > 0
+ * Run alarm again with zero as argument
+
+On a server with very large number of leases and releasing often
+sessions, that can waste a very big CPU time.
+
+Signed-off-by: Florent Fourcot <florent.fourcot@wifirst.fr>
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/lease.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/src/lease.c
++++ b/src/lease.c
+@@ -558,7 +558,7 @@ void lease_prune(struct dhcp_lease *targ
+   for (lease = leases, up = &leases; lease; lease = tmp)
+     {
+       tmp = lease->next;
+-      if ((lease->expires != 0 && difftime(now, lease->expires) > 0) || lease == target)
++      if ((lease->expires != 0 && difftime(now, lease->expires) >= 0) || lease == target)
+       {
+         file_dirty = 1;
+         if (lease->hostname)
diff --git a/package/network/services/dnsmasq/patches/0036-More-etc-hosts-linecount-fixing.patch b/package/network/services/dnsmasq/patches/0036-More-etc-hosts-linecount-fixing.patch
new file mode 100644 (file)
index 0000000..820c646
--- /dev/null
@@ -0,0 +1,20 @@
+From 065e5bb0b1c5b9b4ce124ecf35cb2c51feda70e6 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Fri, 1 Mar 2019 14:38:51 +0000
+Subject: [PATCH 36/57] More /etc/hosts linecount fixing.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/cache.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -1126,6 +1126,7 @@ int read_hostsfile(char *filename, unsig
+         my_syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno); 
+         while (atnl == 0)
+           atnl = gettok(f, token);
++        lineno += atnl;
+         continue;
+       }
+       
diff --git a/package/network/services/dnsmasq/patches/0037-Small-error-message-tweak-for-clarity.patch b/package/network/services/dnsmasq/patches/0037-Small-error-message-tweak-for-clarity.patch
new file mode 100644 (file)
index 0000000..1f85220
--- /dev/null
@@ -0,0 +1,21 @@
+From 8bd28a87a241cbdfafd56d1c952656bde53dfa7b Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Fri, 1 Mar 2019 15:00:12 +0000
+Subject: [PATCH 37/57] Small error-message tweak, for clarity.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/network.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/src/network.c
++++ b/src/network.c
+@@ -1535,7 +1535,7 @@ void check_servers(void)
+               {
+                 count--;
+                 if (++locals <= LOCALS_LOGGED)
+-                      my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
++                      my_syslog(LOG_INFO, _("using only locally-known addresses for %s %s"), s1, s2);
+               }
+             else if (serv->flags & SERV_USE_RESOLV)
+               my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
diff --git a/package/network/services/dnsmasq/patches/0038-Fix-to-credits-in-162e5e0062ce923c494cc64282f293f0ed.patch b/package/network/services/dnsmasq/patches/0038-Fix-to-credits-in-162e5e0062ce923c494cc64282f293f0ed.patch
new file mode 100644 (file)
index 0000000..856a020
--- /dev/null
@@ -0,0 +1,24 @@
+From a066aac332dcddbdfb8325d50a4baeb67f67c793 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Fri, 1 Mar 2019 16:18:07 +0000
+Subject: [PATCH 38/57] Fix to credits in
+ 162e5e0062ce923c494cc64282f293f0ed64fc10
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ CHANGELOG | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -23,8 +23,8 @@ version 2.81
+       Fix bug in DNS non-terminal code, added in 2.80, which could
+       sometimes cause a NODATA rather than an NXDOMAIN reply.
+-      Thanks to Sven Mueller and Maciej Żenczykowski for spotting
+-      and diagnosing the bug and providing patches.
++      Thanks to Norman Rasmussen, Sven Mueller and Maciej Żenczykowski
++      for spotting and diagnosing the bug and providing patches.
+ version 2.80
diff --git a/package/network/services/dnsmasq/patches/0041-Don-t-attempt-to-parse-a-sequence-of-hex-digits-with.patch b/package/network/services/dnsmasq/patches/0041-Don-t-attempt-to-parse-a-sequence-of-hex-digits-with.patch
new file mode 100644 (file)
index 0000000..2ff6f88
--- /dev/null
@@ -0,0 +1,42 @@
+From 6799320edb9f8465659259721e01e15f9d263aeb Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Mon, 4 Mar 2019 22:59:42 +0000
+Subject: [PATCH 41/57] Don't attempt to parse a sequence of hex digits without
+ any colons as IPv6 address.
+
+Another confusion in the heuristic dhcp-option parsing. Sigh.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/option.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/src/option.c
++++ b/src/option.c
+@@ -1181,7 +1181,7 @@ static int parse_dhcp_opt(char *errstr,
+     {
+       /* characterise the value */
+       char c;
+-      int found_dig = 0;
++      int found_dig = 0, found_colon = 0;
+       is_addr = is_addr6 = is_hex = is_dec = is_string = 1;
+       addrs = digs = 1;
+       dots = 0;
+@@ -1195,6 +1195,7 @@ static int parse_dhcp_opt(char *errstr,
+         {
+           digs++;
+           is_dec = is_addr = 0;
++          found_colon = 1;
+         }
+       else if (c == '/') 
+         {
+@@ -1236,6 +1237,9 @@ static int parse_dhcp_opt(char *errstr,
+      
+       if (!found_dig)
+       is_dec = is_addr = 0;
++
++      if (!found_colon)
++      is_addr6 = 0;
+      
+       /* We know that some options take addresses */
+       if (opt_len & OT_ADDR_LIST)
diff --git a/package/network/services/dnsmasq/patches/0042-Remove-unclear-gcc-ism-in-conditional-expression.patch b/package/network/services/dnsmasq/patches/0042-Remove-unclear-gcc-ism-in-conditional-expression.patch
new file mode 100644 (file)
index 0000000..853602f
--- /dev/null
@@ -0,0 +1,21 @@
+From 5ed82ae5f2946367b62f17fa4c48e9703f189c72 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Tue, 5 Mar 2019 16:38:34 +0000
+Subject: [PATCH 42/57] Remove unclear gcc-ism in conditional expression.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/radv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/src/radv.c
++++ b/src/radv.c
+@@ -412,7 +412,7 @@ static void send_ra_alias(time_t now, in
+   if (mtu == 0)
+     {
+       char *mtu_name = ra_param ? ra_param->mtu_name : NULL;
+-      sprintf(daemon->namebuff, "/proc/sys/net/ipv6/conf/%s/mtu", mtu_name ? : iface_name);
++      sprintf(daemon->namebuff, "/proc/sys/net/ipv6/conf/%s/mtu", mtu_name ? mtu_name : iface_name);
+       if ((f = fopen(daemon->namebuff, "r")))
+         {
+           if (fgets(daemon->namebuff, MAXDNAME, f))
diff --git a/package/network/services/dnsmasq/patches/0043-Remove-redundant-prototypes-from-dnsmasq.h.patch b/package/network/services/dnsmasq/patches/0043-Remove-redundant-prototypes-from-dnsmasq.h.patch
new file mode 100644 (file)
index 0000000..1f5edec
--- /dev/null
@@ -0,0 +1,44 @@
+From c61c7bb2257059fe1e14851289594415eb0659d7 Mon Sep 17 00:00:00 2001
+From: Dominik DL6ER <dl6er@dl6er.de>
+Date: Sun, 10 Mar 2019 19:37:57 +0100
+Subject: [PATCH 43/57] Remove redundant prototypes from dnsmasq.h
+
+Dear Simon,
+
+the attached patch removes three redundant prototypes from dnsmasq.h. There is no functional change.
+
+Best regards,
+Dominik
+
+From c0b2ccfd20c4eec9d09468fdfe9b4ca8a8f8591e Mon Sep 17 00:00:00 2001
+From: DL6ER <dl6er@dl6er.de>
+Date: Sun, 10 Mar 2019 19:34:07 +0100
+Subject: [PATCH] Remove redundant prototypes from dnsmasq.h
+
+Signed-off-by: DL6ER <dl6er@dl6er.de>
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/dnsmasq.h | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/src/dnsmasq.h
++++ b/src/dnsmasq.h
+@@ -1205,9 +1205,6 @@ size_t resize_packet(struct dns_header *
+ int add_resource_record(struct dns_header *header, char *limit, int *truncp,
+                       int nameoffset, unsigned char **pp, unsigned long ttl, 
+                       int *offset, unsigned short type, unsigned short class, char *format, ...);
+-unsigned char *skip_questions(struct dns_header *header, size_t plen);
+-int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, 
+-               char *name, int isExtract, int extrabytes);
+ int in_arpa_name_2_addr(char *namein, union all_addr *addrp);
+ int private_net(struct in_addr addr, int ban_localhost);
+@@ -1545,8 +1542,6 @@ void dhcp_update_configs(struct dhcp_con
+ void display_opts(void);
+ int lookup_dhcp_opt(int prot, char *name);
+ int lookup_dhcp_len(int prot, int val);
+-char *option_string(int prot, unsigned int opt, unsigned char *val, 
+-                  int opt_len, char *buf, int buf_len);
+ struct dhcp_config *find_config(struct dhcp_config *configs,
+                               struct dhcp_context *context,
+                               unsigned char *clid, int clid_len,
diff --git a/package/network/services/dnsmasq/patches/0044-Support-TCP-fastopen-on-incoming-and-outgoing-connec.patch b/package/network/services/dnsmasq/patches/0044-Support-TCP-fastopen-on-incoming-and-outgoing-connec.patch
new file mode 100644 (file)
index 0000000..bda77f1
--- /dev/null
@@ -0,0 +1,158 @@
+From 608aa9fcfca2ffeba40d78c7c4e0dcb50e0d5704 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Sun, 10 Mar 2019 22:44:15 +0000
+Subject: [PATCH 44/57] Support TCP fastopen on incoming and outgoing
+ connections.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ CHANGELOG     |  5 ++++-
+ src/dnsmasq.h |  1 +
+ src/forward.c | 50 +++++++++++++++++++++++++++++++++++++++++---------
+ src/network.c |  5 +++++
+ 4 files changed, 51 insertions(+), 10 deletions(-)
+
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -26,7 +26,10 @@ version 2.81
+       Thanks to Norman Rasmussen, Sven Mueller and Maciej Żenczykowski
+       for spotting and diagnosing the bug and providing patches.
+-
++      Support TCP-fastopen (RFC-7413) on both incoming and
++      outgoing TCP connections, if supported and enabled in the OS.
++      
++      
+ version 2.80
+       Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method
+       for the initial patch and motivation.
+--- a/src/dnsmasq.h
++++ b/src/dnsmasq.h
+@@ -128,6 +128,7 @@ typedef unsigned long long u64;
+ #include <netinet/ip.h>
+ #include <netinet/ip6.h>
+ #include <netinet/ip_icmp.h>
++#include <netinet/tcp.h>
+ #include <sys/uio.h>
+ #include <syslog.h>
+ #include <dirent.h>
+--- a/src/forward.c
++++ b/src/forward.c
+@@ -1635,6 +1635,8 @@ static int tcp_key_recurse(time_t now, i
+       
+       while (1)
+       {
++        int data_sent = 0;
++        
+         if (!firstsendto)
+           firstsendto = server;
+         else
+@@ -1667,8 +1669,22 @@ static int tcp_key_recurse(time_t now, i
+               setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
+ #endif        
+             
+-            if (!local_bind(server->tcpfd,  &server->source_addr, server->interface, 0, 1) ||
+-                connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
++            if (!local_bind(server->tcpfd,  &server->source_addr, server->interface, 0, 1))
++              {
++                close(server->tcpfd);
++                server->tcpfd = -1;
++                continue; /* No good, next server */
++              }
++            
++#ifdef MSG_FASTOPEN
++            while(retry_send(sendto(server->tcpfd, packet, m + sizeof(u16),
++                                    MSG_FASTOPEN, &server->addr.sa, sa_len(&server->addr))));
++            
++            if (errno == 0)
++              data_sent = 1;
++#endif
++            
++            if (!data_sent && connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
+               {
+                 close(server->tcpfd);
+                 server->tcpfd = -1;
+@@ -1678,7 +1694,7 @@ static int tcp_key_recurse(time_t now, i
+             server->flags &= ~SERV_GOT_TCP;
+           }
+         
+-        if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) ||
++        if ((!data_sent && !read_write(server->tcpfd, packet, m + sizeof(u16), 0)) ||
+             !read_write(server->tcpfd, &c1, 1, 1) ||
+             !read_write(server->tcpfd, &c2, 1, 1) ||
+             !read_write(server->tcpfd, payload, (c1 << 8) | c2, 1))
+@@ -1951,6 +1967,8 @@ unsigned char *tcp_request(int confd, ti
+                    which can go to the same server, do so. */
+                 while (1) 
+                   {
++                    int data_sent = 0;
++
+                     if (!firstsendto)
+                       firstsendto = last_server;
+                     else
+@@ -1969,6 +1987,8 @@ unsigned char *tcp_request(int confd, ti
+                       continue;
+                   retry:
++                    *length = htons(size);
++
+                     if (last_server->tcpfd == -1)
+                       {
+                         if ((last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
+@@ -1978,10 +1998,24 @@ unsigned char *tcp_request(int confd, ti
+                         /* Copy connection mark of incoming query to outgoing connection. */
+                         if (have_mark)
+                           setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
+-#endif        
++#endif                          
+                     
+-                        if ((!local_bind(last_server->tcpfd,  &last_server->source_addr, last_server->interface, 0, 1) ||
+-                             connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
++                        if ((!local_bind(last_server->tcpfd,  &last_server->source_addr, last_server->interface, 0, 1)))
++                          {
++                            close(last_server->tcpfd);
++                            last_server->tcpfd = -1;
++                            continue;
++                          }
++                        
++#ifdef MSG_FASTOPEN
++                          while(retry_send(sendto(last_server->tcpfd, packet, size + sizeof(u16),
++                                                  MSG_FASTOPEN, &last_server->addr.sa, sa_len(&last_server->addr))));
++                          
++                          if (errno == 0)
++                            data_sent = 1;
++#endif
++                          
++                          if (!data_sent && connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1)
+                           {
+                             close(last_server->tcpfd);
+                             last_server->tcpfd = -1;
+@@ -1991,13 +2025,11 @@ unsigned char *tcp_request(int confd, ti
+                         last_server->flags &= ~SERV_GOT_TCP;
+                       }
+                     
+-                    *length = htons(size);
+-
+                     /* get query name again for logging - may have been overwritten */
+                     if (!(gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
+                       strcpy(daemon->namebuff, "query");
+                     
+-                    if (!read_write(last_server->tcpfd, packet, size + sizeof(u16), 0) ||
++                    if ((!data_sent && !read_write(last_server->tcpfd, packet, size + sizeof(u16), 0)) ||
+                         !read_write(last_server->tcpfd, &c1, 1, 1) ||
+                         !read_write(last_server->tcpfd, &c2, 1, 1) ||
+                         !read_write(last_server->tcpfd, payload, (c1 << 8) | c2, 1))
+--- a/src/network.c
++++ b/src/network.c
+@@ -726,6 +726,11 @@ static int make_sock(union mysockaddr *a
+   
+   if (type == SOCK_STREAM)
+     {
++#ifdef TCP_FASTOPEN
++      int qlen = 5;                           
++      setsockopt(fd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
++#endif
++      
+       if (listen(fd, TCP_BACKLOG) == -1)
+       goto err;
+     }
diff --git a/package/network/services/dnsmasq/patches/0045-Improve-kernel-capability-manipulation-code-under-Li.patch b/package/network/services/dnsmasq/patches/0045-Improve-kernel-capability-manipulation-code-under-Li.patch
new file mode 100644 (file)
index 0000000..828f5ad
--- /dev/null
@@ -0,0 +1,203 @@
+From 305ffb5ef0ba5ab1df32ef80f266a4c9e395ca13 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Sat, 16 Mar 2019 18:17:17 +0000
+Subject: [PATCH 45/57] Improve kernel-capability manipulation code under
+ Linux.
+
+Dnsmasq now fails early if a required capability is not available,
+and tries not to request capabilities not required by its
+configuration.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ CHANGELOG     |   7 ++-
+ src/dnsmasq.c | 119 +++++++++++++++++++++++++++++++++-----------------
+ 2 files changed, 84 insertions(+), 42 deletions(-)
+
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -28,7 +28,12 @@ version 2.81
+       Support TCP-fastopen (RFC-7413) on both incoming and
+       outgoing TCP connections, if supported and enabled in the OS.
+-      
++
++      Improve kernel-capability manipulation code under Linux. Dnsmasq
++      now fails early if a required capability is not available, and
++      tries not to request capabilities not required by its
++      configuration.
++
+       
+ version 2.80
+       Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method
+--- a/src/dnsmasq.c
++++ b/src/dnsmasq.c
+@@ -52,6 +52,9 @@ int main (int argc, char **argv)
+ #if defined(HAVE_LINUX_NETWORK)
+   cap_user_header_t hdr = NULL;
+   cap_user_data_t data = NULL;
++  int need_cap_net_admin = 0;
++  int need_cap_net_raw = 0;
++  int need_cap_net_bind_service = 0;
+   char *bound_device = NULL;
+   int did_bind = 0;
+ #endif 
+@@ -285,11 +288,24 @@ int main (int argc, char **argv)
+     }
+   
+   if (daemon->dhcp || daemon->relay4)
+-    dhcp_init();
++    {
++      dhcp_init();
++#   ifdef HAVE_LINUX_NETWORK
++      if (!option_bool(OPT_NO_PING))
++      need_cap_net_raw = 1;
++      need_cap_net_admin = 1;
++#   endif
++    }
+   
+ #  ifdef HAVE_DHCP6
+   if (daemon->doing_ra || daemon->doing_dhcp6 || daemon->relay6)
+-    ra_init(now);
++    {
++      ra_init(now);
++#   ifdef HAVE_LINUX_NETWORK
++      need_cap_net_raw = 1;
++      need_cap_net_admin = 1;
++#   endif
++    }
+   
+   if (daemon->doing_dhcp6 || daemon->relay6)
+     dhcp6_init();
+@@ -299,7 +315,12 @@ int main (int argc, char **argv)
+ #ifdef HAVE_IPSET
+   if (daemon->ipsets)
+-    ipset_init();
++    {
++      ipset_init();
++#  ifdef HAVE_LINUX_NETWORK
++      need_cap_net_admin = 1;
++#  endif
++    }
+ #endif
+ #if  defined(HAVE_LINUX_NETWORK)
+@@ -440,28 +461,58 @@ int main (int argc, char **argv)
+     }
+ #if defined(HAVE_LINUX_NETWORK)
++  /* We keep CAP_NETADMIN (for ARP-injection) and
++     CAP_NET_RAW (for icmp) if we're doing dhcp,
++     if we have yet to bind ports because of DAD, 
++     or we're doing it dynamically,
++     we need CAP_NET_BIND_SERVICE. */
++  if ((is_dad_listeners() || option_bool(OPT_CLEVERBIND)) &&
++      (option_bool(OPT_TFTP) || (daemon->port != 0 && daemon->port <= 1024)))
++    need_cap_net_bind_service = 1;
++
+   /* determine capability API version here, while we can still
+      call safe_malloc */
+-  if (ent_pw && ent_pw->pw_uid != 0)
++  int capsize = 1; /* for header version 1 */
++  char *fail = NULL;
++  
++  hdr = safe_malloc(sizeof(*hdr));
++  
++  /* find version supported by kernel */
++  memset(hdr, 0, sizeof(*hdr));
++  capget(hdr, NULL);
++  
++  if (hdr->version != LINUX_CAPABILITY_VERSION_1)
+     {
+-      int capsize = 1; /* for header version 1 */
+-      hdr = safe_malloc(sizeof(*hdr));
+-
+-      /* find version supported by kernel */
+-      memset(hdr, 0, sizeof(*hdr));
+-      capget(hdr, NULL);
+-      
+-      if (hdr->version != LINUX_CAPABILITY_VERSION_1)
+-      {
+-        /* if unknown version, use largest supported version (3) */
+-        if (hdr->version != LINUX_CAPABILITY_VERSION_2)
+-          hdr->version = LINUX_CAPABILITY_VERSION_3;
+-        capsize = 2;
+-      }
+-      
+-      data = safe_malloc(sizeof(*data) * capsize);
+-      memset(data, 0, sizeof(*data) * capsize);
++      /* if unknown version, use largest supported version (3) */
++      if (hdr->version != LINUX_CAPABILITY_VERSION_2)
++      hdr->version = LINUX_CAPABILITY_VERSION_3;
++      capsize = 2;
+     }
++  
++  data = safe_malloc(sizeof(*data) * capsize);
++  capget(hdr, data); /* Get current values, for verification */
++
++  if (need_cap_net_admin && !(data->permitted & (1 << CAP_NET_ADMIN)))
++    fail = "NET_ADMIN";
++  else if (need_cap_net_raw && !(data->permitted & (1 << CAP_NET_RAW)))
++    fail = "NET_RAW";
++  else if (need_cap_net_bind_service && !(data->permitted & (1 << CAP_NET_BIND_SERVICE)))
++    fail = "NET_BIND_SERVICE";
++  
++  if (fail)
++    die(_("process is missing required capability %s"), fail, EC_MISC);
++
++  /* Now set bitmaps to set caps after daemonising */
++  memset(data, 0, sizeof(*data) * capsize);
++  
++  if (need_cap_net_admin)
++    data->effective |= (1 << CAP_NET_ADMIN);
++  if (need_cap_net_raw)
++    data->effective |= (1 << CAP_NET_RAW);
++  if (need_cap_net_bind_service)
++    data->effective |= (1 << CAP_NET_BIND_SERVICE);
++  
++  data->permitted = data->effective;  
+ #endif
+   /* Use a pipe to carry signals and other events back to the event loop 
+@@ -626,18 +677,9 @@ int main (int argc, char **argv)
+       if (ent_pw && ent_pw->pw_uid != 0)
+       {     
+ #if defined(HAVE_LINUX_NETWORK)         
+-        /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
+-           CAP_NET_RAW (for icmp) if we're doing dhcp. If we have yet to bind 
+-           ports because of DAD, or we're doing it dynamically,
+-           we need CAP_NET_BIND_SERVICE too. */
+-        if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
+-          data->effective = data->permitted = data->inheritable =
+-            (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | 
+-            (1 << CAP_SETUID) | (1 << CAP_NET_BIND_SERVICE);
+-        else
+-          data->effective = data->permitted = data->inheritable =
+-            (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_SETUID);
+-        
++        /* Need to be able to drop root. */
++        data->effective |= (1 << CAP_SETUID);
++        data->permitted |= (1 << CAP_SETUID);
+         /* Tell kernel to not clear capabilities when dropping root */
+         if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
+           bad_capabilities = errno;
+@@ -678,15 +720,10 @@ int main (int argc, char **argv)
+           }     
+ #ifdef HAVE_LINUX_NETWORK
+-        if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
+-         data->effective = data->permitted =
+-           (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_NET_BIND_SERVICE);
+-       else
+-         data->effective = data->permitted = 
+-           (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
+-        data->inheritable = 0;
++        data->effective &= ~(1 << CAP_SETUID);
++        data->permitted &= ~(1 << CAP_SETUID);
+         
+-        /* lose the setuid and setgid capabilities */
++        /* lose the setuid capability */
+         if (capset(hdr, data) == -1)
+           {
+             send_event(err_pipe[1], EVENT_CAP_ERR, errno, NULL);
diff --git a/package/network/services/dnsmasq/patches/0046-Add-shared-network-DHCP-configuration.patch b/package/network/services/dnsmasq/patches/0046-Add-shared-network-DHCP-configuration.patch
new file mode 100644 (file)
index 0000000..637a027
--- /dev/null
@@ -0,0 +1,626 @@
+From ae5b7e04a1025167f1b80840e61432a3cea9625c Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Wed, 27 Mar 2019 22:33:28 +0000
+Subject: [PATCH 46/57] Add --shared-network DHCP configuration.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ CHANGELOG     |   5 ++
+ man/dnsmasq.8 |  21 ++++++
+ src/dhcp.c    |  76 ++++++++++++++++++----
+ src/dhcp6.c   | 175 ++++++++++++++++++++++++++++----------------------
+ src/dnsmasq.h |  11 ++++
+ src/option.c  |  41 ++++++++++++
+ src/rfc2131.c |  97 +++++++++++++++++-----------
+ src/rfc3315.c |  40 +++++++++---
+ 8 files changed, 332 insertions(+), 134 deletions(-)
+
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -34,6 +34,11 @@ version 2.81
+       tries not to request capabilities not required by its
+       configuration.
++      Add --shared-network config. This enables allocation of addresses
++      the DHCP server in subnets where the server (or relay) doesn't
++      have an interface on the network in that subnet. Many thanks to
++      plank.de for sponsoring this feature.
++
+       
+ version 2.80
+       Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method
+--- a/man/dnsmasq.8
++++ b/man/dnsmasq.8
+@@ -1741,6 +1741,27 @@ It is permissible to add more than one a
+ \fB--bridge-interface=int1,alias1,alias2\fP is exactly equivalent to
+ \fB--bridge-interface=int1,alias1 --bridge-interface=int1,alias2\fP
+ .TP
++.B --shared-network=<interface>|<addr>,<addr>
++The DHCP server determines which dhcp ranges are useable for allocating and
++address to a DHCP client based on the network from which the DHCP request arrives,
++and the IP configuration of the server's interface on that network. The shared-network
++option extends the available subnets (and therefore dhcp ranges) beyond the
++subnets configured on the arrival interface. The first argument is either the
++name of an interface or an address which is configured on a local interface, and the
++second argument is an address which defines another subnet on which addresses can be allocated.
++To be useful, there must be suitable dhcp-range which allows address allocation on this subnet
++and this dhcp-range MUST include the netmask. Use shared-network also needs extra
++consideration of routing. Dnsmasq doesn't have the usual information which it uses to
++determine the default route, so the default route option (or other routing) MUST be
++manually configured. The client must have a route to the server: if the two-address form
++of shared-network is used, this will be to the first specified address. If the interface,address
++form is used, there must be a route to all of the addresses configured on the interface.
++
++The two-address form of shared-network is also usable with a DHCP relay: the first address
++is the address of the relay and the second, as before, specifies an extra subnet which
++may be allocated.
++
++.TP
+ .B \-s, --domain=<domain>[,<address range>[,local]]
+ Specifies DNS domains for the DHCP server. Domains may be be given 
+ unconditionally (without the IP range) or for limited IP ranges. This has two effects;
+--- a/src/dhcp.c
++++ b/src/dhcp.c
+@@ -507,33 +507,83 @@ static int check_listen_addrs(struct in_
+    Note that the current chain may be superseded later for configured hosts or those coming via gateways. */
+-static int complete_context(struct in_addr local, int if_index, char *label,
+-                          struct in_addr netmask, struct in_addr broadcast, void *vparam)
++static void guess_range_netmask(struct in_addr addr, struct in_addr netmask)
+ {
+   struct dhcp_context *context;
+-  struct dhcp_relay *relay;
+-  struct iface_param *param = vparam;
+-  (void)label;
+-  
+   for (context = daemon->dhcp; context; context = context->next)
+-    {
+-      if (!(context->flags & CONTEXT_NETMASK) &&
+-        (is_same_net(local, context->start, netmask) ||
+-         is_same_net(local, context->end, netmask)))
++    if (!(context->flags & CONTEXT_NETMASK) &&
++      (is_same_net(addr, context->start, netmask) ||
++       is_same_net(addr, context->end, netmask)))
+       { 
+       if (context->netmask.s_addr != netmask.s_addr &&
+-          !(is_same_net(local, context->start, netmask) &&
+-            is_same_net(local, context->end, netmask)))
++          !(is_same_net(addr, context->start, netmask) &&
++            is_same_net(addr, context->end, netmask)))
+         {
+           strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
+           strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
+           my_syslog(MS_DHCP | LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
+                     daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
+         }     
+-      context->netmask = netmask;
++      context->netmask = netmask;
+       }
++}
++
++static int complete_context(struct in_addr local, int if_index, char *label,
++                          struct in_addr netmask, struct in_addr broadcast, void *vparam)
++{
++  struct dhcp_context *context;
++  struct dhcp_relay *relay;
++  struct iface_param *param = vparam;
++  struct shared_network *share;
++  
++  (void)label;
++
++  for (share = daemon->shared_networks; share; share = share->next)
++    {
+       
++#ifdef HAVE_DHCP6
++      if (share->shared_addr.s_addr == 0)
++      continue;
++#endif
++      
++      if (share->if_index != 0)
++      {
++        if (share->if_index != if_index)
++          continue;
++      }
++      else
++      {
++        if (share->match_addr.s_addr != local.s_addr)
++          continue;
++      }
++
++      for (context = daemon->dhcp; context; context = context->next)
++      {
++        if (context->netmask.s_addr != 0 &&
++            is_same_net(share->shared_addr, context->start, context->netmask) &&
++            is_same_net(share->shared_addr, context->end, context->netmask))
++          {
++            /* link it onto the current chain if we've not seen it before */
++            if (context->current == context)
++              {
++                /* For a shared network, we have no way to guess what the default route should be. */
++                context->router.s_addr = 0;
++                context->local = local; /* Use configured address for Server Identifier */
++                context->current = param->current;
++                param->current = context;
++              }
++            
++            if (!(context->flags & CONTEXT_BRDCAST))
++              context->broadcast.s_addr  = context->start.s_addr | ~context->netmask.s_addr;
++          }           
++      }
++    }
++
++  guess_range_netmask(local, netmask);
++  
++  for (context = daemon->dhcp; context; context = context->next)
++    {
+       if (context->netmask.s_addr != 0 &&
+         is_same_net(local, context->start, context->netmask) &&
+         is_same_net(local, context->end, context->netmask))
+--- a/src/dhcp6.c
++++ b/src/dhcp6.c
+@@ -299,89 +299,114 @@ static int complete_context6(struct in6_
+                            unsigned int valid, void *vparam)
+ {
+   struct dhcp_context *context;
++  struct shared_network *share;
+   struct dhcp_relay *relay;
+   struct iface_param *param = vparam;
+   struct iname *tmp;
+  
+   (void)scope; /* warning */
+   
+-  if (if_index == param->ind)
+-    {
+-      if (IN6_IS_ADDR_LINKLOCAL(local))
+-      param->ll_addr = *local;
+-      else if (IN6_IS_ADDR_ULA(local))
+-      param->ula_addr = *local;
+-
+-      if (!IN6_IS_ADDR_LOOPBACK(local) &&
+-        !IN6_IS_ADDR_LINKLOCAL(local) &&
+-        !IN6_IS_ADDR_MULTICAST(local))
+-      {
+-        /* if we have --listen-address config, see if the 
+-           arrival interface has a matching address. */
+-        for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
+-          if (tmp->addr.sa.sa_family == AF_INET6 &&
+-              IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local))
+-            param->addr_match = 1;
+-        
+-        /* Determine a globally address on the arrival interface, even
+-           if we have no matching dhcp-context, because we're only
+-           allocating on remote subnets via relays. This
+-           is used as a default for the DNS server option. */
+-        param->fallback = *local;
+-        
+-        for (context = daemon->dhcp6; context; context = context->next)
+-          {
+-            if ((context->flags & CONTEXT_DHCP) &&
+-                !(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
+-                prefix <= context->prefix &&
+-                is_same_net6(local, &context->start6, context->prefix) &&
+-                is_same_net6(local, &context->end6, context->prefix))
+-              {
+-                
+-                
+-                /* link it onto the current chain if we've not seen it before */
+-                if (context->current == context)
+-                  {
+-                    struct dhcp_context *tmp, **up;
+-                    
+-                    /* use interface values only for constructed contexts */
+-                    if (!(context->flags & CONTEXT_CONSTRUCTED))
+-                      preferred = valid = 0xffffffff;
+-                    else if (flags & IFACE_DEPRECATED)
+-                      preferred = 0;
+-                    
+-                    if (context->flags & CONTEXT_DEPRECATE)
+-                      preferred = 0;
+-                    
+-                    /* order chain, longest preferred time first */
+-                    for (up = &param->current, tmp = param->current; tmp; tmp = tmp->current)
+-                      if (tmp->preferred <= preferred)
+-                        break;
+-                      else
+-                        up = &tmp->current;
+-                    
+-                    context->current = *up;
+-                    *up = context;
+-                    context->local6 = *local;
+-                    context->preferred = preferred;
+-                    context->valid = valid;
+-                  }
+-              }
+-          }
+-      }
+-
+-      for (relay = daemon->relay6; relay; relay = relay->next)
+-      if (IN6_ARE_ADDR_EQUAL(local, &relay->local.addr6) && relay->current == relay &&
+-          (IN6_IS_ADDR_UNSPECIFIED(&param->relay_local) || IN6_ARE_ADDR_EQUAL(local, &param->relay_local)))
++  if (if_index != param->ind)
++    return 1;
++  
++  if (IN6_IS_ADDR_LINKLOCAL(local))
++    param->ll_addr = *local;
++  else if (IN6_IS_ADDR_ULA(local))
++    param->ula_addr = *local;
++      
++  if (IN6_IS_ADDR_LOOPBACK(local) ||
++      IN6_IS_ADDR_LINKLOCAL(local) ||
++      IN6_IS_ADDR_MULTICAST(local))
++    return 1;
++  
++  /* if we have --listen-address config, see if the 
++     arrival interface has a matching address. */
++  for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
++    if (tmp->addr.sa.sa_family == AF_INET6 &&
++      IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local))
++      param->addr_match = 1;
++  
++  /* Determine a globally address on the arrival interface, even
++     if we have no matching dhcp-context, because we're only
++     allocating on remote subnets via relays. This
++     is used as a default for the DNS server option. */
++  param->fallback = *local;
++  
++  for (context = daemon->dhcp6; context; context = context->next)
++    if ((context->flags & CONTEXT_DHCP) &&
++      !(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
++      prefix <= context->prefix &&
++      context->current == context)
++      {
++      if (is_same_net6(local, &context->start6, context->prefix) &&
++          is_same_net6(local, &context->end6, context->prefix))
+         {
+-          relay->current = param->relay;
+-          param->relay = relay;
+-          param->relay_local = *local;
++          struct dhcp_context *tmp, **up;
++          
++          /* use interface values only for constructed contexts */
++          if (!(context->flags & CONTEXT_CONSTRUCTED))
++            preferred = valid = 0xffffffff;
++          else if (flags & IFACE_DEPRECATED)
++            preferred = 0;
++                  
++          if (context->flags & CONTEXT_DEPRECATE)
++            preferred = 0;
++          
++          /* order chain, longest preferred time first */
++          for (up = &param->current, tmp = param->current; tmp; tmp = tmp->current)
++            if (tmp->preferred <= preferred)
++              break;
++            else
++              up = &tmp->current;
++          
++          context->current = *up;
++          *up = context;
++          context->local6 = *local;
++          context->preferred = preferred;
++          context->valid = valid;
+         }
+-      
+-    }          
+- 
+- return 1;
++      else
++        {
++          for (share = daemon->shared_networks; share; share = share->next)
++            {
++              /* IPv4 shared_address - ignore */
++              if (share->shared_addr.s_addr != 0)
++                continue;
++                      
++              if (share->if_index != 0)
++                {
++                  if (share->if_index != if_index)
++                    continue;
++                }
++              else
++                {
++                  if (!IN6_ARE_ADDR_EQUAL(&share->match_addr6, local))
++                    continue;
++                }
++              
++              if (is_same_net6(&share->shared_addr6, &context->start6, context->prefix) &&
++                  is_same_net6(&share->shared_addr6, &context->end6, context->prefix))
++                {
++                  context->current = param->current;
++                  param->current = context;
++                  context->local6 = *local;
++                  context->preferred = context->flags & CONTEXT_DEPRECATE ? 0 :0xffffffff;
++                  context->valid = 0xffffffff;
++                }
++            }
++        }      
++      }
++
++  for (relay = daemon->relay6; relay; relay = relay->next)
++    if (IN6_ARE_ADDR_EQUAL(local, &relay->local.addr6) && relay->current == relay &&
++      (IN6_IS_ADDR_UNSPECIFIED(&param->relay_local) || IN6_ARE_ADDR_EQUAL(local, &param->relay_local)))
++      {
++      relay->current = param->relay;
++      param->relay = relay;
++      param->relay_local = *local;
++      }
++     
++  return 1;
+ }
+ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, int prefix, u64 addr)
+--- a/src/dnsmasq.h
++++ b/src/dnsmasq.h
+@@ -910,6 +910,16 @@ struct dhcp_context {
+   struct dhcp_context *next, *current;
+ };
++struct shared_network {
++  int if_index;
++  struct in_addr match_addr, shared_addr;
++#ifdef HAVE_DHCP6
++  /* shared_addr == 0 for IP6 entries. */
++  struct in6_addr match_addr6, shared_addr6;
++#endif
++  struct shared_network *next;
++};
++
+ #define CONTEXT_STATIC         (1u<<0)
+ #define CONTEXT_NETMASK        (1u<<1)
+ #define CONTEXT_BRDCAST        (1u<<2)
+@@ -1107,6 +1117,7 @@ extern struct daemon {
+   struct ping_result *ping_results;
+   FILE *lease_stream;
+   struct dhcp_bridge *bridges;
++  struct shared_network *shared_networks;
+ #ifdef HAVE_DHCP6
+   int duid_len;
+   unsigned char *duid;
+--- a/src/option.c
++++ b/src/option.c
+@@ -166,6 +166,7 @@ struct myoption {
+ #define LOPT_UBUS          354
+ #define LOPT_NAME_MATCH    355
+ #define LOPT_CAA           356
++#define LOPT_SHARED_NET    357
+  
+ #ifdef HAVE_GETOPT_LONG
+ static const struct option opts[] =  
+@@ -259,6 +260,7 @@ static const struct myoption opts[] =
+     { "ptr-record", 1, 0, LOPT_PTR },
+     { "naptr-record", 1, 0, LOPT_NAPTR },
+     { "bridge-interface", 1, 0 , LOPT_BRIDGE },
++    { "shared-network", 1, 0, LOPT_SHARED_NET },
+     { "dhcp-option-force", 1, 0, LOPT_FORCE },
+     { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK },
+     { "log-dhcp", 0, 0, LOPT_LOG_OPTS },
+@@ -431,6 +433,7 @@ static struct {
+   { '3', ARG_DUP, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL },
+   { '4', ARG_DUP, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL },
+   { LOPT_BRIDGE, ARG_DUP, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL },
++  { LOPT_SHARED_NET, ARG_DUP, "<iface>|<addr>,<addr>", gettext_noop("Specify extra networks sharing a broadcast domain for DHCP"), NULL},
+   { '5', OPT_NO_PING, NULL, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL },
+   { '6', ARG_ONE, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL },
+   { LOPT_LUASCRIPT, ARG_DUP, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL },
+@@ -2873,6 +2876,44 @@ static int one_opt(int option, char *arg
+       }
+ #ifdef HAVE_DHCP
++    case LOPT_SHARED_NET: /* --shared-network */
++      {
++      struct shared_network *new = opt_malloc(sizeof(struct shared_network));
++
++#ifdef HAVE_DHCP6
++      new->shared_addr.s_addr = 0;
++#endif
++      new->if_index = 0;
++      
++      if (!(comma = split(arg)))
++        {
++        snerr:
++          free(new);
++          ret_err(_("bad shared-network"));
++        }
++      
++      if (inet_pton(AF_INET, comma, &new->shared_addr))
++        {
++          if (!inet_pton(AF_INET, arg, &new->match_addr) &&
++              !(new->if_index = if_nametoindex(arg)))
++            goto snerr;
++        }
++#ifdef HAVE_DHCP6
++      else if (inet_pton(AF_INET6, comma, &new->shared_addr6))
++        {
++          if (!inet_pton(AF_INET6, arg, &new->match_addr6) &&
++              !(new->if_index = if_nametoindex(arg)))
++            goto snerr;
++        }
++#endif
++      else
++        goto snerr;
++
++      new->next = daemon->shared_networks;
++      daemon->shared_networks = new;
++      break;
++      }
++        
+     case 'F':  /* --dhcp-range */
+       {
+       int k, leasepos = 2;
+--- a/src/rfc2131.c
++++ b/src/rfc2131.c
+@@ -274,8 +274,9 @@ size_t dhcp_reply(struct dhcp_context *c
+   if (mess->giaddr.s_addr || subnet_addr.s_addr || mess->ciaddr.s_addr)
+     {
+       struct dhcp_context *context_tmp, *context_new = NULL;
++      struct shared_network *share = NULL;
+       struct in_addr addr;
+-      int force = 0;
++      int force = 0, via_relay = 0;
+       
+       if (subnet_addr.s_addr)
+       {
+@@ -286,6 +287,7 @@ size_t dhcp_reply(struct dhcp_context *c
+       {
+         addr = mess->giaddr;
+         force = 1;
++        via_relay = 1;
+       }
+       else
+       {
+@@ -302,42 +304,65 @@ size_t dhcp_reply(struct dhcp_context *c
+       } 
+               
+       if (!context_new)
+-      for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next)
+-        {
+-          struct in_addr netmask = context_tmp->netmask;
++      {
++        for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next)
++          {
++            struct in_addr netmask = context_tmp->netmask;
++            
++            /* guess the netmask for relayed networks */
++            if (!(context_tmp->flags & CONTEXT_NETMASK) && context_tmp->netmask.s_addr == 0)
++              {
++                if (IN_CLASSA(ntohl(context_tmp->start.s_addr)) && IN_CLASSA(ntohl(context_tmp->end.s_addr)))
++                  netmask.s_addr = htonl(0xff000000);
++                else if (IN_CLASSB(ntohl(context_tmp->start.s_addr)) && IN_CLASSB(ntohl(context_tmp->end.s_addr)))
++                  netmask.s_addr = htonl(0xffff0000);
++                else if (IN_CLASSC(ntohl(context_tmp->start.s_addr)) && IN_CLASSC(ntohl(context_tmp->end.s_addr)))
++                  netmask.s_addr = htonl(0xffffff00); 
++              }
+-          /* guess the netmask for relayed networks */
+-          if (!(context_tmp->flags & CONTEXT_NETMASK) && context_tmp->netmask.s_addr == 0)
+-            {
+-              if (IN_CLASSA(ntohl(context_tmp->start.s_addr)) && IN_CLASSA(ntohl(context_tmp->end.s_addr)))
+-                netmask.s_addr = htonl(0xff000000);
+-              else if (IN_CLASSB(ntohl(context_tmp->start.s_addr)) && IN_CLASSB(ntohl(context_tmp->end.s_addr)))
+-                netmask.s_addr = htonl(0xffff0000);
+-              else if (IN_CLASSC(ntohl(context_tmp->start.s_addr)) && IN_CLASSC(ntohl(context_tmp->end.s_addr)))
+-                netmask.s_addr = htonl(0xffffff00); 
+-            }
+-          
+-          /* This section fills in context mainly when a client which is on a remote (relayed)
+-             network renews a lease without using the relay, after dnsmasq has restarted. */
+-          if (netmask.s_addr != 0  && 
+-              is_same_net(addr, context_tmp->start, netmask) &&
+-              is_same_net(addr, context_tmp->end, netmask))
+-            {
+-              context_tmp->netmask = netmask;
+-              if (context_tmp->local.s_addr == 0)
+-                context_tmp->local = fallback;
+-              if (context_tmp->router.s_addr == 0)
+-                context_tmp->router = mess->giaddr;
+-         
+-              /* fill in missing broadcast addresses for relayed ranges */
+-              if (!(context_tmp->flags & CONTEXT_BRDCAST) && context_tmp->broadcast.s_addr == 0 )
+-                context_tmp->broadcast.s_addr = context_tmp->start.s_addr | ~context_tmp->netmask.s_addr;
+-              
+-              context_tmp->current = context_new;
+-              context_new = context_tmp;
+-            }
+-        }
+-      
++            /* check to see is a context is OK because of a shared address on
++               the relayed subnet. */
++            if (via_relay)
++              for (share = daemon->shared_networks; share; share = share->next)
++                {
++#ifdef HAVE_DHCP6
++                  if (share->shared_addr.s_addr == 0)
++                    continue;
++#endif
++                  if (share->if_index != 0 ||
++                      share->match_addr.s_addr != mess->giaddr.s_addr)
++                    continue;
++                  
++                  if (netmask.s_addr != 0  && 
++                      is_same_net(share->shared_addr, context_tmp->start, netmask) &&
++                      is_same_net(share->shared_addr, context_tmp->end, netmask))
++                    break;
++                }
++            
++            /* This section fills in context mainly when a client which is on a remote (relayed)
++               network renews a lease without using the relay, after dnsmasq has restarted. */
++            if (share ||
++                (netmask.s_addr != 0  && 
++                 is_same_net(addr, context_tmp->start, netmask) &&
++                 is_same_net(addr, context_tmp->end, netmask)))
++              {
++                context_tmp->netmask = netmask;
++                if (context_tmp->local.s_addr == 0)
++                  context_tmp->local = fallback;
++                if (context_tmp->router.s_addr == 0 && !share)
++                  context_tmp->router = mess->giaddr;
++                
++                /* fill in missing broadcast addresses for relayed ranges */
++                if (!(context_tmp->flags & CONTEXT_BRDCAST) && context_tmp->broadcast.s_addr == 0 )
++                  context_tmp->broadcast.s_addr = context_tmp->start.s_addr | ~context_tmp->netmask.s_addr;
++                
++                context_tmp->current = context_new;
++                context_new = context_tmp;
++              }
++            
++          }
++      }
++        
+       if (context_new || force)
+       context = context_new; 
+     }
+--- a/src/rfc3315.c
++++ b/src/rfc3315.c
+@@ -134,21 +134,41 @@ static int dhcp6_maybe_relay(struct stat
+       else
+       {
+         struct dhcp_context *c;
++        struct shared_network *share = NULL;
+         state->context = NULL;
+-         
++
+         if (!IN6_IS_ADDR_LOOPBACK(state->link_address) &&
+             !IN6_IS_ADDR_LINKLOCAL(state->link_address) &&
+             !IN6_IS_ADDR_MULTICAST(state->link_address))
+           for (c = daemon->dhcp6; c; c = c->next)
+-            if ((c->flags & CONTEXT_DHCP) &&
+-                !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
+-                is_same_net6(state->link_address, &c->start6, c->prefix) &&
+-                is_same_net6(state->link_address, &c->end6, c->prefix))
+-              {
+-                c->preferred = c->valid = 0xffffffff;
+-                c->current = state->context;
+-                state->context = c;
+-              }
++            {
++              for (share = daemon->shared_networks; share; share = share->next)
++                {
++                  if (share->shared_addr.s_addr != 0)
++                    continue;
++                  
++                  if (share->if_index != 0 ||
++                      !IN6_ARE_ADDR_EQUAL(state->link_address, &share->match_addr6))
++                    continue;
++                  
++                  if ((c->flags & CONTEXT_DHCP) &&
++                      !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
++                      is_same_net6(&share->shared_addr6, &c->start6, c->prefix) &&
++                      is_same_net6(&share->shared_addr6, &c->end6, c->prefix))
++                    break;
++                }
++              
++              if (share ||
++                  ((c->flags & CONTEXT_DHCP) &&
++                   !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
++                   is_same_net6(state->link_address, &c->start6, c->prefix) &&
++                   is_same_net6(state->link_address, &c->end6, c->prefix)))
++                {
++                  c->preferred = c->valid = 0xffffffff;
++                  c->current = state->context;
++                  state->context = c;
++                }
++            }
+         
+         if (!state->context)
+           {
diff --git a/package/network/services/dnsmasq/patches/0047-CHANGELOG-typo-fix.patch b/package/network/services/dnsmasq/patches/0047-CHANGELOG-typo-fix.patch
new file mode 100644 (file)
index 0000000..765f31b
--- /dev/null
@@ -0,0 +1,21 @@
+From 1da81f7e23962e160b3b776479631d2a6e7f4e49 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Thu, 28 Mar 2019 13:51:11 +0000
+Subject: [PATCH 47/57] CHANGELOG typo fix.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ CHANGELOG | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -37,7 +37,7 @@ version 2.81
+       Add --shared-network config. This enables allocation of addresses
+       the DHCP server in subnets where the server (or relay) doesn't
+       have an interface on the network in that subnet. Many thanks to
+-      plank.de for sponsoring this feature.
++      kamp.de for sponsoring this feature.
+       
+ version 2.80
diff --git a/package/network/services/dnsmasq/patches/0048-Fix-cmsg-3-API-usage-on-OpenBSD.patch b/package/network/services/dnsmasq/patches/0048-Fix-cmsg-3-API-usage-on-OpenBSD.patch
new file mode 100644 (file)
index 0000000..77d90fd
--- /dev/null
@@ -0,0 +1,52 @@
+From c6cc455dd191fbea56ee14a0ef88a7d655a6fe9a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Courr=C3=A8ges-Anglas?= <jca@wxcvbn.org>
+Date: Fri, 22 Mar 2019 10:56:13 +0100
+Subject: [PATCH 48/57] Fix cmsg(3) API usage on OpenBSD
+
+msg_controllen should be set using CMSG_SPACE() to account for padding.
+RFC3542 provides more details:
+
+  While sending an application may or may not include padding at the end
+  of last ancillary data in msg_controllen and implementations must
+  accept both as valid.
+
+At least OpenBSD rejects control messages if msg_controllen doesn't
+account for padding, so use CMSG_SPACE() for maximal portability.  This
+is consistent with the example provided in the Linux cmsg(3) manpage.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/forward.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/src/forward.c
++++ b/src/forward.c
+@@ -65,13 +65,15 @@ int send_from(int fd, int nowild, char *
+         struct in_pktinfo p;
+         p.ipi_ifindex = 0;
+         p.ipi_spec_dst = source->addr4;
++        msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
+         memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
+-        msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
++        cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+         cmptr->cmsg_level = IPPROTO_IP;
+         cmptr->cmsg_type = IP_PKTINFO;
+ #elif defined(IP_SENDSRCADDR)
++        msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
+         memcpy(CMSG_DATA(cmptr), &(source->addr4), sizeof(source->addr4));
+-        msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
++        cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+         cmptr->cmsg_level = IPPROTO_IP;
+         cmptr->cmsg_type = IP_SENDSRCADDR;
+ #endif
+@@ -81,8 +83,9 @@ int send_from(int fd, int nowild, char *
+         struct in6_pktinfo p;
+         p.ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
+         p.ipi6_addr = source->addr6;
++        msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
+         memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
+-        msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
++        cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+         cmptr->cmsg_type = daemon->v6pktinfo;
+         cmptr->cmsg_level = IPPROTO_IPV6;
+       }
diff --git a/package/network/services/dnsmasq/patches/0049-Apply-fix-from-c6cc455dd191fbea56ee14a0ef88a7d655a6f.patch b/package/network/services/dnsmasq/patches/0049-Apply-fix-from-c6cc455dd191fbea56ee14a0ef88a7d655a6f.patch
new file mode 100644 (file)
index 0000000..4ddd305
--- /dev/null
@@ -0,0 +1,23 @@
+From 7673013d2323834b555052ddbd87381bb5cd7bac Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Thu, 28 Mar 2019 22:04:10 +0000
+Subject: [PATCH 49/57] Apply fix from c6cc455dd191fbea56ee14a0ef88a7d655a6fe9a
+ in DHCP code.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/dhcp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/src/dhcp.c
++++ b/src/dhcp.c
+@@ -401,7 +401,8 @@ void dhcp_packet(time_t now, int pxe_fd)
+       pkt = (struct in_pktinfo *)CMSG_DATA(cmptr);
+       pkt->ipi_ifindex = rcvd_iface_index;
+       pkt->ipi_spec_dst.s_addr = 0;
+-      msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
++      msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
++      cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+       cmptr->cmsg_level = IPPROTO_IP;
+       cmptr->cmsg_type = IP_PKTINFO;
diff --git a/package/network/services/dnsmasq/patches/0050-Don-t-retry-close-syscalls-after-an-EINTR-errors.patch b/package/network/services/dnsmasq/patches/0050-Don-t-retry-close-syscalls-after-an-EINTR-errors.patch
new file mode 100644 (file)
index 0000000..148f157
--- /dev/null
@@ -0,0 +1,113 @@
+From 5fc639cf9a9aafd3a2b50570808a74a4ee5cd12a Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Fri, 29 Mar 2019 21:29:43 +0000
+Subject: [PATCH 50/57] Don't retry close() syscalls after an EINTR errors.
+
+http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2019q1/012953.html
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/dnsmasq.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+--- a/src/dnsmasq.c
++++ b/src/dnsmasq.c
+@@ -552,7 +552,7 @@ int main (int argc, char **argv)
+             char *msg;
+             /* close our copy of write-end */
+-            while (retry_send(close(err_pipe[1])));
++            close(err_pipe[1]);
+             
+             /* check for errors after the fork */
+             if (read_event(err_pipe[0], &ev, &msg))
+@@ -561,7 +561,7 @@ int main (int argc, char **argv)
+             _exit(EC_GOOD);
+           } 
+         
+-        while (retry_send(close(err_pipe[0])));
++        close(err_pipe[0]);
+         /* NO calls to die() from here on. */
+         
+@@ -623,8 +623,7 @@ int main (int argc, char **argv)
+               err = 1;
+             else
+               {
+-                while (retry_send(close(fd)));
+-                if (errno != 0)
++                if (close(fd) == -1)
+                   err = 1;
+               }
+           }
+@@ -957,7 +956,7 @@ int main (int argc, char **argv)
+   /* finished start-up - release original process */
+   if (err_pipe[1] != -1)
+-    while (retry_send(close(err_pipe[1])));
++    close(err_pipe[1]);
+   
+   if (daemon->port != 0)
+     check_servers();
+@@ -1483,7 +1482,7 @@ static void async_event(int pipe, time_t
+           do {
+             helper_write();
+           } while (!helper_buf_empty() || do_script_run(now));
+-          while (retry_send(close(daemon->helperfd)));
++          close(daemon->helperfd);
+         }
+ #endif
+       
+@@ -1728,7 +1727,7 @@ static void check_dns_listeners(time_t n
+         
+         if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
+           {
+-            while (retry_send(close(confd)));
++            close(confd);
+             continue;
+           }
+         
+@@ -1793,7 +1792,7 @@ static void check_dns_listeners(time_t n
+         if (!client_ok)
+           {
+             shutdown(confd, SHUT_RDWR);
+-            while (retry_send(close(confd)));
++            close(confd);
+           }
+         else if (!option_bool(OPT_DEBUG) && pipe(pipefd) == 0 && (p = fork()) != 0)
+           {
+@@ -1812,7 +1811,7 @@ static void check_dns_listeners(time_t n
+                       break;
+                     }
+               }
+-            while (retry_send(close(confd)));
++            close(confd);
+             /* The child can use up to TCP_MAX_QUERIES ids, so skip that many. */
+             daemon->log_id += TCP_MAX_QUERIES;
+@@ -1858,7 +1857,7 @@ static void check_dns_listeners(time_t n
+             buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
+              
+             shutdown(confd, SHUT_RDWR);
+-            while (retry_send(close(confd)));
++            close(confd);
+             
+             if (buff)
+               free(buff);
+@@ -1867,7 +1866,7 @@ static void check_dns_listeners(time_t n
+               if (s->tcpfd != -1)
+                 {
+                   shutdown(s->tcpfd, SHUT_RDWR);
+-                  while (retry_send(close(s->tcpfd)));
++                  close(s->tcpfd);
+                 }
+             if (!option_bool(OPT_DEBUG))
+               {
+@@ -1943,7 +1942,7 @@ int icmp_ping(struct in_addr addr)
+   gotreply = delay_dhcp(dnsmasq_time(), PING_WAIT, fd, addr.s_addr, id);
+ #if defined(HAVE_LINUX_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
+-  while (retry_send(close(fd)));
++  close(fd);
+ #else
+   opt = 1;
+   setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
diff --git a/package/network/services/dnsmasq/patches/0051-Allow-more-then-one-conf-file-on-the-command-line.patch b/package/network/services/dnsmasq/patches/0051-Allow-more-then-one-conf-file-on-the-command-line.patch
new file mode 100644 (file)
index 0000000..0e611af
--- /dev/null
@@ -0,0 +1,45 @@
+From 5c464ef62e02dea96f830425cf43da7f6a272b4c Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Fri, 29 Mar 2019 23:11:05 +0000
+Subject: [PATCH 51/57] Allow more then one --conf-file on the command line.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ man/dnsmasq.8 |  5 +++--
+ src/option.c  | 11 ++++++++---
+ 2 files changed, 11 insertions(+), 5 deletions(-)
+
+--- a/man/dnsmasq.8
++++ b/man/dnsmasq.8
+@@ -1942,8 +1942,9 @@ cannot be lower than 1025 unless dnsmasq
+ of concurrent TFTP connections is limited by the size of the port range. 
+ .TP  
+ .B \-C, --conf-file=<file>
+-Specify a different configuration file. The \fB--conf-file\fP option is also allowed in
+-configuration files, to include multiple configuration files. A
++Specify a configuration file. The presence of this option stops dnsmasq from reading the default configuration
++file (normally /etc/dnsmasq.conf). Multiple files may be specified by repeating the option
++either on the command line or in configuration files. A
+ filename of "-" causes dnsmasq to read configuration from stdin.
+ .TP
+ .B \-7, --conf-dir=<directory>[,<file-extension>......],
+--- a/src/option.c
++++ b/src/option.c
+@@ -5012,9 +5012,14 @@ void read_opts(int argc, char **argv, ch
+         }
+       else if (option == 'C')
+       {
+-          if (conffile)
+-            free(conffile);
+-        conffile = opt_string_alloc(arg);
++          if (!conffile)
++          conffile = opt_string_alloc(arg);
++        else
++          {
++            char *extra = opt_string_alloc(arg);
++            one_file(extra, 0);
++            free(extra);
++          }
+       }
+       else
+       {
diff --git a/package/network/services/dnsmasq/patches/0052-Improved-UBus-supported.patch b/package/network/services/dnsmasq/patches/0052-Improved-UBus-supported.patch
new file mode 100644 (file)
index 0000000..f844c0a
--- /dev/null
@@ -0,0 +1,320 @@
+From a2b8220f4e82e454bbc0013ee83ea3220111d92e Mon Sep 17 00:00:00 2001
+From: Jan Willem Janssen <j.w.janssen@lxtreme.nl>
+Date: Mon, 25 Mar 2019 12:42:23 +0100
+Subject: [PATCH 52/57] Improved UBus supported
+
+- aligned the handling of UBus connections with the DBus code as it
+makes it a bit easier to comprehend;
+- added logging to the various UBus calls to aid debugging from an
+enduser point of view, but be careful to not flood the logs;
+- show the (lack of) support for UBus in the configuration string.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/config.h  |   4 ++
+ src/dnsmasq.c |  32 +++++++++++-
+ src/dnsmasq.h |   6 +++
+ src/ubus.c    | 138 ++++++++++++++++++++++++++++++++++++++++++--------
+ 4 files changed, 157 insertions(+), 23 deletions(-)
+
+--- a/src/config.h
++++ b/src/config.h
+@@ -362,6 +362,10 @@ static char *compile_opts =
+ "no-"
+ #endif
+ "DBus "
++#ifndef HAVE_UBUS
++"no-"
++#endif
++"UBus "
+ #ifndef LOCALEDIR
+ "no-"
+ #endif
+--- a/src/dnsmasq.c
++++ b/src/dnsmasq.c
+@@ -420,6 +420,16 @@ int main (int argc, char **argv)
+   die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL, EC_BADCONF);
+ #endif
++  if (option_bool(OPT_UBUS))
++#ifdef HAVE_UBUS
++    {
++      daemon->ubus = NULL;
++      ubus_init();
++    }
++#else
++  die(_("UBus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
++#endif
++
+   if (daemon->port != 0)
+     pre_allocate_sfds();
+@@ -811,6 +821,16 @@ int main (int argc, char **argv)
+     }
+ #endif
++#ifdef HAVE_UBUS
++  if (option_bool(OPT_UBUS))
++    {
++      if (daemon->ubus)
++        my_syslog(LOG_INFO, _("UBus support enabled: connected to system bus"));
++      else
++        my_syslog(LOG_INFO, _("UBus support enabled: bus connection pending"));
++    }
++#endif
++
+ #ifdef HAVE_DNSSEC
+   if (option_bool(OPT_DNSSEC_VALID))
+     {
+@@ -999,7 +1019,7 @@ int main (int argc, char **argv)
+ #ifdef HAVE_UBUS
+       if (option_bool(OPT_UBUS))
+-        set_ubus_listeners();
++        set_ubus_listeners();
+ #endif
+         
+ #ifdef HAVE_DHCP
+@@ -1134,7 +1154,15 @@ int main (int argc, char **argv)
+ #ifdef HAVE_UBUS
+       if (option_bool(OPT_UBUS))
+-        check_ubus_listeners();
++        {
++          /* if we didn't create a UBus connection, retry now. */
++          if (!daemon->ubus)
++            {
++              ubus_init();
++            }
++
++          check_ubus_listeners();
++        }
+ #endif
+       check_dns_listeners(now);
+--- a/src/dnsmasq.h
++++ b/src/dnsmasq.h
+@@ -1130,6 +1130,11 @@ extern struct daemon {
+ #ifdef HAVE_DBUS
+   struct watch *watches;
+ #endif
++  /* UBus stuff */
++#ifdef HAVE_UBUS
++  /* void * here to avoid depending on ubus headers outside ubus.c */
++  void *ubus;
++#endif
+   /* TFTP stuff */
+   struct tftp_transfer *tftp_trans, *tftp_done_trans;
+@@ -1467,6 +1472,7 @@ void emit_dbus_signal(int action, struct
+ /* ubus.c */
+ #ifdef HAVE_UBUS
++void ubus_init(void);
+ void set_ubus_listeners(void);
+ void check_ubus_listeners(void);
+ void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface);
+--- a/src/ubus.c
++++ b/src/ubus.c
+@@ -20,29 +20,112 @@
+ #include <libubus.h>
+-static struct ubus_context *ubus = NULL;
+ static struct blob_buf b;
++static int notify;
++static int error_logged = 0;
+ static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
+                              struct ubus_request_data *req, const char *method,
+                              struct blob_attr *msg);
+-static struct ubus_method ubus_object_methods[] = {
+-  {.name = "metrics", .handler = ubus_handle_metrics},
++
++static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj);
++
++static const struct ubus_method ubus_object_methods[] = {
++  UBUS_METHOD_NOARG("metrics", ubus_handle_metrics),
+ };
+-static struct ubus_object_type ubus_object_type = UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);
++static struct ubus_object_type ubus_object_type =
++  UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);
+ static struct ubus_object ubus_object = {
+   .name = "dnsmasq",
+   .type = &ubus_object_type,
+   .methods = ubus_object_methods,
+   .n_methods = ARRAY_SIZE(ubus_object_methods),
++  .subscribe_cb = ubus_subscribe_cb,
+ };
++static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
++{
++  (void)ctx;
++
++  my_syslog(LOG_DEBUG, _("UBus subscription callback: %s subscriber(s)"), obj->has_subscribers ? "1" : "0");
++  notify = obj->has_subscribers;
++}
++
++static void ubus_destroy(struct ubus_context *ubus)
++{
++  // Forces re-initialization when we're reusing the same definitions later on.
++  ubus_object.id = 0;
++  ubus_object_type.id = 0;
++
++  ubus_free(ubus);
++  daemon->ubus = NULL;
++}
++
++static void ubus_disconnect_cb(struct ubus_context *ubus)
++{
++  int ret;
++
++  ret = ubus_reconnect(ubus, NULL);
++  if (ret)
++    {
++      my_syslog(LOG_ERR, _("Cannot reconnect to UBus: %s"), ubus_strerror(ret));
++
++      ubus_destroy(ubus);
++    }
++}
++
++void ubus_init()
++{
++  struct ubus_context *ubus = NULL;
++  int ret = 0;
++
++  ubus = ubus_connect(NULL);
++  if (!ubus)
++    {
++      if (!error_logged)
++        {
++          my_syslog(LOG_ERR, _("Cannot initialize UBus: connection failed"));
++          error_logged = 1;
++        }
++
++      ubus_destroy(ubus);
++      return;
++    }
++
++  ret = ubus_add_object(ubus, &ubus_object);
++  if (ret)
++    {
++      if (!error_logged)
++        {
++          my_syslog(LOG_ERR, _("Cannot add object to UBus: %s"), ubus_strerror(ret));
++          error_logged = 1;
++        }
++      return;
++    }
++
++  ubus->connection_lost = ubus_disconnect_cb;
++  daemon->ubus = ubus;
++  error_logged = 0;
++
++  my_syslog(LOG_INFO, _("Connected to system UBus"));
++}
++
+ void set_ubus_listeners()
+ {
++  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
+   if (!ubus)
+-    return;
++    {
++      if (!error_logged)
++        {
++          my_syslog(LOG_ERR, _("Cannot set UBus listeners: no connection"));
++          error_logged = 1;
++        }
++      return;
++    }
++
++  error_logged = 0;
+   poll_listen(ubus->sock.fd, POLLIN);
+   poll_listen(ubus->sock.fd, POLLERR);
+@@ -51,46 +134,57 @@ void set_ubus_listeners()
+ void check_ubus_listeners()
+ {
++  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
+   if (!ubus)
+     {
+-      ubus = ubus_connect(NULL);
+-      if (!ubus)
+-      return;
+-      ubus_add_object(ubus, &ubus_object);
++      if (!error_logged)
++        {
++          my_syslog(LOG_ERR, _("Cannot poll UBus listeners: no connection"));
++          error_logged = 1;
++        }
++      return;
+     }
+   
++  error_logged = 0;
++
+   if (poll_check(ubus->sock.fd, POLLIN))
+     ubus_handle_event(ubus);
+   
+-  if (poll_check(ubus->sock.fd, POLLHUP))
++  if (poll_check(ubus->sock.fd, POLLHUP | POLLERR))
+     {
+-      ubus_free(ubus);
+-      ubus = NULL;
++      my_syslog(LOG_INFO, _("Disconnecting from UBus"));
++
++      ubus_destroy(ubus);
+     }
+ }
+-
+ static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
+                              struct ubus_request_data *req, const char *method,
+                              struct blob_attr *msg)
+ {
+   int i;
+-  blob_buf_init(&b, 0);
+-  for(i=0; i < __METRIC_MAX; i++)
++  (void)obj;
++  (void)method;
++  (void)msg;
++
++  blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
++
++  for (i=0; i < __METRIC_MAX; i++)
+     blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]);
+   
+-  ubus_send_reply(ctx, req, b.head);
+-  
+-  return 0;
++  return ubus_send_reply(ctx, req, b.head);
+ }
+ void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
+ {
+-  if (!ubus || !ubus_object.has_subscribers)
++  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
++  int ret;
++
++  if (!ubus || !notify)
+     return;
+-  blob_buf_init(&b, 0);
++  blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
+   if (mac)
+     blobmsg_add_string(&b, "mac", mac);
+   if (ip)
+@@ -100,7 +194,9 @@ void ubus_event_bcast(const char *type,
+   if (interface)
+     blobmsg_add_string(&b, "interface", interface);
+   
+-  ubus_notify(ubus, &ubus_object, type, b.head, -1);
++  ret = ubus_notify(ubus, &ubus_object, type, b.head, -1);
++  if (!ret)
++    my_syslog(LOG_ERR, _("Failed to send UBus event: %s"), ubus_strerror(ret));
+ }
diff --git a/package/network/services/dnsmasq/patches/0056-Fix-wrong-return-code-from-explore_rrset-with-some-e.patch b/package/network/services/dnsmasq/patches/0056-Fix-wrong-return-code-from-explore_rrset-with-some-e.patch
new file mode 100644 (file)
index 0000000..ddbdb45
--- /dev/null
@@ -0,0 +1,31 @@
+From 05299fdd5a3b6ace43224c7d27d06a57b175639f Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Mon, 15 Jul 2019 22:04:20 +0100
+Subject: [PATCH 56/57] Fix wrong return code from explore_rrset() with some
+ errors.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/dnssec.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/src/dnssec.c
++++ b/src/dnssec.c
+@@ -374,7 +374,7 @@ static int explore_rrset(struct dns_head
+   int gotkey = 0;
+   if (!(p = skip_questions(header, plen)))
+-    return STAT_BOGUS;
++    return 0;
+    /* look for RRSIGs for this RRset and get pointers to each RR in the set. */
+   for (rrsetidx = 0, sigidx = 0, j = ntohs(header->ancount) + ntohs(header->nscount); 
+@@ -386,7 +386,7 @@ static int explore_rrset(struct dns_head
+       pstart = p;
+       
+       if (!(res = extract_name(header, plen, &p, name, 0, 10)))
+-      return STAT_BOGUS; /* bad packet */
++      return 0; /* bad packet */
+       
+       GETSHORT(stype, p);
+       GETSHORT(sclass, p);
diff --git a/package/network/services/dnsmasq/patches/0057-Fix-build-after-y2038-changes-in-glib.patch b/package/network/services/dnsmasq/patches/0057-Fix-build-after-y2038-changes-in-glib.patch
new file mode 100644 (file)
index 0000000..98364ea
--- /dev/null
@@ -0,0 +1,22 @@
+From 3052ce208acf602f0163166dcefb7330d537cedb Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Wed, 24 Jul 2019 17:34:48 +0100
+Subject: [PATCH 57/57] Fix build after y2038 changes in glib.
+
+SIOCGSTAMP is defined in linux/sockios.h, not asm/sockios.h now.
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ src/dnsmasq.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/src/dnsmasq.h
++++ b/src/dnsmasq.h
+@@ -137,6 +137,7 @@ typedef unsigned long long u64;
+ #endif
+ #if defined(HAVE_LINUX_NETWORK)
++#include <linux/sockios.h>
+ #include <linux/capability.h>
+ /* There doesn't seem to be a universally-available 
+    userspace header for these. */