diff --git a/gennghttpxfun.py b/gennghttpxfun.py index f57e2c06..d85eb139 100755 --- a/gennghttpxfun.py +++ b/gennghttpxfun.py @@ -150,6 +150,8 @@ OPTIONS = [ "tls-sct-dir", "backend-connect-timeout", "dns-cache-timeout", + "dns-lookup-timeout", + "dns-max-try", ] LOGVARS = [ diff --git a/src/shrpx.cc b/src/shrpx.cc index 1c7f918f..9fe36c64 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -1491,7 +1491,9 @@ void fill_default_config(Config *config) { { auto &timeoutconf = dnsconf.timeout; timeoutconf.cache = 10_s; + timeoutconf.lookup = 5_s; } + dnsconf.max_try = 2; } } // namespace @@ -2388,6 +2390,18 @@ DNS: that nghttpx caches the unsuccessful results as well. Default: )" << util::duration_str(config->dns.timeout.cache) << R"( + --dns-lookup-timeout= + Set timeout that DNS server is given to respond to the + initial DNS query. For the 2nd and later queries, + server is given time based on this timeout, and it is + scaled linearly. + Default: )" + << util::duration_str(config->dns.timeout.lookup) << R"( + --dns-max-try= + Set the number of DNS query before nghttpx gives up name + lookup. + Default: )" + << config->dns.max_try << R"( Debug: --frontend-http2-dump-request-header= @@ -3049,6 +3063,8 @@ int main(int argc, char **argv) { {SHRPX_OPT_BACKEND_CONNECT_TIMEOUT.c_str(), required_argument, &flag, 142}, {SHRPX_OPT_DNS_CACHE_TIMEOUT.c_str(), required_argument, &flag, 143}, + {SHRPX_OPT_DNS_LOOKUP_TIMEOUT.c_str(), required_argument, &flag, 144}, + {SHRPX_OPT_DNS_MAX_TRY.c_str(), required_argument, &flag, 145}, {nullptr, 0, nullptr, 0}}; int option_index = 0; @@ -3726,6 +3742,14 @@ int main(int argc, char **argv) { // --dns-cache-timeout cmdcfgs.emplace_back(SHRPX_OPT_DNS_CACHE_TIMEOUT, StringRef{optarg}); break; + case 144: + // --dns-lookup-timeou + cmdcfgs.emplace_back(SHRPX_OPT_DNS_LOOKUP_TIMEOUT, StringRef{optarg}); + break; + case 145: + // --dns-max-try + cmdcfgs.emplace_back(SHRPX_OPT_DNS_MAX_TRY, StringRef{optarg}); + break; default: break; } diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index e4a3e530..a963d3b6 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -1370,6 +1370,9 @@ int option_lookup_token(const char *name, size_t namelen) { } break; case 'y': + if (util::strieq_l("dns-max-tr", name, 10)) { + return SHRPX_OPTID_DNS_MAX_TRY; + } if (util::strieq_l("http2-prox", name, 10)) { return SHRPX_OPTID_HTTP2_PROXY; } @@ -1548,6 +1551,9 @@ int option_lookup_token(const char *name, size_t namelen) { } break; case 't': + if (util::strieq_l("dns-lookup-timeou", name, 17)) { + return SHRPX_OPTID_DNS_LOOKUP_TIMEOUT; + } if (util::strieq_l("worker-write-burs", name, 17)) { return SHRPX_OPTID_WORKER_WRITE_BURST; } @@ -3104,6 +3110,22 @@ int parse_config(Config *config, int optid, const StringRef &opt, #endif // !(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L) case SHRPX_OPTID_DNS_CACHE_TIMEOUT: return parse_duration(&config->dns.timeout.cache, opt, optarg); + case SHRPX_OPTID_DNS_LOOKUP_TIMEOUT: + return parse_duration(&config->dns.timeout.lookup, opt, optarg); + case SHRPX_OPTID_DNS_MAX_TRY: { + int n; + if (parse_uint(&n, opt, optarg) != 0) { + return -1; + } + + if (n > 5) { + LOG(ERROR) << opt << ": must be smaller than or equal to 5"; + return -1; + } + + config->dns.max_try = n; + return 0; + } case SHRPX_OPTID_CONF: LOG(WARN) << "conf: ignored"; diff --git a/src/shrpx_config.h b/src/shrpx_config.h index b757dac0..95c39f9c 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -314,6 +314,9 @@ constexpr auto SHRPX_OPT_BACKEND_CONNECT_TIMEOUT = StringRef::from_lit("backend-connect-timeout"); constexpr auto SHRPX_OPT_DNS_CACHE_TIMEOUT = StringRef::from_lit("dns-cache-timeout"); +constexpr auto SHRPX_OPT_DNS_LOOKUP_TIMEOUT = + StringRef::from_lit("dns-lookup-timeout"); +constexpr auto SHRPX_OPT_DNS_MAX_TRY = StringRef::from_lit("dns-max-try"); constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8; @@ -785,7 +788,11 @@ struct APIConfig { struct DNSConfig { struct { ev_tstamp cache; + ev_tstamp lookup; } timeout; + // The number of tries name resolver makes before abandoning + // request. + size_t max_try; }; struct Config { @@ -905,6 +912,8 @@ enum { SHRPX_OPTID_DAEMON, SHRPX_OPTID_DH_PARAM_FILE, SHRPX_OPTID_DNS_CACHE_TIMEOUT, + SHRPX_OPTID_DNS_LOOKUP_TIMEOUT, + SHRPX_OPTID_DNS_MAX_TRY, SHRPX_OPTID_ECDH_CURVES, SHRPX_OPTID_ERROR_PAGE, SHRPX_OPTID_ERRORLOG_FILE, diff --git a/src/shrpx_dns_resolver.cc b/src/shrpx_dns_resolver.cc index 9a26a2ed..104ba633 100644 --- a/src/shrpx_dns_resolver.cc +++ b/src/shrpx_dns_resolver.cc @@ -29,6 +29,7 @@ #include "shrpx_log.h" #include "shrpx_connection.h" +#include "shrpx_config.h" namespace shrpx { @@ -145,11 +146,15 @@ int DNSResolver::resolve(const StringRef &name, int family) { int rv; + auto &dnsconf = get_config()->dns; + ares_options opts{}; opts.sock_state_cb = sock_state_cb; opts.sock_state_cb_data = this; + opts.timeout = static_cast(dnsconf.timeout.lookup * 1000); + opts.tries = dnsconf.max_try; - auto optmask = ARES_OPT_SOCK_STATE_CB; + auto optmask = ARES_OPT_SOCK_STATE_CB | ARES_OPT_TIMEOUTMS | ARES_OPT_TRIES; ares_channel chan; rv = ares_init_options(&chan, &opts, optmask);