From 1371aac52a9dfdd8e620642714d6f8dc041f8927 Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.de>
Date: Wed, 2 Jun 2010 17:09:57 +0200
Subject: [PATCH 5/5] netcopnfig: add resolv.conf fallback in forwarder mode

When NETCONFIG_DNS_FORWARDER_FALLBACK is enabled (default) in forwarder
mode ("bind", "dnsmasq"), netconfig writes an explicit localhost name
server address to the /etc/resolv.conf, followed by the policy resolved
name server list as fallback for the moments, when the local forwarder
process is stopped.
---
 config/sysconfig.config-network  |   10 ++++++++++
 doc/netconfig.8                  |   23 +++++++++++++++++------
 scripts/netconfig.d/dns-resolver |   26 ++++++++++++++++++++++----
 3 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/config/sysconfig.config-network b/config/sysconfig.config-network
index 8686916..5f05be0 100644
--- a/config/sysconfig.config-network
+++ b/config/sysconfig.config-network
@@ -235,6 +235,16 @@ NETCONFIG_DNS_POLICY="auto"
 #
 NETCONFIG_DNS_FORWARDER="resolver"
 
+## Type:        yesno
+## Default:     yes
+#
+# When enabled (default) in forwarder mode ("bind", "dnsmasq"),
+# netconfig writes an explicit localhost nameserver address to the
+# /etc/resolv.conf, followed by the policy resolved name server list
+# as fallback for the moments, when the local forwarder is stopped.
+#
+NETCONFIG_DNS_FORWARDER_FALLBACK="yes"
+
 ## Type:        string
 ## Default:     ""
 #
diff --git a/doc/netconfig.8 b/doc/netconfig.8
index d44018d..c13de44 100644
--- a/doc/netconfig.8
+++ b/doc/netconfig.8
@@ -193,6 +193,14 @@ Empty string defaults to "resolver", that is also the default setting.
 
 See also \fBNETCONFIG MODULES\fR section for more informations.
 .TP
+.B NETCONFIG_DNS_FORWARDER_FALLBACK
+When enabled (default) in forwarder mode ("bind", "dnsmasq"), netconfig
+writes an explicit localhost nameserver address to the /etc/resolv.conf,
+followed by the policy resolved name server list as fallback for the
+moments, when the local forwarder is stopped. Otherwise, the fallback is
+written only, when the NETCONFIG_DNS_STATIC_SERVERS variable contains an
+localhost address.
+.TP
 .B NETCONFIG_DNS_STATIC_SEARCHLIST
 List of DNS domain names used for host-name lookup.
 
@@ -204,10 +212,12 @@ List of namserver IP addresses used for host-name lookup.
 When the NETCONFIG_DNS_FORWARDER variable is set to "resolver", the name
 servers are written directly to /etc/resolv.conf.
 
-Otherwise, the nameserver are written into a forwarder specific
-configuration file and the /etc/resolv.conf does not contain any
-nameservers causing the glibc to use the name server on the local
-machine (the forwarder). See also \fBNETCONFIG MODULES\fR section
+Otherwise, the nameserver are written into a forwarder specific configuration
+file. Whether the nameservers are written as fallback to the /etc/resolv.conf,
+depends on the NETCONFIG_DNS_FORWARDER_FALLBACK variable.
+When the /etc/resolv.conf does not contain any nameservers, the glibc makes
+use of the name server running on the local machine (the forwarder). See also
+\fBNETCONFIG MODULES\fR section
 for more informations.
 .TP
 .B NETCONFIG_DNS_RANKING
@@ -275,8 +285,9 @@ This module writes the DNS settings into the \fI/etc/resolv.conf\fR file.
 When the \fBNETCONFIG_DNS_FORWARDER\fR variable is empty or set to "resolver",
 both, the domain search list and the nameserver list is written.
 
-Otherwise, only the domain search list is written - the nameservers has to
-be handled by the forwarder specific module, e.g. bind.
+Otherwise, only the domain search list is written. Whether the nameservers are
+written to the /etc/resolv.conf or handled by the forwarder specific module
+(e.g. bind) only, depends on the NETCONFIG_DNS_FORWARDER_FALLBACK variable.
 .TP
 .B dns-bind
 This module writes the DNS nameservers as forwarders for the bind nameserver
diff --git a/scripts/netconfig.d/dns-resolver b/scripts/netconfig.d/dns-resolver
index 5f1dadd..52391df 100755
--- a/scripts/netconfig.d/dns-resolver
+++ b/scripts/netconfig.d/dns-resolver
@@ -291,17 +291,35 @@ if [ "$NETCONFIG_DNS_FORWARDER" != "resolver" -a \
      "$NETCONFIG_DNS_FORWARDER" != "" ]; then
     # write explicitly specified loopback addresses (when any);
     # everything else will go into the forwarder specific config.
+    lns=()
+    rns_0=""
+    rns_1=""
+    rns_2=""
     for idx in 0 1 2 ; do
         var="DNS_SERVERS_$idx"
         val=(${!var})
-        new=()
-        for ns in ${val[@]} ; do
+        rns=()
+        for ns in ${val[*]} ; do
             case $ns in
-            127.*|::1) new+=("$ns") ;;
+            127.*|::1) lns+=("$ns") ;;
+            *)         rns+=("$ns") ;;
             esac
         done
-        eval "${var}='${new[@]}'"
+        unset $var
+        eval "rns_$idx='${rns[*]}'"
     done
+    # fallback requires a localhost address, set when needed
+    if  test "$NETCONFIG_DNS_FORWARDER_FALLBACK" = yes ;
+    then
+        test ${#lns[@]} -le 0 && lns=(127.0.0.1)
+    fi
+    # apply localhost addresses + fallback name servers
+    if  test ${#lns[@]} -gt 0 ; then
+       # local addresses have top prioriry in forwarder modes
+       DNS_SERVERS_0="${lns[*]} $rns_0"
+       DNS_SERVERS_1="$rns_1"
+       DNS_SERVERS_2="$rns_2"
+    fi
 fi
 
 write_resolv_conf "$DNS_SEARCHLIST_0 $DNS_SEARCHLIST_1 $DNS_SEARCHLIST_2" \
-- 
1.6.4.2

