0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-05-29 00:03:45 +02:00

ircd: Split all non-matrix definitions back to lib; rename module to net_dns_cache.

This commit is contained in:
Jason Volk 2019-10-05 17:02:50 -07:00
parent 9e3c9be5a8
commit 2b2374db6c
12 changed files with 463 additions and 495 deletions

View file

@ -18,6 +18,7 @@
///
namespace ircd::net::dns
{
struct init;
struct opts;
using records = vector_view<const rfc1035::record *>;
using callback = std::function<void (const hostport &, const json::array &)>;
@ -106,3 +107,9 @@ namespace ircd::net::dns::cache
bool put(const hostport &, const opts &, const records &);
bool put(const hostport &, const opts &, const uint &code, const string_view &msg = {});
}
/// (internal)
struct ircd::net::dns::init
{
init(), ~init() noexcept;
};

View file

@ -1,22 +1,24 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
//
// This file is not included in any include group. It is used when
// implementing the dns::cache by modules and extensions.
//
namespace ircd::net::dns::cache
{
struct waiter;
bool operator==(const waiter &, const waiter &);
bool operator!=(const waiter &, const waiter &);
void fini();
void init();
bool operator==(const waiter &, const waiter &) noexcept;
bool operator!=(const waiter &, const waiter &) noexcept;
extern std::list<waiter> waiting;
extern ctx::mutex mutex;

View file

@ -25,8 +25,6 @@ namespace ircd::net::dns
constexpr const size_t MAX_COUNT {64};
uint16_t resolver_call(const hostport &, const opts &);
void resolver_init(answers_callback);
void resolver_fini();
}
struct ircd::net::dns::resolver

View file

@ -147,6 +147,8 @@ libircd_la_SOURCES += db_port.cc
libircd_la_SOURCES += db_env.cc
libircd_la_SOURCES += db.cc
libircd_la_SOURCES += net.cc
libircd_la_SOURCES += net_dns.cc
libircd_la_SOURCES += net_dns_cache.cc
libircd_la_SOURCES += net_dns_resolver.cc
libircd_la_SOURCES += server.cc
libircd_la_SOURCES += client.cc
@ -194,6 +196,8 @@ magic.lo: AM_CPPFLAGS := @MAGIC_CPPFLAGS@ ${AM_CPPFLAGS}
endif
mods.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
net.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
net_dns.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
net_cache.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
net_dns_resolver.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
openssl.lo: AM_CPPFLAGS := @SSL_CPPFLAGS@ @CRYPTO_CPPFLAGS@ ${AM_CPPFLAGS}
parse.lo: AM_CPPFLAGS := ${SPIRIT_UNIT_CPPFLAGS} ${AM_CPPFLAGS}

View file

@ -13,6 +13,7 @@
namespace ircd::net
{
ctx::dock dock;
std::optional<dns::init> _dns_;
static void init_ipv6();
static void wait_close_sockets();
@ -69,19 +70,17 @@ ircd::net::init_ipv6()
/// Network subsystem initialization
ircd::net::init::init()
{
//TODO: XXX this has to be instantiated in libircd before other loaded
//TODO: modules like s_dns.so; otherwise dynamic linker issues.
const asio::ip::udp::socket _dummy_udp_ {ios::get()};
init_ipv6();
sslv23_client.set_verify_mode(asio::ssl::verify_peer);
sslv23_client.set_default_verify_paths();
_dns_.emplace();
}
/// Network subsystem shutdown
ircd::net::init::~init()
noexcept
{
_dns_.reset();
wait_close_sockets();
}
@ -4190,379 +4189,6 @@ const
return *ssl.native_handle();
}
///////////////////////////////////////////////////////////////////////////////
//
// net/dns.h
//
decltype(ircd::net::dns::log)
ircd::net::dns::log
{
"net.dns"
};
decltype(ircd::net::dns::cache::min_ttl)
ircd::net::dns::cache::min_ttl
{
{ "name", "ircd.net.dns.cache.min_ttl" },
{ "default", 28800L },
};
decltype(ircd::net::dns::cache::error_ttl)
ircd::net::dns::cache::error_ttl
{
{ "name", "ircd.net.dns.cache.error_ttl" },
{ "default", 1200L },
};
decltype(ircd::net::dns::cache::nxdomain_ttl)
ircd::net::dns::cache::nxdomain_ttl
{
{ "name", "ircd.net.dns.cache.nxdomain_ttl" },
{ "default", 86400L },
};
/// Linkage for default opts
decltype(ircd::net::dns::opts_default)
ircd::net::dns::opts_default;
void
ircd::net::dns::resolve(const hostport &hp,
const opts &op,
callback_ipport cb)
{
using prototype = void (const hostport &, const opts &, callback_ipport);
static mods::import<prototype> call
{
"net_dns", "ircd::net::dns::resolve"
};
call(hp, op, std::move(cb));
}
void
ircd::net::dns::resolve(const hostport &hp,
const opts &op,
callback_one cb)
{
using prototype = void (const hostport &, const opts &, callback_one);
static mods::import<prototype> call
{
"net_dns", "ircd::net::dns::resolve"
};
call(hp, op, std::move(cb));
}
void
ircd::net::dns::resolve(const hostport &hp,
const opts &op,
callback cb)
{
using prototype = void (const hostport &, const opts &, callback);
static mods::import<prototype> call
{
"net_dns", "ircd::net::dns::resolve"
};
call(hp, op, std::move(cb));
}
/// Really assumptional and hacky right now. We're just assuming the SRV
/// key is the first two elements of a dot-delimited string which start
/// with underscores. If that isn't good enough in the future this will rot
/// and become a regression hazard.
ircd::string_view
ircd::net::dns::unmake_SRV_key(const string_view &key)
{
if(token_count(key, '.') < 3)
return key;
if(!startswith(token(key, '.', 0), '_'))
return key;
if(!startswith(token(key, '.', 1), '_'))
return key;
return tokens_after(key, '.', 1);
}
ircd::string_view
ircd::net::dns::make_SRV_key(const mutable_buffer &out,
const hostport &hp,
const opts &opts)
{
thread_local char tlbuf[2][rfc1035::NAME_BUFSIZE];
if(!opts.srv)
return fmt::sprintf
{
out, "_%s._%s.%s",
tolower(tlbuf[0], service(hp)),
opts.proto,
tolower(tlbuf[1], host(hp)),
};
else
return fmt::sprintf
{
out, "%s%s",
opts.srv,
tolower(tlbuf[1], host(hp))
};
}
ircd::json::object
ircd::net::dns::random_choice(const json::array &rrs)
{
const size_t &count
{
rrs.size()
};
if(!count)
return json::object{};
const auto choice
{
rand::integer(0, count - 1)
};
assert(choice < count);
const json::object &rr
{
rrs[choice]
};
return rr;
}
bool
ircd::net::dns::expired(const json::object &rr,
const time_t &rr_ts)
{
const seconds &min_seconds
{
cache::min_ttl
};
const seconds &err_seconds
{
cache::error_ttl
};
const time_t &min
{
is_error(rr)?
err_seconds.count():
min_seconds.count()
};
return expired(rr, rr_ts, min);
}
bool
ircd::net::dns::expired(const json::object &rr,
const time_t &rr_ts,
const time_t &min_ttl)
{
const auto &ttl
{
get_ttl(rr)
};
return rr_ts + std::max(ttl, min_ttl) < ircd::time();
}
time_t
ircd::net::dns::get_ttl(const json::object &rr)
{
return rr.get<time_t>("ttl", 0L);
}
bool
ircd::net::dns::is_empty(const json::array &rrs)
{
return std::all_of(begin(rrs), end(rrs), []
(const json::object &rr)
{
return is_empty(rr);
});
}
bool
ircd::net::dns::is_empty(const json::object &rr)
{
return empty(rr) || (rr.has("ttl") && size(rr) == 1);
}
bool
ircd::net::dns::is_error(const json::array &rrs)
{
return !std::none_of(begin(rrs), end(rrs), []
(const json::object &rr)
{
return is_error(rr);
});
}
bool
ircd::net::dns::is_error(const json::object &rr)
{
return rr.has("error");
}
//
// cache
//
bool
ircd::net::dns::cache::put(const hostport &h,
const opts &o,
const uint &r,
const string_view &m)
try
{
using prototype = bool (const hostport &, const opts &, const uint &, const string_view &);
static mods::import<prototype> call
{
"net_dns", "ircd::net::dns::cache::put"
};
return call(h, o, r, m);
}
catch(const mods::unavailable &e)
{
thread_local char buf[rfc1035::NAME_BUFSIZE];
log::dwarning
{
log, "Failed to put error for '%s' in DNS cache :%s",
string(buf, h),
e.what()
};
return false;
}
bool
ircd::net::dns::cache::put(const hostport &h,
const opts &o,
const records &r)
try
{
using prototype = bool (const hostport &, const opts &, const records &);
static mods::import<prototype> call
{
"net_dns", "ircd::net::dns::cache::put"
};
return call(h, o, r);
}
catch(const mods::unavailable &e)
{
thread_local char buf[rfc1035::NAME_BUFSIZE];
log::dwarning
{
log, "Failed to put '%s' in DNS cache :%s",
string(buf, h),
e.what()
};
return false;
}
/// This function has an opportunity to respond from the DNS cache. If it
/// returns true, that indicates it responded by calling back the user and
/// nothing further should be done for them. If it returns false, that
/// indicates it did not respond and to proceed normally. The response can
/// be of a cached successful result, or a cached error. Both will return
/// true.
bool
ircd::net::dns::cache::get(const hostport &h,
const opts &o,
const callback &c)
try
{
using prototype = bool (const hostport &, const opts &, const callback &);
static mods::import<prototype> call
{
"net_dns", "ircd::net::dns::cache::get"
};
return call(h, o, c);
}
catch(const mods::unavailable &e)
{
thread_local char buf[rfc1035::NAME_BUFSIZE];
log::dwarning
{
log, "Failed to get '%s' from DNS cache :%s",
string(buf, h),
e.what()
};
return false;
}
bool
ircd::net::dns::cache::for_each(const hostport &h,
const opts &o,
const closure &c)
{
using prototype = bool (const hostport &, const opts &, const closure &);
static mods::import<prototype> call
{
"net_dns", "ircd::net::dns::cache::for_each"
};
return call(h, o, c);
}
bool
ircd::net::dns::cache::for_each(const string_view &type,
const closure &c)
{
using prototype = bool (const string_view &, const closure &);
static mods::import<prototype> call
{
"net_dns", "ircd::net::dns::cache::for_each"
};
return call(type, c);
}
ircd::string_view
ircd::net::dns::cache::make_type(const mutable_buffer &out,
const uint16_t &type)
try
{
return make_type(out, rfc1035::rqtype.at(type));
}
catch(const std::out_of_range &)
{
throw error
{
"Record type[%u] is not recognized", type
};
}
ircd::string_view
ircd::net::dns::cache::make_type(const mutable_buffer &out,
const string_view &type)
{
return fmt::sprintf
{
out, "ircd.dns.rrs.%s", type
};
}
///////////////////////////////////////////////////////////////////////////////
//
// net/ipport.h

View file

@ -8,7 +8,7 @@
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#include "net_dns.h"
#include <ircd/net/dns_cache.h>
namespace ircd::net::dns
{
@ -18,35 +18,42 @@ namespace ircd::net::dns
static void handle_resolve_A_ipport(const hostport &, const json::object &rr, opts, uint16_t, callback_ipport);
static void handle_resolve_SRV_ipport(const hostport &, const json::object &rr, opts, callback_ipport);
static void handle_resolve_one(const hostport &, const json::array &rr, callback_one);
static void fini();
static void init();
}
ircd::mapi::header
IRCD_MODULE
decltype(ircd::net::dns::log)
ircd::net::dns::log
{
"Domain Name System Client, Cache & Components",
ircd::net::dns::init,
ircd::net::dns::fini,
"net.dns"
};
void
ircd::net::dns::init()
decltype(ircd::net::dns::opts_default)
ircd::net::dns::opts_default;
//
// init
//
ircd::net::dns::init::init()
{
cache::init();
resolver_init(handle_resolved);
assert(!resolver_instance);
resolver_instance = new resolver
{
handle_resolved
};
}
void
ircd::net::dns::fini()
ircd::net::dns::init::~init()
noexcept
{
cache::fini();
resolver_fini();
delete resolver_instance;
resolver_instance = nullptr;
}
//
// net/dns.h
//
void
IRCD_MODULE_EXPORT
ircd::net::dns::resolve(const hostport &hp,
const opts &opts_,
callback_ipport callback)
@ -86,7 +93,6 @@ ircd::net::dns::resolve(const hostport &hp,
}
void
IRCD_MODULE_EXPORT
ircd::net::dns::resolve(const hostport &hp,
const opts &opts,
callback_one callback)
@ -106,7 +112,6 @@ ircd::net::dns::resolve(const hostport &hp,
}
void
IRCD_MODULE_EXPORT
ircd::net::dns::resolve(const hostport &hp,
const opts &opts,
callback cb)
@ -142,6 +147,153 @@ ircd::net::dns::resolve(const hostport &hp,
resolver_call(hp, opts);
}
/// Really assumptional and hacky right now. We're just assuming the SRV
/// key is the first two elements of a dot-delimited string which start
/// with underscores. If that isn't good enough in the future this will rot
/// and become a regression hazard.
ircd::string_view
ircd::net::dns::unmake_SRV_key(const string_view &key)
{
if(token_count(key, '.') < 3)
return key;
if(!startswith(token(key, '.', 0), '_'))
return key;
if(!startswith(token(key, '.', 1), '_'))
return key;
return tokens_after(key, '.', 1);
}
ircd::string_view
ircd::net::dns::make_SRV_key(const mutable_buffer &out,
const hostport &hp,
const opts &opts)
{
thread_local char tlbuf[2][rfc1035::NAME_BUFSIZE];
if(!opts.srv)
return fmt::sprintf
{
out, "_%s._%s.%s",
tolower(tlbuf[0], service(hp)),
opts.proto,
tolower(tlbuf[1], host(hp)),
};
else
return fmt::sprintf
{
out, "%s%s",
opts.srv,
tolower(tlbuf[1], host(hp))
};
}
ircd::json::object
ircd::net::dns::random_choice(const json::array &rrs)
{
const size_t &count
{
rrs.size()
};
if(!count)
return json::object{};
const auto choice
{
rand::integer(0, count - 1)
};
assert(choice < count);
const json::object &rr
{
rrs[choice]
};
return rr;
}
bool
ircd::net::dns::expired(const json::object &rr,
const time_t &rr_ts)
{
const seconds &min_seconds
{
cache::min_ttl
};
const seconds &err_seconds
{
cache::error_ttl
};
const time_t &min
{
is_error(rr)?
err_seconds.count():
min_seconds.count()
};
return expired(rr, rr_ts, min);
}
bool
ircd::net::dns::expired(const json::object &rr,
const time_t &rr_ts,
const time_t &min_ttl)
{
const auto &ttl
{
get_ttl(rr)
};
return rr_ts + std::max(ttl, min_ttl) < ircd::time();
}
time_t
ircd::net::dns::get_ttl(const json::object &rr)
{
return rr.get<time_t>("ttl", 0L);
}
bool
ircd::net::dns::is_empty(const json::array &rrs)
{
return std::all_of(begin(rrs), end(rrs), []
(const json::object &rr)
{
return is_empty(rr);
});
}
bool
ircd::net::dns::is_empty(const json::object &rr)
{
return empty(rr) || (rr.has("ttl") && size(rr) == 1);
}
bool
ircd::net::dns::is_error(const json::array &rrs)
{
return !std::none_of(begin(rrs), end(rrs), []
(const json::object &rr)
{
return is_error(rr);
});
}
bool
ircd::net::dns::is_error(const json::object &rr)
{
return rr.has("error");
}
//
// internal
//
void
ircd::net::dns::handle_resolve_one(const hostport &hp,
const json::array &rrs,

238
ircd/net_dns_cache.cc Normal file
View file

@ -0,0 +1,238 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#include <ircd/net/dns_cache.h>
decltype(ircd::net::dns::cache::min_ttl)
ircd::net::dns::cache::min_ttl
{
{ "name", "ircd.net.dns.cache.min_ttl" },
{ "default", 28800L },
};
decltype(ircd::net::dns::cache::error_ttl)
ircd::net::dns::cache::error_ttl
{
{ "name", "ircd.net.dns.cache.error_ttl" },
{ "default", 1200L },
};
decltype(ircd::net::dns::cache::nxdomain_ttl)
ircd::net::dns::cache::nxdomain_ttl
{
{ "name", "ircd.net.dns.cache.nxdomain_ttl" },
{ "default", 86400L },
};
decltype(ircd::net::dns::cache::waiting)
ircd::net::dns::cache::waiting;
decltype(ircd::net::dns::cache::mutex)
ircd::net::dns::cache::mutex;
decltype(ircd::net::dns::cache::dock)
ircd::net::dns::cache::dock;
bool
ircd::net::dns::cache::put(const hostport &h,
const opts &o,
const uint &r,
const string_view &m)
try
{
using prototype = bool (const hostport &, const opts &, const uint &, const string_view &);
static mods::import<prototype> call
{
"net_dns_cache", "ircd::net::dns::cache::put"
};
return call(h, o, r, m);
}
catch(const mods::unavailable &e)
{
thread_local char buf[rfc1035::NAME_BUFSIZE];
log::dwarning
{
log, "Failed to put error for '%s' in DNS cache :%s",
string(buf, h),
e.what()
};
return false;
}
bool
ircd::net::dns::cache::put(const hostport &h,
const opts &o,
const records &r)
try
{
using prototype = bool (const hostport &, const opts &, const records &);
static mods::import<prototype> call
{
"net_dns_cache", "ircd::net::dns::cache::put"
};
return call(h, o, r);
}
catch(const mods::unavailable &e)
{
thread_local char buf[rfc1035::NAME_BUFSIZE];
log::dwarning
{
log, "Failed to put '%s' in DNS cache :%s",
string(buf, h),
e.what()
};
return false;
}
/// This function has an opportunity to respond from the DNS cache. If it
/// returns true, that indicates it responded by calling back the user and
/// nothing further should be done for them. If it returns false, that
/// indicates it did not respond and to proceed normally. The response can
/// be of a cached successful result, or a cached error. Both will return
/// true.
bool
ircd::net::dns::cache::get(const hostport &h,
const opts &o,
const callback &c)
try
{
using prototype = bool (const hostport &, const opts &, const callback &);
static mods::import<prototype> call
{
"net_dns_cache", "ircd::net::dns::cache::get"
};
return call(h, o, c);
}
catch(const mods::unavailable &e)
{
thread_local char buf[rfc1035::NAME_BUFSIZE];
log::dwarning
{
log, "Failed to get '%s' from DNS cache :%s",
string(buf, h),
e.what()
};
return false;
}
bool
ircd::net::dns::cache::for_each(const hostport &h,
const opts &o,
const closure &c)
{
using prototype = bool (const hostport &, const opts &, const closure &);
static mods::import<prototype> call
{
"net_dns_cache", "ircd::net::dns::cache::for_each"
};
return call(h, o, c);
}
bool
ircd::net::dns::cache::for_each(const string_view &type,
const closure &c)
{
using prototype = bool (const string_view &, const closure &);
static mods::import<prototype> call
{
"net_dns_cache", "ircd::net::dns::cache::for_each"
};
return call(type, c);
}
ircd::string_view
ircd::net::dns::cache::make_type(const mutable_buffer &out,
const uint16_t &type)
try
{
return make_type(out, rfc1035::rqtype.at(type));
}
catch(const std::out_of_range &)
{
throw error
{
"Record type[%u] is not recognized", type
};
}
ircd::string_view
ircd::net::dns::cache::make_type(const mutable_buffer &out,
const string_view &type)
{
return fmt::sprintf
{
out, "ircd.dns.rrs.%s", type
};
}
//
// cache::waiter
//
bool
ircd::net::dns::cache::operator==(const waiter &a, const waiter &b)
noexcept
{
return
a.opts.qtype == b.opts.qtype &&
a.key && b.key &&
a.key == b.key;
}
bool
ircd::net::dns::cache::operator!=(const waiter &a, const waiter &b)
noexcept
{
return !operator==(a, b);
}
//
// cache::waiter::waiter
//
ircd::net::dns::cache::waiter::waiter(const hostport &hp,
const dns::opts &opts,
dns::callback &&callback)
:callback
{
std::move(callback)
}
,opts
{
opts
}
,port
{
net::port(hp)
}
,key
{
opts.qtype == 33?
make_SRV_key(keybuf, hp, opts):
strlcpy(keybuf, host(hp))
}
{
this->opts.srv = {};
this->opts.proto = {};
assert(this->opts.qtype);
}

View file

@ -56,23 +56,6 @@ ircd::net::dns::resolver::servers
// interface
//
void
ircd::net::dns::resolver_init(answers_callback callback)
{
assert(!ircd::net::dns::resolver_instance);
ircd::net::dns::resolver_instance = new resolver
{
std::move(callback)
};
}
void
ircd::net::dns::resolver_fini()
{
delete ircd::net::dns::resolver_instance;
ircd::net::dns::resolver_instance = nullptr;
}
uint16_t
ircd::net::dns::resolver_call(const hostport &hp,
const opts &opts)
@ -84,7 +67,11 @@ ircd::net::dns::resolver_call(const hostport &hp,
host(hp)
};
auto &resolver{*dns::resolver_instance};
auto &resolver
{
*dns::resolver_instance
};
if(unlikely(!resolver.ns.is_open()))
throw error
{

View file

@ -237,7 +237,7 @@ ircd::m::homeserver::homeserver(const struct opts *const &opts)
signon(*this);
if(primary == this)
mods::imports.emplace("net_dns"s, "net_dns"s);
mods::imports.emplace("net_dns_cache"s, "net_dns_cache"s);
if(primary == this)
m::init::backfill::init();

View file

@ -221,7 +221,7 @@ noexcept try
_fetch.reset(nullptr);
mods::imports.erase("net_dns"s);
mods::imports.erase("net_dns_cache"s);
//TODO: remove this for non-interfering shutdown
//server::interrupt_all();

View file

@ -39,20 +39,16 @@ AM_LDFLAGS = \
moduledir = @moduledir@
net_dns_cache_la_SOURCES = net_dns_cache.cc
stats_la_SOURCES = stats.cc
net_dns_la_SOURCES = net_dns.cc net_dns_cache.cc
net_dns_la_CPPFLAGS = -include $(top_srcdir)/include/ircd/asio.h
net_dns_la_CPPFLAGS += $(AM_CPPFLAGS) @BOOST_CPPFLAGS@
net_dns_la_LDFLAGS = $(AM_LDFLAGS) @BOOST_LDFLAGS@
net_dns_la_LDFLAGS += -Wl,--no-gnu-unique
console_la_SOURCES = console.cc
web_root_la_SOURCES = web_root.cc
web_hook_la_SOURCES = web_hook.cc
well_known_la_SOURCES = well_known.cc
module_LTLIBRARIES = \
net_dns_cache.la \
stats.la \
net_dns.la \
console.la \
web_root.la \
web_hook.la \

View file

@ -8,7 +8,7 @@
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#include "net_dns.h"
#include <ircd/net/dns_cache.h>
namespace ircd::net::dns::cache
{
@ -21,8 +21,18 @@ namespace ircd::net::dns::cache
extern const m::room::id::buf dns_room_id;
extern m::hookfn<m::vm::eval &> hook;
static void init(), fini();
}
ircd::mapi::header
IRCD_MODULE
{
"DNS cache using Matrix rooms.",
ircd::net::dns::cache::init,
ircd::net::dns::cache::fini,
};
decltype(ircd::net::dns::cache::dns_room_id)
ircd::net::dns::cache::dns_room_id
{
@ -32,25 +42,21 @@ ircd::net::dns::cache::dns_room_id
decltype(ircd::net::dns::cache::hook)
ircd::net::dns::cache::hook
{
ircd::net::dns::cache::handle,
{
{ "_site", "vm.effect" },
{ "room_id", string_view{dns_room_id} },
}
ircd::net::dns::cache::handle,
{
{ "_site", "vm.effect" },
{ "room_id", string_view{dns_room_id} },
}
};
decltype(ircd::net::dns::cache::waiting)
ircd::net::dns::cache::waiting;
decltype(ircd::net::dns::cache::mutex)
ircd::net::dns::cache::mutex;
decltype(ircd::net::dns::cache::dock)
ircd::net::dns::cache::dock;
void
ircd::net::dns::cache::init()
{
log::debug
{
"DNS cache room %s currently set.",
string_view{dns_room_id}
};
}
void
@ -623,55 +629,6 @@ catch(const std::exception &e)
return true;
}
//
// cache::waiter
//
bool
ircd::net::dns::cache::operator==(const waiter &a, const waiter &b)
{
return a.opts.qtype == b.opts.qtype &&
a.key && b.key &&
a.key == b.key;
}
bool
ircd::net::dns::cache::operator!=(const waiter &a, const waiter &b)
{
return !operator==(a, b);
}
//
// cache::waiter::waiter
//
ircd::net::dns::cache::waiter::waiter(const hostport &hp,
const dns::opts &opts,
dns::callback &&callback)
:callback
{
std::move(callback)
}
,opts
{
opts
}
,port
{
net::port(hp)
}
,key
{
opts.qtype == 33?
make_SRV_key(keybuf, hp, opts):
strlcpy(keybuf, host(hp))
}
{
this->opts.srv = {};
this->opts.proto = {};
assert(this->opts.qtype);
}
//
// cache room creation
//
@ -691,6 +648,7 @@ ircd::net::dns::cache::create_room_hook
{ "room_id", "!ircd" },
{ "type", "m.room.create" },
},
[](const m::event &, m::vm::eval &)
{
create_room();