]> git.ipfire.org Git - people/stevee/network.git/commitdiff
dns: Adds a number of new functions.
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 13 Oct 2012 18:39:27 +0000 (18:39 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 13 Oct 2012 18:39:27 +0000 (18:39 +0000)
The configuration file layout is the same like for the
static routes.
DNS servers from DHCP are now taken into account and prioritized.
Duplicate entries are removed.

dhclient-script
functions.dns
functions.radvd
functions.util
network

index 789eee3241baef3a65f59f4c79ef13cf4688b9e7..9325a21bb7111b2cf7375ee9bfd4f12c69f85785 100644 (file)
@@ -99,6 +99,7 @@ case "${reason}" in
                                        routing_db_set ${interface} ipv4 active 1
                                        routing_db_set ${interface} ipv4 domain-name "${new_domain_name}"
                                        routing_db_set ${interface} ipv4 domain-name-servers "${new_domain_name_servers}"
+                                       routing_db_set ${interface} ipv4 domain-name-servers-priority "${DNS_SERVER_DYNAMIC_PRIORITY}"
 
                                        # Update the routing tables.
                                        routing_update ${interface} ipv4
index 5f964ba52c5e69458446b6273536a668cc99b9ea..660663761641e52119272526b8428b7c9812a6bb 100644 (file)
@@ -36,6 +36,11 @@ NETWORK_CONFIG_FILE_PARAMS="${NETWORK_CONFIG_FILE_PARAMS} DNS_SEARCH_DOMAINS"
 DNS_ADVERTISE_SERVERS="true"
 
 DNS_SERVER_CONFIG_FILE="${NETWORK_CONFIG_DIR}/dns-servers"
+NETWORK_CONFIG_DNS_SERVER_PARAMS="server priority"
+
+# Set the default priority for DNS servers.
+DNS_SERVER_DEFAULT_PRIORITY="100"
+DNS_SERVER_DYNAMIC_PRIORITY="10"
 
 # Path to the configuration file of the DNS resolver.
 RESOLV_CONF="/etc/resolv.conf"
@@ -51,33 +56,56 @@ function dns_get_hostname() {
        )
 }
 
-function __dns_server_println() {
-       local server=${1}
-       local priority=${2}
+function dns_server_list() {
+       [ -r "${DNS_SERVER_CONFIG_FILE}" ] || return ${EXIT_OK}
 
-       print "%-20s %s" "${server}" "${priority}"
-}
+       local line
+       local ${NETWORK_CONFIG_DNS_SERVER_PARAMS}
+
+       local format="%-20s %-8s"
+       print "${format}" "SERVER" "PRIORITY"
 
-function __dns_server_sort() {
-       sort -k2 -g | uniq
+       while read -r line; do
+               dns_server_parse_line ${line} || continue
+
+               print "${format}" "${server}" "${priority}"
+       done < ${DNS_SERVER_CONFIG_FILE}
+
+       return ${EXIT_OK}
 }
 
-function dns_server_list() {
+function dns_server_list_sorted() {
        [ -r "${DNS_SERVER_CONFIG_FILE}" ] || return ${EXIT_OK}
 
-       local server priority
-       while read server priority; do
-               if [ -n "${server}" ] && [ -n "${priority}" ]; then
-                       __dns_server_println "${server}" "${priority}"
-               fi
-       done < ${DNS_SERVER_CONFIG_FILE} | __dns_server_sort
-}
+       local servers=$(
+               # First get all servers from the configuration file.
+               while read -r line; do
+                       dns_server_parse_line ${line} || continue
 
-function dns_server_list_no_priority() {
-       local server priority
-       dns_server_list | while read server priority; do
-               echo "${server}"
-       done
+                       print "%d %s" "${priority}" "${server}"
+               done < ${DNS_SERVER_CONFIG_FILE}
+
+               # Then get all dynamically assigned DNS servers.
+               dns_server_get_zone_name_servers
+       )
+
+       # Nothing to do if we have got no DNS servers.
+       isset servers || return ${EXIT_OK}
+
+       # Sort everything we have got.
+       servers=$(sort -g -k1 <<< "${servers}")
+
+       # Remove the priority bit.
+       local server server_list
+       while read -r priority server; do
+               list_append server_list "${server}"
+       done <<< "${servers}"
+
+       # Return the list but remove duplicate entries, keeping
+       # the first and removing all others.
+       list_unique ${server_list}
+
+       return ${EXIT_OK}
 }
 
 function dns_server_add() {
@@ -86,35 +114,103 @@ function dns_server_add() {
 
        local priority=${2}
        if ! isset priority; then
-               priority=20
+               priority="${DNS_SERVER_DEFAULT_PRIORITY}"
        fi
        assert isinteger priority
 
-       (
-               dns_server_list
-               __dns_server_println "${server}" "${priority}"
-       ) | __dns_server_sort > ${DNS_SERVER_CONFIG_FILE}.new
+       # Add a new line to the configuration file.
+       print "server=\"%s\" priority=\"%d\"" "${server}" "${priority}" \
+               >> ${DNS_SERVER_CONFIG_FILE}
 
-       mv ${DNS_SERVER_CONFIG_FILE}{.new,}
+       return ${EXIT_OK}
+}
+
+function dns_server_exists() {
+       local entry=${1}
+       assert isset entry
+
+       [ -r "${DNS_SERVER_CONFIG_FILE}" ] || return ${EXIT_FALSE}
+
+       local line ${NETWORK_CONFIG_DNS_SERVER_PARAMS}
+       while read -r line; do
+               dns_server_parse_line ${line} || continue
+
+               [ "${entry}" = "${server}" ] && return ${EXIT_TRUE}
+       done < ${DNS_SERVER_CONFIG_FILE}
+
+       return ${EXIT_FALSE}
 }
 
 function dns_server_remove() {
-       local server=${1}
-       assert isset server
+       local entry=${1}
+       assert isset entry
 
-       local entry priority
-       local entries=$(dns_server_list)
+       # Check if the DNS server configuration file exists.
+       [ -r "${DNS_SERVER_CONFIG_FILE}" ] || return ${EXIT_ERROR}
 
-       while read entry priority; do
+       # Create a tempfile.
+       local tempfile=$(mktemp)
+
+       local line ${NETWORK_CONFIG_DNS_SERVER_PARAMS}
+       while read -r line; do
+               dns_server_parse_line ${line} || continue
+
+               # Skip the line with the server we are searching for.
                [ "${entry}" = "${server}" ] && continue
-               __dns_server_println "${server}" "${priority}"
-       done <<< ${entries} | __dns_server_sort > ${DNS_SERVER_CONFIG_FILE}
+
+               # Re-add the old line.
+               print "${line}"
+       done < ${DNS_SERVER_CONFIG_FILE} > ${tempfile}
+
+       # Overwrite the old content without the entry that has just been removed.
+       fread "${tempfile}" > ${DNS_SERVER_CONFIG_FILE}
+
+       # Remove the temporary file.
+       rm -f ${tempfile}
+
+       return ${EXIT_OK}
 }
 
 function dns_server_flush() {
        : > ${DNS_SERVER_CONFIG_FILE}
 }
 
+function dns_server_parse_line() {
+       local arg
+
+       for arg in ${NETWORK_CONFIG_DNS_SERVER_PARAMS}; do
+               assign "${arg}" ""
+       done
+
+       while read -r arg; do
+               case "${arg}" in
+                       server=*)
+                               server=$(cli_get_val ${arg})
+                               ;;
+                       priority=*)
+                               priority=$(cli_get_val ${arg})
+                               ;;
+               esac
+       done <<< "$(args $@)"
+
+       # The server address must be set.
+       isset server || return ${EXIT_ERROR}
+
+       # The server address must also be a valid IP address.
+       ip_is_valid ${server} || return ${EXIT_ERROR}
+
+       # If priority is set, it must be an integer number.
+       if isset priority; then
+               isinteger priority || return ${EXIT_ERROR}
+
+       # Otherwise assign the default priority.
+       else
+               priority=${DNS_SERVER_DEFAULT_PRIORITY}
+       fi
+
+       return ${EXIT_OK}
+}
+
 # Update resolv.conf(5) when initializing the network.
 init_register dns_generate_resolvconf
 
@@ -149,39 +245,35 @@ function dns_generate_resolvconf() {
        search_domains=$(list_unique ${search_domains})
 
        # Write search domains to file.
+       print "# Search domains" >> ${file}
        for domainname in ${search_domains}; do
                print "search ${domainname}"
        done >> ${file}
 
+       print "\n# Nameservers" >> ${file}
+
        # Add the local resolver as the first DNS server if enabled.
        if enabled DNS_USE_LOCAL_RESOLVER; then
                print "nameserver ::1" >> ${file}
        fi
 
-       # First pull in zone name servers.
-       local server
-       for server in $(dns_get_zone_name_servers); do
-               print "nameserver ${server}"
-       done >> ${file}
-
-       # Dump all DNS servers (if any).
-       local priority
-       dns_server_list | while read server priority; do
+       # Dump all DNS servers.
+       for server in $(dns_server_list_sorted); do
                print "nameserver ${server}"
        done >> ${file}
 }
 
-function dns_get_zone_name_servers() {
-       local servers
-       local zone
+function dns_server_get_zone_name_servers() {
+       local priority proto server servers zone
+
        for zone in $(zones_get_all); do
-               local proto
                for proto in ${IP_SUPPORTED_PROTOCOLS}; do
-                       servers=$(routing_db_get ${zone} ${proto} domain-name-servers)
+                       priority=$(routing_db_get ${zone} ${proto} domain-name-servers-priority)
+                       isset priority || priority="${DNS_SERVER_DYNAMIC_PRIORITY}"
 
-                       local server
+                       servers=$(routing_db_get ${zone} ${proto} domain-name-servers)
                        for server in ${servers}; do
-                               print "${server}"
+                               print "${priority} ${server}"
                        done
                done
        done
index 804398e522fe09e25486c1d6f2ef91d6401f6c21..7970a54b2f296b489fe6aee8c1fb6296f480cc6d 100644 (file)
@@ -114,7 +114,7 @@ function __radvd_config_dns() {
        # resolver.
 
        local server servers
-       for server in $(dns_server_list_no_priority); do
+       for server in $(dns_server_list_sorted); do
                # Filter out non IPv6 addresses.
                ipv6_is_valid ${server} || continue
 
index 68fac1b39fc71f48e2d719eea823890864921a8b..3a4751f4198e819d41e288f82e00070d2560ae93 100644 (file)
@@ -89,12 +89,24 @@ function basename() {
        echo "${1##*/}"
 }
 
+function format() {
+       local key=${1}
+       assert isset key
+
+       local format=${2}
+       assert isset format
+
+       shift 2
+
+       printf -v "${key}" "${format}" "$@"
+}
+
 function assign() {
        local key=${1}
        assert isset key
        shift
 
-       printf -v "${key}" "%s" "$@"
+       format "${key}" "%s" "$@"
 }
 
 function fread() {
diff --git a/network b/network
index 61dfcdfac4fca2f70d768f90b941cc34534168d3..00a4f76d747a25fd871a24df1268b51e40cf599a 100755 (executable)
--- a/network
+++ b/network
@@ -1055,15 +1055,24 @@ function cli_dns() {
 
        case "${cmd}" in
                list)
-                       __dns_server_println "SERVER" "PRIORITY"
                        dns_server_list
                        exit ${EXIT_OK}
                        ;;
                add)
+                       if dns_server_exists ${server}; then
+                               error "DNS server '${server}' already exists!"
+                               exit ${EXIT_ERROR}
+                       fi
+
                        log INFO "Adding new DNS server: ${server}"
                        dns_server_add ${server} ${priority}
                        ;;
                remove)
+                       if ! dns_server_exists ${server}; then
+                               error "DNS server '${server}' does not exist!"
+                               exit ${EXIT_ERROR}
+                       fi
+
                        log INFO "Removing DNS server: ${server}"
                        dns_server_remove ${server} ${priority}
                        ;;