diff --git a/gennghttpxfun.py b/gennghttpxfun.py index ec1c015a..f57e2c06 100755 --- a/gennghttpxfun.py +++ b/gennghttpxfun.py @@ -149,6 +149,7 @@ OPTIONS = [ "ecdh-curves", "tls-sct-dir", "backend-connect-timeout", + "dns-cache-timeout", ] LOGVARS = [ diff --git a/src/shrpx.cc b/src/shrpx.cc index 4f6f28a3..1c7f918f 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -1486,6 +1486,12 @@ void fill_default_config(Config *config) { auto &apiconf = config->api; apiconf.max_request_body = 16_k; + + auto &dnsconf = config->dns; + { + auto &timeoutconf = dnsconf.timeout; + timeoutconf.cache = 10_s; + } } } // namespace @@ -2376,6 +2382,13 @@ API: Default: )" << util::utos_unit(config->api.max_request_body) << R"( +DNS: + --dns-cache-timeout= + Set duration that cached DNS results remain valid. Note + that nghttpx caches the unsuccessful results as well. + Default: )" + << util::duration_str(config->dns.timeout.cache) << R"( + Debug: --frontend-http2-dump-request-header= Dumps request headers received by HTTP/2 frontend to the @@ -3035,6 +3048,7 @@ int main(int argc, char **argv) { {SHRPX_OPT_TLS_SCT_DIR.c_str(), required_argument, &flag, 141}, {SHRPX_OPT_BACKEND_CONNECT_TIMEOUT.c_str(), required_argument, &flag, 142}, + {SHRPX_OPT_DNS_CACHE_TIMEOUT.c_str(), required_argument, &flag, 143}, {nullptr, 0, nullptr, 0}}; int option_index = 0; @@ -3708,6 +3722,10 @@ int main(int argc, char **argv) { cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_CONNECT_TIMEOUT, StringRef{optarg}); break; + case 143: + // --dns-cache-timeout + cmdcfgs.emplace_back(SHRPX_OPT_DNS_CACHE_TIMEOUT, StringRef{optarg}); + break; default: break; } diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index b4b1b8ad..e4a3e530 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -1531,6 +1531,9 @@ int option_lookup_token(const char *name, size_t namelen) { } break; case 't': + if (util::strieq_l("dns-cache-timeou", name, 16)) { + return SHRPX_OPTID_DNS_CACHE_TIMEOUT; + } if (util::strieq_l("worker-read-burs", name, 16)) { return SHRPX_OPTID_WORKER_READ_BURST; } @@ -3099,6 +3102,8 @@ int parse_config(Config *config, int optid, const StringRef &opt, LOG(WARN) << opt << ": This option requires OpenSSL >= 1.0.2"; return 0; #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_CONF: LOG(WARN) << "conf: ignored"; diff --git a/src/shrpx_config.h b/src/shrpx_config.h index d6ed19d6..b757dac0 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -312,6 +312,8 @@ constexpr auto SHRPX_OPT_ECDH_CURVES = StringRef::from_lit("ecdh-curves"); constexpr auto SHRPX_OPT_TLS_SCT_DIR = StringRef::from_lit("tls-sct-dir"); 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 size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8; @@ -780,6 +782,12 @@ struct APIConfig { bool enabled; }; +struct DNSConfig { + struct { + ev_tstamp cache; + } timeout; +}; + struct Config { Config() : balloc(4096, 4096), @@ -790,6 +798,7 @@ struct Config { logging{}, conn{}, api{}, + dns{}, num_worker{0}, padding{0}, rlimit_nofile{0}, @@ -818,6 +827,7 @@ struct Config { LoggingConfig logging; ConnectionConfig conn; APIConfig api; + DNSConfig dns; StringRef pid_file; StringRef conf_path; StringRef user; @@ -894,6 +904,7 @@ enum { SHRPX_OPTID_CONF, SHRPX_OPTID_DAEMON, SHRPX_OPTID_DH_PARAM_FILE, + SHRPX_OPTID_DNS_CACHE_TIMEOUT, SHRPX_OPTID_ECDH_CURVES, SHRPX_OPTID_ERROR_PAGE, SHRPX_OPTID_ERRORLOG_FILE, diff --git a/src/shrpx_dns_tracker.cc b/src/shrpx_dns_tracker.cc index 3acb100a..53d2c733 100644 --- a/src/shrpx_dns_tracker.cc +++ b/src/shrpx_dns_tracker.cc @@ -23,6 +23,7 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "shrpx_dns_tracker.h" +#include "shrpx_config.h" #include "util.h" namespace shrpx { @@ -43,18 +44,16 @@ DNSTracker::~DNSTracker() { } } -namespace { -constexpr auto DNS_TTL = 30_s; -} // namespace - ResolverEntry DNSTracker::make_entry(std::unique_ptr resolv, ImmutableString host, int status, const Address *result) { + auto &dnsconf = get_config()->dns; + auto ent = ResolverEntry{}; ent.resolv = std::move(resolv); ent.host = std::move(host); ent.status = status; - ent.expiry = ev_now(loop_) + DNS_TTL; + ent.expiry = ev_now(loop_) + dnsconf.timeout.cache; if (result) { ent.result = *result; } @@ -233,9 +232,11 @@ void DNSTracker::add_to_qlist(ResolverEntry &ent, DNSQuery *dnsq) { cb(status, result); } + auto &dnsconf = get_config()->dns; + ent.resolv.reset(); ent.status = status; - ent.expiry = ev_now(loop) + DNS_TTL; + ent.expiry = ev_now(loop) + dnsconf.timeout.cache; if (ent.status == DNS_STATUS_OK) { ent.result = *result; }