Compare commits

..
26 Commits
Author SHA1 Message Date
Simon Kelley 7ddb99d251 Debian changelog entry for CVE-2019-14834 2020-04-08 17:32:53 +01:00
Geert Stappers ba26d3485b [PATCH] src/dnsmasq.c: Labeled a lonely #endif 2020-04-06 15:42:39 +01:00
Matthias Andree 081a1c4014 2.81rc5 CHANGELOG and man/dnsmasq.8 manual page improvements
Hi Simon,

>         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
>         kamp.de for sponsoring this feature.
Does this paragraph lack a preposition "by" early on the 2nd line, or am
I mis-guessing the purpose?

...enables allocation of addresses *by* the DHCP server...

The manual page also seems to offer room for linguistic improvement
(apparently written by a German, so I see the typical patterns, and also
the misuse of which vs. that.

I am attaching a patch series vs. git to fix several issues in the
manpage and CHANGELOG.

From 35b88d98429e2fe016d9989d220f6faf2b933764 Mon Sep 17 00:00:00 2001
From: Matthias Andree <matthias.andree@gmx.de>
Date: Sun, 5 Apr 2020 11:18:05 +0200
Subject: [PATCH 1/5] man/dnsmasq.8: Properly capitalize DHCP acronym.
2020-04-06 15:29:24 +01:00
Simon Kelley 532246fc9e Tweak to DNSSEC logging. 2020-04-04 18:50:56 +01:00
Simon Kelley 8caf3d7c6c Fix rare problem allocating frec for DNSSEC.
A call to get_new_frec() for a DNSSEC query could manage to
free the original frec that we're doing the DNSSEC query to validate.
Bad things then happen.

This requires that the original frec is old, so it doesn't happen
in practice. I found it when running under gdb, and there have been
reports of SEGV associated with large system-clock warps which are
probably the same thing.
2020-04-04 17:00:32 +01:00
Oldřich Jedlička d162bee356 Allow overriding of ubus service name.
Same as for the dbus, allow specifying ubus service name (namespace) on
the command line as an optional argument to --enable-ubus option.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
2020-03-28 18:16:53 +00:00
Simon Kelley b43585c34b Fix nameserver list in auth mode.
If dnsmasq is not acting as an authoritative nameserver (no second
argument to --auth-server) then it should not appear in the NS RRset.

This leaves simply the list of servers specified in --auth-sec-servers.
2020-03-28 17:41:06 +00:00
Oldřich Jedlička 3f60ecd6f0 Fixed resource leak on ubus_init failure.
When ubus_add_object fails, the ubus_connect object is not freed, so the
connection leaks. Add ubus_destroy to free the connection object.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
2020-03-19 22:20:18 +00:00
Simon Kelley 0506a5ed4e Handle old kernels that don't do NETLINK_NO_ENOBUFS.
Deal with both old kernel header files that don't define it,
and old kernels that don't implement it.

Also generalise Linux kernel version handling.
2020-03-19 21:56:45 +00:00
Dominik DL6ER e7ee1aa093 Extend stop-dns-rebind to reject IPv6 LL and ULA addresses.
We also reject the loopback address if rebind-localhost-ok is NOT set.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2020-03-17 22:59:17 +00:00
Simon Kelley 63ed917ad9 Update to Debian runit mods. 2020-03-17 17:07:49 +00:00
Simon Kelley 63e21bdea3 Remove 19036 trust anchor, now expired. 2020-03-17 14:43:42 +00:00
Simon Kelley 1627d577af Set NETLINK_NO_ENOBUFS in netlink socket, to avoid POLLERR returns. 2020-03-10 23:55:18 +00:00
Conrad Kostecki b837c4528d Update German translation. 2020-03-10 21:20:46 +00:00
Petr Menšík 46bdfe691a Fix error in IPv6 prefix calculation.
Error with prefixed address assignment. When it is calculating number of
addresses from prefixlen, it rotates only 32bit int instead of 64b uint.
Only result is assigned to 64b variable.

Two examples:

dhcp-host=[2000::1230:0:0/92],correct-prefix
dhcp-host=[2000::1234:5678:0/92],incorrect-prefix

If prefix length is lower than 96, the result is zero. It means
incorrect-prefix is not refused as it should. Fix is simple, attaching
patch with it. Just rotate 64b int.
2020-03-08 15:56:19 +00:00
Vladislav Grishenko dded78b233 Add DHCPv6 ntp-server (56) option handling.
There was discussion in the past regarding DHCPv6 NTP server option
which needs special subclassing per RFC5908.

Patch adds support for unicast, multicast IPv6 address and for FQDN string,
preserving possibly used (as suggested earlier) hex value.

Unfortunately it's still not fully free from limitations - only address list or
only fqdn value list is possible, not mixed due current
state option parsing & flagging.
2020-03-08 15:34:34 +00:00
Kevin Darbyshire-Bryant b594e8defa rfc3315: fix incorrect logical '&&' warning
rfc3315.c:1711:28: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
    if (!(addr_list->flags && ADDRLIST_DECLINED) ||
                           ^  ~~~~~~~~~~~~~~~~~

It's a flag bit so should be bitwise '&' operator

Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
2020-03-08 15:10:27 +00:00
Kevin Darbyshire-Bryant 70c50efd0d suppress non linux network unused var warnings
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
2020-03-08 15:09:44 +00:00
Brad Smith ea3c60ac07 Diverge error handling between *BSD and Linux. 2020-03-08 14:53:59 +00:00
Simon Kelley fc19399a1f Fix compiler warning. 2020-03-05 22:13:45 +00:00
Simon Kelley 980b14f174 Compiler warning. 2020-03-05 18:01:48 +00:00
Simon Kelley 1df73fe831 Remove compiler warnings in IPv6 checksum code in dump.c 2020-03-05 17:51:17 +00:00
Simon Kelley c125c1dfee Update decline address handling in DHCPv6 for new multi-address world.
When dhcp-host options can have many IPv6 addresses, we need
to deal with one of them being declined by a client. The other
addresses are still valid.

It seems that this logic never worked, even with only one address, since
the DECLINED flag was never tested.
2020-03-05 17:10:14 +00:00
Matthias Andree e39c484ebd Fix parameters to setsockopt() for TCP_FASTOPEN. 2020-03-05 15:58:31 +00:00
Simon Kelley 977a5a2df1 Merge i18n messages. 2020-03-02 22:34:12 +00:00
Simon Kelley 02df0007c8 Trivial formatting fix. 2020-03-02 22:30:28 +00:00
34 changed files with 7361 additions and 5476 deletions

No files matched your search

+5 -5
View File
@@ -1,12 +1,12 @@
version 2.81 version 2.81
Impove cache behaviour for TCP connections. For ease of Improve cache behaviour for TCP connections. For ease of
implementaion, dnsmasq has always forked a new process to handle implementaion, dnsmasq has always forked a new process to handle
each incoming TCP connection. A side-effect of this is that each incoming TCP connection. A side-effect of this is that
any DNS queries answered from TCP connections are not cached: any DNS queries answered from TCP connections are not cached:
when TCP connections were rare, this was not a problem. when TCP connections were rare, this was not a problem.
With the coming of DNSSEC, it's now the case that some With the coming of DNSSEC, it is now the case that some
DNSSEC queries have answers which spill to TCP, and if, DNSSEC queries have answers which spill to TCP, and if,
for instance, this applies to the keys for the root then for instance, this applies to the keys for the root, then
those never get cached, and performance is very bad. those never get cached, and performance is very bad.
This fix passes cache entries back from the TCP child process to This fix passes cache entries back from the TCP child process to
the main server process, and fixes the problem. the main server process, and fixes the problem.
@@ -35,7 +35,7 @@ version 2.81
configuration. configuration.
Add --shared-network config. This enables allocation of addresses Add --shared-network config. This enables allocation of addresses
the DHCP server in subnets where the server (or relay) doesn't by the DHCP server in subnets where the server (or relay) does not
have an interface on the network in that subnet. Many thanks to have an interface on the network in that subnet. Many thanks to
kamp.de for sponsoring this feature. kamp.de for sponsoring this feature.
@@ -66,7 +66,7 @@ version 2.81
Evgenii Seliavka for the suggestion and initial patch. Evgenii Seliavka for the suggestion and initial patch.
In the router advert code, handle case where we have two In the router advert code, handle case where we have two
different interfaces on the same IPv6 net, and we're doing different interfaces on the same IPv6 net, and we are doing
RA/DHCP service on only one of them. Thanks to NIIBE Yutaka RA/DHCP service on only one of them. Thanks to NIIBE Yutaka
for spotting this case and making the initial patch. for spotting this case and making the initial patch.
+2 -1
View File
@@ -12,8 +12,9 @@ dnsmasq (2.81-1) unstable; urgency=low
* Fix breakage of dig +trace. (closes: #942363) * Fix breakage of dig +trace. (closes: #942363)
* Fix build faliure with newer Nettle libraries. (closes: #940985) * Fix build faliure with newer Nettle libraries. (closes: #940985)
* Support runscript init-system (closes: #929884) * Support runscript init-system (closes: #929884)
* Security fix for CVE-2019-14834 (closes: #948373)
-- Simon Kelley <simon@thekelleys.org.uk> Mon, 27 Jan 2020 22:31:15 +0000 -- Simon Kelley <simon@thekelleys.org.uk> Wed, 8 Apr 2020 17:33:15 +0000
dnsmasq (2.80-1) unstable; urgency=low dnsmasq (2.80-1) unstable; urgency=low
+1 -1
View File
@@ -1 +1 @@
debian/dnsmasq.runscript name=dnsmasq,logscript,since=2.80-1+runit debian/dnsmasq.runscript name=dnsmasq,logscript,presubj
+39 -27
View File
@@ -1,4 +1,4 @@
.TH DNSMASQ 8 .TH DNSMASQ 8 2020-04-05
.SH NAME .SH NAME
dnsmasq \- A lightweight DHCP and caching DNS server. dnsmasq \- A lightweight DHCP and caching DNS server.
.SH SYNOPSIS .SH SYNOPSIS
@@ -244,7 +244,7 @@ specified interface. The <domain> is the "glue record". It should
resolve in the global DNS to an A and/or AAAA record which points to resolve in the global DNS to an A and/or AAAA record which points to
the address dnsmasq is listening on. When an interface is specified, the address dnsmasq is listening on. When an interface is specified,
it may be qualified with "/4" or "/6" to specify only the IPv4 or IPv6 it may be qualified with "/4" or "/6" to specify only the IPv4 or IPv6
addresses associated with the interface. Since any defined authoritative zones are also available as part of the normal recusive DNS service supplied by dnsmasq, it can make sense to have an --auth-server declaration with no interfaces or address, but simply specifying the glue record. addresses associated with the interface. Since any defined authoritative zones are also available as part of the normal recusive DNS service supplied by dnsmasq, it can make sense to have an --auth-server declaration with no interfaces or address, but simply specifying the primary external nameserver.
.TP .TP
.B --local-service .B --local-service
Accept DNS queries only from hosts whose address is on a local subnet, Accept DNS queries only from hosts whose address is on a local subnet,
@@ -366,10 +366,13 @@ been built with DBus support. If the service name is given, dnsmasq
provides service at that name, rather than the default which is provides service at that name, rather than the default which is
.B uk.org.thekelleys.dnsmasq .B uk.org.thekelleys.dnsmasq
.TP .TP
.B --enable-ubus .B --enable-ubus[=<service-name>]
Enable dnsmasq UBus interface. It sends notifications via UBus on Enable dnsmasq UBus interface. It sends notifications via UBus on
DHCPACK and DHCPRELEASE events. Furthermore it offers metrics. DHCPACK and DHCPRELEASE events. Furthermore it offers metrics.
Requires that dnsmasq has been built with UBus support. Requires that dnsmasq has been built with UBus support. If the service
name is given, dnsmasq provides service at that namespace, rather than
the default which is
.B dnsmasq
.TP .TP
.B \-o, --strict-order .B \-o, --strict-order
By default, dnsmasq will send queries to any of the upstream servers By default, dnsmasq will send queries to any of the upstream servers
@@ -395,11 +398,13 @@ were previously disabled.
.TP .TP
.B --stop-dns-rebind .B --stop-dns-rebind
Reject (and log) addresses from upstream nameservers which are in the Reject (and log) addresses from upstream nameservers which are in the
private IP ranges. This blocks an attack where a browser behind a private ranges. This blocks an attack where a browser behind a
firewall is used to probe machines on the local network. firewall is used to probe machines on the local network. For IPv6, the
private range covers the IPv4-mapped addresses in private space plus
all link-local (LL) and site-local (ULA) addresses.
.TP .TP
.B --rebind-localhost-ok .B --rebind-localhost-ok
Exempt 127.0.0.0/8 from rebinding checks. This address range is Exempt 127.0.0.0/8 and ::1 from rebinding checks. This address range is
returned by realtime black hole servers, so blocking it may disable returned by realtime black hole servers, so blocking it may disable
these services. these services.
.TP .TP
@@ -904,7 +909,7 @@ then the address can be simply ::
The optional The optional
.B set:<tag> .B set:<tag>
sets an alphanumeric label which marks this network so that sets an alphanumeric label which marks this network so that
dhcp options may be specified on a per-network basis. DHCP options may be specified on a per-network basis.
When it is prefixed with 'tag:' instead, then its meaning changes from setting When it is prefixed with 'tag:' instead, then its meaning changes from setting
a tag to matching it. Only one tag may be set, but more than one tag a tag to matching it. Only one tag may be set, but more than one tag
may be matched. may be matched.
@@ -1012,7 +1017,7 @@ may contain an IPv4 address or one or more IPv6 addresses, or both. IPv6 address
.B --dhcp-host=laptop,[1234::56] .B --dhcp-host=laptop,[1234::56]
IPv6 addresses may contain only the host-identifier part: IPv6 addresses may contain only the host-identifier part:
.B --dhcp-host=laptop,[::56] .B --dhcp-host=laptop,[::56]
in which case they act as wildcards in constructed dhcp ranges, with in which case they act as wildcards in constructed DHCP ranges, with
the appropriate network part inserted. For IPv6, an address may include a prefix length: the appropriate network part inserted. For IPv6, an address may include a prefix length:
.B --dhcp-host=laptop,[1234:50/126] .B --dhcp-host=laptop,[1234:50/126]
which (in this case) specifies four addresses, 1234::50 to 1234::53. This (an the ability which (in this case) specifies four addresses, 1234::50 to 1234::53. This (an the ability
@@ -1349,7 +1354,7 @@ vendor-identifying vendor classes for the specified enterprise. Please
see RFC 3925 for more details of these rare and interesting beasts. see RFC 3925 for more details of these rare and interesting beasts.
.TP .TP
.B --dhcp-name-match=set:<tag>,<name>[*] .B --dhcp-name-match=set:<tag>,<name>[*]
Set the tag if the given name is supplied by a dhcp client. There may be a single trailing wildcard *, which has the usual meaning. Combined with dhcp-ignore or dhcp-ignore-names this gives the ability to ignore certain clients by name, or disallow certain hostnames from being claimed by a client. Set the tag if the given name is supplied by a DHCP client. There may be a single trailing wildcard *, which has the usual meaning. Combined with dhcp-ignore or dhcp-ignore-names this gives the ability to ignore certain clients by name, or disallow certain hostnames from being claimed by a client.
.TP .TP
.B --tag-if=set:<tag>[,set:<tag>[,tag:<tag>[,tag:<tag>]]] .B --tag-if=set:<tag>[,set:<tag>[,tag:<tag>[,tag:<tag>]]]
Perform boolean operations on tags. Any tag appearing as set:<tag> is set if Perform boolean operations on tags. Any tag appearing as set:<tag> is set if
@@ -1746,7 +1751,7 @@ option also forces the leasechange script to be called on changes
to the client-id and lease length and expiry time. to the client-id and lease length and expiry time.
.TP .TP
.B --script-on-renewal .B --script-on-renewal
Call the dhcp script when the lease expiry time changes, for instance when the Call the DHCP script when the lease expiry time changes, for instance when the
lease is renewed. lease is renewed.
.TP .TP
.B --bridge-interface=<interface>,<alias>[,<alias>] .B --bridge-interface=<interface>,<alias>[,<alias>]
@@ -1762,25 +1767,34 @@ It is permissible to add more than one alias using more than one \fB--bridge-int
\fB--bridge-interface=int1,alias1,alias2\fP is exactly equivalent to \fB--bridge-interface=int1,alias1,alias2\fP is exactly equivalent to
\fB--bridge-interface=int1,alias1 --bridge-interface=int1,alias2\fP \fB--bridge-interface=int1,alias1 --bridge-interface=int1,alias2\fP
.TP .TP
.B --shared-network=<interface>|<addr>,<addr> .B --shared-network=<interface>,<addr>
The DHCP server determines which dhcp ranges are useable for allocating and .PD 0
.TP
.B --shared-network=<addr>,<addr>
.PD 1v
The DHCP server determines which DHCP ranges are useable for allocating an
address to a DHCP client based on the network from which the DHCP request arrives, 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 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 option extends the available subnets (and therefore DHCP ranges) beyond the
subnets configured on the arrival interface. The first argument is either the subnets configured on the arrival interface.
name of an interface or an address which is configured on a local interface, and the
The first argument is either the
name of an interface, or an address that is configured on a local interface, and the
second argument is an address which defines another subnet on which addresses can be allocated. 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 To be useful, there must be a suitable dhcp-range which allows address allocation on this subnet
consideration of routing. Dnsmasq doesn't have the usual information which it uses to and this dhcp-range MUST include the netmask.
Using shared-network also needs extra
consideration of routing. Dnsmasq does not have the usual information that it uses to
determine the default route, so the default route option (or other routing) MUST be 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 configured manually. 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 of shared-network is used, this needs to 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. 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 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 is the address of the relay and the second, as before, specifies an extra subnet which
may be allocated. addresses may be allocated from.
.TP .TP
.B \-s, --domain=<domain>[,<address range>[,local]] .B \-s, --domain=<domain>[,<address range>[,local]]
@@ -1790,7 +1804,7 @@ firstly it causes the DHCP server to return the domain to any hosts
which request it, and secondly it sets the domain which it is legal which request it, and secondly it sets the domain which it is legal
for DHCP-configured hosts to claim. The intention is to constrain for DHCP-configured hosts to claim. The intention is to constrain
hostnames so that an untrusted host on the LAN cannot advertise hostnames so that an untrusted host on the LAN cannot advertise
its name via dhcp as e.g. "microsoft.com" and capture traffic not its name via DHCP as e.g. "microsoft.com" and capture traffic not
meant for it. If no domain suffix is specified, then any DHCP meant for it. If no domain suffix is specified, then any DHCP
hostname with a domain part (ie with a period) will be disallowed hostname with a domain part (ie with a period) will be disallowed
and logged. If suffix is specified, then hostnames with a domain and logged. If suffix is specified, then hostnames with a domain
@@ -1881,7 +1895,7 @@ The mtu: parameter may be an arbitrary interface name, in which case the MTU val
for (eg) advertising the MTU of a WAN interface on the other interfaces of a router. for (eg) advertising the MTU of a WAN interface on the other interfaces of a router.
.TP .TP
.B --dhcp-reply-delay=[tag:<tag>,]<integer> .B --dhcp-reply-delay=[tag:<tag>,]<integer>
Delays sending DHCPOFFER and proxydhcp replies for at least the specified number of seconds. Delays sending DHCPOFFER and PROXYDHCP replies for at least the specified number of seconds.
This can be used as workaround for bugs in PXE boot firmware that does not function properly when This can be used as workaround for bugs in PXE boot firmware that does not function properly when
receiving an instant reply. receiving an instant reply.
This option takes into account the time already spent waiting (e.g. performing ping check) if any. This option takes into account the time already spent waiting (e.g. performing ping check) if any.
@@ -2017,7 +2031,7 @@ and
.I /etc/ethers .I /etc/ethers
and any file given by \fB--dhcp-hostsfile\fP, \fB--dhcp-hostsdir\fP, \fB--dhcp-optsfile\fP, and any file given by \fB--dhcp-hostsfile\fP, \fB--dhcp-hostsdir\fP, \fB--dhcp-optsfile\fP,
\fB--dhcp-optsdir\fP, \fB--addn-hosts\fP or \fB--hostsdir\fP. \fB--dhcp-optsdir\fP, \fB--addn-hosts\fP or \fB--hostsdir\fP.
The dhcp lease change script is called for all The DHCP lease change script is called for all
existing DHCP leases. If existing DHCP leases. If
.B .B
--no-poll --no-poll
@@ -2195,7 +2209,6 @@ as is the tag "bootp", allowing some control over the options returned to
different classes of hosts. different classes of hosts.
.SH AUTHORITATIVE CONFIGURATION .SH AUTHORITATIVE CONFIGURATION
.PP
Configuring dnsmasq to act as an authoritative DNS server is Configuring dnsmasq to act as an authoritative DNS server is
complicated by the fact that it involves configuration of external DNS complicated by the fact that it involves configuration of external DNS
servers to provide delegation. We will walk through three scenarios of servers to provide delegation. We will walk through three scenarios of
@@ -2365,7 +2378,6 @@ used, and must match the zone's domain.
.SH EXIT CODES .SH EXIT CODES
.PP
0 - Dnsmasq successfully forked into the background, or terminated 0 - Dnsmasq successfully forked into the background, or terminated
normally if backgrounding is not enabled. normally if backgrounding is not enabled.
.PP .PP
+673 -500
View File
File diff suppressed because it is too large. Load diff
+683 -495
View File
File diff suppressed because it is too large. Load diff
+781 -623
View File
File diff suppressed because it is too large. Load diff
+684 -495
View File
File diff suppressed because it is too large. Load diff
+693 -497
View File
File diff suppressed because it is too large. Load diff
+781 -623
View File
File diff suppressed because it is too large. Load diff
+673 -495
View File
File diff suppressed because it is too large. Load diff
+683 -495
View File
File diff suppressed because it is too large. Load diff
+781 -623
View File
File diff suppressed because it is too large. Load diff
+673 -495
View File
File diff suppressed because it is too large. Load diff
+13 -9
View File
@@ -628,16 +628,20 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
{ {
struct name_list *secondary; struct name_list *secondary;
newoffset = ansp - (unsigned char *)header; /* Only include the machine running dnsmasq if it's acting as an auth server */
if (add_resource_record(header, limit, &trunc, -offset, &ansp, if (daemon->authinterface)
daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver))
{ {
if (offset == 0) newoffset = ansp - (unsigned char *)header;
offset = newoffset; if (add_resource_record(header, limit, &trunc, -offset, &ansp,
if (ns) daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver))
anscount++; {
else if (offset == 0)
authcount++; offset = newoffset;
if (ns)
anscount++;
else
authcount++;
}
} }
if (!subnet) if (!subnet)
+1
View File
@@ -50,6 +50,7 @@
#define RANDFILE "/dev/urandom" #define RANDFILE "/dev/urandom"
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" /* Default - may be overridden by config */ #define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" /* Default - may be overridden by config */
#define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq" #define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq"
#define DNSMASQ_UBUS_NAME "dnsmasq" /* Default - may be overridden by config */
#define AUTH_TTL 600 /* default TTL for auth DNS */ #define AUTH_TTL 600 /* default TTL for auth DNS */
#define SOA_REFRESH 1200 /* SOA refresh default */ #define SOA_REFRESH 1200 /* SOA refresh default */
#define SOA_RETRY 180 /* SOA retry default */ #define SOA_RETRY 180 /* SOA retry default */
+1 -1
View File
@@ -649,7 +649,7 @@ static const struct opttab_t opttab6[] = {
{ "sntp-server", 31, OT_ADDR_LIST }, { "sntp-server", 31, OT_ADDR_LIST },
{ "information-refresh-time", 32, OT_TIME }, { "information-refresh-time", 32, OT_TIME },
{ "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME }, { "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME },
{ "ntp-server", 56, 0 }, { "ntp-server", 56, 0 /* OT_ADDR_LIST | OT_RFC1035_NAME */ },
{ "bootfile-url", 59, OT_NAME }, { "bootfile-url", 59, OT_NAME },
{ "bootfile-param", 60, OT_CSTRING }, { "bootfile-param", 60, OT_CSTRING },
{ NULL, 0, 0 } { NULL, 0, 0 }
+4
View File
@@ -59,8 +59,12 @@
#define OPTION6_REMOTE_ID 37 #define OPTION6_REMOTE_ID 37
#define OPTION6_SUBSCRIBER_ID 38 #define OPTION6_SUBSCRIBER_ID 38
#define OPTION6_FQDN 39 #define OPTION6_FQDN 39
#define OPTION6_NTP_SERVER 56
#define OPTION6_CLIENT_MAC 79 #define OPTION6_CLIENT_MAC 79
#define NTP_SUBOPTION_SRV_ADDR 1
#define NTP_SUBOPTION_MC_ADDR 2
#define NTP_SUBOPTION_SRV_FQDN 3
#define DHCP6SUCCESS 0 #define DHCP6SUCCESS 0
#define DHCP6UNSPEC 1 #define DHCP6UNSPEC 1
+8 -4
View File
@@ -94,6 +94,10 @@ int main (int argc, char **argv)
read_opts(argc, argv, compile_opts); read_opts(argc, argv, compile_opts);
#ifdef HAVE_LINUX_NETWORK
daemon->kernel_version = kernel_version();
#endif
if (daemon->edns_pktsz < PACKETSZ) if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = PACKETSZ; daemon->edns_pktsz = PACKETSZ;
@@ -1679,7 +1683,7 @@ static int set_dns_listeners(time_t now)
/* will we be able to get memory? */ /* will we be able to get memory? */
if (daemon->port != 0) if (daemon->port != 0)
get_new_frec(now, &wait, 0); get_new_frec(now, &wait, NULL);
for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next) for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
poll_listen(serverfdp->fd, POLLIN); poll_listen(serverfdp->fd, POLLIN);
@@ -1860,6 +1864,7 @@ static void check_dns_listeners(time_t now)
if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1) if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
{ {
char a; char a;
(void)a; /* suppress potential unused warning */
daemon->tcp_pids[i] = p; daemon->tcp_pids[i] = p;
daemon->tcp_pipes[i] = pipefd[0]; daemon->tcp_pipes[i] = pipefd[0];
@@ -1911,6 +1916,7 @@ static void check_dns_listeners(time_t now)
if (!option_bool(OPT_DEBUG)) if (!option_bool(OPT_DEBUG))
{ {
char a = 0; char a = 0;
(void)a; /* suppress potential unused warning */
alarm(CHILD_LIFETIME); alarm(CHILD_LIFETIME);
close(pipefd[0]); /* close read end in child. */ close(pipefd[0]); /* close read end in child. */
daemon->pipe_to_parent = pipefd[1]; daemon->pipe_to_parent = pipefd[1];
@@ -2106,6 +2112,4 @@ int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id)
return 0; return 0;
} }
#endif #endif /* HAVE_DHCP */
+9 -2
View File
@@ -141,6 +141,7 @@ typedef unsigned long long u64;
#endif #endif
#if defined(HAVE_LINUX_NETWORK) #if defined(HAVE_LINUX_NETWORK)
#include <linux/version.h>
#include <linux/sockios.h> #include <linux/sockios.h>
#include <linux/capability.h> #include <linux/capability.h>
/* There doesn't seem to be a universally-available /* There doesn't seem to be a universally-available
@@ -384,10 +385,12 @@ struct ds_config {
#define ADDRLIST_REVONLY 4 #define ADDRLIST_REVONLY 4
#define ADDRLIST_PREFIX 8 #define ADDRLIST_PREFIX 8
#define ADDRLIST_WILDCARD 16 #define ADDRLIST_WILDCARD 16
#define ADDRLIST_DECLINED 32
struct addrlist { struct addrlist {
union all_addr addr; union all_addr addr;
int flags, prefixlen; int flags, prefixlen;
time_t decline_time;
struct addrlist *next; struct addrlist *next;
}; };
@@ -1060,6 +1063,7 @@ extern struct daemon {
unsigned int duid_enterprise, duid_config_len; unsigned int duid_enterprise, duid_config_len;
unsigned char *duid_config; unsigned char *duid_config;
char *dbus_name; char *dbus_name;
char *ubus_name;
char *dump_file; char *dump_file;
int dump_mask; int dump_mask;
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry; unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
@@ -1106,7 +1110,7 @@ extern struct daemon {
int inotifyfd; int inotifyfd;
#endif #endif
#if defined(HAVE_LINUX_NETWORK) #if defined(HAVE_LINUX_NETWORK)
int netlinkfd; int netlinkfd, kernel_version;
#elif defined(HAVE_BSD_NETWORK) #elif defined(HAVE_BSD_NETWORK)
int dhcp_raw_fd, dhcp_icmp_fd, routefd; int dhcp_raw_fd, dhcp_icmp_fd, routefd;
#endif #endif
@@ -1286,6 +1290,9 @@ int read_write(int fd, unsigned char *packet, int size, int rw);
void close_fds(long max_fd, int spare1, int spare2, int spare3); void close_fds(long max_fd, int spare1, int spare2, int spare3);
int wildcard_match(const char* wildcard, const char* match); int wildcard_match(const char* wildcard, const char* match);
int wildcard_matchn(const char* wildcard, const char* match, int num); int wildcard_matchn(const char* wildcard, const char* match, int num);
#ifdef HAVE_LINUX_NETWORK
int kernel_version(void);
#endif
/* log.c */ /* log.c */
void die(char *message, char *arg1, int exit_code) ATTRIBUTE_NORETURN; void die(char *message, char *arg1, int exit_code) ATTRIBUTE_NORETURN;
@@ -1317,7 +1324,7 @@ void receive_query(struct listener *listen, time_t now);
unsigned char *tcp_request(int confd, time_t now, unsigned char *tcp_request(int confd, time_t now,
union mysockaddr *local_addr, struct in_addr netmask, int auth_dns); union mysockaddr *local_addr, struct in_addr netmask, int auth_dns);
void server_gone(struct server *server); void server_gone(struct server *server);
struct frec *get_new_frec(time_t now, int *wait, int force); struct frec *get_new_frec(time_t now, int *wait, struct frec *force);
int send_from(int fd, int nowild, char *packet, size_t len, int send_from(int fd, int nowild, char *packet, size_t len,
union mysockaddr *to, union all_addr *source, union mysockaddr *to, union all_addr *source,
unsigned int iface); unsigned int iface);
+1 -1
View File
@@ -1003,7 +1003,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
cache_end_insert(); cache_end_insert();
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "no DS"); log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS");
} }
return STAT_OK; return STAT_OK;
+6 -2
View File
@@ -132,8 +132,12 @@ void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, unio
} }
/* start UDP checksum */ /* start UDP checksum */
for (sum = 0, i = 0; i < IN6ADDRSZ; i++) for (sum = 0, i = 0; i < IN6ADDRSZ; i+=2)
sum += ((u16 *)&ip6.ip6_src)[i]; {
sum += ip6.ip6_src.s6_addr[i] + (ip6.ip6_src.s6_addr[i+1] << 8) ;
sum += ip6.ip6_dst.s6_addr[i] + (ip6.ip6_dst.s6_addr[i+1] << 8) ;
}
} }
else else
{ {
+15 -9
View File
@@ -93,10 +93,13 @@ int send_from(int fd, int nowild, char *packet, size_t len,
while (retry_send(sendmsg(fd, &msg, 0))); while (retry_send(sendmsg(fd, &msg, 0)));
/* If interface is still in DAD, EINVAL results - ignore that. */ if (errno != 0)
if (errno != 0 && errno != EINVAL)
{ {
my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno)); #ifdef HAVE_LINUX_NETWORK
/* If interface is still in DAD, EINVAL results - ignore that. */
if (errno != EINVAL)
my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
#endif
return 0; return 0;
} }
@@ -345,7 +348,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
type &= ~SERV_DO_DNSSEC; type &= ~SERV_DO_DNSSEC;
if (daemon->servers && !flags) if (daemon->servers && !flags)
forward = get_new_frec(now, NULL, 0); forward = get_new_frec(now, NULL, NULL);
/* table full - flags == 0, return REFUSED */ /* table full - flags == 0, return REFUSED */
if (forward) if (forward)
@@ -1036,7 +1039,9 @@ void reply_query(int fd, int family, time_t now)
/* Find the original query that started it all.... */ /* Find the original query that started it all.... */
for (orig = forward; orig->dependent; orig = orig->dependent); for (orig = forward; orig->dependent; orig = orig->dependent);
if (--orig->work_counter == 0 || !(new = get_new_frec(now, NULL, 1))) /* Make sure we don't expire and free the orig frec during the
allocation of a new one. */
if (--orig->work_counter == 0 || !(new = get_new_frec(now, NULL, orig)))
status = STAT_ABANDONED; status = STAT_ABANDONED;
else else
{ {
@@ -2248,9 +2253,10 @@ static void free_frec(struct frec *f)
else return *wait zero if one available, or *wait is delay to else return *wait zero if one available, or *wait is delay to
when the oldest in-use record will expire. Impose an absolute when the oldest in-use record will expire. Impose an absolute
limit of 4*TIMEOUT before we wipe things (for random sockets). limit of 4*TIMEOUT before we wipe things (for random sockets).
If force is set, always return a result, even if we have If force is non-NULL, always return a result, even if we have
to allocate above the limit. */ to allocate above the limit, and never free the record pointed
struct frec *get_new_frec(time_t now, int *wait, int force) to by the force argument. */
struct frec *get_new_frec(time_t now, int *wait, struct frec *force)
{ {
struct frec *f, *oldest, *target; struct frec *f, *oldest, *target;
int count; int count;
@@ -2267,7 +2273,7 @@ struct frec *get_new_frec(time_t now, int *wait, int force)
/* Don't free DNSSEC sub-queries here, as we may end up with /* Don't free DNSSEC sub-queries here, as we may end up with
dangling references to them. They'll go when their "real" query dangling references to them. They'll go when their "real" query
is freed. */ is freed. */
if (!f->dependent) if (!f->dependent && f != force)
#endif #endif
{ {
if (difftime(now, f->time) >= 4*TIMEOUT) if (difftime(now, f->time) >= 4*TIMEOUT)
+1 -16
View File
@@ -22,9 +22,7 @@
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/utsname.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <linux/version.h>
#include <linux/netlink.h> #include <linux/netlink.h>
/* We want to be able to compile against old header files /* We want to be able to compile against old header files
@@ -87,20 +85,7 @@ static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, con
void ipset_init(void) void ipset_init(void)
{ {
struct utsname utsname; old_kernel = (daemon->kernel_version < KERNEL_VERSION(2,6,32));
int version;
char *split;
if (uname(&utsname) < 0)
die(_("failed to find kernel version: %s"), NULL, EC_MISC);
split = strtok(utsname.release, ".");
version = (split ? atoi(split) : 0);
split = strtok(NULL, ".");
version = version * 256 + (split ? atoi(split) : 0);
split = strtok(NULL, ".");
version = version * 256 + (split ? atoi(split) : 0);
old_kernel = (version < KERNEL_VERSION(2,6,32));
if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1) if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1)
return; return;
+12
View File
@@ -22,6 +22,15 @@
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
/* Blergh. Radv does this, so that's our excuse. */
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif
#ifndef NETLINK_NO_ENOBUFS
#define NETLINK_NO_ENOBUFS 5
#endif
/* linux 2.6.19 buggers up the headers, patch it up here. */ /* linux 2.6.19 buggers up the headers, patch it up here. */
#ifndef IFA_RTA #ifndef IFA_RTA
# define IFA_RTA(r) \ # define IFA_RTA(r) \
@@ -44,6 +53,7 @@ void netlink_init(void)
{ {
struct sockaddr_nl addr; struct sockaddr_nl addr;
socklen_t slen = sizeof(addr); socklen_t slen = sizeof(addr);
int opt = 1;
addr.nl_family = AF_NETLINK; addr.nl_family = AF_NETLINK;
addr.nl_pad = 0; addr.nl_pad = 0;
@@ -72,6 +82,8 @@ void netlink_init(void)
} }
if (daemon->netlinkfd == -1 || if (daemon->netlinkfd == -1 ||
(daemon->kernel_version >= KERNEL_VERSION(2,6,30) &&
setsockopt(daemon->netlinkfd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, sizeof(opt)) == -1) ||
getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == -1) getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == -1)
die(_("cannot create netlink socket: %s"), NULL, EC_MISC); die(_("cannot create netlink socket: %s"), NULL, EC_MISC);
+4 -1
View File
@@ -728,7 +728,7 @@ static int make_sock(union mysockaddr *addr, int type, int dienow)
{ {
#ifdef TCP_FASTOPEN #ifdef TCP_FASTOPEN
int qlen = 5; int qlen = 5;
setsockopt(fd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)); setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
#endif #endif
if (listen(fd, TCP_BACKLOG) == -1) if (listen(fd, TCP_BACKLOG) == -1)
@@ -785,6 +785,8 @@ int set_ipv6pktinfo(int fd)
/* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */ /* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */
int tcp_interface(int fd, int af) int tcp_interface(int fd, int af)
{ {
(void)fd; /* suppress potential unused warning */
(void)af; /* suppress potential unused warning */
int if_index = 0; int if_index = 0;
#ifdef HAVE_LINUX_NETWORK #ifdef HAVE_LINUX_NETWORK
@@ -1187,6 +1189,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind
#endif #endif
} }
(void)intname; /* suppress potential unused warning */
#if defined(SO_BINDTODEVICE) #if defined(SO_BINDTODEVICE)
if (intname[0] != 0 && if (intname[0] != 0 &&
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1) setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
+27 -6
View File
@@ -238,7 +238,7 @@ static const struct myoption opts[] =
{ "caa-record", 1, 0 , LOPT_CAA }, { "caa-record", 1, 0 , LOPT_CAA },
{ "dns-rr", 1, 0, LOPT_RR }, { "dns-rr", 1, 0, LOPT_RR },
{ "enable-dbus", 2, 0, '1' }, { "enable-dbus", 2, 0, '1' },
{ "enable-ubus", 0, 0, LOPT_UBUS }, { "enable-ubus", 2, 0, LOPT_UBUS },
{ "bootp-dynamic", 2, 0, '3' }, { "bootp-dynamic", 2, 0, '3' },
{ "dhcp-mac", 1, 0, '4' }, { "dhcp-mac", 1, 0, '4' },
{ "no-ping", 0, 0, '5' }, { "no-ping", 0, 0, '5' },
@@ -428,7 +428,7 @@ static struct {
{ 'z', OPT_NOWILD, NULL, gettext_noop("Bind only to interfaces in use."), NULL }, { 'z', OPT_NOWILD, NULL, gettext_noop("Bind only to interfaces in use."), NULL },
{ 'Z', OPT_ETHERS, NULL, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE }, { 'Z', OPT_ETHERS, NULL, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE },
{ '1', ARG_ONE, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL }, { '1', ARG_ONE, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL },
{ LOPT_UBUS, OPT_UBUS, NULL, gettext_noop("Enable the UBus interface."), NULL }, { LOPT_UBUS, ARG_ONE, "[=<busname>]", gettext_noop("Enable the UBus interface."), NULL },
{ '2', ARG_DUP, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL }, { '2', ARG_DUP, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL },
{ '3', ARG_DUP, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL }, { '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 }, { '4', ARG_DUP, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL },
@@ -1261,6 +1261,12 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
if (!found_colon) if (!found_colon)
is_addr6 = 0; is_addr6 = 0;
#ifdef HAVE_DHCP6
/* NTP server option takes hex, addresses or FQDN */
if (is6 && new->opt == OPTION6_NTP_SERVER && !is_hex)
opt_len |= is_addr6 ? OT_ADDR_LIST : OT_RFC1035_NAME;
#endif
/* We know that some options take addresses */ /* We know that some options take addresses */
if (opt_len & OT_ADDR_LIST) if (opt_len & OT_ADDR_LIST)
{ {
@@ -1521,8 +1527,9 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
} }
else if (comma && (opt_len & OT_RFC1035_NAME)) else if (comma && (opt_len & OT_RFC1035_NAME))
{ {
unsigned char *p = NULL, *newp, *end; unsigned char *p = NULL, *q, *newp, *end;
int len = 0; int len = 0;
int header_size = (is6 && new->opt == OPTION6_NTP_SERVER) ? 4 : 0;
arg = comma; arg = comma;
comma = split(arg); comma = split(arg);
@@ -1532,7 +1539,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
if (!dom) if (!dom)
goto_err(_("bad domain in dhcp-option")); goto_err(_("bad domain in dhcp-option"));
newp = opt_malloc(len + strlen(dom) + 2); newp = opt_malloc(len + header_size + strlen(dom) + 2);
if (p) if (p)
{ {
@@ -1541,8 +1548,14 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
} }
p = newp; p = newp;
end = do_rfc1035_name(p + len, dom, NULL); q = p + len;
end = do_rfc1035_name(q + header_size, dom, NULL);
*end++ = 0; *end++ = 0;
if (is6 && new->opt == OPTION6_NTP_SERVER)
{
PUTSHORT(NTP_SUBOPTION_SRV_FQDN, q);
PUTSHORT(end - q - 2, q);
}
len = end - p; len = end - p;
free(dom); free(dom);
@@ -1869,6 +1882,14 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
daemon->dbus_name = DNSMASQ_SERVICE; daemon->dbus_name = DNSMASQ_SERVICE;
break; break;
case LOPT_UBUS: /* --enable-ubus */
set_option_bool(OPT_UBUS);
if (arg)
daemon->ubus_name = opt_string_alloc(arg);
else
daemon->ubus_name = DNSMASQ_UBUS_NAME;
break;
case '8': /* --log-facility */ case '8': /* --log-facility */
/* may be a filename */ /* may be a filename */
if (strchr(arg, '/') || strcmp (arg, "-") == 0) if (strchr(arg, '/') || strcmp (arg, "-") == 0)
@@ -3309,7 +3330,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (!atoi_check(pref, &new_addr->prefixlen) || if (!atoi_check(pref, &new_addr->prefixlen) ||
new_addr->prefixlen > 128 || new_addr->prefixlen > 128 ||
(((1<<(128-new_addr->prefixlen))-1) & addrpart) != 0) ((((u64)1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
{ {
dhcp_config_free(new); dhcp_config_free(new);
ret_err(_("bad IPv6 prefix")); ret_err(_("bad IPv6 prefix"));
+19 -5
View File
@@ -844,12 +844,26 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND))) private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
return 1; return 1;
if ((flags & F_IPV6) && /* Block IPv4-mapped IPv6 addresses in private IPv4 address space */
IN6_IS_ADDR_V4MAPPED(&addr.addr6)) if (flags & F_IPV6)
{ {
struct in_addr v4; if (IN6_IS_ADDR_V4MAPPED(&addr.addr6))
v4.s_addr = ((const uint32_t *) (&addr.addr6))[3]; {
if (private_net(v4, !option_bool(OPT_LOCAL_REBIND))) struct in_addr v4;
v4.s_addr = ((const uint32_t *) (&addr.addr6))[3];
if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
return 1;
}
/* Check for link-local (LL) and site-local (ULA) IPv6 addresses */
if (IN6_IS_ADDR_LINKLOCAL(&addr.addr6) ||
IN6_IS_ADDR_SITELOCAL(&addr.addr6))
return 1;
/* Check for the IPv6 loopback address (::1) when
option rebind-localhost-ok is NOT set */
if (!option_bool(OPT_LOCAL_REBIND) &&
IN6_IS_ADDR_LOOPBACK(&addr.addr6))
return 1; return 1;
} }
} }
+1 -1
View File
@@ -413,7 +413,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
for (o2 = offset + 5; o2 < offset + len + 5; o2 += elen + 1) for (o2 = offset + 5; o2 < offset + len + 5; o2 += elen + 1)
{ {
elen = option_uint(opt, o2, 1); elen = option_uint(opt, o2, 1);
if ((o2 + elen + 1 <= option_len(opt)) && if ((o2 + elen + 1 <= (unsigned)option_len(opt)) &&
(match = match_bytes(o, option_ptr(opt, o2 + 1), elen))) (match = match_bytes(o, option_ptr(opt, o2 + 1), elen)))
break; break;
} }
+58 -39
View File
@@ -49,8 +49,8 @@ static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz);
static void mark_context_used(struct state *state, struct in6_addr *addr); static void mark_context_used(struct state *state, struct in6_addr *addr);
static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr); static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr);
static int check_address(struct state *state, struct in6_addr *addr); static int check_address(struct state *state, struct in6_addr *addr);
static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state); static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now);
static int config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr); static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option, static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option,
unsigned int *min_time, struct in6_addr *addr, time_t now); unsigned int *min_time, struct in6_addr *addr, time_t now);
static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now); static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now);
@@ -679,7 +679,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
/* If the client asks for an address on the same network as a configured address, /* If the client asks for an address on the same network as a configured address,
offer the configured address instead, to make moving to newly-configured offer the configured address instead, to make moving to newly-configured
addresses automatic. */ addresses automatic. */
if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr, state)) if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr, state, now))
{ {
req_addr = addr; req_addr = addr;
mark_config_used(c, &addr); mark_config_used(c, &addr);
@@ -703,7 +703,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
for (c = state->context; c; c = c->current) for (c = state->context; c; c = c->current)
if (!(c->flags & CONTEXT_CONF_USED) && if (!(c->flags & CONTEXT_CONF_USED) &&
match_netid(c->filter, solicit_tags, plain_range) && match_netid(c->filter, solicit_tags, plain_range) &&
config_valid(config, c, &addr, state)) config_valid(config, c, &addr, state, now))
{ {
mark_config_used(state->context, &addr); mark_config_used(state->context, &addr);
if (have_config(config, CONFIG_TIME)) if (have_config(config, CONFIG_TIME))
@@ -847,7 +847,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ); memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
if ((c = address6_valid(state->context, &req_addr, tagif, 1))) if ((c = address6_valid(state->context, &req_addr, tagif, 1)))
config_ok = config_implies(config, c, &req_addr); config_ok = (config_implies(config, c, &req_addr) != NULL);
if ((dynamic = address6_available(state->context, &req_addr, tagif, 1)) || c) if ((dynamic = address6_available(state->context, &req_addr, tagif, 1)) || c)
{ {
@@ -1186,18 +1186,19 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
{ {
struct dhcp_lease *lease; struct dhcp_lease *lease;
struct in6_addr addr; struct in6_addr addr;
struct addrlist *addr_list;
/* align */ /* align */
memcpy(&addr, opt6_ptr(ia_option, 0), IN6ADDRSZ); memcpy(&addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
if (have_config(config, CONFIG_ADDR6) && IN6_ARE_ADDR_EQUAL(&config->addr6, &addr)) if ((addr_list = config_implies(config, state->context, &addr)))
{ {
prettyprint_time(daemon->dhcp_buff3, DECLINE_BACKOFF); prettyprint_time(daemon->dhcp_buff3, DECLINE_BACKOFF);
inet_ntop(AF_INET6, &addr, daemon->addrbuff, ADDRSTRLEN); inet_ntop(AF_INET6, &addr, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"), my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"),
daemon->addrbuff, daemon->dhcp_buff3); daemon->addrbuff, daemon->dhcp_buff3);
config->flags |= CONFIG_DECLINED; addr_list->flags |= ADDRLIST_DECLINED;
config->decline_time = now; addr_list->decline_time = now;
} }
else else
/* make sure this host gets a different address next time. */ /* make sure this host gets a different address next time. */
@@ -1310,23 +1311,39 @@ static struct dhcp_netid *add_options(struct state *state, int do_refresh)
for (a = (struct in6_addr *)opt_cfg->val, j = 0; j < opt_cfg->len; j+=IN6ADDRSZ, a++) for (a = (struct in6_addr *)opt_cfg->val, j = 0; j < opt_cfg->len; j+=IN6ADDRSZ, a++)
{ {
struct in6_addr *p = NULL;
if (IN6_IS_ADDR_UNSPECIFIED(a)) if (IN6_IS_ADDR_UNSPECIFIED(a))
{ {
if (!add_local_addrs(state->context)) if (!add_local_addrs(state->context))
put_opt6(state->fallback, IN6ADDRSZ); p = state->fallback;
} }
else if (IN6_IS_ADDR_ULA_ZERO(a)) else if (IN6_IS_ADDR_ULA_ZERO(a))
{ {
if (!IN6_IS_ADDR_UNSPECIFIED(state->ula_addr)) if (!IN6_IS_ADDR_UNSPECIFIED(state->ula_addr))
put_opt6(state->ula_addr, IN6ADDRSZ); p = state->ula_addr;
} }
else if (IN6_IS_ADDR_LINK_LOCAL_ZERO(a)) else if (IN6_IS_ADDR_LINK_LOCAL_ZERO(a))
{ {
if (!IN6_IS_ADDR_UNSPECIFIED(state->ll_addr)) if (!IN6_IS_ADDR_UNSPECIFIED(state->ll_addr))
put_opt6(state->ll_addr, IN6ADDRSZ); p = state->ll_addr;
} }
else else
put_opt6(a, IN6ADDRSZ); p = a;
if (!p)
continue;
else if (opt_cfg->opt == OPTION6_NTP_SERVER)
{
if (IN6_IS_ADDR_MULTICAST(p))
o1 = new_opt6(NTP_SUBOPTION_MC_ADDR);
else
o1 = new_opt6(NTP_SUBOPTION_SRV_ADDR);
put_opt6(p, IN6ADDRSZ);
end_opt6(o1);
}
else
put_opt6(p, IN6ADDRSZ);
} }
end_opt6(o); end_opt6(o);
@@ -1669,14 +1686,14 @@ static int check_address(struct state *state, struct in6_addr *addr)
/* return true of *addr could have been generated from config. */ /* return true of *addr could have been generated from config. */
static int config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr) static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr)
{ {
int prefix; int prefix;
struct in6_addr wild_addr; struct in6_addr wild_addr;
struct addrlist *addr_list; struct addrlist *addr_list;
if (!config || !(config->flags & CONFIG_ADDR6)) if (!config || !(config->flags & CONFIG_ADDR6))
return 0; return NULL;
for (addr_list = config->addr6; addr_list; addr_list = addr_list->next) for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
{ {
@@ -1692,13 +1709,13 @@ static int config_implies(struct dhcp_config *config, struct dhcp_context *conte
continue; continue;
if (is_same_net6(&wild_addr, addr, prefix)) if (is_same_net6(&wild_addr, addr, prefix))
return 1; return addr_list;
} }
return 0; return NULL;
} }
static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state) static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now)
{ {
u64 addrpart, i, addresses; u64 addrpart, i, addresses;
struct addrlist *addr_list; struct addrlist *addr_list;
@@ -1707,33 +1724,35 @@ static int config_valid(struct dhcp_config *config, struct dhcp_context *context
return 0; return 0;
for (addr_list = config->addr6; addr_list; addr_list = addr_list->next) for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
{ if (!(addr_list->flags & ADDRLIST_DECLINED) ||
addrpart = addr6part(&addr_list->addr.addr6); difftime(now, addr_list->decline_time) >= (float)DECLINE_BACKOFF)
addresses = 1; {
addrpart = addr6part(&addr_list->addr.addr6);
addresses = 1;
if (addr_list->flags & ADDRLIST_PREFIX) if (addr_list->flags & ADDRLIST_PREFIX)
addresses = 1<<(128-addr_list->prefixlen); addresses = (u64)1<<(128-addr_list->prefixlen);
if ((addr_list->flags & ADDRLIST_WILDCARD)) if ((addr_list->flags & ADDRLIST_WILDCARD))
{ {
if (context->prefix != 64) if (context->prefix != 64)
continue; continue;
*addr = context->start6; *addr = context->start6;
} }
else if (is_same_net6(&context->start6, &addr_list->addr.addr6, context->prefix)) else if (is_same_net6(&context->start6, &addr_list->addr.addr6, context->prefix))
*addr = addr_list->addr.addr6; *addr = addr_list->addr.addr6;
else else
continue; continue;
for (i = 0 ; i < addresses; i++) for (i = 0 ; i < addresses; i++)
{ {
setaddr6part(addr, addrpart+i); setaddr6part(addr, addrpart+i);
if (check_address(state, addr)) if (check_address(state, addr))
return 1; return 1;
} }
} }
return 0; return 0;
} }
+1 -1
View File
@@ -611,7 +611,7 @@ void check_tftp_listeners(time_t now)
{ {
/* don't complain about timeout when we're awaiting the last /* don't complain about timeout when we're awaiting the last
ACK, some clients never send it */ ACK, some clients never send it */
if (len == transfer->blocksize + 4) if ((unsigned)len == transfer->blocksize + 4)
endcon = 1; endcon = 1;
len = 0; len = 0;
} }
+3 -1
View File
@@ -38,7 +38,7 @@ static struct ubus_object_type ubus_object_type =
UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods); UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);
static struct ubus_object ubus_object = { static struct ubus_object ubus_object = {
.name = "dnsmasq", .name = NULL,
.type = &ubus_object_type, .type = &ubus_object_type,
.methods = ubus_object_methods, .methods = ubus_object_methods,
.n_methods = ARRAY_SIZE(ubus_object_methods), .n_methods = ARRAY_SIZE(ubus_object_methods),
@@ -94,6 +94,7 @@ void ubus_init()
return; return;
} }
ubus_object.name = daemon->ubus_name;
ret = ubus_add_object(ubus, &ubus_object); ret = ubus_add_object(ubus, &ubus_object);
if (ret) if (ret)
{ {
@@ -102,6 +103,7 @@ void ubus_init()
my_syslog(LOG_ERR, _("Cannot add object to UBus: %s"), ubus_strerror(ret)); my_syslog(LOG_ERR, _("Cannot add object to UBus: %s"), ubus_strerror(ret));
error_logged = 1; error_logged = 1;
} }
ubus_destroy(ubus);
return; return;
} }
+24 -1
View File
@@ -30,6 +30,10 @@
#include <idna.h> #include <idna.h>
#endif #endif
#ifdef HAVE_LINUX_NETWORK
#include <sys/utsname.h>
#endif
/* SURF random number generator */ /* SURF random number generator */
static u32 seed[32]; static u32 seed[32];
@@ -731,7 +735,7 @@ void close_fds(long max_fd, int spare1, int spare2, int spare3)
fd == spare1 || fd == spare2 || fd == spare3) fd == spare1 || fd == spare2 || fd == spare3)
continue; continue;
close(fd); close(fd);
} }
closedir(d); closedir(d);
@@ -782,3 +786,22 @@ int wildcard_matchn(const char* wildcard, const char* match, int num)
return (!num) || (*wildcard == *match); return (!num) || (*wildcard == *match);
} }
#ifdef HAVE_LINUX_NETWORK
int kernel_version(void)
{
struct utsname utsname;
int version;
char *split;
if (uname(&utsname) < 0)
die(_("failed to find kernel version: %s"), NULL, EC_MISC);
split = strtok(utsname.release, ".");
version = (split ? atoi(split) : 0);
split = strtok(NULL, ".");
version = version * 256 + (split ? atoi(split) : 0);
split = strtok(NULL, ".");
return version * 256 + (split ? atoi(split) : 0);
}
#endif
+1 -2
View File
@@ -1,9 +1,8 @@
# The root DNSSEC trust anchor, valid as at 10/02/2017 # The root DNSSEC trust anchor, valid as at 11/01/2019
# Note that this is a DS record (ie a hash of the root Zone Signing Key) # Note that this is a DS record (ie a hash of the root Zone Signing Key)
# If was downloaded from https://data.iana.org/root-anchors/root-anchors.xml # If was downloaded from https://data.iana.org/root-anchors/root-anchors.xml
trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D