0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-15 14:31:11 +01:00

ircd::net::dns: Add retries.

This commit is contained in:
Jason Volk 2018-05-08 15:16:07 -07:00
parent 477fe01e40
commit c47324f741
2 changed files with 50 additions and 14 deletions

View file

@ -26,6 +26,7 @@ struct ircd::net::dns::resolver
static conf::item<milliseconds> timeout; static conf::item<milliseconds> timeout;
static conf::item<milliseconds> send_rate; static conf::item<milliseconds> send_rate;
static conf::item<size_t> send_burst; static conf::item<size_t> send_burst;
static conf::item<size_t> retry_max;
std::vector<ip::udp::endpoint> server; // The list of active servers std::vector<ip::udp::endpoint> server; // The list of active servers
size_t server_next{0}; // Round-robin state to hit servers size_t server_next{0}; // Round-robin state to hit servers
@ -76,7 +77,7 @@ struct ircd::net::dns::resolver::tag
dns::opts opts; // note: invalid after query sent dns::opts opts; // note: invalid after query sent
const_buffer question; const_buffer question;
callback cb; callback cb;
steady_point last; steady_point last {};
uint8_t tries {0}; uint8_t tries {0};
char hostbuf[256]; char hostbuf[256];
char qbuf[384]; char qbuf[384];

View file

@ -2824,6 +2824,13 @@ ircd::net::dns::resolver::send_burst
{ "default", 8L }, { "default", 8L },
}; };
decltype(ircd::net::dns::resolver::retry_max)
ircd::net::dns::resolver::retry_max
{
{ "name", "ircd.net.dns.resolver.retry_max" },
{ "default", 4L },
};
ircd::net::dns::resolver::resolver() ircd::net::dns::resolver::resolver()
:ns{*ircd::ios} :ns{*ircd::ios}
,reply ,reply
@ -2868,12 +2875,14 @@ ircd::net::dns::resolver::sendq_worker()
assert(sendq.size() < 65535); assert(sendq.size() < 65535);
assert(sendq.size() <= tags.size()); assert(sendq.size() <= tags.size());
if(tags.size() > size_t(send_burst))
ctx::sleep(milliseconds(send_rate)); ctx::sleep(milliseconds(send_rate));
const unwind::nominal::assertion na; const unwind::nominal::assertion na;
assert(!sendq.empty()); assert(!sendq.empty());
flush(sendq.front()); const uint16_t next(sendq.front());
sendq.pop_front(); sendq.pop_front();
flush(next);
} }
} }
@ -2925,7 +2934,7 @@ ircd::net::dns::resolver::check_timeouts(const milliseconds &timeout)
{ {
const auto &id(it->first); const auto &id(it->first);
auto &tag(it->second); auto &tag(it->second);
if(!check_timeout(id, tag, cutoff)) if(check_timeout(id, tag, cutoff))
it = tags.erase(it); it = tags.erase(it);
else else
++it; ++it;
@ -2938,26 +2947,49 @@ ircd::net::dns::resolver::check_timeout(const uint16_t &id,
const steady_point &cutoff) const steady_point &cutoff)
{ {
if(tag.last == steady_point{}) if(tag.last == steady_point{})
return true; return false;
if(tag.last < cutoff) if(tag.last > cutoff)
return true; return false;
//TODO: retry log::warning
log.error("DNS timeout id:%u", id); {
log, "DNS timeout id:%u on attempt %u", id, tag.tries
};
tag.last = steady_point{};
if(tag.tries < size_t(retry_max))
{
submit(tag);
return false;
}
if(!tag.cb)
return true;
// Callback gets a fresh stack off this timeout worker ctx's stack. // Callback gets a fresh stack off this timeout worker ctx's stack.
std::string host{tag.hp.host}; ircd::post([this, id, &tag]
if(tag.cb) ircd::post([cb(std::move(tag.cb)), host(std::move(host)), port(tag.hp.port)]
{ {
using boost::system::system_error; using boost::system::system_error;
const error_code ec static const error_code ec
{ {
boost::system::errc::timed_out, boost::system::system_category() boost::system::errc::timed_out, boost::system::system_category()
}; };
const hostport hp{host, port}; // Have to check if the tag is still mapped at this point. It may
cb(std::make_exception_ptr(system_error{ec}), hp, {}); // have been removed if a belated reply came in while this closure
// was posting. If so, that's good news and we bail on the timeout.
if(!tags.count(id))
return;
log::error
{
log, "DNS timeout id:%u", id
};
tag.cb(std::make_exception_ptr(system_error{ec}), tag.hp, {});
const auto erased(tags.erase(tag.id));
assert(erased == 1);
}); });
return false; return false;
@ -3035,6 +3067,7 @@ ircd::net::dns::resolver::set_tag(A&&... args)
void void
ircd::net::dns::resolver::queue_query(tag &tag) ircd::net::dns::resolver::queue_query(tag &tag)
{ {
assert(sendq.size() <= tags.size());
sendq.emplace_back(tag.id); sendq.emplace_back(tag.id);
dock.notify_one(); dock.notify_one();
} }
@ -3168,6 +3201,8 @@ try
tags.erase(it); tags.erase(it);
}}; }};
assert(tag.tries > 0);
tag.last = steady_point{};
handle_reply(header, body, tag); handle_reply(header, body, tag);
} }
catch(const std::exception &e) catch(const std::exception &e)