mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-04 13:48:30 +00:00
Compare commits
26
Commits
v2.81rc4
...
v2.82test1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab5ebe9507 | ||
|
|
837e8f4eb5 | ||
|
|
e2cb655958 | ||
|
|
8270648da1 | ||
|
|
619000a3c5 | ||
|
|
1c1b925052 | ||
|
|
49bdf1ead9 | ||
|
|
60a3ae19c5 | ||
|
|
951a22165c | ||
|
|
51cdd1a227 | ||
|
|
66adee85be | ||
|
|
4890bcdea2 | ||
|
|
8baf583a3f | ||
|
|
913fa15fb1 | ||
|
|
00fe2f49e0 | ||
|
|
ec2067df75 | ||
|
|
7ddb99d251 | ||
|
|
ba26d3485b | ||
|
|
081a1c4014 | ||
|
|
532246fc9e | ||
|
|
8caf3d7c6c | ||
|
|
d162bee356 | ||
|
|
b43585c34b | ||
|
|
3f60ecd6f0 | ||
|
|
0506a5ed4e | ||
|
|
e7ee1aa093 |
No files matched your search
@@ -1,12 +1,12 @@
|
||||
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
|
||||
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 +35,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 +66,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.
|
||||
|
||||
|
||||
Vendored
+26
-1
@@ -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
|
||||
|
||||
|
||||
Vendored
+3
-2
@@ -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
|
||||
|
||||
Vendored
+17
-10
@@ -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
|
||||
|
||||
+39
-27
@@ -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
|
||||
@@ -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
|
||||
|
||||
+13
-9
@@ -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)
|
||||
|
||||
@@ -50,6 +50,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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+12
-3
@@ -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)
|
||||
|
||||
+41
-33
@@ -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,31 +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;
|
||||
(void)a; /* suppress potential unused warning */
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1911,16 +1919,16 @@ static void check_dns_listeners(time_t now)
|
||||
terminate the process. */
|
||||
if (!option_bool(OPT_DEBUG))
|
||||
{
|
||||
char a = 0;
|
||||
(void)a; /* suppress potential unused warning */
|
||||
#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. */
|
||||
@@ -1947,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);
|
||||
}
|
||||
@@ -2108,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 */
|
||||
+10
-4
@@ -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;
|
||||
};
|
||||
@@ -1062,6 +1064,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 +1111,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 +1291,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 +1325,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 +1451,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
|
||||
|
||||
|
||||
+1
-1
@@ -1003,7 +1003,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;
|
||||
|
||||
+25
-21
@@ -348,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)
|
||||
@@ -676,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;
|
||||
@@ -960,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);
|
||||
}
|
||||
|
||||
@@ -1039,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
|
||||
{
|
||||
@@ -1282,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;
|
||||
@@ -1295,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;
|
||||
@@ -1325,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 */
|
||||
@@ -1347,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) &&
|
||||
@@ -1385,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)
|
||||
{
|
||||
@@ -1398,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))
|
||||
{
|
||||
@@ -1423,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)
|
||||
@@ -1444,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;
|
||||
|
||||
@@ -1498,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
|
||||
@@ -2251,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;
|
||||
@@ -2270,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
@@ -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;
|
||||
|
||||
+12
-3
@@ -27,6 +27,9 @@
|
||||
#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
|
||||
@@ -46,7 +49,7 @@ 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);
|
||||
@@ -79,15 +82,21 @@ void netlink_init(void)
|
||||
}
|
||||
|
||||
if (daemon->netlinkfd == -1 ||
|
||||
setsockopt(daemon->netlinkfd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, sizeof(opt)) == -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)
|
||||
|
||||
+130
-26
@@ -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;
|
||||
|
||||
@@ -895,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;
|
||||
}
|
||||
|
||||
@@ -937,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
|
||||
@@ -970,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1301,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, " ");
|
||||
|
||||
+12
-4
@@ -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 == '-')
|
||||
@@ -1881,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)
|
||||
|
||||
+21
-7
@@ -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)))
|
||||
{
|
||||
|
||||
+18
-17
@@ -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
@@ -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
@@ -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
|
||||
Reference in new issue
Block a user