diff options
Diffstat (limited to 'dhcpcd-hooks/20-resolv.conf')
-rw-r--r-- | dhcpcd-hooks/20-resolv.conf | 87 |
1 files changed, 77 insertions, 10 deletions
diff --git a/dhcpcd-hooks/20-resolv.conf b/dhcpcd-hooks/20-resolv.conf index 437c116..e757ddf 100644 --- a/dhcpcd-hooks/20-resolv.conf +++ b/dhcpcd-hooks/20-resolv.conf @@ -1,14 +1,71 @@ # Generate /etc/resolv.conf # Support resolvconf(8) if available +# We can merge other dhcpcd resolv.conf files into one like resolvconf, +# but resolvconf is preferred as other applications like VPN clients +# can readily hook into it. +# Also, resolvconf can configure local nameservers such as bind +# or dnsmasq. This is important as the libc resolver isn't that powerful. -make_resolv_conf() +resolv_conf_dir="${state_dir}/resolv.conf" + +build_resolv_conf() +{ + local cf="/etc/resolv.conf.${interface}" + local interfaces= header= search= srvs= servers= x= + + # Build a list of interfaces + interfaces=$(list_interfaces "${resolv_conf_dir}") + + # Build the resolv.conf + if [ -n "${interfaces}" ]; then + # Build the header + for x in ${interfaces}; do + header="${header}${header:+, }${x}" + done + + # Build the search list + search=$(cd "${resolv_conf_dir}"; \ + key_get_value "search " ${interfaces}) + [ -n "${search}" ] && search="search $(uniqify ${search})\n" + + # Build the nameserver list + srvs=$(cd "${resolv_conf_dir}"; \ + key_get_value "nameserver " ${interfaces}) + for x in $(uniqify ${srvs}); do + servers="${servers}nameserver ${x}\n" + done + fi + header="${signature_base}${header:+ ${from} }${header}" + + # Assemble resolv.conf using our head and tail files + [ -f "${cf}" ] && rm -f "${cf}" + echo "${header}" > "${cf}" + if [ -f /etc/resolv.conf.head ]; then + cat /etc/resolv.conf.head >> "${cf}" + else + echo "# /etc/resolv.conf.head can replace this line" >> "${cf}" + fi + printf "${search}${servers}" >> "${cf}" + if [ -f /etc/resolv.conf.tail ]; then + cat /etc/resolv.conf.tail >> "${cf}" + else + echo "# /etc/resolv.conf.tail can replace this line" >> "${cf}" + fi + mv -f "${cf}" /etc/resolv.conf +} + +add_resolv_conf() { + local x= conf="${signature}\n" + + # If we don't have any configuration, remove it if [ -z "${new_domain_name_servers}" -a \ -z "${new_domain_name}" -a \ -z "${new_domain_search}" ]; then - return 0 + remove_resolv_conf + return $? fi - local x= conf="${signature}\n" + if [ -n "${new_domain_search}" ]; then conf="${conf}search ${new_domain_search}\n" elif [ -n "${new_domain_name}" ]; then @@ -19,22 +76,32 @@ make_resolv_conf() done if type resolvconf >/dev/null 2>&1; then printf "${conf}" | resolvconf -a "${interface}" - else - save_conf /etc/resolv.conf - printf "${conf}" > /etc/resolv.conf + return $? + fi + + if [ -e "${resolv_conf_dir}/${interface}" ]; then + rm -f "${resolv_conf_dir}/${interface}" + fi + if [ ! -d "${resolv_conf_dir}" ]; then + mkdir -p "${resolv_conf_dir}" fi + printf "${conf}" > "${resolv_conf_dir}/${interface}" + build_resolv_conf } -restore_resolv_conf() +remove_resolv_conf() { if type resolvconf >/dev/null 2>&1; then resolvconf -d "${interface}" -f else - restore_conf /etc/resolv.conf || return 0 + if [ -e "${resolv_conf_dir}/${interface}" ]; then + rm -f "${resolv_conf_dir}/${interface}" + fi + build_resolv_conf fi } case "${reason}" in -BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT) make_resolv_conf;; -EXPIRE|FAIL|IPV4LL|RELEASE|STOP) restore_resolv_conf;; +BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT) add_resolv_conf;; +PREINIT|EXPIRE|FAIL|IPV4LL|RELEASE|STOP) remove_resolv_conf;; esac |