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
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<DualDNSResolver>(loop_);
auto resolv = std::make_unique<DualDNSResolver>(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<DualDNSResolver>(loop_);
auto resolv = std::make_unique<DualDNSResolver>(loop_, family_);
auto host = StringRef{ent.host};
rv = resolv->resolve(host);

View File

@ -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

View File

@ -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;

View File

@ -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

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
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