mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-21 14:37:57 +00:00
dnsmasq: backport latest patches
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>
This commit is contained in:
parent
7d684b7673
commit
e9eec39aac
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
---
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
---
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
---
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
---
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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);
|
@ -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;
|
||||
|
@ -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)
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
@ -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
|
@ -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)
|
@ -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))
|
@ -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,
|
@ -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;
|
||||
}
|
@ -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);
|
@ -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 = ¶m->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(¶m->relay_local) || IN6_ARE_ADDR_EQUAL(local, ¶m->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 = ¶m->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(¶m->relay_local) || IN6_ARE_ADDR_EQUAL(local, ¶m->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)
|
||||
{
|
@ -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
|
@ -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;
|
||||
}
|
@ -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;
|
||||
|
@ -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));
|
@ -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
|
||||
{
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
@ -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. */
|
Loading…
Reference in New Issue
Block a user