diff --git a/src/initscripts/init.d/unbound b/src/initscripts/init.d/unbound index 6c7be6cfd..08f98059e 100644 --- a/src/initscripts/init.d/unbound +++ b/src/initscripts/init.d/unbound @@ -86,6 +86,24 @@ update_forwarders() { esac done + # Determine EDNS buffer size + local current_edns_buffer_size=$(unbound-control get_option edns-buffer-size) + + if [ -n "${current_edns_buffer_size}" ]; then + local new_edns_buffer_size=${current_edns_buffer_size} + + for ns in ${forwarders}; do + local edns_buffer_size=$(ns_determine_edns_buffer_size ${ns}) + if [ -n "${edns_buffer_size}" ]; then + if [ ${edns_buffer_size} -lt ${current_edns_buffer_size} ]; then + new_edns_buffer_size=${edns_buffer_size} + fi + fi + done + + unbound-control -q set_option edns-buffer-size: ${new_edns_buffer_size} + fi + # Show warning for any broken upstream name servers if [ -n "${broken_forwarders}" ]; then boot_mesg "Ignoring broken upstream name server(s): ${broken_forwarders:1}" ${WARNING} @@ -249,6 +267,7 @@ get_memory_amount() { test_name_server() { local ns=${1} + local args # Return codes: # 0 DNSSEC validating @@ -259,9 +278,15 @@ test_name_server() { # Exit when the server is not reachable ns_is_online ${ns} || return 1 + # Determine the maximum edns buffer size that works + local edns_buffer_size=$(ns_determine_edns_buffer_size ${ns}) + if [ -n "${edns_buffer_size}" ]; then + args="${args} +bufsize=${edns_buffer_size}" + fi + local errors for rr in DNSKEY DS RRSIG; do - if ! ns_forwards_${rr} ${ns}; then + if ! ns_forwards_${rr} ${ns} ${args}; then errors="${errors} ${rr}" fi done @@ -271,7 +296,7 @@ test_name_server() { return 3 fi - if ns_is_validating ${ns}; then + if ns_is_validating ${ns} ${args}; then # Return 0 if validating return 0 else @@ -283,41 +308,62 @@ test_name_server() { # Sends an A query to the nameserver w/o DNSSEC ns_is_online() { local ns=${1} + shift - dig @${ns} +nodnssec A ${TEST_DOMAIN} >/dev/null + dig @${ns} +nodnssec A ${TEST_DOMAIN} $@ >/dev/null } # Resolving ${TEST_DOMAIN_FAIL} will fail if the nameserver is validating ns_is_validating() { local ns=${1} + shift - dig @${ns} A ${TEST_DOMAIN_FAIL} | grep -q SERVFAIL + dig @${ns} A ${TEST_DOMAIN_FAIL} $@ | grep -q SERVFAIL } # Checks if we can retrieve the DNSKEY for this domain. # dig will print the SOA if nothing was found ns_forwards_DNSKEY() { local ns=${1} + shift - dig @${ns} DNSKEY ${TEST_DOMAIN} | grep -qv SOA + dig @${ns} DNSKEY ${TEST_DOMAIN} $@ | grep -qv SOA } ns_forwards_DS() { local ns=${1} + shift - dig @${ns} DS ${TEST_DOMAIN} | grep -qv SOA + dig @${ns} DS ${TEST_DOMAIN} $@ | grep -qv SOA } ns_forwards_RRSIG() { local ns=${1} + shift - dig @${ns} +dnssec A ${TEST_DOMAIN} | grep -q RRSIG + dig @${ns} +dnssec A ${TEST_DOMAIN} $@ | grep -q RRSIG } ns_supports_tcp() { local ns=${1} + shift - dig @${ns} +tcp A ${TEST_DOMAIN} >/dev/null || return 1 + dig @${ns} +tcp A ${TEST_DOMAIN} $@ >/dev/null || return 1 +} + +ns_determine_edns_buffer_size() { + local ns=${1} + shift + + local b + for b in 4096 2048 1500 1480 1464 1400 1280 512; do + if dig @${ns} +dnssec +bufsize=${b} A ${TEST_DOMAIN} $@ >/dev/null; then + echo "${b}" + return 0 + fi + done + + return 1 } case "$1" in @@ -394,6 +440,7 @@ case "$1" in ;; *) echo "Test failed for an unknown reason" + exit ${ret} ;; esac @@ -403,6 +450,11 @@ case "$1" in echo "${ns} does not support TCP fallback" fi + edns_buffer_size=$(ns_determine_edns_buffer_size ${ns}) + if [ -n "${edns_buffer_size}" ]; then + echo "EDNS buffer size for ${ns}: ${edns_buffer_size}" + fi + exit ${ret} ;;