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_VERSION:=2.78
PKG_RELEASE:=2
PKG_RELEASE:=7
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/
@ -17,12 +17,14 @@ PKG_HASH:=89949f438c74b0c7543f06689c319484bd126cc4b1f8c745c742ab397681252b
PKG_LICENSE:=GPL-2.0
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_INSTALL:=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)_auth \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset \
@ -75,8 +77,8 @@ endef
define Package/dnsmasq-full/description
$(call Package/dnsmasq/description)
This is a fully configurable variant with DHCPv6, DNSSEC, Authoritative DNS and
IPset, Conntrack support & NO_ID enabled by default.
This is a fully configurable variant with DHCPv4, DHCPv6, DNSSEC, Authoritative DNS
and IPset, Conntrack support & NO_ID enabled by default.
endef
define Package/dnsmasq/conffiles
@ -86,9 +88,12 @@ endef
define Package/dnsmasq-full/config
if PACKAGE_dnsmasq-full
config PACKAGE_dnsmasq_full_dhcp
bool "Build with DHCP support."
default y
config PACKAGE_dnsmasq_full_dhcpv6
bool "Build with DHCPv6 support."
depends on IPV6
depends on IPV6 && PACKAGE_dnsmasq_full_dhcp
default n
config PACKAGE_dnsmasq_full_dnssec
bool "Build with DNSSEC support."
@ -124,7 +129,8 @@ ifeq ($(BUILD_VARIANT),nodhcpv6)
endif
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)_auth),,-DNO_AUTH) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset),,-DNO_IPSET) \

View File

@ -13,7 +13,6 @@ ADD_LOCAL_FQDN=""
BASECONFIGFILE="/var/etc/dnsmasq.conf"
BASEHOSTFILE="/tmp/hosts/dhcp"
BASETIMESTAMPFILE="/etc/dnsmasq.time"
TRUSTANCHORSFILE="/usr/share/dnsmasq/trust-anchors.conf"
TIMEVALIDFILE="/var/state/dnsmasqsec"
BASEDHCPSTAMPFILE="/var/run/dnsmasq"
@ -295,7 +294,7 @@ dhcp_host_add() {
config_get_bool dns "$cfg" dns 0
[ "$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
@ -636,7 +635,7 @@ dhcp_domain_add() {
record="${record:+$record }$name"
done
echo "$ip $record" >> $HOSTFILE
echo "$ip $record" >> $HOSTFILE_TMP
}
dhcp_srv_add() {
@ -742,7 +741,7 @@ dnsmasq_start()
CONFIGFILE="${BASECONFIGFILE}.${cfg}"
CONFIGFILE_TMP="${CONFIGFILE}.$$"
HOSTFILE="${BASEHOSTFILE}.${cfg}"
TIMESTAMPFILE="${BASETIMESTAMPFILE}.${cfg}"
HOSTFILE_TMP="${HOSTFILE}.$$"
BASEDHCPSTAMPFILE_CFG="${BASEDHCPSTAMPFILE}.${cfg}"
# before we can call xappend
@ -752,14 +751,17 @@ dnsmasq_start()
mkdir -p /var/lib/misc
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" > $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
[ -f /etc/dnsmasq.conf ] && {
xappend "--conf-file=/etc/dnsmasq.conf"
[ -f "${dnsmasqconffile}" ] && {
xappend "--conf-file=${dnsmasqconffile}"
}
$PROG --version | grep -osqE "^Compile time options:.* DHCPv6( |$)" && DHCPv6CAPABLE=1 || DHCPv6CAPABLE=0
@ -997,6 +999,7 @@ dnsmasq_start()
echo >> $CONFIGFILE_TMP
mv -f $CONFIGFILE_TMP $CONFIGFILE
mv -f $HOSTFILE_TMP $HOSTFILE
[ "$resolvfile" = "/tmp/resolv.conf.auto" ] && {
rm -f /tmp/resolv.conf
@ -1015,11 +1018,6 @@ dnsmasq_start()
[ -n "$user_dhcpscript" ] && procd_set_param env USER_DHCPSCRIPT="$user_dhcpscript"
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_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
@ -1046,7 +1044,7 @@ dnsmasq_stop()
service_triggers()
{
procd_add_reload_trigger "dhcp"
procd_add_reload_trigger "dhcp" "system"
procd_add_raw_trigger "interface.*" 2000 /etc/init.d/dnsmasq reload
}
@ -1086,7 +1084,7 @@ start_service() {
reload_service() {
rc_procd start_service "$@"
return 0
procd_send_signal dnsmasq "$@"
}
stop_service() {

View File

@ -9,7 +9,7 @@
struct daemon *daemon;
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 void poll_resolv(int force, int do_reload, time_t now);
@ -25,7 +25,7 @@
+ .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)
+ return;
@ -37,6 +37,8 @@
+ blobmsg_add_string(&b, "ip", ip);
+ if (name)
+ blobmsg_add_string(&b, "name", name);
+ if (interface)
+ blobmsg_add_string(&b, "interface", interface);
+ ubus_notify(ubus, &ubus_object, type, b.head, -1);
+}
+
@ -72,7 +74,7 @@
int main (int argc, char **argv)
{
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();
#endif
@ -80,7 +82,7 @@
#ifdef HAVE_DHCP
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();
#endif
@ -106,7 +108,7 @@
# 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 */
#ifdef HAVE_IPSET
@ -118,9 +120,9 @@
string ? string : "",
err ? err : "");
+ 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"))
+ 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)

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);