mirror of
https://github.com/matrix-construct/construct
synced 2024-10-31 19:08:59 +01:00
ircd::net::dns::cache: Move cache waiter calling out of module.
This commit is contained in:
parent
e08fc4b99f
commit
637b6ecede
3 changed files with 92 additions and 96 deletions
|
@ -11,12 +11,20 @@
|
|||
/// (internal) DNS cache
|
||||
namespace ircd::net::dns::cache
|
||||
{
|
||||
struct waiter;
|
||||
using closure = std::function<bool (const string_view &, const json::object &)>;
|
||||
|
||||
extern conf::item<seconds> min_ttl;
|
||||
extern conf::item<seconds> error_ttl;
|
||||
extern conf::item<seconds> nxdomain_ttl;
|
||||
|
||||
extern ctx::dock dock;
|
||||
extern ctx::mutex mutex;
|
||||
extern std::list<waiter> waiting;
|
||||
|
||||
bool operator==(const waiter &, const waiter &) noexcept;
|
||||
bool operator!=(const waiter &, const waiter &) noexcept;
|
||||
|
||||
string_view make_type(const mutable_buffer &out, const string_view &);
|
||||
string_view make_type(const mutable_buffer &out, const uint16_t &);
|
||||
|
||||
|
@ -27,19 +35,6 @@ namespace ircd::net::dns::cache
|
|||
bool put(const hostport &, const opts &, const uint &code, const string_view &msg = {});
|
||||
}
|
||||
|
||||
/// (internal) DNS cache
|
||||
namespace ircd::net::dns::cache
|
||||
{
|
||||
struct waiter;
|
||||
|
||||
bool operator==(const waiter &, const waiter &) noexcept;
|
||||
bool operator!=(const waiter &, const waiter &) noexcept;
|
||||
|
||||
extern std::list<waiter> waiting;
|
||||
extern ctx::mutex mutex;
|
||||
extern ctx::dock dock;
|
||||
}
|
||||
|
||||
/// DNS cache result waiter
|
||||
struct ircd::net::dns::cache::waiter
|
||||
{
|
||||
|
@ -54,4 +49,7 @@ struct ircd::net::dns::cache::waiter
|
|||
waiter(const waiter &) = delete;
|
||||
waiter &operator=(waiter &&) = delete;
|
||||
waiter &operator=(const waiter &) = delete;
|
||||
|
||||
static bool call(waiter &, const uint16_t &type, const string_view &tgt, const json::array &rrs);
|
||||
static size_t call(const uint16_t &type, const string_view &tgt, const json::array &rrs);
|
||||
};
|
||||
|
|
|
@ -234,3 +234,79 @@ ircd::net::dns::cache::waiter::waiter(const hostport &hp,
|
|||
this->opts.proto = {};
|
||||
assert(this->opts.qtype);
|
||||
}
|
||||
|
||||
/// Note complications due to reentrance and other factors:
|
||||
/// - This function is invoked from several different places on both the
|
||||
/// timeout and receive contexts, in addition to any evaluator context.
|
||||
/// - This function calls back to users making DNS queries, and they may
|
||||
/// conduct another query in their callback frame -- mid-loop in this
|
||||
/// function.
|
||||
size_t
|
||||
ircd::net::dns::cache::waiter::call(const uint16_t &type,
|
||||
const string_view &tgt,
|
||||
const json::array &rrs)
|
||||
{
|
||||
const ctx::uninterruptible::nothrow ui;
|
||||
size_t ret(0), last; do
|
||||
{
|
||||
const std::lock_guard lock
|
||||
{
|
||||
mutex
|
||||
};
|
||||
|
||||
auto it(begin(waiting));
|
||||
for(last = ret; it != end(waiting); ++it)
|
||||
if(call(*it, type, tgt, rrs))
|
||||
{
|
||||
it = waiting.erase(it);
|
||||
++ret;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(last < ret);
|
||||
|
||||
if(ret)
|
||||
dock.notify_all();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::net::dns::cache::waiter::call(waiter &waiter,
|
||||
const uint16_t &type,
|
||||
const string_view &tgt,
|
||||
const json::array &rrs)
|
||||
try
|
||||
{
|
||||
if(tgt != waiter.key)
|
||||
return false;
|
||||
|
||||
if(type != waiter.opts.qtype)
|
||||
return false;
|
||||
|
||||
const hostport &target
|
||||
{
|
||||
waiter.opts.qtype == 33?
|
||||
unmake_SRV_key(waiter.key):
|
||||
waiter.key,
|
||||
|
||||
waiter.port
|
||||
};
|
||||
|
||||
assert(waiter.callback);
|
||||
waiter.callback(target, rrs);
|
||||
return true;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::critical
|
||||
{
|
||||
log, "callback:%p %s,%s :%s",
|
||||
(const void *)&waiter,
|
||||
type,
|
||||
tgt,
|
||||
e.what(),
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
namespace ircd::net::dns::cache
|
||||
{
|
||||
static bool call_waiter(const string_view &, const string_view &, const json::array &, waiter &);
|
||||
static size_t call_waiters(const string_view &, const string_view &, const json::array &);
|
||||
static void handle(const m::event &, m::vm::eval &);
|
||||
|
||||
static bool put(const string_view &type, const string_view &state_key, const records &rrs);
|
||||
|
@ -200,7 +198,7 @@ catch(const http::error &e)
|
|||
|
||||
const json::value error_records{&error_value, 1};
|
||||
const json::strung error{error_records};
|
||||
call_waiters(type, state_key, error);
|
||||
waiter::call(rfc1035::qtype.at(lstrip(type, "ircd.dns.rrs.")), state_key, error);
|
||||
return false;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
|
@ -224,7 +222,7 @@ catch(const std::exception &e)
|
|||
const json::value error_value{error_object};
|
||||
const json::value error_records{&error_value, 1};
|
||||
const json::strung error{error_records};
|
||||
call_waiters(type, state_key, error);
|
||||
waiter::call(rfc1035::qtype.at(lstrip(type, "ircd.dns.rrs.")), state_key, error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -327,7 +325,7 @@ catch(const http::error &e)
|
|||
|
||||
const json::value error_records{&error_value, 1};
|
||||
const json::strung error{error_records};
|
||||
call_waiters(type, state_key, error);
|
||||
waiter::call(rfc1035::qtype.at(lstrip(type, "ircd.dns.rrs.")), state_key, error);
|
||||
return false;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
|
@ -350,7 +348,7 @@ catch(const std::exception &e)
|
|||
const json::value error_value{error_object};
|
||||
const json::value error_records{&error_value, 1};
|
||||
const json::strung error{error_records};
|
||||
call_waiters(type, state_key, error);
|
||||
waiter::call(rfc1035::qtype.at(lstrip(type, "ircd.dns.rrs.")), state_key, error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -536,7 +534,7 @@ try
|
|||
json::get<"content"_>(event).get("")
|
||||
};
|
||||
|
||||
call_waiters(type, state_key, rrs);
|
||||
waiter::call(rfc1035::qtype.at(lstrip(type, "ircd.dns.rrs.")), state_key, rrs);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
|
@ -546,82 +544,6 @@ catch(const std::exception &e)
|
|||
};
|
||||
}
|
||||
|
||||
/// Note complications due to reentrance and other factors:
|
||||
/// - This function is invoked from several different places on both the
|
||||
/// timeout and receive contexts, in addition to any evaluator context.
|
||||
/// - This function calls back to users making DNS queries, and they may
|
||||
/// conduct another query in their callback frame -- mid-loop in this
|
||||
/// function.
|
||||
size_t
|
||||
ircd::net::dns::cache::call_waiters(const string_view &type,
|
||||
const string_view &state_key,
|
||||
const json::array &rrs)
|
||||
{
|
||||
const ctx::uninterruptible::nothrow ui;
|
||||
size_t ret(0), last; do
|
||||
{
|
||||
const std::lock_guard lock
|
||||
{
|
||||
mutex
|
||||
};
|
||||
|
||||
auto it(begin(waiting));
|
||||
for(last = ret; it != end(waiting); ++it)
|
||||
if(call_waiter(type, state_key, rrs, *it))
|
||||
{
|
||||
it = waiting.erase(it);
|
||||
++ret;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(last < ret);
|
||||
|
||||
if(ret)
|
||||
dock.notify_all();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::net::dns::cache::call_waiter(const string_view &type,
|
||||
const string_view &state_key,
|
||||
const json::array &rrs,
|
||||
waiter &waiter)
|
||||
try
|
||||
{
|
||||
if(state_key != waiter.key)
|
||||
return false;
|
||||
|
||||
if(lstrip(type, "ircd.dns.rrs.") != rfc1035::rqtype.at(waiter.opts.qtype))
|
||||
return false;
|
||||
|
||||
const hostport &target
|
||||
{
|
||||
waiter.opts.qtype == 33?
|
||||
unmake_SRV_key(waiter.key):
|
||||
waiter.key,
|
||||
|
||||
waiter.port
|
||||
};
|
||||
|
||||
assert(waiter.callback);
|
||||
waiter.callback(target, rrs);
|
||||
return true;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::critical
|
||||
{
|
||||
log, "callback:%p %s,%s :%s",
|
||||
(const void *)&waiter,
|
||||
type,
|
||||
state_key,
|
||||
e.what(),
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// cache room creation
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue