dnsmasq: rewrite config on host name modification

This commit is contained in:
coolsnowwolf 2017-12-28 14:15:44 +08:00
parent d1a4dbb0a5
commit 84bc8c0a5c
4 changed files with 80 additions and 29 deletions

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmasq PKG_NAME:=dnsmasq
PKG_VERSION:=2.78 PKG_VERSION:=2.78
PKG_RELEASE:=2 PKG_RELEASE:=7
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/ PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/
@ -17,12 +17,14 @@ PKG_HASH:=89949f438c74b0c7543f06689c319484bd126cc4b1f8c745c742ab397681252b
PKG_LICENSE:=GPL-2.0 PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING PKG_LICENSE_FILES:=COPYING
PKG_CPE_ID:=cpe:/a:thekelleys:dnsmasq
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL:=1 PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1 PKG_BUILD_PARALLEL:=1
PKG_CONFIG_DEPENDS:=CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcpv6 \ PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcp \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcpv6 \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dnssec \ CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dnssec \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_auth \ CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_auth \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset \ CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset \
@ -75,8 +77,8 @@ endef
define Package/dnsmasq-full/description define Package/dnsmasq-full/description
$(call Package/dnsmasq/description) $(call Package/dnsmasq/description)
This is a fully configurable variant with DHCPv6, DNSSEC, Authoritative DNS and This is a fully configurable variant with DHCPv4, DHCPv6, DNSSEC, Authoritative DNS
IPset, Conntrack support & NO_ID enabled by default. and IPset, Conntrack support & NO_ID enabled by default.
endef endef
define Package/dnsmasq/conffiles define Package/dnsmasq/conffiles
@ -86,9 +88,12 @@ endef
define Package/dnsmasq-full/config define Package/dnsmasq-full/config
if PACKAGE_dnsmasq-full if PACKAGE_dnsmasq-full
config PACKAGE_dnsmasq_full_dhcp
bool "Build with DHCP support."
default y
config PACKAGE_dnsmasq_full_dhcpv6 config PACKAGE_dnsmasq_full_dhcpv6
bool "Build with DHCPv6 support." bool "Build with DHCPv6 support."
depends on IPV6 depends on IPV6 && PACKAGE_dnsmasq_full_dhcp
default n default n
config PACKAGE_dnsmasq_full_dnssec config PACKAGE_dnsmasq_full_dnssec
bool "Build with DNSSEC support." bool "Build with DNSSEC support."
@ -124,7 +129,8 @@ ifeq ($(BUILD_VARIANT),nodhcpv6)
endif endif
ifeq ($(BUILD_VARIANT),full) ifeq ($(BUILD_VARIANT),full)
COPTS += $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcpv6),,-DNO_DHCP6) \ COPTS += $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcp),,-DNO_DHCP) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcpv6),,-DNO_DHCP6) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dnssec),-DHAVE_DNSSEC) \ $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dnssec),-DHAVE_DNSSEC) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_auth),,-DNO_AUTH) \ $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_auth),,-DNO_AUTH) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset),,-DNO_IPSET) \ $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset),,-DNO_IPSET) \

View File

@ -13,7 +13,6 @@ ADD_LOCAL_FQDN=""
BASECONFIGFILE="/var/etc/dnsmasq.conf" BASECONFIGFILE="/var/etc/dnsmasq.conf"
BASEHOSTFILE="/tmp/hosts/dhcp" BASEHOSTFILE="/tmp/hosts/dhcp"
BASETIMESTAMPFILE="/etc/dnsmasq.time"
TRUSTANCHORSFILE="/usr/share/dnsmasq/trust-anchors.conf" TRUSTANCHORSFILE="/usr/share/dnsmasq/trust-anchors.conf"
TIMEVALIDFILE="/var/state/dnsmasqsec" TIMEVALIDFILE="/var/state/dnsmasqsec"
BASEDHCPSTAMPFILE="/var/run/dnsmasq" BASEDHCPSTAMPFILE="/var/run/dnsmasq"
@ -295,7 +294,7 @@ dhcp_host_add() {
config_get_bool dns "$cfg" dns 0 config_get_bool dns "$cfg" dns 0
[ "$dns" = "1" -a -n "$ip" -a -n "$name" ] && { [ "$dns" = "1" -a -n "$ip" -a -n "$name" ] && {
echo "$ip $name${DOMAIN:+.$DOMAIN}" >> $HOSTFILE echo "$ip $name${DOMAIN:+.$DOMAIN}" >> $HOSTFILE_TMP
} }
config_get mac "$cfg" mac config_get mac "$cfg" mac
@ -636,7 +635,7 @@ dhcp_domain_add() {
record="${record:+$record }$name" record="${record:+$record }$name"
done done
echo "$ip $record" >> $HOSTFILE echo "$ip $record" >> $HOSTFILE_TMP
} }
dhcp_srv_add() { dhcp_srv_add() {
@ -742,7 +741,7 @@ dnsmasq_start()
CONFIGFILE="${BASECONFIGFILE}.${cfg}" CONFIGFILE="${BASECONFIGFILE}.${cfg}"
CONFIGFILE_TMP="${CONFIGFILE}.$$" CONFIGFILE_TMP="${CONFIGFILE}.$$"
HOSTFILE="${BASEHOSTFILE}.${cfg}" HOSTFILE="${BASEHOSTFILE}.${cfg}"
TIMESTAMPFILE="${BASETIMESTAMPFILE}.${cfg}" HOSTFILE_TMP="${HOSTFILE}.$$"
BASEDHCPSTAMPFILE_CFG="${BASEDHCPSTAMPFILE}.${cfg}" BASEDHCPSTAMPFILE_CFG="${BASEDHCPSTAMPFILE}.${cfg}"
# before we can call xappend # before we can call xappend
@ -752,14 +751,17 @@ dnsmasq_start()
mkdir -p /var/lib/misc mkdir -p /var/lib/misc
chown dnsmasq:dnsmasq /var/run/dnsmasq chown dnsmasq:dnsmasq /var/run/dnsmasq
[ -f "$TIMESTAMPFILE" ] && rm -f "$TIMESTAMPFILE"
echo "# auto-generated config file from /etc/config/dhcp" > $CONFIGFILE_TMP echo "# auto-generated config file from /etc/config/dhcp" > $CONFIGFILE_TMP
echo "# auto-generated config file from /etc/config/dhcp" > $HOSTFILE echo "# auto-generated config file from /etc/config/dhcp" > $HOSTFILE_TMP
local dnsmasqconffile="/etc/dnsmasq.${cfg}.conf"
if [ ! -r "$dnsmasqconffile" ]; then
dnsmasqconffile=/etc/dnsmasq.conf
fi
# if we did this last, we could override auto-generated config # if we did this last, we could override auto-generated config
[ -f /etc/dnsmasq.conf ] && { [ -f "${dnsmasqconffile}" ] && {
xappend "--conf-file=/etc/dnsmasq.conf" xappend "--conf-file=${dnsmasqconffile}"
} }
$PROG --version | grep -osqE "^Compile time options:.* DHCPv6( |$)" && DHCPv6CAPABLE=1 || DHCPv6CAPABLE=0 $PROG --version | grep -osqE "^Compile time options:.* DHCPv6( |$)" && DHCPv6CAPABLE=1 || DHCPv6CAPABLE=0
@ -997,6 +999,7 @@ dnsmasq_start()
echo >> $CONFIGFILE_TMP echo >> $CONFIGFILE_TMP
mv -f $CONFIGFILE_TMP $CONFIGFILE mv -f $CONFIGFILE_TMP $CONFIGFILE
mv -f $HOSTFILE_TMP $HOSTFILE
[ "$resolvfile" = "/tmp/resolv.conf.auto" ] && { [ "$resolvfile" = "/tmp/resolv.conf.auto" ] && {
rm -f /tmp/resolv.conf rm -f /tmp/resolv.conf
@ -1015,11 +1018,6 @@ dnsmasq_start()
[ -n "$user_dhcpscript" ] && procd_set_param env USER_DHCPSCRIPT="$user_dhcpscript" [ -n "$user_dhcpscript" ] && procd_set_param env USER_DHCPSCRIPT="$user_dhcpscript"
procd_set_param respawn procd_set_param respawn
local dnsmasqconffile="/etc/dnsmasq.${cfg}.conf"
if [ ! -r "$dnsmasqconffile" ]; then
dnsmasqconffile=/etc/dnsmasq.conf
fi
procd_add_jail dnsmasq ubus log procd_add_jail dnsmasq ubus log
procd_add_jail_mount $CONFIGFILE $TRUSTANCHORSFILE $HOSTFILE $RFC6761FILE /etc/passwd /etc/group /etc/TZ /dev/null /dev/urandom $dnsmasqconffile $dnsmasqconfdir $resolvfile $user_dhcpscript /etc/hosts /etc/ethers /sbin/hotplug-call $EXTRA_MOUNT $DHCPSCRIPT procd_add_jail_mount $CONFIGFILE $TRUSTANCHORSFILE $HOSTFILE $RFC6761FILE /etc/passwd /etc/group /etc/TZ /dev/null /dev/urandom $dnsmasqconffile $dnsmasqconfdir $resolvfile $user_dhcpscript /etc/hosts /etc/ethers /sbin/hotplug-call $EXTRA_MOUNT $DHCPSCRIPT
procd_add_jail_mount_rw /var/run/dnsmasq/ $leasefile procd_add_jail_mount_rw /var/run/dnsmasq/ $leasefile
@ -1046,7 +1044,7 @@ dnsmasq_stop()
service_triggers() service_triggers()
{ {
procd_add_reload_trigger "dhcp" procd_add_reload_trigger "dhcp" "system"
procd_add_raw_trigger "interface.*" 2000 /etc/init.d/dnsmasq reload procd_add_raw_trigger "interface.*" 2000 /etc/init.d/dnsmasq reload
} }
@ -1086,7 +1084,7 @@ start_service() {
reload_service() { reload_service() {
rc_procd start_service "$@" rc_procd start_service "$@"
return 0 procd_send_signal dnsmasq "$@"
} }
stop_service() { stop_service() {

View File

@ -9,7 +9,7 @@
struct daemon *daemon; struct daemon *daemon;
static volatile pid_t pid = 0; static volatile pid_t pid = 0;
@@ -32,6 +34,62 @@ static void fatal_event(struct event_des @@ -32,6 +34,64 @@ static void fatal_event(struct event_des
static int read_event(int fd, struct event_desc *evp, char **msg); static int read_event(int fd, struct event_desc *evp, char **msg);
static void poll_resolv(int force, int do_reload, time_t now); static void poll_resolv(int force, int do_reload, time_t now);
@ -25,7 +25,7 @@
+ .type = &ubus_object_type, + .type = &ubus_object_type,
+}; +};
+ +
+void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name) +void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
+{ +{
+ if (!ubus || !ubus_object.has_subscribers) + if (!ubus || !ubus_object.has_subscribers)
+ return; + return;
@ -37,6 +37,8 @@
+ blobmsg_add_string(&b, "ip", ip); + blobmsg_add_string(&b, "ip", ip);
+ if (name) + if (name)
+ blobmsg_add_string(&b, "name", name); + blobmsg_add_string(&b, "name", name);
+ if (interface)
+ blobmsg_add_string(&b, "interface", interface);
+ ubus_notify(ubus, &ubus_object, type, b.head, -1); + ubus_notify(ubus, &ubus_object, type, b.head, -1);
+} +}
+ +
@ -72,7 +74,7 @@
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
int bind_fallback = 0; int bind_fallback = 0;
@@ -911,6 +969,7 @@ int main (int argc, char **argv) @@ -911,6 +971,7 @@ int main (int argc, char **argv)
set_dbus_listeners(); set_dbus_listeners();
#endif #endif
@ -80,7 +82,7 @@
#ifdef HAVE_DHCP #ifdef HAVE_DHCP
if (daemon->dhcp || daemon->relay4) if (daemon->dhcp || daemon->relay4)
{ {
@@ -1041,6 +1100,8 @@ int main (int argc, char **argv) @@ -1041,6 +1102,8 @@ int main (int argc, char **argv)
check_dbus_listeners(); check_dbus_listeners();
#endif #endif
@ -106,7 +108,7 @@
# endif # endif
#endif #endif
+void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name); +void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface);
+ +
/* ipset.c */ /* ipset.c */
#ifdef HAVE_IPSET #ifdef HAVE_IPSET
@ -118,9 +120,9 @@
string ? string : "", string ? string : "",
err ? err : ""); err ? err : "");
+ if (!strcmp(type, "DHCPACK")) + if (!strcmp(type, "DHCPACK"))
+ ubus_event_bcast("dhcp.ack", addr ? inet_ntoa(a) : NULL, daemon->namebuff, string ? string : NULL); + ubus_event_bcast("dhcp.ack", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface);
+ else if (!strcmp(type, "DHCPRELEASE")) + else if (!strcmp(type, "DHCPRELEASE"))
+ ubus_event_bcast("dhcp.release", addr ? inet_ntoa(a) : NULL, daemon->namebuff, string ? string : NULL); + ubus_event_bcast("dhcp.release", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface);
} }
static void log_options(unsigned char *start, u32 xid) static void log_options(unsigned char *start, u32 xid)

View File

@ -0,0 +1,45 @@
From ef3d137a646fa8309e1ff5184e3e145eef40cc4d Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Tue, 5 Dec 2017 22:37:29 +0000
Subject: [PATCH] Fix infinite retries in strict-order mode.
If all configured dns servers return refused in
response to a query; dnsmasq will end up in an infinite loop
retransmitting the dns query resulting into high CPU load.
Problem is caused by the dns refuse retransmission logic which does
not check for the end of a dns server list iteration in strict mode.
Having one configured dns server returning a refused reply easily
triggers this problem in strict order mode. This was introduced in
9396752c115b3ab733fa476b30da73237e12e7ba
Thanks to Hans Dedecker <dedeckeh@gmail.com> for spotting this
and the initial patch.
---
src/forward.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
--- a/src/forward.c
+++ b/src/forward.c
@@ -797,10 +797,20 @@ void reply_query(int fd, int family, tim
unsigned char *pheader;
size_t plen;
int is_sign;
-
+
+ /* In strict order mode, there must be a server later in the chain
+ left to send to, otherwise without the forwardall mechanism,
+ code further on will cycle around the list forwever if they
+ all return REFUSED. Note that server is always non-NULL before
+ this executes. */
+ if (option_bool(OPT_ORDER))
+ for (server = forward->sentto->next; server; server = server->next)
+ if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR | SERV_LOOP)))
+ break;
+
/* recreate query from reply */
pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign, NULL);
- if (!is_sign)
+ if (!is_sign && server)
{
header->ancount = htons(0);
header->nscount = htons(0);