diff --git a/src/shrpx_dns_tracker.cc b/src/shrpx_dns_tracker.cc index 67ebcb46..dcc79e56 100644 --- a/src/shrpx_dns_tracker.cc +++ b/src/shrpx_dns_tracker.cc @@ -36,7 +36,8 @@ void gccb(struct ev_loop *loop, ev_timer *w, int revents) { } } // namespace -DNSTracker::DNSTracker(struct ev_loop *loop) : loop_(loop) { +DNSTracker::DNSTracker(struct ev_loop *loop, int family) + : loop_(loop), family_(family) { ev_timer_init(&gc_timer_, gccb, 0., 12_h); gc_timer_.data = this; } @@ -111,7 +112,7 @@ DNSResolverStatus DNSTracker::resolve(Address *result, DNSQuery *dnsq) { LOG(INFO) << "DNS entry not found for " << dnsq->host; } - auto resolv = std::make_unique(loop_); + auto resolv = std::make_unique(loop_, family_); auto host_copy = ImmutableString{std::begin(dnsq->host), std::end(dnsq->host)}; auto host = StringRef{host_copy}; @@ -180,7 +181,7 @@ DNSResolverStatus DNSTracker::resolve(Address *result, DNSQuery *dnsq) { << ", but it has been expired"; } - auto resolv = std::make_unique(loop_); + auto resolv = std::make_unique(loop_, family_); auto host = StringRef{ent.host}; rv = resolv->resolve(host); diff --git a/src/shrpx_dns_tracker.h b/src/shrpx_dns_tracker.h index e08247c5..87b9f967 100644 --- a/src/shrpx_dns_tracker.h +++ b/src/shrpx_dns_tracker.h @@ -75,7 +75,7 @@ struct ResolverEntry { class DNSTracker { public: - DNSTracker(struct ev_loop *loop); + DNSTracker(struct ev_loop *loop, int family); ~DNSTracker(); // Lookups host name described in |dnsq|. If name lookup finishes @@ -111,6 +111,8 @@ private: // increase memory consumption, interval could be very long. ev_timer gc_timer_; struct ev_loop *loop_; + // IP version preference. + int family_; }; } // namespace shrpx diff --git a/src/shrpx_dual_dns_resolver.cc b/src/shrpx_dual_dns_resolver.cc index f03eea6f..8c6c5c9b 100644 --- a/src/shrpx_dual_dns_resolver.cc +++ b/src/shrpx_dual_dns_resolver.cc @@ -26,8 +26,8 @@ namespace shrpx { -DualDNSResolver::DualDNSResolver(struct ev_loop *loop) - : resolv4_(loop), resolv6_(loop) { +DualDNSResolver::DualDNSResolver(struct ev_loop *loop, int family) + : family_(family), resolv4_(loop), resolv6_(loop) { auto cb = [this](DNSResolverStatus, const Address *) { Address result; @@ -44,14 +44,22 @@ DualDNSResolver::DualDNSResolver(struct ev_loop *loop) cb(status, &result); }; - resolv4_.set_complete_cb(cb); - resolv6_.set_complete_cb(cb); + if (family_ == AF_UNSPEC || family_ == AF_INET) { + resolv4_.set_complete_cb(cb); + } + if (family_ == AF_UNSPEC || family_ == AF_INET6) { + resolv6_.set_complete_cb(cb); + } } int DualDNSResolver::resolve(const StringRef &host) { - int rv4, rv6; - rv4 = resolv4_.resolve(host, AF_INET); - rv6 = resolv6_.resolve(host, AF_INET6); + int rv4 = 0, rv6 = 0; + if (family_ == AF_UNSPEC || family_ == AF_INET) { + rv4 = resolv4_.resolve(host, AF_INET); + } + if (family_ == AF_UNSPEC || family_ == AF_INET6) { + rv6 = resolv6_.resolve(host, AF_INET6); + } if (rv4 != 0 && rv6 != 0) { return -1; diff --git a/src/shrpx_dual_dns_resolver.h b/src/shrpx_dual_dns_resolver.h index 6f314ea5..98065dab 100644 --- a/src/shrpx_dual_dns_resolver.h +++ b/src/shrpx_dual_dns_resolver.h @@ -42,7 +42,11 @@ namespace shrpx { // how CompleteCb is called have the same semantics with DNSResolver. class DualDNSResolver { public: - DualDNSResolver(struct ev_loop *loop); + // |family| controls IP version preference. If |family| == + // AF_UNSPEC, bot A and AAAA lookups are performed. If |family| == + // AF_INET, only A lookup is performed. If |family| == AF_INET6, + // only AAAA lookup is performed. + DualDNSResolver(struct ev_loop *loop, int family); // Resolves |host|. |host| must be NULL-terminated string. int resolve(const StringRef &host); @@ -51,6 +55,8 @@ public: DNSResolverStatus get_status(Address *result) const; private: + // IP version preference. + int family_; // For A record DNSResolver resolv4_; // For AAAA record diff --git a/src/shrpx_worker.cc b/src/shrpx_worker.cc index 2226bf43..d7bddda2 100644 --- a/src/shrpx_worker.cc +++ b/src/shrpx_worker.cc @@ -161,7 +161,7 @@ Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx, #endif // ENABLE_HTTP3 && HAVE_LIBBPF randgen_(util::make_mt19937()), worker_stat_{}, - dns_tracker_(loop), + dns_tracker_(loop, get_config()->conn.downstream->family), #ifdef ENABLE_HTTP3 quic_upstream_addrs_{get_config()->conn.quic_listener.addrs}, #endif // ENABLE_HTTP3