nghttpx: Respect backend-address-family on dynamic DNS lookup

This commit is contained in:
Tatsuhiro Tsujikawa 2022-09-15 19:06:23 +09:00
parent f13cff01bb
commit 6a513dc9fd
5 changed files with 30 additions and 13 deletions

View File

@ -36,7 +36,8 @@ void gccb(struct ev_loop *loop, ev_timer *w, int revents) {
} }
} // namespace } // 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); ev_timer_init(&gc_timer_, gccb, 0., 12_h);
gc_timer_.data = this; gc_timer_.data = this;
} }
@ -111,7 +112,7 @@ DNSResolverStatus DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
LOG(INFO) << "DNS entry not found for " << dnsq->host; LOG(INFO) << "DNS entry not found for " << dnsq->host;
} }
auto resolv = std::make_unique<DualDNSResolver>(loop_); auto resolv = std::make_unique<DualDNSResolver>(loop_, family_);
auto host_copy = auto host_copy =
ImmutableString{std::begin(dnsq->host), std::end(dnsq->host)}; ImmutableString{std::begin(dnsq->host), std::end(dnsq->host)};
auto host = StringRef{host_copy}; auto host = StringRef{host_copy};
@ -180,7 +181,7 @@ DNSResolverStatus DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
<< ", but it has been expired"; << ", but it has been expired";
} }
auto resolv = std::make_unique<DualDNSResolver>(loop_); auto resolv = std::make_unique<DualDNSResolver>(loop_, family_);
auto host = StringRef{ent.host}; auto host = StringRef{ent.host};
rv = resolv->resolve(host); rv = resolv->resolve(host);

View File

@ -75,7 +75,7 @@ struct ResolverEntry {
class DNSTracker { class DNSTracker {
public: public:
DNSTracker(struct ev_loop *loop); DNSTracker(struct ev_loop *loop, int family);
~DNSTracker(); ~DNSTracker();
// Lookups host name described in |dnsq|. If name lookup finishes // Lookups host name described in |dnsq|. If name lookup finishes
@ -111,6 +111,8 @@ private:
// increase memory consumption, interval could be very long. // increase memory consumption, interval could be very long.
ev_timer gc_timer_; ev_timer gc_timer_;
struct ev_loop *loop_; struct ev_loop *loop_;
// IP version preference.
int family_;
}; };
} // namespace shrpx } // namespace shrpx

View File

@ -26,8 +26,8 @@
namespace shrpx { namespace shrpx {
DualDNSResolver::DualDNSResolver(struct ev_loop *loop) DualDNSResolver::DualDNSResolver(struct ev_loop *loop, int family)
: resolv4_(loop), resolv6_(loop) { : family_(family), resolv4_(loop), resolv6_(loop) {
auto cb = [this](DNSResolverStatus, const Address *) { auto cb = [this](DNSResolverStatus, const Address *) {
Address result; Address result;
@ -44,14 +44,22 @@ DualDNSResolver::DualDNSResolver(struct ev_loop *loop)
cb(status, &result); cb(status, &result);
}; };
resolv4_.set_complete_cb(cb); if (family_ == AF_UNSPEC || family_ == AF_INET) {
resolv6_.set_complete_cb(cb); resolv4_.set_complete_cb(cb);
}
if (family_ == AF_UNSPEC || family_ == AF_INET6) {
resolv6_.set_complete_cb(cb);
}
} }
int DualDNSResolver::resolve(const StringRef &host) { int DualDNSResolver::resolve(const StringRef &host) {
int rv4, rv6; int rv4 = 0, rv6 = 0;
rv4 = resolv4_.resolve(host, AF_INET); if (family_ == AF_UNSPEC || family_ == AF_INET) {
rv6 = resolv6_.resolve(host, AF_INET6); rv4 = resolv4_.resolve(host, AF_INET);
}
if (family_ == AF_UNSPEC || family_ == AF_INET6) {
rv6 = resolv6_.resolve(host, AF_INET6);
}
if (rv4 != 0 && rv6 != 0) { if (rv4 != 0 && rv6 != 0) {
return -1; return -1;

View File

@ -42,7 +42,11 @@ namespace shrpx {
// how CompleteCb is called have the same semantics with DNSResolver. // how CompleteCb is called have the same semantics with DNSResolver.
class DualDNSResolver { class DualDNSResolver {
public: 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. // Resolves |host|. |host| must be NULL-terminated string.
int resolve(const StringRef &host); int resolve(const StringRef &host);
@ -51,6 +55,8 @@ public:
DNSResolverStatus get_status(Address *result) const; DNSResolverStatus get_status(Address *result) const;
private: private:
// IP version preference.
int family_;
// For A record // For A record
DNSResolver resolv4_; DNSResolver resolv4_;
// For AAAA record // For AAAA record

View File

@ -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 #endif // ENABLE_HTTP3 && HAVE_LIBBPF
randgen_(util::make_mt19937()), randgen_(util::make_mt19937()),
worker_stat_{}, worker_stat_{},
dns_tracker_(loop), dns_tracker_(loop, get_config()->conn.downstream->family),
#ifdef ENABLE_HTTP3 #ifdef ENABLE_HTTP3
quic_upstream_addrs_{get_config()->conn.quic_listener.addrs}, quic_upstream_addrs_{get_config()->conn.quic_listener.addrs},
#endif // ENABLE_HTTP3 #endif // ENABLE_HTTP3