Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make DnsResolver better #1443

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 17 additions & 28 deletions src/manager/DnsCache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,42 +23,31 @@

#define GET_CURRENT_SECOND std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now().time_since_epoch()).count()

#define CONFIDENT_INC 10
#define TTL_INC 10
#define TTL_INC 5

const DnsCache::DnsHandle *DnsCache::get_inner(const HostPort& host_port, int type)
const DnsCache::DnsHandle *DnsCache::get_inner(const HostPort& host_port,
int type)
{
int64_t cur_time = GET_CURRENT_SECOND;
int64_t cur = GET_CURRENT_SECOND;
std::lock_guard<std::mutex> lock(mutex_);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的cache_pool_返回const DnsHandle *,但下面又用const_cast去改value,这里多出的的const设计感觉很突兀

const DnsHandle *handle = cache_pool_.get(host_port);

if (handle)
if (handle && ((type == GET_TYPE_TTL && cur > handle->value.expire_time) ||
(type == GET_TYPE_CONFIDENT && cur > handle->value.confident_time)))
{
switch (type)
if (!handle->value.delayed())
{
case GET_TYPE_TTL:
if (cur_time > handle->value.expire_time)
{
const_cast<DnsHandle *>(handle)->value.expire_time += TTL_INC;
cache_pool_.release(handle);
return NULL;
}

break;

case GET_TYPE_CONFIDENT:
if (cur_time > handle->value.confident_time)
{
const_cast<DnsHandle *>(handle)->value.confident_time += CONFIDENT_INC;
cache_pool_.release(handle);
return NULL;
}

break;

default:
break;
DnsHandle *h = const_cast<DnsHandle *>(handle);
if (type == GET_TYPE_TTL)
h->value.expire_time += TTL_INC;
else
h->value.confident_time += TTL_INC;

h->value.addrinfo->ai_flags |= 2;
}

cache_pool_.release(handle);
return NULL;
}

return handle;
Expand Down
7 changes: 6 additions & 1 deletion src/manager/DnsCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ struct DnsCacheValue
struct addrinfo *addrinfo;
int64_t confident_time;
int64_t expire_time;

bool delayed() const
{
return addrinfo->ai_flags & 2;
}
};

// RAII: NO. Release handle by user
Expand Down Expand Up @@ -143,7 +148,7 @@ class DnsCache
{
struct addrinfo *ai = value.addrinfo;

if (ai && (ai->ai_flags & AI_PASSIVE))
if (ai && (ai->ai_flags & 1))
freeaddrinfo(ai);
else
protocol::DnsUtil::freeaddrinfo(ai);
Expand Down
106 changes: 79 additions & 27 deletions src/nameservice/WFDnsResolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,11 @@ static int __readaddrinfo(const char *path,
return ret;
}

// Add AI_PASSIVE to point that this addrinfo is alloced by getaddrinfo
static void __add_passive_flags(struct addrinfo *ai)
static void __set_thread_dns_flag(struct addrinfo *ai)
{
while (ai)
{
ai->ai_flags |= AI_PASSIVE;
ai->ai_flags = 1;
ai = ai->ai_next;
}
}
Expand All @@ -346,6 +345,32 @@ static ThreadDnsTask *__create_thread_dns_task(const std::string& host,
return task;
}

static std::string __get_cache_host(const std::string& hostname,
int family)
{
char c;

if (family == AF_UNSPEC)
c = '*';
else if (family == AF_INET)
c = '4';
else if (family == AF_INET6)
c = '6';
else
c = '?';

return hostname + c;
}

static std::string __get_guard_name(const std::string& cache_host,
unsigned short port)
{
std::string guard_name("INTERNAL-dns:");
guard_name.append(cache_host).append(":");
guard_name.append(std::to_string(port));
return guard_name;
}

void WFResolverTask::dispatch()
{
const ParsedURI& uri = ns_params_.uri;
Expand All @@ -355,11 +380,22 @@ void WFResolverTask::dispatch()
DnsCache *dns_cache = WFGlobal::get_dns_cache();
const DnsCache::DnsHandle *addr_handle;
std::string hostname = host_;
int family = ep_params_.address_family;
std::string cache_host = __get_cache_host(hostname, family);

if (ns_params_.retry_times == 0)
addr_handle = dns_cache->get_ttl(hostname, port_);
addr_handle = dns_cache->get_ttl(cache_host, port_);
else
addr_handle = dns_cache->get_confident(hostname, port_);
addr_handle = dns_cache->get_confident(cache_host, port_);

if (in_guard_ && (addr_handle == NULL || addr_handle->value.delayed()))
{
if (addr_handle)
dns_cache->release(addr_handle);

this->request_dns();
return;
}

if (addr_handle)
{
Expand Down Expand Up @@ -411,7 +447,7 @@ void WFResolverTask::dispatch()
DnsOutput dns_out;

DnsRoutine::run(&dns_in, &dns_out);
__add_passive_flags((struct addrinfo *)dns_out.get_addrinfo());
__set_thread_dns_flag((struct addrinfo *)dns_out.get_addrinfo());
dns_callback_internal(&dns_out, (unsigned int)-1, (unsigned int)-1);
this->subtask_done();
return;
Expand All @@ -434,13 +470,25 @@ void WFResolverTask::dispatch()
{
DnsOutput out;
DnsRoutine::create(&out, ret, ai);
__add_passive_flags((struct addrinfo *)out.get_addrinfo());
__set_thread_dns_flag((struct addrinfo *)out.get_addrinfo());
dns_callback_internal(&out, dns_ttl_default_, dns_ttl_min_);
this->subtask_done();
return;
}
}

std::string guard_name = __get_guard_name(cache_host, port_);
WFConditional *guard = WFTaskFactory::create_guard(guard_name, this);

in_guard_ = true;
has_next_ = true;

series_of(this)->push_front(guard);
this->subtask_done();
}

void WFResolverTask::request_dns()
{
WFDnsClient *client = WFGlobal::get_dns_client();
if (client)
{
Expand All @@ -456,7 +504,7 @@ void WFResolverTask::dispatch()
auto&& cb = std::bind(&WFResolverTask::dns_single_callback,
this,
std::placeholders::_1);
WFDnsTask *dns_task = client->create_dns_task(hostname, std::move(cb));
WFDnsTask *dns_task = client->create_dns_task(host_, std::move(cb));

if (family == AF_INET6)
dns_task->get_req()->set_question_type(DNS_TYPE_AAAA);
Expand All @@ -476,10 +524,10 @@ void WFResolverTask::dispatch()
dctx[0].port = port_;
dctx[1].port = port_;

task_v4 = client->create_dns_task(hostname, dns_partial_callback);
task_v4 = client->create_dns_task(host_, dns_partial_callback);
task_v4->user_data = dctx;

task_v6 = client->create_dns_task(hostname, dns_partial_callback);
task_v6 = client->create_dns_task(host_, dns_partial_callback);
task_v6->get_req()->set_question_type(DNS_TYPE_AAAA);
task_v6->user_data = dctx + 1;

Expand All @@ -504,7 +552,7 @@ void WFResolverTask::dispatch()
auto&& cb = std::bind(&WFResolverTask::thread_dns_callback,
this,
std::placeholders::_1);
dns_task = __create_thread_dns_task(hostname, port_,
dns_task = __create_thread_dns_task(host_, port_,
ep_params_.address_family,
std::move(cb));
series_of(this)->push_front(dns_task);
Expand All @@ -519,12 +567,7 @@ SubTask *WFResolverTask::done()
SeriesWork *series = series_of(this);

if (!has_next_)
{
if (this->callback)
this->callback(this);

delete this;
}
task_callback();
else
has_next_ = false;

Expand Down Expand Up @@ -558,8 +601,10 @@ void WFResolverTask::dns_callback_internal(void *thrd_dns_output,
struct addrinfo *addrinfo = dns_out->move_addrinfo();
const DnsCache::DnsHandle *addr_handle;
std::string hostname = host_;
int family = ep_params_.address_family;
std::string cache_host = __get_cache_host(hostname, family);

addr_handle = dns_cache->put(hostname, port_, addrinfo,
addr_handle = dns_cache->put(cache_host, port_, addrinfo,
(unsigned int)ttl_default,
(unsigned int)ttl_min);
if (route_manager->get(ns_params_.type, addrinfo, ns_params_.info,
Expand Down Expand Up @@ -596,10 +641,7 @@ void WFResolverTask::dns_single_callback(void *net_dns_task)
this->error = dns_task->get_error();
}

if (this->callback)
this->callback(this);

delete this;
task_callback();
}

void WFResolverTask::dns_partial_callback(void *net_dns_task)
Expand Down Expand Up @@ -659,10 +701,7 @@ void WFResolverTask::dns_parallel_callback(const void *parallel)

delete[] c4;

if (this->callback)
this->callback(this);

delete this;
task_callback();
}

void WFResolverTask::thread_dns_callback(void *thrd_dns_task)
Expand All @@ -672,7 +711,7 @@ void WFResolverTask::thread_dns_callback(void *thrd_dns_task)
if (dns_task->get_state() == WFT_STATE_SUCCESS)
{
DnsOutput *out = dns_task->get_output();
__add_passive_flags((struct addrinfo *)out->get_addrinfo());
__set_thread_dns_flag((struct addrinfo *)out->get_addrinfo());
dns_callback_internal(out, dns_ttl_default_, dns_ttl_min_);
}
else
Expand All @@ -681,6 +720,19 @@ void WFResolverTask::thread_dns_callback(void *thrd_dns_task)
this->error = dns_task->get_error();
}

task_callback();
}

void WFResolverTask::task_callback()
{
if (in_guard_)
{
int family = ep_params_.address_family;
std::string cache_host = __get_cache_host(host_, family);
std::string guard_name = __get_guard_name(cache_host, port_);
WFTaskFactory::release_guard_safe(guard_name);
}

if (this->callback)
this->callback(this);

Expand Down
6 changes: 6 additions & 0 deletions src/nameservice/WFDnsResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class WFResolverTask : public WFRouterTask
dns_ttl_default_ = dns_ttl_default;
dns_ttl_min_ = dns_ttl_min;
has_next_ = false;
in_guard_ = false;
}

WFResolverTask(const struct WFNSParams *ns_params,
Expand All @@ -46,6 +47,7 @@ class WFResolverTask : public WFRouterTask
ns_params_(*ns_params)
{
has_next_ = false;
in_guard_ = false;
}

protected:
Expand All @@ -62,6 +64,9 @@ class WFResolverTask : public WFRouterTask
unsigned int ttl_default,
unsigned int ttl_min);

void request_dns();
void task_callback();

protected:
struct WFNSParams ns_params_;
unsigned int dns_ttl_default_;
Expand All @@ -72,6 +77,7 @@ class WFResolverTask : public WFRouterTask
const char *host_;
unsigned short port_;
bool has_next_;
bool in_guard_;
};

class WFDnsResolver : public WFNSPolicy
Expand Down
Loading