Skip to content

Commit f11a9ee

Browse files
committed
Fix on domain resolver
1 parent d6562fe commit f11a9ee

1 file changed

Lines changed: 40 additions & 17 deletions

File tree

net/utils.cpp

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -266,36 +266,59 @@ class DefaultResolver : public Resolver {
266266
struct IPAddrList : public intrusive_list<IPAddrNode>, spinlock {
267267
~IPAddrList() { delete_all(); }
268268
};
269+
struct ResolveCtx {
270+
std::string host;
271+
Delegate<bool, IPAddr> filter;
272+
spinlock lock;
273+
IPAddrList *addrs;
274+
photon::semaphore sem;
275+
};
269276
IPAddr do_resolve(std::string_view host, Delegate<bool, IPAddr> filter) {
270277
auto ctr = [&]() -> IPAddrList* {
271278
auto addrs = new IPAddrList();
272-
photon::semaphore sem;
273-
std::thread([&]() {
274-
auto now = std::chrono::steady_clock::now();
279+
std::shared_ptr<ResolveCtx> ctx = std::make_shared<ResolveCtx>();
280+
ctx->addrs = addrs;
281+
ctx->host = std::string(host);
282+
ctx->filter = filter;
283+
std::thread([ctx]() {
275284
IPAddrList ret;
276285
auto cb = [&](IPAddr addr) -> int {
277-
if (filter && !filter.fire(addr))
286+
SCOPED_LOCK(ctx->lock);
287+
if (ctx->filter && !ctx->filter.fire(addr))
278288
return 0;
279289
ret.push_back(new IPAddrNode(addr));
280290
return 0;
281291
};
282-
_gethostbyname(host, cb);
283-
auto time_elapsed = std::chrono::duration_cast<std::chrono::microseconds>(
284-
std::chrono::steady_clock::now() - now).count();
285-
if ((uint64_t)time_elapsed <= resolve_timeout_) {
286-
addrs->push_back(std::move(ret));
287-
sem.signal(1);
288-
} else {
289-
LOG_ERROR("resolve timeout");
290-
while(!ret.empty())
291-
delete ret.pop_front();
292+
_gethostbyname(ctx->host, cb);
293+
{
294+
SCOPED_LOCK(ctx->lock);
295+
if (ctx->addrs) {
296+
ctx->addrs->push_back(std::move(ret));
297+
ctx->sem.signal(1);
298+
} else {
299+
LOG_ERROR("resolve timeout");
300+
while(!ret.empty())
301+
delete ret.pop_front();
302+
}
292303
}
293304
}).detach();
294-
sem.wait(1, resolve_timeout_);
305+
ctx->sem.wait(1, resolve_timeout_);
306+
{
307+
SCOPED_LOCK(ctx->lock);
308+
ctx->addrs = nullptr;
309+
ctx->filter = {};
310+
}
311+
if (addrs->empty()) {
312+
delete addrs;
313+
return nullptr;
314+
}
295315
return addrs;
296316
};
297-
auto ips = dnscache_.borrow(host, ctr);
298-
if (ips->empty()) LOG_ERRNO_RETURN(0, IPAddr(), "Domain resolution for '`' failed", host);
317+
auto ips = dnscache_.borrow(host, ctr, 1UL * 1000);
318+
if (!ips || ips->empty()) {
319+
ips.recycle(true);
320+
LOG_ERRNO_RETURN(0, IPAddr(), "Domain resolution for '`' failed", host);
321+
}
299322
SCOPED_LOCK(*ips);
300323
auto ret = ips->front();
301324
ips->node = ret->next(); // access in round robin order

0 commit comments

Comments
 (0)