mirror of
https://github.com/matrix-construct/construct
synced 2024-09-27 11:18:51 +02: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
|
/// (internal) DNS cache
|
||||||
namespace ircd::net::dns::cache
|
namespace ircd::net::dns::cache
|
||||||
{
|
{
|
||||||
|
struct waiter;
|
||||||
using closure = std::function<bool (const string_view &, const json::object &)>;
|
using closure = std::function<bool (const string_view &, const json::object &)>;
|
||||||
|
|
||||||
extern conf::item<seconds> min_ttl;
|
extern conf::item<seconds> min_ttl;
|
||||||
extern conf::item<seconds> error_ttl;
|
extern conf::item<seconds> error_ttl;
|
||||||
extern conf::item<seconds> nxdomain_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 string_view &);
|
||||||
string_view make_type(const mutable_buffer &out, const uint16_t &);
|
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 = {});
|
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
|
/// DNS cache result waiter
|
||||||
struct ircd::net::dns::cache::waiter
|
struct ircd::net::dns::cache::waiter
|
||||||
{
|
{
|
||||||
|
@ -54,4 +49,7 @@ struct ircd::net::dns::cache::waiter
|
||||||
waiter(const waiter &) = delete;
|
waiter(const waiter &) = delete;
|
||||||
waiter &operator=(waiter &&) = delete;
|
waiter &operator=(waiter &&) = delete;
|
||||||
waiter &operator=(const 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 = {};
|
this->opts.proto = {};
|
||||||
assert(this->opts.qtype);
|
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
|
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 void handle(const m::event &, m::vm::eval &);
|
||||||
|
|
||||||
static bool put(const string_view &type, const string_view &state_key, const records &rrs);
|
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::value error_records{&error_value, 1};
|
||||||
const json::strung error{error_records};
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
catch(const std::exception &e)
|
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_value{error_object};
|
||||||
const json::value error_records{&error_value, 1};
|
const json::value error_records{&error_value, 1};
|
||||||
const json::strung error{error_records};
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +325,7 @@ catch(const http::error &e)
|
||||||
|
|
||||||
const json::value error_records{&error_value, 1};
|
const json::value error_records{&error_value, 1};
|
||||||
const json::strung error{error_records};
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
catch(const std::exception &e)
|
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_value{error_object};
|
||||||
const json::value error_records{&error_value, 1};
|
const json::value error_records{&error_value, 1};
|
||||||
const json::strung error{error_records};
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,7 +534,7 @@ try
|
||||||
json::get<"content"_>(event).get("")
|
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)
|
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
|
// cache room creation
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue