From 2f9a51ca0d95eedc13ccabc017ce5a5b869c760b Mon Sep 17 00:00:00 2001
From: Paul Oranje <por@xs4all.nl>
Date: Tue, 20 Jun 2017 10:15:24 +0200
Subject: [PATCH] unbound: manage resolv.conf iff when listening on
 127.0.0.1#53

With this patch the unbound init routines manage resolv.conf if and only if
when unbound will listen on 127.0.0.1#53 and dnsmasq is not.

Also logs some cases where config values are overriden with sane defaults.

Fixes (partially) LEDE FS#785
Fixes LEDE FS#4487

Signed-off-by: Paul Oranje <por@xs4all.nl>
---
 net/unbound/Makefile         |  2 +-
 net/unbound/files/dnsmasq.sh |  2 +-
 net/unbound/files/unbound.sh | 93 +++++++++++++++++++++++++-------------------
 3 files changed, 54 insertions(+), 43 deletions(-)

diff --git a/net/unbound/Makefile b/net/unbound/Makefile
index d8db017a..8177fb63 100644
--- a/net/unbound/Makefile
+++ b/net/unbound/Makefile
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=unbound
 PKG_VERSION:=1.6.1
-PKG_RELEASE:=6
+PKG_RELEASE:=7
 
 PKG_LICENSE:=BSD-3-Clause
 PKG_LICENSE_FILES:=LICENSE
diff --git a/net/unbound/files/dnsmasq.sh b/net/unbound/files/dnsmasq.sh
index 07920861..ee58543a 100644
--- a/net/unbound/files/dnsmasq.sh
+++ b/net/unbound/files/dnsmasq.sh
@@ -38,7 +38,7 @@ dnsmasq_local_zone() {
   fi
 
 
-  if [ -n "$fwd_domain" -a -n "$fwd_port" -a ! "$fwd_port" -eq 53 ] ; then
+  if [ -n "$fwd_domain" -a -n "$fwd_port" -a ! "${fwd_port:-53}" -eq 53 ] ; then
     # dnsmasq localhost listening ports (possible multiple instances)
     UNBOUND_N_FWD_PORTS="$UNBOUND_N_FWD_PORTS $fwd_port"
     UNBOUND_TXT_FWD_ZONE="$UNBOUND_TXT_FWD_ZONE $fwd_domain"
diff --git a/net/unbound/files/unbound.sh b/net/unbound/files/unbound.sh
index 4daefda4..e677ddd6 100644
--- a/net/unbound/files/unbound.sh
+++ b/net/unbound/files/unbound.sh
@@ -256,32 +256,11 @@ create_domain_insecure() {
 ##############################################################################
 
 unbound_mkdir() {
-  local resolvsym=0
   local dhcp_origin=$( uci get dhcp.@odhcpd[0].leasefile )
   local dhcp_dir=$( dirname "$dhcp_origin" )
   local filestuff
 
 
-  if [ ! -x /usr/sbin/dnsmasq -o ! -x /etc/init.d/dnsmasq ] ; then
-    resolvsym=1
-  else
-    /etc/init.d/dnsmasq enabled || resolvsym=1
-  fi
-
-
-  if [ "$resolvsym" -gt 0 ] ; then
-    rm -f /tmp/resolv.conf
-
-
-    {
-      # Set resolver file to local but not if /etc/init.d/dnsmasq will do it.
-      echo "nameserver 127.0.0.1"
-      echo "nameserver ::1"
-      echo "search $UNBOUND_TXT_DOMAIN"
-    } > /tmp/resolv.conf
-  fi
-
-
   if [ "$UNBOUND_D_DHCP_LINK" = "odhcpd" -a ! -d "$dhcp_dir" ] ; then
     # make sure odhcpd has a directory to write (not done itself, yet)
     mkdir -p "$dhcp_dir"
@@ -863,29 +842,71 @@ unbound_uci() {
 
   if [ "$UNBOUND_N_EDNS_SIZE" -lt 512 \
     -o 4096 -lt "$UNBOUND_N_EDNS_SIZE" ] ; then
-    # exceeds range, back to default
+    logger -t unbound -s "edns_size exceeds range, using default"
     UNBOUND_N_EDNS_SIZE=1280
   fi
 
 
-  if [ "$UNBOUND_N_RX_PORT" -lt 1024 \
-    -o 10240 -lt "$UNBOUND_N_RX_PORT" ] ; then
-    # special port or in 5 digits, back to default
+  if [ "$UNBOUND_N_RX_PORT" -ne 53 ] \
+  && [ "$UNBOUND_N_RX_PORT" -lt 1024 -o 10240 -lt "$UNBOUND_N_RX_PORT" ] ; then
+    logger -t unbound -s "privileged port or in 5 digits, using default"
     UNBOUND_N_RX_PORT=53
   fi
 
 
   if [ "$UNBOUND_TTL_MIN" -gt 1800 ] ; then
-    # that could have had awful side effects
+    logger -t unbound -s "ttl_min could have had awful side effects, using 300"
     UNBOUND_TTL_MIN=300
   fi
 }
 
 ##############################################################################
 
+_resolv_setup() {
+  if [ "$UNBOUND_N_RX_PORT" != "53" ] ; then
+    return
+  fi
+
+  if [ -x /etc/init.d/dnsmasq ] && /etc/init.d/dnsmasq enabled \
+  && nslookup localhost 127.0.0.1#53 >/dev/null 2>&1 ; then
+    # unbound is configured for port 53, but dnsmasq is enabled and a resolver
+    #   listens on localhost:53, lets assume dnsmasq manages the resolver file.
+    # TODO:
+    #   really check if dnsmasq runs a local (main) resolver in stead of using
+    #   nslookup that times out when no resolver listens on localhost:53.
+    return
+  fi
+
+  # unbound is designated to listen on 127.0.0.1#53,
+  #   set resolver file to local.
+  rm -f /tmp/resolv.conf
+  {
+    echo "# /tmp/resolv.conf generated by Unbound UCI $( date )"
+    echo "nameserver 127.0.0.1"
+    echo "nameserver ::1"
+    echo "search $UNBOUND_TXT_DOMAIN"
+  } > /tmp/resolv.conf
+}
+
+##############################################################################
+
+_resolv_teardown() {
+  case $( cat /tmp/resolv.conf ) in
+  *"generated by Unbound UCI"*)
+    # our resolver file, reset to auto resolver file.
+    rm -f /tmp/resolv.conf
+    ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
+    ;;
+  esac
+}
+
+##############################################################################
+
 unbound_start() {
   config_load unbound
   config_foreach unbound_uci unbound
+
+
   unbound_mkdir
 
 
@@ -902,28 +923,18 @@ unbound_start() {
 
     unbound_control
   fi
+
+
+  _resolv_setup
 }
 
 ##############################################################################
 
 unbound_stop() {
-  local resolvsym=0
+  _resolv_teardown
 
-  rootzone_update
-
-
-  if [ ! -x /usr/sbin/dnsmasq -o ! -x /etc/init.d/dnsmasq ] ; then
-    resolvsym=1
-  else
-    /etc/init.d/dnsmasq enabled || resolvsym=1
-  fi
 
-
-  if [ "$resolvsym" -gt 0 ] ; then
-    # set resolver file to normal, but don't stomp on dnsmasq
-    rm -f /tmp/resolv.conf
-    ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
-  fi
+  rootzone_update
 }
 
 ##############################################################################
-- 
2.11.0

