nghttpx: Convert DNSResolverStatus to enum class

This commit is contained in:
Tatsuhiro Tsujikawa 2018-10-17 09:42:43 +09:00
parent 0963f38935
commit 00554779e1
9 changed files with 165 additions and 169 deletions

View File

@ -37,7 +37,7 @@ namespace {
void sock_state_cb(void *data, int s, int read, int write) { void sock_state_cb(void *data, int s, int read, int write) {
auto resolv = static_cast<DNSResolver *>(data); auto resolv = static_cast<DNSResolver *>(data);
if (resolv->get_status(nullptr) != DNS_STATUS_RUNNING) { if (resolv->get_status(nullptr) != DNSResolverStatus::RUNNING) {
return; return;
} }
@ -70,10 +70,12 @@ void process_result(DNSResolver *resolv) {
Address result; Address result;
auto status = resolv->get_status(&result); auto status = resolv->get_status(&result);
switch (status) { switch (status) {
case DNS_STATUS_OK: case DNSResolverStatus::OK:
case DNS_STATUS_ERROR: case DNSResolverStatus::ERROR:
cb(status, &result); cb(status, &result);
break; break;
default:
break;
} }
// resolv may be deleted here. // resolv may be deleted here.
} }
@ -117,7 +119,7 @@ DNSResolver::DNSResolver(struct ev_loop *loop)
loop_(loop), loop_(loop),
channel_(nullptr), channel_(nullptr),
family_(AF_UNSPEC), family_(AF_UNSPEC),
status_(DNS_STATUS_IDLE) { status_(DNSResolverStatus::IDLE) {
ev_timer_init(&timer_, timeoutcb, 0., 0.); ev_timer_init(&timer_, timeoutcb, 0., 0.);
timer_.data = this; timer_.data = this;
} }
@ -134,7 +136,7 @@ DNSResolver::~DNSResolver() {
} }
int DNSResolver::resolve(const StringRef &name, int family) { int DNSResolver::resolve(const StringRef &name, int family) {
if (status_ != DNS_STATUS_IDLE) { if (status_ != DNSResolverStatus::IDLE) {
return -1; return -1;
} }
@ -164,12 +166,12 @@ int DNSResolver::resolve(const StringRef &name, int family) {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "ares_init_options failed: " << ares_strerror(rv); LOG(INFO) << "ares_init_options failed: " << ares_strerror(rv);
} }
status_ = DNS_STATUS_ERROR; status_ = DNSResolverStatus::ERROR;
return -1; return -1;
} }
channel_ = chan; channel_ = chan;
status_ = DNS_STATUS_RUNNING; status_ = DNSResolverStatus::RUNNING;
ares_gethostbyname(channel_, name_.c_str(), family_, host_cb, this); ares_gethostbyname(channel_, name_.c_str(), family_, host_cb, this);
reset_timeout(); reset_timeout();
@ -186,20 +188,19 @@ int DNSResolver::on_timeout() {
} }
int DNSResolver::handle_event(int rfd, int wfd) { int DNSResolver::handle_event(int rfd, int wfd) {
if (status_ == DNS_STATUS_IDLE) { if (status_ == DNSResolverStatus::IDLE) {
return -1; return -1;
} }
ares_process_fd(channel_, rfd, wfd); ares_process_fd(channel_, rfd, wfd);
switch (status_) { switch (status_) {
case DNS_STATUS_RUNNING: { case DNSResolverStatus::RUNNING:
reset_timeout(); reset_timeout();
return 0; return 0;
} case DNSResolverStatus::OK:
case DNS_STATUS_OK:
return 0; return 0;
case DNS_STATUS_ERROR: case DNSResolverStatus::ERROR:
return -1; return -1;
default: default:
// Unreachable // Unreachable
@ -209,7 +210,7 @@ int DNSResolver::handle_event(int rfd, int wfd) {
} }
void DNSResolver::reset_timeout() { void DNSResolver::reset_timeout() {
if (status_ != DNS_STATUS_RUNNING) { if (status_ != DNSResolverStatus::RUNNING) {
return; return;
} }
timeval tvout; timeval tvout;
@ -223,8 +224,8 @@ void DNSResolver::reset_timeout() {
ev_timer_again(loop_, &timer_); ev_timer_again(loop_, &timer_);
} }
int DNSResolver::get_status(Address *result) const { DNSResolverStatus DNSResolver::get_status(Address *result) const {
if (status_ != DNS_STATUS_OK) { if (status_ != DNSResolverStatus::OK) {
return status_; return status_;
} }
@ -294,7 +295,7 @@ void DNSResolver::on_result(int status, hostent *hostent) {
LOG(INFO) << "Name lookup for " << name_ LOG(INFO) << "Name lookup for " << name_
<< " failed: " << ares_strerror(status); << " failed: " << ares_strerror(status);
} }
status_ = DNS_STATUS_ERROR; status_ = DNSResolverStatus::ERROR;
return; return;
} }
@ -303,13 +304,13 @@ void DNSResolver::on_result(int status, hostent *hostent) {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "Name lookup for " << name_ << "failed: no address returned"; LOG(INFO) << "Name lookup for " << name_ << "failed: no address returned";
} }
status_ = DNS_STATUS_ERROR; status_ = DNSResolverStatus::ERROR;
return; return;
} }
switch (hostent->h_addrtype) { switch (hostent->h_addrtype) {
case AF_INET: case AF_INET:
status_ = DNS_STATUS_OK; status_ = DNSResolverStatus::OK;
result_.len = sizeof(result_.su.in); result_.len = sizeof(result_.su.in);
result_.su.in = {}; result_.su.in = {};
result_.su.in.sin_family = AF_INET; result_.su.in.sin_family = AF_INET;
@ -319,7 +320,7 @@ void DNSResolver::on_result(int status, hostent *hostent) {
memcpy(&result_.su.in.sin_addr, ap, sizeof(result_.su.in.sin_addr)); memcpy(&result_.su.in.sin_addr, ap, sizeof(result_.su.in.sin_addr));
break; break;
case AF_INET6: case AF_INET6:
status_ = DNS_STATUS_OK; status_ = DNSResolverStatus::OK;
result_.len = sizeof(result_.su.in6); result_.len = sizeof(result_.su.in6);
result_.su.in6 = {}; result_.su.in6 = {};
result_.su.in6.sin6_family = AF_INET6; result_.su.in6.sin6_family = AF_INET6;
@ -332,7 +333,7 @@ void DNSResolver::on_result(int status, hostent *hostent) {
assert(0); assert(0);
} }
if (status_ == DNS_STATUS_OK) { if (status_ == DNSResolverStatus::OK) {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "Name lookup succeeded: " << name_ << " -> " LOG(INFO) << "Name lookup succeeded: " << name_ << " -> "
<< util::numeric_name(&result_.su.sa, result_.len); << util::numeric_name(&result_.su.sa, result_.len);
@ -340,7 +341,7 @@ void DNSResolver::on_result(int status, hostent *hostent) {
return; return;
} }
status_ = DNS_STATUS_ERROR; status_ = DNSResolverStatus::ERROR;
} }
void DNSResolver::set_complete_cb(CompleteCb cb) { void DNSResolver::set_complete_cb(CompleteCb cb) {

View File

@ -42,27 +42,29 @@ using namespace nghttp2;
namespace shrpx { namespace shrpx {
enum DNSResolverStatus { enum class DNSResolverStatus {
// Resolver is in initial status // Resolver is in initial status
DNS_STATUS_IDLE, IDLE,
// Resolver is currently resolving host name // Resolver is currently resolving host name
DNS_STATUS_RUNNING, RUNNING,
// Resolver successfully resolved host name // Resolver successfully resolved host name
DNS_STATUS_OK, OK,
// Resolver failed to resolve host name // Resolver failed to resolve host name
DNS_STATUS_ERROR, ERROR,
}; };
// Callback function called when host name lookup is finished. // Callback function called when host name lookup is finished.
// |status| is either DNS_STATUS_OK, or DNS_STATUS_ERROR. If |status| // |status| is either DNSResolverStatus::OK, or
// is DNS_STATUS_OK, |result| points to the resolved address. Note // DNSResolverStatus::ERROR. If |status| is DNSResolverStatus::OK,
// that port portion of |result| is undefined, and must be initialized // |result| points to the resolved address. Note that port portion of
// by application. This callback function is not called if name // |result| is undefined, and must be initialized by application.
// lookup finishes in DNSResolver::resolve() completely. In this // This callback function is not called if name lookup finishes in
// case, application should call DNSResolver::get_status() to get // DNSResolver::resolve() completely. In this case, application
// current status and result. In other words, callback is called if // should call DNSResolver::get_status() to get current status and
// get_status() returns DNS_STATUS_RUNNING. // result. In other words, callback is called if get_status() returns
using CompleteCb = std::function<void(int status, const Address *result)>; // DNSResolverStatus::RUNNING.
using CompleteCb =
std::function<void(DNSResolverStatus status, const Address *result)>;
// DNSResolver is asynchronous name resolver, backed by c-ares // DNSResolver is asynchronous name resolver, backed by c-ares
// library. // library.
@ -73,9 +75,9 @@ public:
// Starts resolving hostname |name|. // Starts resolving hostname |name|.
int resolve(const StringRef &name, int family); int resolve(const StringRef &name, int family);
// Returns status. If status_ is DNS_STATUS_SUCCESS && |result| is // Returns status. If status_ is DNSResolverStatus::SUCCESS &&
// not nullptr, |*result| is filled. // |result| is not nullptr, |*result| is filled.
int get_status(Address *result) const; DNSResolverStatus get_status(Address *result) const;
// Sets callback function when name lookup finishes. The callback // Sets callback function when name lookup finishes. The callback
// function is called in a way that it can destroy this DNSResolver. // function is called in a way that it can destroy this DNSResolver.
void set_complete_cb(CompleteCb cb); void set_complete_cb(CompleteCb cb);
@ -108,7 +110,7 @@ private:
// AF_INET or AF_INET6. AF_INET for A record lookup, and AF_INET6 // AF_INET or AF_INET6. AF_INET for A record lookup, and AF_INET6
// for AAAA record lookup. // for AAAA record lookup.
int family_; int family_;
int status_; DNSResolverStatus status_;
}; };
} // namespace shrpx } // namespace shrpx

View File

@ -49,7 +49,7 @@ DNSTracker::~DNSTracker() {
while (!qlist.empty()) { while (!qlist.empty()) {
auto head = qlist.head; auto head = qlist.head;
qlist.remove(head); qlist.remove(head);
head->status = DNS_STATUS_ERROR; head->status = DNSResolverStatus::ERROR;
head->in_qlist = false; head->in_qlist = false;
// TODO Not sure we should call callback here, or it is even be // TODO Not sure we should call callback here, or it is even be
// safe to do that. // safe to do that.
@ -58,7 +58,8 @@ DNSTracker::~DNSTracker() {
} }
ResolverEntry DNSTracker::make_entry(std::unique_ptr<DualDNSResolver> resolv, ResolverEntry DNSTracker::make_entry(std::unique_ptr<DualDNSResolver> resolv,
ImmutableString host, int status, ImmutableString host,
DNSResolverStatus status,
const Address *result) { const Address *result) {
auto &dnsconf = get_config()->dns; auto &dnsconf = get_config()->dns;
@ -67,10 +68,12 @@ ResolverEntry DNSTracker::make_entry(std::unique_ptr<DualDNSResolver> resolv,
ent.host = std::move(host); ent.host = std::move(host);
ent.status = status; ent.status = status;
switch (status) { switch (status) {
case DNS_STATUS_ERROR: case DNSResolverStatus::ERROR:
case DNS_STATUS_OK: case DNSResolverStatus::OK:
ent.expiry = ev_now(loop_) + dnsconf.timeout.cache; ent.expiry = ev_now(loop_) + dnsconf.timeout.cache;
break; break;
default:
break;
} }
if (result) { if (result) {
ent.result = *result; ent.result = *result;
@ -80,23 +83,25 @@ ResolverEntry DNSTracker::make_entry(std::unique_ptr<DualDNSResolver> resolv,
void DNSTracker::update_entry(ResolverEntry &ent, void DNSTracker::update_entry(ResolverEntry &ent,
std::unique_ptr<DualDNSResolver> resolv, std::unique_ptr<DualDNSResolver> resolv,
int status, const Address *result) { DNSResolverStatus status, const Address *result) {
auto &dnsconf = get_config()->dns; auto &dnsconf = get_config()->dns;
ent.resolv = std::move(resolv); ent.resolv = std::move(resolv);
ent.status = status; ent.status = status;
switch (status) { switch (status) {
case DNS_STATUS_ERROR: case DNSResolverStatus::ERROR:
case DNS_STATUS_OK: case DNSResolverStatus::OK:
ent.expiry = ev_now(loop_) + dnsconf.timeout.cache; ent.expiry = ev_now(loop_) + dnsconf.timeout.cache;
break; break;
default:
break;
} }
if (result) { if (result) {
ent.result = *result; ent.result = *result;
} }
} }
int DNSTracker::resolve(Address *result, DNSQuery *dnsq) { DNSResolverStatus DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
int rv; int rv;
auto it = ents_.find(dnsq->host); auto it = ents_.find(dnsq->host);
@ -118,46 +123,41 @@ int DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
} }
ents_.emplace(host, make_entry(nullptr, std::move(host_copy), ents_.emplace(host, make_entry(nullptr, std::move(host_copy),
DNS_STATUS_ERROR, nullptr)); DNSResolverStatus::ERROR, nullptr));
start_gc_timer(); start_gc_timer();
return DNS_STATUS_ERROR; return DNSResolverStatus::ERROR;
} }
rv = resolv->get_status(result); switch (resolv->get_status(result)) {
switch (rv) { case DNSResolverStatus::ERROR:
case DNS_STATUS_ERROR: {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "Name lookup failed for " << host; LOG(INFO) << "Name lookup failed for " << host;
} }
ents_.emplace(host, make_entry(nullptr, std::move(host_copy), ents_.emplace(host, make_entry(nullptr, std::move(host_copy),
DNS_STATUS_ERROR, nullptr)); DNSResolverStatus::ERROR, nullptr));
start_gc_timer(); start_gc_timer();
return DNS_STATUS_ERROR; return DNSResolverStatus::ERROR;
} case DNSResolverStatus::OK:
case DNS_STATUS_OK: {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "Name lookup succeeded: " << host << " -> " LOG(INFO) << "Name lookup succeeded: " << host << " -> "
<< util::numeric_name(&result->su.sa, result->len); << util::numeric_name(&result->su.sa, result->len);
} }
ents_.emplace(host, make_entry(nullptr, std::move(host_copy), ents_.emplace(host, make_entry(nullptr, std::move(host_copy),
DNS_STATUS_OK, result)); DNSResolverStatus::OK, result));
start_gc_timer(); start_gc_timer();
return DNS_STATUS_OK; return DNSResolverStatus::OK;
} case DNSResolverStatus::RUNNING: {
case DNS_STATUS_RUNNING: {
assert(rv == DNS_STATUS_RUNNING);
auto p = ents_.emplace(host, auto p = ents_.emplace(host,
make_entry(std::move(resolv), std::move(host_copy), make_entry(std::move(resolv), std::move(host_copy),
DNS_STATUS_RUNNING, nullptr)); DNSResolverStatus::RUNNING, nullptr));
start_gc_timer(); start_gc_timer();
@ -165,7 +165,7 @@ int DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
add_to_qlist(ent, dnsq); add_to_qlist(ent, dnsq);
return DNS_STATUS_RUNNING; return DNSResolverStatus::RUNNING;
} }
default: default:
assert(0); assert(0);
@ -174,7 +174,7 @@ int DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
auto &ent = (*it).second; auto &ent = (*it).second;
if (ent.status != DNS_STATUS_RUNNING && ent.expiry < ev_now(loop_)) { if (ent.status != DNSResolverStatus::RUNNING && ent.expiry < ev_now(loop_)) {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "DNS entry found for " << dnsq->host LOG(INFO) << "DNS entry found for " << dnsq->host
<< ", but it has been expired"; << ", but it has been expired";
@ -189,57 +189,53 @@ int DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
LOG(INFO) << "Name lookup failed for " << host; LOG(INFO) << "Name lookup failed for " << host;
} }
update_entry(ent, nullptr, DNS_STATUS_ERROR, nullptr); update_entry(ent, nullptr, DNSResolverStatus::ERROR, nullptr);
return DNS_STATUS_ERROR; return DNSResolverStatus::ERROR;
} }
rv = resolv->get_status(result); switch (resolv->get_status(result)) {
switch (rv) { case DNSResolverStatus::ERROR:
case DNS_STATUS_ERROR: {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "Name lookup failed for " << host; LOG(INFO) << "Name lookup failed for " << host;
} }
update_entry(ent, nullptr, DNS_STATUS_ERROR, nullptr); update_entry(ent, nullptr, DNSResolverStatus::ERROR, nullptr);
return DNS_STATUS_ERROR; return DNSResolverStatus::ERROR;
} case DNSResolverStatus::OK:
case DNS_STATUS_OK: {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "Name lookup succeeded: " << host << " -> " LOG(INFO) << "Name lookup succeeded: " << host << " -> "
<< util::numeric_name(&result->su.sa, result->len); << util::numeric_name(&result->su.sa, result->len);
} }
update_entry(ent, nullptr, DNS_STATUS_OK, result); update_entry(ent, nullptr, DNSResolverStatus::OK, result);
return DNS_STATUS_OK; return DNSResolverStatus::OK;
} case DNSResolverStatus::RUNNING:
case DNS_STATUS_RUNNING: { update_entry(ent, std::move(resolv), DNSResolverStatus::RUNNING, nullptr);
update_entry(ent, std::move(resolv), DNS_STATUS_RUNNING, nullptr);
add_to_qlist(ent, dnsq); add_to_qlist(ent, dnsq);
return DNS_STATUS_RUNNING; return DNSResolverStatus::RUNNING;
}
default: default:
assert(0); assert(0);
} }
} }
switch (ent.status) { switch (ent.status) {
case DNS_STATUS_RUNNING: case DNSResolverStatus::RUNNING:
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "Waiting for name lookup complete for " << dnsq->host; LOG(INFO) << "Waiting for name lookup complete for " << dnsq->host;
} }
ent.qlist.append(dnsq); ent.qlist.append(dnsq);
dnsq->in_qlist = true; dnsq->in_qlist = true;
return DNS_STATUS_RUNNING; return DNSResolverStatus::RUNNING;
case DNS_STATUS_ERROR: case DNSResolverStatus::ERROR:
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "Name lookup failed for " << dnsq->host << " (cached)"; LOG(INFO) << "Name lookup failed for " << dnsq->host << " (cached)";
} }
return DNS_STATUS_ERROR; return DNSResolverStatus::ERROR;
case DNS_STATUS_OK: case DNSResolverStatus::OK:
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "Name lookup succeeded (cached): " << dnsq->host << " -> " LOG(INFO) << "Name lookup succeeded (cached): " << dnsq->host << " -> "
<< util::numeric_name(&ent.result.su.sa, ent.result.len); << util::numeric_name(&ent.result.su.sa, ent.result.len);
@ -247,7 +243,7 @@ int DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
if (result) { if (result) {
memcpy(result, &ent.result, sizeof(*result)); memcpy(result, &ent.result, sizeof(*result));
} }
return DNS_STATUS_OK; return DNSResolverStatus::OK;
default: default:
assert(0); assert(0);
abort(); abort();
@ -256,26 +252,27 @@ int DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
void DNSTracker::add_to_qlist(ResolverEntry &ent, DNSQuery *dnsq) { void DNSTracker::add_to_qlist(ResolverEntry &ent, DNSQuery *dnsq) {
auto loop = loop_; auto loop = loop_;
ent.resolv->set_complete_cb([&ent, loop](int status, const Address *result) { ent.resolv->set_complete_cb(
auto &qlist = ent.qlist; [&ent, loop](DNSResolverStatus status, const Address *result) {
while (!qlist.empty()) { auto &qlist = ent.qlist;
auto head = qlist.head; while (!qlist.empty()) {
qlist.remove(head); auto head = qlist.head;
head->status = status; qlist.remove(head);
head->in_qlist = false; head->status = status;
auto cb = head->cb; head->in_qlist = false;
cb(status, result); auto cb = head->cb;
} cb(status, result);
}
auto &dnsconf = get_config()->dns; auto &dnsconf = get_config()->dns;
ent.resolv.reset(); ent.resolv.reset();
ent.status = status; ent.status = status;
ent.expiry = ev_now(loop) + dnsconf.timeout.cache; ent.expiry = ev_now(loop) + dnsconf.timeout.cache;
if (ent.status == DNS_STATUS_OK) { if (ent.status == DNSResolverStatus::OK) {
ent.result = *result; ent.result = *result;
} }
}); });
ent.qlist.append(dnsq); ent.qlist.append(dnsq);
dnsq->in_qlist = true; dnsq->in_qlist = true;
} }

View File

@ -41,7 +41,7 @@ struct DNSQuery {
cb(std::move(cb)), cb(std::move(cb)),
dlnext(nullptr), dlnext(nullptr),
dlprev(nullptr), dlprev(nullptr),
status(DNS_STATUS_IDLE), status(DNSResolverStatus::IDLE),
in_qlist(false) {} in_qlist(false) {}
// Host name we lookup for. // Host name we lookup for.
@ -51,7 +51,7 @@ struct DNSQuery {
// DNSTracker::resolve(). // DNSTracker::resolve().
CompleteCb cb; CompleteCb cb;
DNSQuery *dlnext, *dlprev; DNSQuery *dlnext, *dlprev;
int status; DNSResolverStatus status;
// true if this object is in linked list ResolverEntry::qlist. // true if this object is in linked list ResolverEntry::qlist.
bool in_qlist; bool in_qlist;
}; };
@ -59,13 +59,14 @@ struct DNSQuery {
struct ResolverEntry { struct ResolverEntry {
// Host name this entry lookups for. // Host name this entry lookups for.
ImmutableString host; ImmutableString host;
// DNS resolver. Only non-nullptr if status is DNS_STATUS_RUNNING. // DNS resolver. Only non-nullptr if status is
// DNSResolverStatus::RUNNING.
std::unique_ptr<DualDNSResolver> resolv; std::unique_ptr<DualDNSResolver> resolv;
// DNSQuery interested in this name lookup result. The result is // DNSQuery interested in this name lookup result. The result is
// notified to them all. // notified to them all.
DList<DNSQuery> qlist; DList<DNSQuery> qlist;
// Use the same enum with DNSResolverStatus // Use the same enum with DNSResolverStatus
int status; DNSResolverStatus status;
// result and its expiry time // result and its expiry time
Address result; Address result;
// time point when cached result expires. // time point when cached result expires.
@ -80,12 +81,13 @@ public:
// Lookups host name described in |dnsq|. If name lookup finishes // Lookups host name described in |dnsq|. If name lookup finishes
// within this function (either it came from /etc/hosts, host name // within this function (either it came from /etc/hosts, host name
// is numeric, lookup result is cached, etc), it returns // is numeric, lookup result is cached, etc), it returns
// DNS_STATUS_OK or DNS_STATUS_ERROR. If lookup is successful, // DNSResolverStatus::OK or DNSResolverStatus::ERROR. If lookup is
// DNS_STATUS_OK is returned, and |result| is filled. If lookup // successful, DNSResolverStatus::OK is returned, and |result| is
// failed, DNS_STATUS_ERROR is returned. If name lookup is being // filled. If lookup failed, DNSResolverStatus::ERROR is returned.
// done background, it returns DNS_STATUS_RUNNING. Its completion // If name lookup is being done background, it returns
// is notified by calling dnsq->cb. // DNSResolverStatus::RUNNING. Its completion is notified by
int resolve(Address *result, DNSQuery *dnsq); // calling dnsq->cb.
DNSResolverStatus resolve(Address *result, DNSQuery *dnsq);
// Cancels name lookup requested by |dnsq|. // Cancels name lookup requested by |dnsq|.
void cancel(DNSQuery *dnsq); void cancel(DNSQuery *dnsq);
// Removes expired entries from ents_. // Removes expired entries from ents_.
@ -95,11 +97,11 @@ public:
private: private:
ResolverEntry make_entry(std::unique_ptr<DualDNSResolver> resolv, ResolverEntry make_entry(std::unique_ptr<DualDNSResolver> resolv,
ImmutableString host, int status, ImmutableString host, DNSResolverStatus status,
const Address *result); const Address *result);
void update_entry(ResolverEntry &ent, std::unique_ptr<DualDNSResolver> resolv, void update_entry(ResolverEntry &ent, std::unique_ptr<DualDNSResolver> resolv,
int status, const Address *result); DNSResolverStatus status, const Address *result);
void add_to_qlist(ResolverEntry &ent, DNSQuery *dnsq); void add_to_qlist(ResolverEntry &ent, DNSQuery *dnsq);

View File

@ -28,21 +28,20 @@ namespace shrpx {
DualDNSResolver::DualDNSResolver(struct ev_loop *loop) DualDNSResolver::DualDNSResolver(struct ev_loop *loop)
: resolv4_(loop), resolv6_(loop) { : resolv4_(loop), resolv6_(loop) {
auto cb = [this](int, const Address *) { auto cb = [this](DNSResolverStatus, const Address *) {
int rv;
Address result; Address result;
rv = this->get_status(&result); auto status = this->get_status(&result);
switch (rv) { switch (status) {
case DNS_STATUS_ERROR: case DNSResolverStatus::ERROR:
case DNS_STATUS_OK: case DNSResolverStatus::OK:
break; break;
default: default:
return; return;
} }
auto cb = this->get_complete_cb(); auto cb = this->get_complete_cb();
cb(rv, &result); cb(status, &result);
}; };
resolv4_.set_complete_cb(cb); resolv4_.set_complete_cb(cb);
@ -65,23 +64,22 @@ CompleteCb DualDNSResolver::get_complete_cb() const { return complete_cb_; }
void DualDNSResolver::set_complete_cb(CompleteCb cb) { complete_cb_ = cb; } void DualDNSResolver::set_complete_cb(CompleteCb cb) { complete_cb_ = cb; }
int DualDNSResolver::get_status(Address *result) const { DNSResolverStatus DualDNSResolver::get_status(Address *result) const {
int rv4, rv6; auto rv6 = resolv6_.get_status(result);
rv6 = resolv6_.get_status(result); if (rv6 == DNSResolverStatus::OK) {
if (rv6 == DNS_STATUS_OK) { return DNSResolverStatus::OK;
return DNS_STATUS_OK;
} }
rv4 = resolv4_.get_status(result); auto rv4 = resolv4_.get_status(result);
if (rv4 == DNS_STATUS_OK) { if (rv4 == DNSResolverStatus::OK) {
return DNS_STATUS_OK; return DNSResolverStatus::OK;
} }
if (rv4 == DNS_STATUS_RUNNING || rv6 == DNS_STATUS_RUNNING) { if (rv4 == DNSResolverStatus::RUNNING || rv6 == DNSResolverStatus::RUNNING) {
return DNS_STATUS_RUNNING; return DNSResolverStatus::RUNNING;
} }
if (rv4 == DNS_STATUS_ERROR || rv6 == DNS_STATUS_ERROR) { if (rv4 == DNSResolverStatus::ERROR || rv6 == DNSResolverStatus::ERROR) {
return DNS_STATUS_ERROR; return DNSResolverStatus::ERROR;
} }
return DNS_STATUS_IDLE; return DNSResolverStatus::IDLE;
} }
} // namespace shrpx } // namespace shrpx

View File

@ -48,7 +48,7 @@ public:
int resolve(const StringRef &host); int resolve(const StringRef &host);
CompleteCb get_complete_cb() const; CompleteCb get_complete_cb() const;
void set_complete_cb(CompleteCb cb); void set_complete_cb(CompleteCb cb);
int get_status(Address *result) const; DNSResolverStatus get_status(Address *result) const;
private: private:
// For A record // For A record

View File

@ -305,13 +305,11 @@ int Http2Session::disconnect(bool hard) {
} }
int Http2Session::resolve_name() { int Http2Session::resolve_name() {
int rv;
auto dns_query = std::make_unique<DNSQuery>( auto dns_query = std::make_unique<DNSQuery>(
addr_->host, [this](int status, const Address *result) { addr_->host, [this](DNSResolverStatus status, const Address *result) {
int rv; int rv;
if (status == DNS_STATUS_OK) { if (status == DNSResolverStatus::OK) {
*resolved_addr_ = *result; *resolved_addr_ = *result;
util::set_port(*this->resolved_addr_, this->addr_->port); util::set_port(*this->resolved_addr_, this->addr_->port);
} }
@ -323,15 +321,14 @@ int Http2Session::resolve_name() {
}); });
resolved_addr_ = std::make_unique<Address>(); resolved_addr_ = std::make_unique<Address>();
auto dns_tracker = worker_->get_dns_tracker(); auto dns_tracker = worker_->get_dns_tracker();
rv = dns_tracker->resolve(resolved_addr_.get(), dns_query.get()); switch (dns_tracker->resolve(resolved_addr_.get(), dns_query.get())) {
switch (rv) { case DNSResolverStatus::ERROR:
case DNS_STATUS_ERROR:
return -1; return -1;
case DNS_STATUS_RUNNING: case DNSResolverStatus::RUNNING:
dns_query_ = std::move(dns_query); dns_query_ = std::move(dns_query);
state_ = RESOLVING_NAME; state_ = RESOLVING_NAME;
return 0; return 0;
case DNS_STATUS_OK: case DNSResolverStatus::OK:
util::set_port(*resolved_addr_, addr_->port); util::set_port(*resolved_addr_, addr_->port);
return 0; return 0;
default: default:
@ -469,11 +466,11 @@ int Http2Session::initiate_connection() {
} }
if (state_ == RESOLVING_NAME) { if (state_ == RESOLVING_NAME) {
if (dns_query_->status == DNS_STATUS_ERROR) { if (dns_query_->status == DNSResolverStatus::ERROR) {
downstream_failure(addr_, nullptr); downstream_failure(addr_, nullptr);
return -1; return -1;
} }
assert(dns_query_->status == DNS_STATUS_OK); assert(dns_query_->status == DNSResolverStatus::OK);
state_ = DISCONNECTED; state_ = DISCONNECTED;
dns_query_.reset(); dns_query_.reset();
raddr_ = resolved_addr_.get(); raddr_ = resolved_addr_.get();
@ -534,11 +531,11 @@ int Http2Session::initiate_connection() {
} }
if (state_ == RESOLVING_NAME) { if (state_ == RESOLVING_NAME) {
if (dns_query_->status == DNS_STATUS_ERROR) { if (dns_query_->status == DNSResolverStatus::ERROR) {
downstream_failure(addr_, nullptr); downstream_failure(addr_, nullptr);
return -1; return -1;
} }
assert(dns_query_->status == DNS_STATUS_OK); assert(dns_query_->status == DNSResolverStatus::OK);
state_ = DISCONNECTED; state_ = DISCONNECTED;
dns_query_.reset(); dns_query_.reset();
raddr_ = resolved_addr_.get(); raddr_ = resolved_addr_.get();

View File

@ -317,10 +317,11 @@ int HttpDownstreamConnection::initiate_connection() {
if (addr->dns) { if (addr->dns) {
if (!check_dns_result) { if (!check_dns_result) {
auto dns_query = std::make_unique<DNSQuery>( auto dns_query = std::make_unique<DNSQuery>(
addr->host, [this](int status, const Address *result) { addr->host,
[this](DNSResolverStatus status, const Address *result) {
int rv; int rv;
if (status == DNS_STATUS_OK) { if (status == DNSResolverStatus::OK) {
*this->resolved_addr_ = *result; *this->resolved_addr_ = *result;
} }
@ -337,31 +338,30 @@ int HttpDownstreamConnection::initiate_connection() {
if (!resolved_addr_) { if (!resolved_addr_) {
resolved_addr_ = std::make_unique<Address>(); resolved_addr_ = std::make_unique<Address>();
} }
rv = dns_tracker->resolve(resolved_addr_.get(), dns_query.get()); switch (dns_tracker->resolve(resolved_addr_.get(), dns_query.get())) {
switch (rv) { case DNSResolverStatus::ERROR:
case DNS_STATUS_ERROR:
downstream_failure(addr, nullptr); downstream_failure(addr, nullptr);
if (end == next_downstream) { if (end == next_downstream) {
return SHRPX_ERR_NETWORK; return SHRPX_ERR_NETWORK;
} }
continue; continue;
case DNS_STATUS_RUNNING: case DNSResolverStatus::RUNNING:
dns_query_ = std::move(dns_query); dns_query_ = std::move(dns_query);
// Remember current addr // Remember current addr
addr_ = addr; addr_ = addr;
return 0; return 0;
case DNS_STATUS_OK: case DNSResolverStatus::OK:
break; break;
default: default:
assert(0); assert(0);
} }
} else { } else {
switch (dns_query_->status) { switch (dns_query_->status) {
case DNS_STATUS_ERROR: case DNSResolverStatus::ERROR:
dns_query_.reset(); dns_query_.reset();
downstream_failure(addr, nullptr); downstream_failure(addr, nullptr);
continue; continue;
case DNS_STATUS_OK: case DNSResolverStatus::OK:
dns_query_.reset(); dns_query_.reset();
break; break;
default: default:

View File

@ -228,10 +228,10 @@ int LiveCheck::initiate_connection() {
if (addr_->dns) { if (addr_->dns) {
if (!dns_query_) { if (!dns_query_) {
auto dns_query = std::make_unique<DNSQuery>( auto dns_query = std::make_unique<DNSQuery>(
addr_->host, [this](int status, const Address *result) { addr_->host, [this](DNSResolverStatus status, const Address *result) {
int rv; int rv;
if (status == DNS_STATUS_OK) { if (status == DNSResolverStatus::OK) {
*this->resolved_addr_ = *result; *this->resolved_addr_ = *result;
} }
rv = this->initiate_connection(); rv = this->initiate_connection();
@ -245,24 +245,23 @@ int LiveCheck::initiate_connection() {
resolved_addr_ = std::make_unique<Address>(); resolved_addr_ = std::make_unique<Address>();
} }
rv = dns_tracker->resolve(resolved_addr_.get(), dns_query.get()); switch (dns_tracker->resolve(resolved_addr_.get(), dns_query.get())) {
switch (rv) { case DNSResolverStatus::ERROR:
case DNS_STATUS_ERROR:
return -1; return -1;
case DNS_STATUS_RUNNING: case DNSResolverStatus::RUNNING:
dns_query_ = std::move(dns_query); dns_query_ = std::move(dns_query);
return 0; return 0;
case DNS_STATUS_OK: case DNSResolverStatus::OK:
break; break;
default: default:
assert(0); assert(0);
} }
} else { } else {
switch (dns_query_->status) { switch (dns_query_->status) {
case DNS_STATUS_ERROR: case DNSResolverStatus::ERROR:
dns_query_.reset(); dns_query_.reset();
return -1; return -1;
case DNS_STATUS_OK: case DNSResolverStatus::OK:
dns_query_.reset(); dns_query_.reset();
break; break;
default: default: