nghttpx: Convert DNSResolverStatus to enum class
This commit is contained in:
parent
0963f38935
commit
00554779e1
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,7 +252,8 @@ 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(
|
||||||
|
[&ent, loop](DNSResolverStatus status, const Address *result) {
|
||||||
auto &qlist = ent.qlist;
|
auto &qlist = ent.qlist;
|
||||||
while (!qlist.empty()) {
|
while (!qlist.empty()) {
|
||||||
auto head = qlist.head;
|
auto head = qlist.head;
|
||||||
|
@ -272,7 +269,7 @@ void DNSTracker::add_to_qlist(ResolverEntry &ent, DNSQuery *dnsq) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue