Compare commits

..
41 Commits
Author SHA1 Message Date
Simon Kelley 45903b7776 Fix remote buffer overflow CERT VU#434904
The problem is in the sort_rrset() function and allows a remote
attacker to overwrite memory. Any dnsmasq instance with DNSSEC
enabled is vulnerable.
2020-11-11 23:25:04 +00:00
Matthias Andree f60fea1fb0 CHANGELOG: Fix three typoes. 2020-07-19 21:54:44 +01:00
Simon Kelley 4d85e409cd Change default lease time for DHCPv6 to one day.
Also remove floor on valid and preffered times in RA when
no time is specified.
2020-07-12 22:45:46 +01:00
Simon Kelley 2bd02d2f59 Backdated CHANGELOG update. 2020-07-12 21:57:38 +01:00
Simon Kelley 7e194a0a7d Apply floor of 60s to TTL of DNSKEY and DS records in cache.
Short TTLs and specifically zero TTLs can mess up DNSSEC validation.
2020-07-12 17:43:25 +01:00
Simon Kelley 9beb4d9ea2 Fix BNF in man page description for --server. 2020-07-05 17:17:39 +01:00
Simon Kelley ab5ebe9507 Bump Debian version to 2.82 2020-06-26 22:23:15 +01:00
Simon Kelley 837e8f4eb5 Remove runit support when building debs for Ubuntu. 2020-06-26 22:13:27 +01:00
Simon Kelley e2cb655958 Thorough clean-up following 8270648da1. 2020-06-20 22:30:12 +01:00
Frank 8270648da1 Fix memory corruption on EAGAIN return from pipe during TCP requests.
This patch fixes a buffer overflow in TCP requests. Since the read is not
actually being retried, the byte written by the child can be left
in the pipe. When that happens, cache_recv_insert() reads the length of the
name, which is now multiplied by 256 due to the extra 0 byte (8 bit shift)
and results in daemon->namebuff being overflowed.

Namebuff is immediately before the daemon struct in memory so it
ends up corrupting the beginning of the daemon struct.
2020-06-20 15:17:56 +01:00
Simon Kelley 619000a3c5 Suppress logging of listen addresses during startup.
The initial call to enumerate_interfaces() happens before the
logging subsystem in initialised and the startup banner logged.
It's not intended that syslog be written at this point.
2020-04-29 00:09:58 +01:00
Petr Menšík 1c1b925052 Remove duplicate address family from listener
Since address already contain family, remove separate family from
listener. Use now family from address itself.
2020-04-29 00:06:57 +01:00
Petr Menšík 49bdf1ead9 Handle listening on duplicate addresses
Save listening address into listener. Use it to find existing listeners
before creating new one. If it exist, increase just used counter.
Release only listeners not already used.

Duplicates family in listener.
2020-04-29 00:06:31 +01:00
Petr Mensik 60a3ae19c5 Cleanup interfaces no longer available
Clean addresses and interfaces not found after enumerate. Free unused
records to speed up checking active interfaces and reduce used memory.
2020-04-29 00:06:01 +01:00
Petr Mensik 951a22165c Compare address and interface index for allowed interface
If interface is recreated with the same address but different index, it
would not change any other parameter.

Test also address family on incoming TCP queries.
2020-04-29 00:04:29 +01:00
Petr Mensik 51cdd1a227 Explicitly mark address port not used
On many places return value is ignored. Usually it means port is always
the same and not needed to be displayed. Unify warnings.
2020-04-29 00:04:04 +01:00
Petr Mensik 66adee85be Log listening on new interfaces
Log in debug mode listening on interfaces. They can be dynamically
found, include interface number, since it is checked on TCP connections.
Print also addresses found on them.
2020-04-29 00:03:21 +01:00
Simon Kelley 4890bcdea2 Workaround for reported recvmsg() ignoring MSG_PEEK. 2020-04-28 14:02:53 +01:00
Simon Kelley 8baf583a3f Allow IPv6 addresses ofthe form [::ffff:1.2.3.4] in --dhcp-option. 2020-04-23 23:14:45 +01:00
Simon Kelley 913fa15fb1 Convert failure of setsockopt(..., SOL_NETLINK, NETLINK_NO_ENOBUFS, ...) into warning.
We call this, which avoids POLLERR returns from netlink on a loaded system,
if the kernel is new enough to support it. Sadly, qemu-user doesn't support
the socket option, so if it fails despite the kernel being new enough to
support it, we just emit a warning, rather than failing hard.
2020-04-19 23:16:52 +01:00
Simon Kelley 00fe2f49e0 Debian package fix for kFreeBSD. 2020-04-19 21:59:13 +01:00
Simon Kelley ec2067df75 Debian package fixes.
Add runit /etc files to conffiles.
Fix broken copyright file in dnsmasq binary package.
2020-04-12 16:12:50 +01:00
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
28 changed files with 748 additions and 409 deletions

No files matched your search

+33 -6
View File
@@ -1,12 +1,39 @@
version 2.83
Fix a remote buffer overflow problem in the DNSSEC code. Any
dnsmasq with DNSSEC compiled in and enabled is vulnerable to this,
referenced by CERT VU#434904.
version 2.82
Improve behaviour in the face of network interfaces which come
and go and change index. Thanks to Petr Mensik for the patch.
Convert hard startup failure on NETLINK_NO_ENOBUFS under qemu-user
to a warning.
Allow IPv6 addresses ofthe form [::ffff:1.2.3.4] in --dhcp-option.
Fix crash under heavy TCP connection load introduced in 2.81.
Thanks to Frank for good work chasing this down.
Change default lease time for DHCPv6 to one day.
Alter calculation of preferred and valid times in router
advertisements, so that these do not have a floor applied
of the lease time in the dhcp-range if this is not explicitly
specified and is merely the default.
Thanks to Martin-Éric Racine for suggestions on this.
version 2.81
Impove cache behaviour for TCP connections. For ease of
implementaion, dnsmasq has always forked a new process to handle
Improve cache behaviour for TCP connections. For ease of
implementation, dnsmasq has always forked a new process to handle
each incoming TCP connection. A side-effect of this is that
any DNS queries answered from TCP connections are not cached:
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,
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.
This fix passes cache entries back from the TCP child process to
the main server process, and fixes the problem.
@@ -35,7 +62,7 @@ version 2.81
configuration.
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
kamp.de for sponsoring this feature.
@@ -66,7 +93,7 @@ version 2.81
Evgenii Seliavka for the suggestion and initial patch.
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
for spotting this case and making the initial patch.
+26 -1
View File
@@ -1,3 +1,27 @@
dnsmasq (2.82-1) unstable; urgency=low
* New upstream.
-- Simon Kelley <simon@thekelleys.org.uk> Fri, 26 Jun 2020 22:22:41 +0000
dnsmasq (2.81-4) unstable; urgency=low
* Remove runit support when building for Ubuntu. (closes: #960401)
-- Simon Kelley <simon@thekelleys.org.uk> Fri, 26 Jun 2020 21:52:44 +0000
dnsmasq (2.81-3) unstable; urgency=low
* Fixes to control file for bug 958100
-- Simon Kelley <simon@thekelleys.org.uk> Sun, 19 Apr 2020 21:44:12 +0000
dnsmasq (2.81-2) unstable; urgency=low
* Fix FTBFS on kFreeBSD. (closes: #958100)
-- Simon Kelley <simon@thekelleys.org.uk> Sat, 18 Apr 2020 18:34:15 +0000
dnsmasq (2.81-1) unstable; urgency=low
* New upstream.
@@ -12,8 +36,9 @@ dnsmasq (2.81-1) unstable; urgency=low
* Fix breakage of dig +trace. (closes: #942363)
* Fix build faliure with newer Nettle libraries. (closes: #940985)
* 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
+3 -2
View File
@@ -3,8 +3,9 @@ Section: net
Priority: optional
Build-depends: gettext, libnetfilter-conntrack-dev [linux-any],
libidn2-dev, libdbus-1-dev (>=0.61), libgmp-dev,
nettle-dev (>=2.4-3), libbsd-dev [!linux-any],
liblua5.2-dev, dh-runit, debhelper-compat (= 10)
nettle-dev (>=2.4-3), libbsd-dev [kfreebsd-any],
liblua5.2-dev, dh-runit, debhelper-compat (= 10),
pkg-config
Maintainer: Simon Kelley <simon@thekelleys.org.uk>
Homepage: http://www.thekelleys.org.uk/dnsmasq/doc.html
Vcs-Git: http://thekelleys.org.uk/git/dnsmasq.git
+1 -1
View File
@@ -1 +1 @@
debian/dnsmasq.runscript name=dnsmasq,logscript,since=2.80-1+runit
debian/dnsmasq.runscript name=dnsmasq,logscript,presubj
+17 -10
View File
@@ -98,9 +98,10 @@ ifeq (,$(filter nodnssec,$(DEB_BUILD_OPTIONS)))
DEB_COPTS += -DHAVE_DNSSEC
endif
ifneq ($(DEB_HOST_ARCH_OS),linux)
ifeq ($(DEB_HOST_ARCH_OS),kfreebsd)
# For strlcpy in FreeBSD
LDFLAGS += -lbsd
LIBS += $(shell ${PKG_CONFIG} --libs libbsd-overlay)
CFLAGS += $(shell ${PKG_CONFIG} --cflags libbsd-overlay)
endif
define build_tree
@@ -169,16 +170,20 @@ binary-indep: checkroot
-d debian/trees/daemon/etc/resolvconf/update.d \
-d debian/trees/daemon/usr/lib/resolvconf/dpkg-event.d \
-d debian/trees/daemon/usr/share/dnsmasq \
-d debian/trees/daemon/usr/share/doc/dnsmasq \
-d debian/trees/daemon/etc/default \
-d debian/trees/daemon/lib/systemd/system \
-d debian/trees/daemon/usr/lib/tmpfiles.d \
-d debian/trees/daemon/etc/insserv.conf.d
install -m 644 debian/conffiles debian/trees/daemon/DEBIAN
install -m 755 debian/postinst debian/postrm debian/prerm debian/trees/daemon/DEBIAN
rm -f debian/dnsmasq.postinst.debhelper debian/dnsmasq.postrm.debhelper
dh_runit -pdnsmasq -Pdebian/trees/daemon
cat debian/dnsmasq.postinst.debhelper >> debian/trees/daemon/DEBIAN/postinst
cat debian/dnsmasq.postrm.debhelper >> debian/trees/daemon/DEBIAN/postrm
if ! dpkg-vendor --derives-from Ubuntu; then \
rm -f debian/dnsmasq.postinst.debhelper debian/dnsmasq.postrm.debhelper; \
dh_runit -pdnsmasq -Pdebian/trees/daemon; \
cat debian/dnsmasq.postinst.debhelper >> debian/trees/daemon/DEBIAN/postinst; \
cat debian/dnsmasq.postrm.debhelper >> debian/trees/daemon/DEBIAN/postrm; \
cd debian/trees/daemon && find etc/sv -type f -printf '/%p\n' >>DEBIAN/conffiles; \
fi
install -m 755 debian/init debian/trees/daemon/etc/init.d/dnsmasq
install -m 755 debian/resolvconf debian/trees/daemon/etc/resolvconf/update.d/dnsmasq
install -m 755 debian/resolvconf-package debian/trees/daemon/usr/lib/resolvconf/dpkg-event.d/dnsmasq
@@ -190,7 +195,9 @@ binary-indep: checkroot
install -m 644 debian/systemd@.service debian/trees/daemon/lib/systemd/system/dnsmasq@.service
install -m 644 debian/tmpfiles.conf debian/trees/daemon/usr/lib/tmpfiles.d/dnsmasq.conf
install -m 644 debian/insserv debian/trees/daemon/etc/insserv.conf.d/dnsmasq
ln -s $(package) debian/trees/daemon/usr/share/doc/dnsmasq
install -m 644 debian/copyright debian/trees/daemon/usr/share/doc/dnsmasq/copyright
install -m 644 debian/changelog debian/trees/daemon/usr/share/doc/dnsmasq/changelog.Debian
gzip -9n debian/trees/daemon/usr/share/doc/dnsmasq/changelog.Debian
cd debian/trees/daemon && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | LC_ALL=C sort -z | xargs -r0 md5sum > DEBIAN/md5sums
dpkg-gencontrol $(PACKAGE_VERSION) -Tdebian/dnsmasq.substvars -pdnsmasq -Pdebian/trees/daemon
find debian/trees/daemon -depth -newermt '$(BUILD_DATE)' -print0 | xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
@@ -200,7 +207,7 @@ binary-indep: checkroot
binary-arch: checkroot
$(call build_tree,debian/trees/base)
make $(TARGET) BUILDDIR=debian/build/no-lua PREFIX=/usr DESTDIR=`pwd`/debian/trees/base CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="$(DEB_COPTS)" CC=$(CC) PKG_CONFIG=$(PKG_CONFIG)
make $(TARGET) BUILDDIR=debian/build/no-lua PREFIX=/usr DESTDIR=`pwd`/debian/trees/base CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="$(DEB_COPTS)" CC=$(CC) PKG_CONFIG=$(PKG_CONFIG) LIBS="$(LIBS)"
ifeq (,$(findstring nodoc,$(DEB_BUILD_OPTIONS)))
$(call add_docs,debian/trees/base)
else
@@ -219,7 +226,7 @@ endif
dpkg --build debian/trees/base ..
$(call build_tree,debian/trees/lua-base)
make $(TARGET) BUILDDIR=debian/build/lua PREFIX=/usr DESTDIR=`pwd`/debian/trees/lua-base CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="-DHAVE_LUASCRIPT $(DEB_COPTS)" CC=$(CC) PKG_CONFIG=$(PKG_CONFIG)
make $(TARGET) BUILDDIR=debian/build/lua PREFIX=/usr DESTDIR=`pwd`/debian/trees/lua-base CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="-DHAVE_LUASCRIPT $(DEB_COPTS)" CC=$(CC) PKG_CONFIG=$(PKG_CONFIG) LIBS="$(LIBS)"
ifeq (,$(findstring nodoc,$(DEB_BUILD_OPTIONS)))
$(call add_docs,debian/trees/lua-base)
else
@@ -249,7 +256,7 @@ ifeq ($(DEB_HOST_ARCH_OS),linux)
ifeq (,$(findstring nodoc,$(DEB_BUILD_OPTIONS)))
install -m 755 -d debian/trees/utils/usr/share/man/man1
endif
make -C contrib/lease-tools PREFIX=/usr DESTDIR=`pwd`/debian/trees/utils CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="$(DEB_COPTS)" CC=$(CC) PKG_CONFIG=$(PKG_CONFIG)
make -C contrib/lease-tools PREFIX=/usr DESTDIR=`pwd`/debian/trees/utils CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="$(DEB_COPTS)" CC=$(CC) PKG_CONFIG=$(PKG_CONFIG) LIBS="$(LIBS)"
install -m 755 contrib/lease-tools/dhcp_release debian/trees/utils/usr/bin/dhcp_release
install -m 755 contrib/lease-tools/dhcp_release6 debian/trees/utils/usr/bin/dhcp_release6
install -m 755 contrib/lease-tools/dhcp_lease_time debian/trees/utils/usr/bin/dhcp_lease_time
+41 -29
View File
@@ -1,4 +1,4 @@
.TH DNSMASQ 8
.TH DNSMASQ 8 2020-04-05
.SH NAME
dnsmasq \- A lightweight DHCP and caching DNS server.
.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
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
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
.B --local-service
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
.B uk.org.thekelleys.dnsmasq
.TP
.B --enable-ubus
.B --enable-ubus[=<service-name>]
Enable dnsmasq UBus interface. It sends notifications via UBus on
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
.B \-o, --strict-order
By default, dnsmasq will send queries to any of the upstream servers
@@ -395,11 +398,13 @@ were previously disabled.
.TP
.B --stop-dns-rebind
Reject (and log) addresses from upstream nameservers which are in the
private IP ranges. This blocks an attack where a browser behind a
firewall is used to probe machines on the local network.
private ranges. This blocks an attack where a browser behind a
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
.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
these services.
.TP
@@ -423,7 +428,7 @@ Tells dnsmasq to never forward A or AAAA queries for plain names, without dots
or domain parts, to upstream nameservers. If the name is not known
from /etc/hosts or DHCP then a "not found" answer is returned.
.TP
.B \-S, --local, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source-ip>|<interface>[#<port>]]
.B \-S, --local, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>]][@<source-ip>|<interface>[#<port>]]
Specify IP address of upstream servers directly. Setting this flag does
not suppress reading of /etc/resolv.conf, use \fB--no-resolv\fP to do that. If one or more
optional domains are given, that server is used only for those domains
@@ -856,7 +861,7 @@ in
options. If the lease time is given, then leases
will be given for that length of time. The lease time is in seconds,
or minutes (eg 45m) or hours (eg 1h) or "infinite". If not given,
the default lease time is one hour. The
the default lease time is one hour for IPv4 and one day for IPv6. The
minimum lease time is two minutes. For IPv6 ranges, the lease time
maybe "deprecated"; this sets the preferred lifetime sent in a DHCP
lease or router advertisement to zero, which causes clients to use
@@ -904,7 +909,7 @@ then the address can be simply ::
The optional
.B set:<tag>
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
a tag to matching it. Only one tag may be set, but more than one tag
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]
IPv6 addresses may contain only the host-identifier part:
.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:
.B --dhcp-host=laptop,[1234:50/126]
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.
.TP
.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
.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
@@ -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.
.TP
.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.
.TP
.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 --bridge-interface=int1,alias2\fP
.TP
.B --shared-network=<interface>|<addr>,<addr>
The DHCP server determines which dhcp ranges are useable for allocating and
.B --shared-network=<interface>,<addr>
.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,
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
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 that 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
To be useful, there must be a suitable dhcp-range which allows address allocation on this subnet
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
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
configured manually. The client must have a route to the server: if the two-address form
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.
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.
addresses may be allocated from.
.TP
.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
for DHCP-configured hosts to claim. The intention is to constrain
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
hostname with a domain part (ie with a period) will be disallowed
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.
.TP
.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
receiving an instant reply.
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
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.
The dhcp lease change script is called for all
The DHCP lease change script is called for all
existing DHCP leases. If
.B
--no-poll
@@ -2195,7 +2209,6 @@ as is the tag "bootp", allowing some control over the options returned to
different classes of hosts.
.SH AUTHORITATIVE CONFIGURATION
.PP
Configuring dnsmasq to act as an authoritative DNS server is
complicated by the fact that it involves configuration of external DNS
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
.PP
0 - Dnsmasq successfully forked into the background, or terminated
normally if backgrounding is not enabled.
.PP
+56 -71
View File
@@ -9,10 +9,10 @@
# Simon Kelley <simon@thekelleys.org.uk>, 2005.
msgid ""
msgstr ""
"Project-Id-Version: dnsmasq 2.80\n"
"Project-Id-Version: dnsmasq 2.81\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-06-18 12:24+0100\n"
"PO-Revision-Date: 2018-09-29 00:13+0200\n"
"PO-Revision-Date: 2020-03-08 20:25+0100\n"
"Last-Translator: Conrad Kostecki <conrad@kostecki.com>\n"
"Language-Team: German <de@li.org>\n"
"Language: de\n"
@@ -20,7 +20,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Generator: Poedit 2.3\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: cache.c:559
@@ -431,7 +431,7 @@ msgstr "DBus-Schnittstelle zum Festlegen vorgelagerter Server usw. festlegen."
#: option.c:431
msgid "Enable the UBus interface."
msgstr ""
msgstr "UBus-Schnittstelle aktivieren."
#: option.c:432
msgid "Do not provide DHCP on this interface, only provide DNS."
@@ -451,7 +451,7 @@ msgstr "DHCP-Anfragen von Alias-Schnittstellen für die Hauptschnittstelle beant
#: option.c:436
msgid "Specify extra networks sharing a broadcast domain for DHCP"
msgstr ""
msgstr "Geben Sie zusätzliche Netzwerke an, die eine Broadcast-Domäne für DHCP gemeinsam nutzen"
#: option.c:437
msgid "Disable ICMP echo address checking in the DHCP server."
@@ -546,7 +546,7 @@ msgstr "Bereich für vorübergehende Ports für TFTP-Übertragungen."
#: option.c:459
msgid "Use only one port for TFTP server."
msgstr ""
msgstr "Bitte nur einen Port für den TFTP-Server nutzen."
#: option.c:460
msgid "Extra logging for DHCP."
@@ -577,9 +577,8 @@ msgid "Set tag if client includes matching option in request."
msgstr "Marke setzen, wenn Klient eine entsprechende Option anfragt."
#: option.c:467
#, fuzzy
msgid "Set tag if client provides given name."
msgstr "Marke setzen, wenn Klient eine entsprechende Option anfragt."
msgstr "Setzt das Tag, wenn der Client diesen Namen anbietet."
#: option.c:468
msgid "Use alternative ports for DHCP."
@@ -651,9 +650,8 @@ msgid "Attempt to allocate sequential IP addresses to DHCP clients."
msgstr "Versuche sequenzielle IP-Adressen an DHCP-Klienten zu vergeben."
#: option.c:485
#, fuzzy
msgid "Ignore client identifier option sent by DHCP clients."
msgstr "Von DHCP-Clients gelieferte Hostnamen ignorieren."
msgstr "Ignorieren Sie die von DHCP-Clients gesendete Client-ID-Option."
#: option.c:486
msgid "Copy connection-track mark from queries to upstream connections."
@@ -677,7 +675,7 @@ msgstr "Spezifiziere Host (A/AAAA und PTR) Einträge"
#: option.c:491
msgid "Specify certification authority authorization record"
msgstr ""
msgstr "Geben Sie den Autorisierungsdatensatz der Zertifizierungsstelle an"
#: option.c:492
msgid "Specify arbitrary DNS resource record"
@@ -781,20 +779,19 @@ msgstr "Verzögere DHCP-Antworten für mindestens Anzahl von Sekunden."
#: option.c:517
msgid "Enables DHCPv4 Rapid Commit option."
msgstr ""
msgstr "Aktiviert die Option DHCPv4 Rapid Commit."
#: option.c:518
msgid "Path to debug packet dump file"
msgstr ""
msgstr "Pfad zur Debug-Paketdatei, wohin gedumpt werden soll"
#: option.c:519
msgid "Mask which packets to dump"
msgstr ""
msgstr "Maskiere Pakete, welche gedumpt werden sollen"
#: option.c:520
#, fuzzy
msgid "Call dhcp-script when lease expiry changes."
msgstr "Rufe dhcp-script mit Änderungen an der lokalen ARP-Tabelle auf."
msgstr "Rufe dhcp-script auf, wenn der Ablauf des Leases sich ändert."
#: option.c:725
#, c-format
@@ -931,7 +928,7 @@ msgstr "unzulässige Brücken-Schnittstelle"
#: option.c:2941
msgid "bad shared-network"
msgstr ""
msgstr "unzulässiger geteiltes Netz"
#: option.c:2996
msgid "only one tag allowed"
@@ -970,9 +967,8 @@ msgid "bad hex constant"
msgstr "Falscher Hexwert"
#: option.c:3315
#, fuzzy
msgid "bad IPv6 prefix"
msgstr "unzulässiger Präfix"
msgstr "unzulässiger IPv6-Präfix"
#: option.c:3362
#, c-format
@@ -1008,9 +1004,8 @@ msgid "bad DUID"
msgstr "unzulässige DUID"
#: option.c:4023
#, fuzzy
msgid "missing address in alias"
msgstr "Adresse ungültig"
msgstr "Adresse fehlt in Alias"
#: option.c:4029
msgid "invalid alias range"
@@ -1037,9 +1032,8 @@ msgid "bad RR record"
msgstr "unzulässiger RR-Eintrag"
#: option.c:4236
#, fuzzy
msgid "bad CAA record"
msgstr "unzulässiger RR-Eintrag"
msgstr "unzulässiger CAA-Eintrag"
#: option.c:4265
msgid "bad TXT record"
@@ -1071,7 +1065,7 @@ msgstr "Unzulässiger Name in host-record"
#: option.c:4444
msgid "bad value for dnssec-check-unsigned"
msgstr ""
msgstr "Ungültiger Wert für dnssec-check-unsigned"
#: option.c:4480
msgid "bad trust anchor"
@@ -1310,9 +1304,9 @@ msgid "domain"
msgstr "Domain"
#: network.c:1543
#, fuzzy, c-format
#, c-format
msgid "using only locally-known addresses for %s %s"
msgstr "Benutze lokale Adressen nur für %s %s"
msgstr "Benutze nur lokal-bekannte Adressen für %s %s"
#: network.c:1546
#, c-format
@@ -1394,9 +1388,8 @@ msgid "loop detection not available: set HAVE_LOOP in src/config.h"
msgstr "Loop-Erkennung nicht verfügbar, Aktiviere HAVE_LOOP in src/config.h"
#: dnsmasq.c:232
#, fuzzy
msgid "Ubus not available: set HAVE_UBUS in src/config.h"
msgstr "DBus nicht verfügbar: setzen Sie HAVE_DBUS in src/config.h"
msgstr "UBus nicht verfügbar: setzen Sie HAVE_UBUS in src/config.h"
#: dnsmasq.c:236
msgid "max_port cannot be smaller than min_port"
@@ -1404,7 +1397,7 @@ msgstr "max_port darf nicht kleiner als min_port sein"
#: dnsmasq.c:243
msgid "--auth-server required when an auth zone is defined."
msgstr ""
msgstr "--Auth-Server ist notwendig, wenn eine Auth-Zone definiert ist."
#: dnsmasq.c:248
msgid "zone serial must be configured in --auth-soa"
@@ -1429,9 +1422,8 @@ msgid "unknown interface %s"
msgstr "unbekannte Schnittstelle %s"
#: dnsmasq.c:406
#, fuzzy
msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
msgstr "DBus nicht verfügbar: setzen Sie HAVE_DBUS in src/config.h"
msgstr "Paketdump nicht verfügbar: setzen Sie HAVE_DUMP in src/config.h"
#: dnsmasq.c:416 dnsmasq.c:1171
#, c-format
@@ -1443,9 +1435,8 @@ msgid "DBus not available: set HAVE_DBUS in src/config.h"
msgstr "DBus nicht verfügbar: setzen Sie HAVE_DBUS in src/config.h"
#: dnsmasq.c:429
#, fuzzy
msgid "UBus not available: set HAVE_UBUS in src/config.h"
msgstr "DBus nicht verfügbar: setzen Sie HAVE_DBUS in src/config.h"
msgstr "UBus nicht verfügbar: setzen Sie HAVE_UBUS in src/config.h"
#: dnsmasq.c:459
#, c-format
@@ -1455,7 +1446,7 @@ msgstr "Unbekannter Benutzer oder Gruppe: %s"
#: dnsmasq.c:535
#, c-format
msgid "process is missing required capability %s"
msgstr ""
msgstr "Prozess benötigt nicht vorhandene Fähigkeit %s"
#: dnsmasq.c:567
#, c-format
@@ -1475,7 +1466,7 @@ msgstr "gestartet, Version %s, Cachegröße %d"
#: dnsmasq.c:822
msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
msgstr ""
msgstr "Die Cachegröße größer als 10000 kann Performanceprobleme verursachen und der positive Nutzen ist zudem unwahrscheinlich."
#: dnsmasq.c:825
#, c-format
@@ -1500,18 +1491,16 @@ msgid "DBus support enabled: bus connection pending"
msgstr "DBus-Unterstützung eingeschaltet: warte auf Systembus-Verbindung"
#: dnsmasq.c:850
#, fuzzy
msgid "UBus support enabled: connected to system bus"
msgstr "DBus-Unterstützung eingeschaltet: mit Systembus verbunden"
msgstr "UBus-Unterstützung aktiviert: Mit Systembus verbunden"
#: dnsmasq.c:852
#, fuzzy
msgid "UBus support enabled: bus connection pending"
msgstr "DBus-Unterstützung eingeschaltet: warte auf Systembus-Verbindung"
msgstr "UBus-Unterstützung aktiviert: BUS-Verbindung wird hergestellt"
#: dnsmasq.c:872
msgid "DNSSEC validation enabled but all unsigned answers are trusted"
msgstr ""
msgstr "DNSSEC-Validierung aktiviert, jedoch wird allen unsignierten Antworten vertraut"
#: dnsmasq.c:874
msgid "DNSSEC validation enabled"
@@ -1528,7 +1517,7 @@ msgstr "DNSSEC Signatur-Zeitstempel werden erst überprüft, sobald die Systemuh
#: dnsmasq.c:884
#, c-format
msgid "configured with trust anchor for %s keytag %u"
msgstr ""
msgstr "konfiguriert mit Vertrauensanker für% s Schlüsselwort % u"
#: dnsmasq.c:890
#, c-format
@@ -1580,9 +1569,8 @@ msgid "secure mode"
msgstr "sicherer Modus"
#: dnsmasq.c:961
#, fuzzy
msgid "single port mode"
msgstr "unzulässige Portnummer"
msgstr "Einzelport-Modus"
#: dnsmasq.c:964
#, c-format
@@ -1762,14 +1750,14 @@ msgid "DHCP relay %s -> %s"
msgstr "DHCP Weiterleitung %s -> %s"
#: lease.c:64
#, fuzzy, c-format
#, c-format
msgid "ignoring invalid line in lease database: %s %s %s %s ..."
msgstr "Fehler beim Parsen der Lease-Datenbank, ungültige Zeile: %s %s %s %s ..."
msgstr "ignoriere fehlerhafte Zeile in Lease-Datenbank: %s %s %s %s ..."
#: lease.c:101
#, c-format
msgid "ignoring invalid line in lease database, bad address: %s"
msgstr ""
msgstr "ignoriere fehlerhafte Zeile in Lease-Datenbank, ungültige Adresse: %s"
#: lease.c:108
msgid "too many stored leases"
@@ -1781,9 +1769,8 @@ msgid "cannot open or create lease file %s: %s"
msgstr "kann Lease-Datei %s nicht öffnen: %s"
#: lease.c:185
#, fuzzy
msgid "failed to parse lease database cleanly"
msgstr "Fehler beim Parsen der Lease-Datenbank, ungültige Zeile: %s %s %s %s ..."
msgstr "Fehler beim korrekten Parsen der Lease-Datenbank"
#: lease.c:188
#, c-format
@@ -2287,12 +2274,12 @@ msgstr "Prüfe jetzt DNSSEC Signatur-Zeitstempel."
#: dnssec.c:902
#, c-format
msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
msgstr ""
msgstr "Unsichere DS-Antwort für %s, bitte Domainkonfiguration und Upstream DNS-Server für DNSSEC-Unterstützung überprüfen"
#: blockdata.c:55
#, fuzzy, c-format
#, c-format
msgid "pool memory in use %u, max %u, allocated %u"
msgstr "DNSSEC Speicher in Benutzung %u, Max %u, zugewiesen %u"
msgstr "Pool Speicher in Benutzung %u, Max %u, zugewiesen %u"
#: tables.c:61
#, c-format
@@ -2369,65 +2356,63 @@ msgid "inotify, new or changed file %s"
msgstr "inotify, neue oder geänderte Datei %s"
#: dump.c:64
#, fuzzy, c-format
#, c-format
msgid "cannot create %s: %s"
msgstr "kann %s nicht lesen: %s"
msgstr "kann %s nicht erstellen: %s"
#: dump.c:70
#, fuzzy, c-format
#, c-format
msgid "bad header in %s"
msgstr "Adresse in Nutzung"
msgstr "Unzulässiger Header in %s"
#: dump.c:201
#, fuzzy
msgid "failed to write packet dump"
msgstr "Fehlgeschlagen, folgendes Paket zu senden: %s"
msgstr "schreiben des Paketmitschnitt fehlgeschlagen"
#: dump.c:203
#, c-format
msgid "dumping UDP packet %u mask 0x%04x"
msgstr ""
msgstr "Dumpe UDP Paket %u Maske 0x%04x"
#: ubus.c:52
#, c-format
msgid "UBus subscription callback: %s subscriber(s)"
msgstr ""
msgstr "UBus-Subskription Rückruf: %s Teilnehmer"
#: ubus.c:73
#, fuzzy, c-format
#, c-format
msgid "Cannot reconnect to UBus: %s"
msgstr "Kann Logdatei %s nicht öffnen: %s"
msgstr "Kann mit UBus nicht erneut verbinden: %s"
#: ubus.c:89
msgid "Cannot initialize UBus: connection failed"
msgstr ""
msgstr "Kann UBus nicht initialisieren: Verbindung fehlgeschlagen"
#: ubus.c:102
#, fuzzy, c-format
#, c-format
msgid "Cannot add object to UBus: %s"
msgstr "Kann Logdatei %s nicht öffnen: %s"
msgstr "Kann Objekt zu UBus nicht hinzufügen: %s"
#: ubus.c:112
#, fuzzy
msgid "Connected to system UBus"
msgstr "Mit System-DBus verbunden"
msgstr "Mit System-UBus verbunden"
#: ubus.c:122
msgid "Cannot set UBus listeners: no connection"
msgstr ""
msgstr "Kann UBus-Zuhörer nicht setzen: Keine Verbindung"
#: ubus.c:142
msgid "Cannot poll UBus listeners: no connection"
msgstr ""
msgstr "Kann UBus-Zuhörer nicht abfragen: Keine Verbindung"
#: ubus.c:155
msgid "Disconnecting from UBus"
msgstr ""
msgstr "Mit System-UBus trennen"
#: ubus.c:199
#, fuzzy, c-format
#, c-format
msgid "Failed to send UBus event: %s"
msgstr "Fehlgeschlagen, folgendes Paket zu senden: %s"
msgstr "Fehlgeschlagen, folgendes UBus-Event zu senden: %s"
#~ msgid "Specify DHCPv6 prefix class"
#~ msgstr "Spezifiziere DHCPv6 Prefix Klasse"
+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;
newoffset = ansp - (unsigned char *)header;
if (add_resource_record(header, limit, &trunc, -offset, &ansp,
daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver))
/* Only include the machine running dnsmasq if it's acting as an auth server */
if (daemon->authinterface)
{
if (offset == 0)
offset = newoffset;
if (ns)
anscount++;
else
authcount++;
newoffset = ansp - (unsigned char *)header;
if (add_resource_record(header, limit, &trunc, -offset, &ansp,
daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver))
{
if (offset == 0)
offset = newoffset;
if (ns)
anscount++;
else
authcount++;
}
}
if (!subnet)
+17 -4
View File
@@ -472,16 +472,29 @@ void cache_start_insert(void)
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
time_t now, unsigned long ttl, unsigned int flags)
{
/* Don't log DNSSEC records here, done elsewhere */
if (flags & (F_IPV4 | F_IPV6 | F_CNAME | F_SRV))
#ifdef HAVE_DNSSEC
if (flags & (F_DNSKEY | F_DS))
{
/* The DNSSEC validation process works by getting needed records into the
cache, then retrying the validation until they are all in place.
This can be messed up by very short TTLs, and _really_ messed up by
zero TTLs, so we force the TTL to be at least long enough to do a validation.
Ideally, we should use some kind of reference counting so that records are
locked until the validation that asked for them is complete, but this
is much easier, and just as effective. */
if (ttl < DNSSEC_MIN_TTL)
ttl = DNSSEC_MIN_TTL;
}
else
#endif
{
/* Don't log DNSSEC records here, done elsewhere */
log_query(flags | F_UPSTREAM, name, addr, NULL);
/* Don't mess with TTL for DNSSEC records. */
if (daemon->max_cache_ttl != 0 && daemon->max_cache_ttl < ttl)
ttl = daemon->max_cache_ttl;
if (daemon->min_cache_ttl != 0 && daemon->min_cache_ttl > ttl)
ttl = daemon->min_cache_ttl;
}
}
return really_insert(name, addr, class, now, ttl, flags);
}
+4 -1
View File
@@ -40,9 +40,11 @@
#define DHCP_PACKET_MAX 16384 /* hard limit on DHCP packet size */
#define SMALLDNAME 50 /* most domain names are smaller than this */
#define CNAME_CHAIN 10 /* chains longer than this atr dropped for loop protection */
#define DNSSEC_MIN_TTL 60 /* DNSKEY and DS records in cache last at least this long */
#define HOSTSFILE "/etc/hosts"
#define ETHERSFILE "/etc/ethers"
#define DEFLEASE 3600 /* default lease time, 1 hour */
#define DEFLEASE 3600 /* default DHCPv4 lease time, one hour */
#define DEFLEASE6 (3600*24) /* default lease time for DHCPv6. One day. */
#define CHUSER "nobody"
#define CHGRP "dip"
#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
@@ -50,6 +52,7 @@
#define RANDFILE "/dev/urandom"
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" /* Default - may be overridden by config */
#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 SOA_REFRESH 1200 /* SOA refresh default */
#define SOA_RETRY 180 /* SOA retry default */
+1 -1
View File
@@ -237,7 +237,7 @@ static DBusMessage *dbus_reply_server_loop(DBusMessage *message)
for (serv = daemon->servers; serv; serv = serv->next)
if (serv->flags & SERV_LOOP)
{
prettyprint_addr(&serv->addr, daemon->addrbuff);
(void)prettyprint_addr(&serv->addr, daemon->addrbuff);
dbus_message_iter_append_basic (&args_iter, DBUS_TYPE_STRING, &daemon->addrbuff);
}
+13 -4
View File
@@ -38,7 +38,7 @@ void dhcp_common_init(void)
ssize_t recv_dhcp_packet(int fd, struct msghdr *msg)
{
ssize_t sz;
ssize_t sz, new_sz;
while (1)
{
@@ -65,9 +65,18 @@ ssize_t recv_dhcp_packet(int fd, struct msghdr *msg)
}
}
while ((sz = recvmsg(fd, msg, 0)) == -1 && errno == EINTR);
while ((new_sz = recvmsg(fd, msg, 0)) == -1 && errno == EINTR);
/* Some kernels seem to ignore MSG_PEEK, and dequeue the packet anyway.
If that happens we get EAGAIN here because the socket is non-blocking.
Use the result of the original testing recvmsg as long as the buffer
was big enough. There's a small race here that may lose the odd packet,
but it's UDP anyway. */
return (msg->msg_flags & MSG_TRUNC) ? -1 : sz;
if (new_sz == -1 && (errno == EWOULDBLOCK || errno == EAGAIN))
new_sz = sz;
return (msg->msg_flags & MSG_TRUNC) ? -1 : new_sz;
}
struct dhcp_netid *run_tag_if(struct dhcp_netid *tags)
@@ -649,7 +658,7 @@ static const struct opttab_t opttab6[] = {
{ "sntp-server", 31, OT_ADDR_LIST },
{ "information-refresh-time", 32, OT_TIME },
{ "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-param", 60, OT_CSTRING },
{ NULL, 0, 0 }
+4
View File
@@ -59,8 +59,12 @@
#define OPTION6_REMOTE_ID 37
#define OPTION6_SUBSCRIBER_ID 38
#define OPTION6_FQDN 39
#define OPTION6_NTP_SERVER 56
#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 DHCP6UNSPEC 1
+41 -31
View File
@@ -58,6 +58,7 @@ int main (int argc, char **argv)
char *bound_device = NULL;
int did_bind = 0;
struct server *serv;
char *netlink_warn;
#endif
#if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
struct dhcp_context *context;
@@ -89,11 +90,15 @@ int main (int argc, char **argv)
sigaction(SIGPIPE, &sigact, NULL);
umask(022); /* known umask, create leases and pid files as 0644 */
rand_init(); /* Must precede read_opts() */
read_opts(argc, argv, compile_opts);
#ifdef HAVE_LINUX_NETWORK
daemon->kernel_version = kernel_version();
#endif
if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = PACKETSZ;
@@ -323,7 +328,7 @@ int main (int argc, char **argv)
#endif
#if defined(HAVE_LINUX_NETWORK)
netlink_init();
netlink_warn = netlink_init();
#elif defined(HAVE_BSD_NETWORK)
route_init();
#endif
@@ -942,6 +947,9 @@ int main (int argc, char **argv)
# ifdef HAVE_LINUX_NETWORK
if (did_bind)
my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device);
if (netlink_warn)
my_syslog(LOG_WARNING, netlink_warn);
# endif
/* after dhcp_construct_contexts */
@@ -1679,7 +1687,7 @@ static int set_dns_listeners(time_t now)
/* will we be able to get memory? */
if (daemon->port != 0)
get_new_frec(now, &wait, 0);
get_new_frec(now, &wait, NULL);
for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
poll_listen(serverfdp->fd, POLLIN);
@@ -1816,7 +1824,8 @@ static void check_dns_listeners(time_t now)
addr.addr4 = tcp_addr.in.sin_addr;
for (iface = daemon->interfaces; iface; iface = iface->next)
if (iface->index == if_index)
if (iface->index == if_index &&
iface->addr.sa.sa_family == tcp_addr.sa.sa_family)
break;
if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
@@ -1855,30 +1864,30 @@ static void check_dns_listeners(time_t now)
else
{
int i;
#ifdef HAVE_LINUX_NETWORK
/* The child process inherits the netlink socket,
which it never uses, but when the parent (us)
uses it in the future, the answer may go to the
child, resulting in the parent blocking
forever awaiting the result. To avoid this
the child closes the netlink socket, but there's
a nasty race, since the parent may use netlink
before the child has done the close.
To avoid this, the parent blocks here until a
single byte comes back up the pipe, which
is sent by the child after it has closed the
netlink socket. */
unsigned char a;
read_write(pipefd[0], &a, 1, 1);
#endif
for (i = 0; i < MAX_PROCS; i++)
if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
{
char a;
daemon->tcp_pids[i] = p;
daemon->tcp_pipes[i] = pipefd[0];
#ifdef HAVE_LINUX_NETWORK
/* The child process inherits the netlink socket,
which it never uses, but when the parent (us)
uses it in the future, the answer may go to the
child, resulting in the parent blocking
forever awaiting the result. To avoid this
the child closes the netlink socket, but there's
a nasty race, since the parent may use netlink
before the child has done the close.
To avoid this, the parent blocks here until a
single byte comes back up the pipe, which
is sent by the child after it has closed the
netlink socket. */
retry_send(read(pipefd[0], &a, 1));
#endif
break;
}
}
@@ -1910,15 +1919,16 @@ static void check_dns_listeners(time_t now)
terminate the process. */
if (!option_bool(OPT_DEBUG))
{
char a = 0;
#ifdef HAVE_LINUX_NETWORK
/* See comment above re: netlink socket. */
unsigned char a = 0;
close(daemon->netlinkfd);
read_write(pipefd[1], &a, 1, 0);
#endif
alarm(CHILD_LIFETIME);
close(pipefd[0]); /* close read end in child. */
daemon->pipe_to_parent = pipefd[1];
#ifdef HAVE_LINUX_NETWORK
/* See comment above re netlink socket. */
close(daemon->netlinkfd);
retry_send(write(pipefd[1], &a, 1));
#endif
}
/* start with no upstream connections. */
@@ -1945,8 +1955,10 @@ static void check_dns_listeners(time_t now)
shutdown(s->tcpfd, SHUT_RDWR);
close(s->tcpfd);
}
if (!option_bool(OPT_DEBUG))
{
close(daemon->pipe_to_parent);
flush_log();
_exit(0);
}
@@ -2106,6 +2118,4 @@ int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id)
return 0;
}
#endif
#endif /* HAVE_DHCP */
+11 -4
View File
@@ -141,6 +141,7 @@ typedef unsigned long long u64;
#endif
#if defined(HAVE_LINUX_NETWORK)
#include <linux/version.h>
#include <linux/sockios.h>
#include <linux/capability.h>
/* There doesn't seem to be a universally-available
@@ -571,7 +572,8 @@ struct irec {
};
struct listener {
int fd, tcpfd, tftpfd, family;
int fd, tcpfd, tftpfd, used;
union mysockaddr addr;
struct irec *iface; /* only sometimes valid for non-wildcard */
struct listener *next;
};
@@ -940,6 +942,7 @@ struct shared_network {
#define CONTEXT_OLD (1u<<16)
#define CONTEXT_V6 (1u<<17)
#define CONTEXT_RA_OFF_LINK (1u<<18)
#define CONTEXT_SETLEASE (1u<<19)
struct ping_result {
struct in_addr addr;
@@ -1062,6 +1065,7 @@ extern struct daemon {
unsigned int duid_enterprise, duid_config_len;
unsigned char *duid_config;
char *dbus_name;
char *ubus_name;
char *dump_file;
int dump_mask;
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
@@ -1108,7 +1112,7 @@ extern struct daemon {
int inotifyfd;
#endif
#if defined(HAVE_LINUX_NETWORK)
int netlinkfd;
int netlinkfd, kernel_version;
#elif defined(HAVE_BSD_NETWORK)
int dhcp_raw_fd, dhcp_icmp_fd, routefd;
#endif
@@ -1288,6 +1292,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);
int wildcard_match(const char* wildcard, const char* match);
int wildcard_matchn(const char* wildcard, const char* match, int num);
#ifdef HAVE_LINUX_NETWORK
int kernel_version(void);
#endif
/* log.c */
void die(char *message, char *arg1, int exit_code) ATTRIBUTE_NORETURN;
@@ -1319,7 +1326,7 @@ void receive_query(struct listener *listen, time_t now);
unsigned char *tcp_request(int confd, time_t now,
union mysockaddr *local_addr, struct in_addr netmask, int auth_dns);
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,
union mysockaddr *to, union all_addr *source,
unsigned int iface);
@@ -1445,7 +1452,7 @@ void clear_cache_and_reload(time_t now);
/* netlink.c */
#ifdef HAVE_LINUX_NETWORK
void netlink_init(void);
char *netlink_init(void);
void netlink_multicast(void);
#endif
+153 -122
View File
@@ -223,138 +223,147 @@ static int check_date_range(unsigned long curtime, u32 date_start, u32 date_end)
&& serial_compare_32(curtime, date_end) == SERIAL_LT;
}
/* Return bytes of canonicalised rdata, when the return value is zero, the remaining
data, pointed to by *p, should be used raw. */
static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff, int bufflen,
unsigned char **p, u16 **desc)
/* Return bytes of canonicalised rrdata one by one.
Init state->ip with the RR, and state->end with the end of same.
Init state->op to NULL.
Init state->desc to RR descriptor.
Init state->buff with a MAXDNAME * 2 buffer.
After each call which returns 1, state->op points to the next byte of data.
On returning 0, the end has been reached.
*/
struct rdata_state {
u16 *desc;
size_t c;
unsigned char *end, *ip, *op;
char *buff;
};
static int get_rdata(struct dns_header *header, size_t plen, struct rdata_state *state)
{
int d = **desc;
int d;
/* No more data needs mangling */
if (d == (u16)-1)
if (state->op && state->c != 1)
{
/* If there's more data than we have space for, just return what fits,
we'll get called again for more chunks */
if (end - *p > bufflen)
{
memcpy(buff, *p, bufflen);
*p += bufflen;
return bufflen;
}
return 0;
state->op++;
state->c--;
return 1;
}
(*desc)++;
if (d == 0 && extract_name(header, plen, p, buff, 1, 0))
/* domain-name, canonicalise */
return to_wire(buff);
else
{
/* plain data preceding a domain-name, don't run off the end of the data */
if ((end - *p) < d)
d = end - *p;
while (1)
{
d = *(state->desc);
if (d != 0)
if (d == (u16)-1)
{
memcpy(buff, *p, d);
*p += d;
/* all the bytes to the end. */
if ((state->c = state->end - state->ip) != 0)
{
state->op = state->ip;
state->ip = state->end;;
}
else
return 0;
}
else
{
state->desc++;
if (d == (u16)0)
{
/* domain-name, canonicalise */
int len;
if (!extract_name(header, plen, &state->ip, state->buff, 1, 0) ||
(len = to_wire(state->buff)) == 0)
continue;
state->c = len;
state->op = (unsigned char *)state->buff;
}
else
{
/* plain data preceding a domain-name, don't run off the end of the data */
if ((state->end - state->ip) < d)
d = state->end - state->ip;
if (d == 0)
continue;
state->op = state->ip;
state->c = d;
state->ip += d;
}
}
return d;
return 1;
}
}
/* Bubble sort the RRset into the canonical order.
Note that the byte-streams from two RRs may get unsynced: consider
RRs which have two domain-names at the start and then other data.
The domain-names may have different lengths in each RR, but sort equal
------------
|abcde|fghi|
------------
|abcd|efghi|
------------
leaving the following bytes as deciding the order. Hence the nasty left1 and left2 variables.
*/
/* Bubble sort the RRset into the canonical order. */
static int sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int rrsetidx,
unsigned char **rrset, char *buff1, char *buff2)
{
int swap, quit, i, j;
int swap, i, j;
do
{
for (swap = 0, i = 0; i < rrsetidx-1; i++)
{
int rdlen1, rdlen2, left1, left2, len1, len2, len, rc;
u16 *dp1, *dp2;
unsigned char *end1, *end2;
int rdlen1, rdlen2;
struct rdata_state state1, state2;
/* Note that these have been determined to be OK previously,
so we don't need to check for NULL return here. */
unsigned char *p1 = skip_name(rrset[i], header, plen, 10);
unsigned char *p2 = skip_name(rrset[i+1], header, plen, 10);
state1.ip = skip_name(rrset[i], header, plen, 10);
state2.ip = skip_name(rrset[i+1], header, plen, 10);
state1.op = state2.op = NULL;
state1.buff = buff1;
state2.buff = buff2;
state1.desc = state2.desc = rr_desc;
p1 += 8; /* skip class, type, ttl */
GETSHORT(rdlen1, p1);
end1 = p1 + rdlen1;
state1.ip += 8; /* skip class, type, ttl */
GETSHORT(rdlen1, state1.ip);
if (!CHECK_LEN(header, state1.ip, plen, rdlen1))
return rrsetidx; /* short packet */
state1.end = state1.ip + rdlen1;
p2 += 8; /* skip class, type, ttl */
GETSHORT(rdlen2, p2);
end2 = p2 + rdlen2;
dp1 = dp2 = rr_desc;
for (quit = 0, left1 = 0, left2 = 0, len1 = 0, len2 = 0; !quit;)
state2.ip += 8; /* skip class, type, ttl */
GETSHORT(rdlen2, state2.ip);
if (!CHECK_LEN(header, state2.ip, plen, rdlen2))
return rrsetidx; /* short packet */
state2.end = state2.ip + rdlen2;
while (1)
{
if (left1 != 0)
memmove(buff1, buff1 + len1 - left1, left1);
int ok1, ok2;
if ((len1 = get_rdata(header, plen, end1, buff1 + left1, (MAXDNAME * 2) - left1, &p1, &dp1)) == 0)
{
quit = 1;
len1 = end1 - p1;
memcpy(buff1 + left1, p1, len1);
}
len1 += left1;
if (left2 != 0)
memmove(buff2, buff2 + len2 - left2, left2);
if ((len2 = get_rdata(header, plen, end2, buff2 + left2, (MAXDNAME *2) - left2, &p2, &dp2)) == 0)
{
quit = 1;
len2 = end2 - p2;
memcpy(buff2 + left2, p2, len2);
}
len2 += left2;
if (len1 > len2)
left1 = len1 - len2, left2 = 0, len = len2;
else
left2 = len2 - len1, left1 = 0, len = len1;
rc = (len == 0) ? 0 : memcmp(buff1, buff2, len);
if (rc > 0 || (rc == 0 && quit && len1 > len2))
{
unsigned char *tmp = rrset[i+1];
rrset[i+1] = rrset[i];
rrset[i] = tmp;
swap = quit = 1;
}
else if (rc == 0 && quit && len1 == len2)
ok1 = get_rdata(header, plen, &state1);
ok2 = get_rdata(header, plen, &state2);
if (!ok1 && !ok2)
{
/* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */
for (j = i+1; j < rrsetidx-1; j++)
rrset[j] = rrset[j+1];
rrsetidx--;
i--;
break;
}
else if (rc < 0)
quit = 1;
else if (ok1 && (!ok2 || *state1.op > *state2.op))
{
unsigned char *tmp = rrset[i+1];
rrset[i+1] = rrset[i];
rrset[i] = tmp;
swap = 1;
break;
}
else if (ok2 && (!ok1 || *state2.op > *state1.op))
break;
/* arrive here when bytes are equal, go round the loop again
and compare the next ones. */
}
}
} while (swap);
@@ -569,15 +578,18 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
wire_len = to_wire(keyname);
hash->update(ctx, (unsigned int)wire_len, (unsigned char*)keyname);
from_wire(keyname);
#define RRBUFLEN 300 /* Most RRs are smaller than this. */
for (i = 0; i < rrsetidx; ++i)
{
int seg;
unsigned char *end, *cp;
u16 len, *dp;
int j;
struct rdata_state state;
u16 len;
unsigned char rrbuf[RRBUFLEN];
p = rrset[i];
if (!extract_name(header, plen, &p, name, 1, 10))
return STAT_BOGUS;
@@ -586,12 +598,11 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
/* if more labels than in RRsig name, hash *.<no labels in rrsig labels field> 4035 5.3.2 */
if (labels < name_labels)
{
int k;
for (k = name_labels - labels; k != 0; k--)
for (j = name_labels - labels; j != 0; j--)
{
while (*name_start != '.' && *name_start != 0)
name_start++;
if (k != 1 && *name_start == '.')
if (j != 1 && *name_start == '.')
name_start++;
}
@@ -612,24 +623,44 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
if (!CHECK_LEN(header, p, plen, rdlen))
return STAT_BOGUS;
end = p + rdlen;
/* canonicalise rdata and calculate length of same, use
name buffer as workspace for get_rdata. */
state.ip = p;
state.op = NULL;
state.desc = rr_desc;
state.buff = name;
state.end = p + rdlen;
/* canonicalise rdata and calculate length of same, use name buffer as workspace.
Note that name buffer is twice MAXDNAME long in DNSSEC mode. */
cp = p;
dp = rr_desc;
for (len = 0; (seg = get_rdata(header, plen, end, name, MAXDNAME * 2, &cp, &dp)) != 0; len += seg);
len += end - cp;
len = htons(len);
for (j = 0; get_rdata(header, plen, &state); j++)
if (j < RRBUFLEN)
rrbuf[j] = *state.op;
len = htons((u16)j);
hash->update(ctx, 2, (unsigned char *)&len);
/* If the RR is shorter than RRBUFLEN (most of them, in practice)
then we can just digest it now. If it exceeds RRBUFLEN we have to
go back to the start and do it in chunks. */
if (j >= RRBUFLEN)
{
state.ip = p;
state.op = NULL;
state.desc = rr_desc;
for (j = 0; get_rdata(header, plen, &state); j++)
{
rrbuf[j] = *state.op;
if (j == RRBUFLEN - 1)
{
hash->update(ctx, RRBUFLEN, rrbuf);
j = -1;
}
}
}
/* Now canonicalise again and digest. */
cp = p;
dp = rr_desc;
while ((seg = get_rdata(header, plen, end, name, MAXDNAME * 2, &cp, &dp)))
hash->update(ctx, seg, (unsigned char *)name);
if (cp != end)
hash->update(ctx, end - cp, cp);
if (j != 0)
hash->update(ctx, j, rrbuf);
}
hash->digest(ctx, hash->digest_size, digest);
@@ -1003,7 +1034,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
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;
+31 -24
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)));
/* If interface is still in DAD, EINVAL results - ignore that. */
if (errno != 0 && errno != EINVAL)
if (errno != 0)
{
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;
}
@@ -345,7 +348,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
type &= ~SERV_DO_DNSSEC;
if (daemon->servers && !flags)
forward = get_new_frec(now, NULL, 0);
forward = get_new_frec(now, NULL, NULL);
/* table full - flags == 0, return REFUSED */
if (forward)
@@ -673,7 +676,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
if (!(header->hb4 & HB4_RA) && rcode == NOERROR &&
server && !(server->flags & SERV_WARNED_RECURSIVE))
{
prettyprint_addr(&server->addr, daemon->namebuff);
(void)prettyprint_addr(&server->addr, daemon->namebuff);
my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
if (!option_bool(OPT_LOG))
server->flags |= SERV_WARNED_RECURSIVE;
@@ -957,7 +960,7 @@ void reply_query(int fd, int family, time_t now)
{
forward->sentto->edns_pktsz = SAFE_PKTSZ;
forward->sentto->pktsz_reduced = now;
prettyprint_addr(&forward->sentto->addr, daemon->addrbuff);
(void)prettyprint_addr(&forward->sentto->addr, daemon->addrbuff);
my_syslog(LOG_WARNING, _("reducing DNS packet size for nameserver %s to %d"), daemon->addrbuff, SAFE_PKTSZ);
}
@@ -1036,7 +1039,9 @@ void reply_query(int fd, int family, time_t now)
/* Find the original query that started it all.... */
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;
else
{
@@ -1279,8 +1284,9 @@ void receive_query(struct listener *listen, time_t now)
CMSG_SPACE(sizeof(struct sockaddr_dl))];
#endif
} control_u;
int family = listen->addr.sa.sa_family;
/* Can always get recvd interface for IPv6 */
int check_dst = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
int check_dst = !option_bool(OPT_NOWILD) || family == AF_INET6;
/* packet buffer overwritten */
daemon->srv_save = NULL;
@@ -1292,7 +1298,7 @@ void receive_query(struct listener *listen, time_t now)
{
auth_dns = listen->iface->dns_auth;
if (listen->family == AF_INET)
if (family == AF_INET)
{
dst_addr_4 = dst_addr.addr4 = listen->iface->addr.in.sin_addr;
netmask = listen->iface->netmask;
@@ -1322,9 +1328,9 @@ void receive_query(struct listener *listen, time_t now)
information disclosure. */
memset(daemon->packet + n, 0, daemon->edns_pktsz - n);
source_addr.sa.sa_family = listen->family;
source_addr.sa.sa_family = family;
if (listen->family == AF_INET)
if (family == AF_INET)
{
/* Source-port == 0 is an error, we can't send back to that.
http://www.ietf.org/mail-archive/web/dnsop/current/msg11441.html */
@@ -1344,7 +1350,7 @@ void receive_query(struct listener *listen, time_t now)
{
struct addrlist *addr;
if (listen->family == AF_INET6)
if (family == AF_INET6)
{
for (addr = daemon->interface_addrs; addr; addr = addr->next)
if ((addr->flags & ADDRLIST_IPV6) &&
@@ -1382,7 +1388,7 @@ void receive_query(struct listener *listen, time_t now)
return;
#if defined(HAVE_LINUX_NETWORK)
if (listen->family == AF_INET)
if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
{
@@ -1395,7 +1401,7 @@ void receive_query(struct listener *listen, time_t now)
if_index = p.p->ipi_ifindex;
}
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
if (listen->family == AF_INET)
if (family == AF_INET)
{
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
{
@@ -1420,7 +1426,7 @@ void receive_query(struct listener *listen, time_t now)
}
#endif
if (listen->family == AF_INET6)
if (family == AF_INET6)
{
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
@@ -1441,16 +1447,16 @@ void receive_query(struct listener *listen, time_t now)
if (!indextoname(listen->fd, if_index, ifr.ifr_name))
return;
if (!iface_check(listen->family, &dst_addr, ifr.ifr_name, &auth_dns))
if (!iface_check(family, &dst_addr, ifr.ifr_name, &auth_dns))
{
if (!option_bool(OPT_CLEVERBIND))
enumerate_interfaces(0);
if (!loopback_exception(listen->fd, listen->family, &dst_addr, ifr.ifr_name) &&
!label_exception(if_index, listen->family, &dst_addr))
if (!loopback_exception(listen->fd, family, &dst_addr, ifr.ifr_name) &&
!label_exception(if_index, family, &dst_addr))
return;
}
if (listen->family == AF_INET && option_bool(OPT_LOCALISE))
if (family == AF_INET && option_bool(OPT_LOCALISE))
{
struct irec *iface;
@@ -1495,7 +1501,7 @@ void receive_query(struct listener *listen, time_t now)
#endif
char *types = querystr(auth_dns ? "auth" : "query", type);
if (listen->family == AF_INET)
if (family == AF_INET)
log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
(union all_addr *)&source_addr.in.sin_addr, types);
else
@@ -2248,9 +2254,10 @@ static void free_frec(struct frec *f)
else return *wait zero if one available, or *wait is delay to
when the oldest in-use record will expire. Impose an absolute
limit of 4*TIMEOUT before we wipe things (for random sockets).
If force is set, always return a result, even if we have
to allocate above the limit. */
struct frec *get_new_frec(time_t now, int *wait, int force)
If force is non-NULL, always return a result, even if we have
to allocate above the limit, and never free the record pointed
to by the force argument. */
struct frec *get_new_frec(time_t now, int *wait, struct frec *force)
{
struct frec *f, *oldest, *target;
int count;
@@ -2267,7 +2274,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
dangling references to them. They'll go when their "real" query
is freed. */
if (!f->dependent)
if (!f->dependent && f != force)
#endif
{
if (difftime(now, f->time) >= 4*TIMEOUT)
+1 -16
View File
@@ -22,9 +22,7 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/utsname.h>
#include <arpa/inet.h>
#include <linux/version.h>
#include <linux/netlink.h>
/* 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)
{
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, ".");
version = version * 256 + (split ? atoi(split) : 0);
old_kernel = (version < KERNEL_VERSION(2,6,32));
old_kernel = (daemon->kernel_version < KERNEL_VERSION(2,6,32));
if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1)
return;
+19 -2
View File
@@ -22,6 +22,15 @@
#include <linux/netlink.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. */
#ifndef IFA_RTA
# define IFA_RTA(r) \
@@ -40,10 +49,11 @@ static u32 netlink_pid;
static void nl_async(struct nlmsghdr *h);
void netlink_init(void)
char *netlink_init(void)
{
struct sockaddr_nl addr;
socklen_t slen = sizeof(addr);
int opt = 1;
addr.nl_family = AF_NETLINK;
addr.nl_pad = 0;
@@ -74,12 +84,19 @@ void netlink_init(void)
if (daemon->netlinkfd == -1 ||
getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == -1)
die(_("cannot create netlink socket: %s"), NULL, EC_MISC);
/* save pid assigned by bind() and retrieved by getsockname() */
netlink_pid = addr.nl_pid;
iov.iov_len = 100;
iov.iov_base = safe_malloc(iov.iov_len);
if (daemon->kernel_version >= KERNEL_VERSION(2,6,30) &&
setsockopt(daemon->netlinkfd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, sizeof(opt)) == -1)
return _("warning: failed to set NETLINK_NO_ENOBUFS on netlink socket");
return NULL;
}
static ssize_t netlink_recv(void)
+133 -26
View File
@@ -388,10 +388,11 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
/* check whether the interface IP has been added already
we call this routine multiple times. */
for (iface = daemon->interfaces; iface; iface = iface->next)
if (sockaddr_isequal(&iface->addr, addr))
if (sockaddr_isequal(&iface->addr, addr) && iface->index == if_index)
{
iface->dad = !!(iface_flags & IFACE_TENTATIVE);
iface->found = 1; /* for garbage collection */
iface->netmask = netmask;
return 1;
}
@@ -532,7 +533,82 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, prefix, 0);
}
/*
* Clean old interfaces no longer found.
*/
static void clean_interfaces()
{
struct irec *iface;
struct irec **up = &daemon->interfaces;
for (iface = *up; iface; iface = *up)
{
if (!iface->found && !iface->done)
{
*up = iface->next;
free(iface->name);
free(iface);
}
else
{
up = &iface->next;
}
}
}
/** Release listener if no other interface needs it.
*
* @return 1 if released, 0 if still required
*/
static int release_listener(struct listener *l)
{
if (l->used > 1)
{
struct irec *iface;
for (iface = daemon->interfaces; iface; iface = iface->next)
if (iface->done && sockaddr_isequal(&l->addr, &iface->addr))
{
if (iface->found)
{
/* update listener to point to active interface instead */
if (!l->iface->found)
l->iface = iface;
}
else
{
l->used--;
iface->done = 0;
}
}
/* Someone is still using this listener, skip its deletion */
if (l->used > 0)
return 0;
}
if (l->iface->done)
{
int port;
port = prettyprint_addr(&l->iface->addr, daemon->addrbuff);
my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s port %d"),
l->iface->name, l->iface->index, daemon->addrbuff, port);
/* In case it ever returns */
l->iface->done = 0;
}
if (l->fd != -1)
close(l->fd);
if (l->tcpfd != -1)
close(l->tcpfd);
if (l->tftpfd != -1)
close(l->tftpfd);
free(l);
return 1;
}
int enumerate_interfaces(int reset)
{
static struct addrlist *spare = NULL;
@@ -630,6 +706,7 @@ int enumerate_interfaces(int reset)
in OPT_CLEVERBIND mode, that at listener will just disappear after
a call to enumerate_interfaces, this is checked OK on all calls. */
struct listener *l, *tmp, **up;
int freed = 0;
for (up = &daemon->listeners, l = daemon->listeners; l; l = tmp)
{
@@ -637,25 +714,17 @@ int enumerate_interfaces(int reset)
if (!l->iface || l->iface->found)
up = &l->next;
else
else if (release_listener(l))
{
*up = l->next;
/* In case it ever returns */
l->iface->done = 0;
if (l->fd != -1)
close(l->fd);
if (l->tcpfd != -1)
close(l->tcpfd);
if (l->tftpfd != -1)
close(l->tftpfd);
free(l);
*up = tmp;
freed = 1;
}
}
if (freed)
clean_interfaces();
}
errno = errsave;
spare = param.spare;
@@ -785,6 +854,8 @@ int set_ipv6pktinfo(int fd)
/* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */
int tcp_interface(int fd, int af)
{
(void)fd; /* suppress potential unused warning */
(void)af; /* suppress potential unused warning */
int if_index = 0;
#ifdef HAVE_LINUX_NETWORK
@@ -893,10 +964,11 @@ static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, in
{
l = safe_malloc(sizeof(struct listener));
l->next = NULL;
l->family = addr->sa.sa_family;
l->fd = fd;
l->tcpfd = tcpfd;
l->tftpfd = tftpfd;
l->tftpfd = tftpfd;
l->addr = *addr;
l->used = 1;
l->iface = NULL;
}
@@ -935,20 +1007,48 @@ void create_wildcard_listeners(void)
daemon->listeners = l;
}
static struct listener *find_listener(union mysockaddr *addr)
{
struct listener *l;
for (l = daemon->listeners; l; l = l->next)
if (sockaddr_isequal(&l->addr, addr))
return l;
return NULL;
}
void create_bound_listeners(int dienow)
{
struct listener *new;
struct irec *iface;
struct iname *if_tmp;
struct listener *existing;
for (iface = daemon->interfaces; iface; iface = iface->next)
if (!iface->done && !iface->dad && iface->found &&
(new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
if (!iface->done && !iface->dad && iface->found)
{
new->iface = iface;
new->next = daemon->listeners;
daemon->listeners = new;
iface->done = 1;
existing = find_listener(&iface->addr);
if (existing)
{
iface->done = 1;
existing->used++; /* increase usage counter */
}
else if ((new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
{
new->iface = iface;
new->next = daemon->listeners;
daemon->listeners = new;
iface->done = 1;
/* Don't log the initial set of listen addresses created
at startup, since this is happening before the logging
system is initialised and the sign-on printed. */
if (!dienow)
{
int port = prettyprint_addr(&iface->addr, daemon->addrbuff);
my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s port %d"),
iface->name, iface->index, daemon->addrbuff, port);
}
}
}
/* Check for --listen-address options that haven't been used because there's
@@ -968,6 +1068,12 @@ void create_bound_listeners(int dienow)
{
new->next = daemon->listeners;
daemon->listeners = new;
if (!dienow)
{
int port = prettyprint_addr(&if_tmp->addr, daemon->addrbuff);
my_syslog(LOG_DEBUG, _("listening on %s port %d"), daemon->addrbuff, port);
}
}
}
@@ -1187,6 +1293,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind
#endif
}
(void)intname; /* suppress potential unused warning */
#if defined(SO_BINDTODEVICE)
if (intname[0] != 0 &&
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
@@ -1298,7 +1405,7 @@ void pre_allocate_sfds(void)
errno != 0 &&
option_bool(OPT_NOWILD))
{
prettyprint_addr(&srv->source_addr, daemon->namebuff);
(void)prettyprint_addr(&srv->source_addr, daemon->namebuff);
if (srv->interface[0] != 0)
{
strcat(daemon->namebuff, " ");
+37 -10
View File
@@ -238,7 +238,7 @@ static const struct myoption opts[] =
{ "caa-record", 1, 0 , LOPT_CAA },
{ "dns-rr", 1, 0, LOPT_RR },
{ "enable-dbus", 2, 0, '1' },
{ "enable-ubus", 0, 0, LOPT_UBUS },
{ "enable-ubus", 2, 0, LOPT_UBUS },
{ "bootp-dynamic", 2, 0, '3' },
{ "dhcp-mac", 1, 0, '4' },
{ "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_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 },
{ 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 },
{ '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 },
@@ -1225,7 +1225,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
}
else if (c == '.')
{
is_addr6 = is_dec = is_hex = 0;
is_dec = is_hex = 0;
dots++;
}
else if (c == '-')
@@ -1260,6 +1260,12 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
if (!found_colon)
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 */
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))
{
unsigned char *p = NULL, *newp, *end;
unsigned char *p = NULL, *q, *newp, *end;
int len = 0;
int header_size = (is6 && new->opt == OPTION6_NTP_SERVER) ? 4 : 0;
arg = comma;
comma = split(arg);
@@ -1532,7 +1539,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
if (!dom)
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)
{
@@ -1541,8 +1548,14 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
}
p = newp;
end = do_rfc1035_name(p + len, dom, NULL);
q = p + len;
end = do_rfc1035_name(q + header_size, dom, NULL);
*end++ = 0;
if (is6 && new->opt == OPTION6_NTP_SERVER)
{
PUTSHORT(NTP_SUBOPTION_SRV_FQDN, q);
PUTSHORT(end - q - 2, q);
}
len = end - p;
free(dom);
@@ -1868,7 +1881,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
else
daemon->dbus_name = DNSMASQ_SERVICE;
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 */
/* may be a filename */
if (strchr(arg, '/') || strcmp (arg, "-") == 0)
@@ -2970,7 +2991,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context));
memset (new, 0, sizeof(*new));
new->lease_time = DEFLEASE;
while(1)
{
@@ -3020,6 +3040,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (inet_pton(AF_INET, a[0], &new->start))
{
new->next = daemon->dhcp;
new->lease_time = DEFLEASE;
daemon->dhcp = new;
new->end = new->start;
if (strcmp(a[1], "static") == 0)
@@ -3067,6 +3088,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->flags |= CONTEXT_V6;
new->prefix = 64; /* default */
new->end6 = new->start6;
new->lease_time = DEFLEASE6;
new->next = daemon->dhcp6;
daemon->dhcp6 = new;
@@ -3166,7 +3188,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
if (strcmp(a[leasepos], "infinite") == 0)
new->lease_time = 0xffffffff;
{
new->lease_time = 0xffffffff;
new->flags |= CONTEXT_SETLEASE;
}
else if (strcmp(a[leasepos], "deprecated") == 0)
new->flags |= CONTEXT_DEPRECATE;
else
@@ -3205,6 +3230,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
ret_err_free(_("bad dhcp-range"), new);
new->lease_time = atoi(a[leasepos]) * fac;
new->flags |= CONTEXT_SETLEASE;
/* Leases of a minute or less confuse
some clients, notably Apple's */
if (new->lease_time < 120)
@@ -3212,6 +3238,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
}
}
break;
}
@@ -3309,7 +3336,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (!atoi_check(pref, &new_addr->prefixlen) ||
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);
ret_err(_("bad IPv6 prefix"));
+5 -2
View File
@@ -626,8 +626,11 @@ static int add_prefixes(struct in6_addr *local, int prefix,
real_prefix = context->prefix;
}
/* find floor time, don't reduce below 3 * RA interval. */
if (time > context->lease_time)
/* find floor time, don't reduce below 3 * RA interval.
If the lease time has been left as default, don't
use that as a floor. */
if ((context->flags & CONTEXT_SETLEASE) &&
time > context->lease_time)
{
time = context->lease_time;
if (time < ((unsigned int)(3 * param->adv_interval)))
+21 -7
View File
@@ -843,17 +843,31 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
if ((flags & F_IPV4) &&
private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
return 1;
if ((flags & F_IPV6) &&
IN6_IS_ADDR_V4MAPPED(&addr.addr6))
/* Block IPv4-mapped IPv6 addresses in private IPv4 address space */
if (flags & F_IPV6)
{
struct in_addr v4;
v4.s_addr = ((const uint32_t *) (&addr.addr6))[3];
if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
if (IN6_IS_ADDR_V4MAPPED(&addr.addr6))
{
struct in_addr v4;
v4.s_addr = ((const uint32_t *) (&addr.addr6))[3];
if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
return 1;
}
/* 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;
}
}
#ifdef HAVE_IPSET
if (ipsets && (flags & (F_IPV4 | F_IPV6)))
{
+22 -6
View File
@@ -1311,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++)
{
struct in6_addr *p = NULL;
if (IN6_IS_ADDR_UNSPECIFIED(a))
{
if (!add_local_addrs(state->context))
put_opt6(state->fallback, IN6ADDRSZ);
p = state->fallback;
}
else if (IN6_IS_ADDR_ULA_ZERO(a))
{
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))
{
if (!IN6_IS_ADDR_UNSPECIFIED(state->ll_addr))
put_opt6(state->ll_addr, IN6ADDRSZ);
p = state->ll_addr;
}
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);
@@ -1708,14 +1724,14 @@ static int config_valid(struct dhcp_config *config, struct dhcp_context *context
return 0;
for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
if (!(addr_list->flags && ADDRLIST_DECLINED) ||
if (!(addr_list->flags & ADDRLIST_DECLINED) ||
difftime(now, addr_list->decline_time) >= (float)DECLINE_BACKOFF)
{
addrpart = addr6part(&addr_list->addr.addr6);
addresses = 1;
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))
{
+18 -17
View File
@@ -61,8 +61,9 @@ void tftp_request(struct listener *listen, time_t now)
char *prefix = daemon->tftp_prefix;
struct tftp_prefix *pref;
union all_addr addra;
int family = listen->addr.sa.sa_family;
/* Can always get recvd interface for IPv6 */
int check_dest = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
int check_dest = !option_bool(OPT_NOWILD) || family == AF_INET6;
union {
struct cmsghdr align; /* this ensures alignment */
char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
@@ -121,10 +122,10 @@ void tftp_request(struct listener *listen, time_t now)
if (msg.msg_controllen < sizeof(struct cmsghdr))
return;
addr.sa.sa_family = listen->family;
addr.sa.sa_family = family;
#if defined(HAVE_LINUX_NETWORK)
if (listen->family == AF_INET)
if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
{
@@ -138,7 +139,7 @@ void tftp_request(struct listener *listen, time_t now)
}
#elif defined(HAVE_SOLARIS_NETWORK)
if (listen->family == AF_INET)
if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
{
union {
@@ -154,7 +155,7 @@ void tftp_request(struct listener *listen, time_t now)
}
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
if (listen->family == AF_INET)
if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
{
union {
@@ -171,7 +172,7 @@ void tftp_request(struct listener *listen, time_t now)
#endif
if (listen->family == AF_INET6)
if (family == AF_INET6)
{
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
@@ -194,7 +195,7 @@ void tftp_request(struct listener *listen, time_t now)
addra.addr4 = addr.in.sin_addr;
if (listen->family == AF_INET6)
if (family == AF_INET6)
addra.addr6 = addr.in6.sin6_addr;
if (daemon->tftp_interfaces)
@@ -210,12 +211,12 @@ void tftp_request(struct listener *listen, time_t now)
else
{
/* Do the same as DHCP */
if (!iface_check(listen->family, &addra, name, NULL))
if (!iface_check(family, &addra, name, NULL))
{
if (!option_bool(OPT_CLEVERBIND))
enumerate_interfaces(0);
if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) &&
!label_exception(if_index, listen->family, &addra))
if (!loopback_exception(listen->tftpfd, family, &addra, name) &&
!label_exception(if_index, family, &addra))
return;
}
@@ -281,7 +282,7 @@ void tftp_request(struct listener *listen, time_t now)
prefix = pref->prefix;
}
if (listen->family == AF_INET)
if (family == AF_INET)
{
addr.in.sin_port = htons(port);
#ifdef HAVE_SOCKADDR_SA_LEN
@@ -304,7 +305,7 @@ void tftp_request(struct listener *listen, time_t now)
if (option_bool(OPT_SINGLE_PORT))
transfer->sockfd = listen->tftpfd;
else if ((transfer->sockfd = socket(listen->family, SOCK_DGRAM, 0)) == -1)
else if ((transfer->sockfd = socket(family, SOCK_DGRAM, 0)) == -1)
{
free(transfer);
return;
@@ -322,7 +323,7 @@ void tftp_request(struct listener *listen, time_t now)
transfer->opt_blocksize = transfer->opt_transize = 0;
transfer->netascii = transfer->carrylf = 0;
prettyprint_addr(&peer, daemon->addrbuff);
(void)prettyprint_addr(&peer, daemon->addrbuff);
/* if we have a nailed-down range, iterate until we find a free one. */
while (!option_bool(OPT_SINGLE_PORT))
@@ -337,7 +338,7 @@ void tftp_request(struct listener *listen, time_t now)
{
if (++port <= daemon->end_tftp_port)
{
if (listen->family == AF_INET)
if (family == AF_INET)
addr.in.sin_port = htons(port);
else
addr.in6.sin6_port = htons(port);
@@ -375,7 +376,7 @@ void tftp_request(struct listener *listen, time_t now)
if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
{
/* 32 bytes for IP, UDP and TFTP headers, 52 bytes for IPv6 */
int overhead = (listen->family == AF_INET) ? 32 : 52;
int overhead = (family == AF_INET) ? 32 : 52;
transfer->blocksize = atoi(opt);
if (transfer->blocksize < 1)
transfer->blocksize = 1;
@@ -624,7 +625,7 @@ void check_tftp_listeners(time_t now)
{
strcpy(daemon->namebuff, transfer->file->filename);
sanitise(daemon->namebuff);
prettyprint_addr(&transfer->peer, daemon->addrbuff);
(void)prettyprint_addr(&transfer->peer, daemon->addrbuff);
my_syslog(MS_TFTP | LOG_INFO, endcon ? _("failed sending %s to %s") : _("sent %s to %s"), daemon->namebuff, daemon->addrbuff);
/* unlink */
*up = tmp;
@@ -667,7 +668,7 @@ static void handle_tftp(time_t now, struct tftp_transfer *transfer, ssize_t len)
char *end = daemon->packet + len;
char *err = next(&p, end);
prettyprint_addr(&transfer->peer, daemon->addrbuff);
(void)prettyprint_addr(&transfer->peer, daemon->addrbuff);
/* Sanitise error message */
if (!err)
+3 -1
View File
@@ -38,7 +38,7 @@ static struct ubus_object_type ubus_object_type =
UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);
static struct ubus_object ubus_object = {
.name = "dnsmasq",
.name = NULL,
.type = &ubus_object_type,
.methods = ubus_object_methods,
.n_methods = ARRAY_SIZE(ubus_object_methods),
@@ -94,6 +94,7 @@ void ubus_init()
return;
}
ubus_object.name = daemon->ubus_name;
ret = ubus_add_object(ubus, &ubus_object);
if (ret)
{
@@ -102,6 +103,7 @@ void ubus_init()
my_syslog(LOG_ERR, _("Cannot add object to UBus: %s"), ubus_strerror(ret));
error_logged = 1;
}
ubus_destroy(ubus);
return;
}
+23
View File
@@ -30,6 +30,10 @@
#include <idna.h>
#endif
#ifdef HAVE_LINUX_NETWORK
#include <sys/utsname.h>
#endif
/* SURF random number generator */
static u32 seed[32];
@@ -782,3 +786,22 @@ int wildcard_matchn(const char* wildcard, const char* match, int num)
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)
# 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