ircd: Move matrix application related to derived library.

This commit is contained in:
Jason Volk 2019-09-25 12:48:00 -07:00
parent fb3c6b47a4
commit 89e0a7fc82
24 changed files with 337 additions and 218 deletions

View File

@ -3,6 +3,7 @@ ACLOCAL_AMFLAGS = -I tools/m4
SUBDIRS = include/ircd
SUBDIRS += ircd
SUBDIRS += matrix
SUBDIRS += modules
SUBDIRS += share
SUBDIRS += construct

View File

@ -42,6 +42,7 @@ AC_CONFIG_FILES(\
include/ircd/Makefile \
construct/Makefile \
ircd/Makefile \
matrix/Makefile \
modules/Makefile \
share/Makefile \
)
@ -500,6 +501,42 @@ AC_ARG_ENABLE(lowmem-compile, AC_HELP_STRING([--enable-lowmem-compile], [Enable
AM_CONDITIONAL([LOWMEM_COMPILE], [[[[ $lowmem_compile = "yes" ]]]])
dnl
dnl Gold linker
dnl
AC_ARG_ENABLE(gold, AC_HELP_STRING([--enable-ld-gold], [Use the gold linker.]),
[
ld_gold="yes"
], [
ld_gold="yes"
])
AM_CONDITIONAL([LD_GOLD], [[[[ $ld_gold = "yes" ]]]])
AM_COND_IF([LD_GOLD],
[
AM_COND_IF([GCC],
[
LDFLAGS+=" -Wl,-fuse-ld=gold"
LDFLAGS+=" -Wl,--gdb-index"
])
AM_COND_IF([CLANG],
[
LDFLAGS+=" -fuse-ld=gold"
])
LDFLAGS+=" -Wl,--warn-common"
LDFLAGS+=" -Wl,--warn-execstack"
LDFLAGS+=" -Wl,--detect-odr-violations"
LDFLAGS+=" -Wl,--rosegment"
LDFLAGS+=" -Wl,--icf=all"
LDFLAGS+=" -Wl,-z,noexecstack"
LDFLAGS+=" -Wl,-z,combreloc"
LDFLAGS+=" -Wl,-z,text-unlikely-segment"
])
dnl
dnl Optimization
dnl

View File

@ -102,7 +102,6 @@ noexcept try
auto argv(_argv), envp(_envp);
const char *const progname(_argv[0]);
parseargs(&argc, &argv, opts);
applyargs();
// cores are not dumped without consent of the user to maintain the privacy
// of cryptographic key material in memory at the time of the crash. Note
@ -118,9 +117,6 @@ noexcept try
if(printversion)
return print_version();
if(quietmode)
ircd::log::console_disable();
// The matrix origin is the first positional argument after any switched
// arguments. The matrix origin is the hostpart of MXID's for the server.
const ircd::string_view origin
@ -151,26 +147,30 @@ noexcept try
"usage :%s <origin> [servername]", progname
};
// Set the required name conf items based on the positional program
// arguments. This operation will throw if the strings are not fit for
// purpose as host/domain names.
ircd::network_name.set(origin);
ircd::server_name.set(hostname);
// Sets various other conf items based on the program options captured into
// the globals preceding this frame.
applyargs();
// The smoketest uses this ircd::run::level callback to set a flag when
// each ircd::run::level is reached. All flags must be set to pass.
// each ircd::run::level is reached. All flags must be set to pass. The
// smoketest is inert unless the -smoketest program option is used.
const ircd::run::changed smoketester{[](const auto &level)
{
smoketest.at(size_t(level) + 1) = true;
if(smoketest[0] && level == ircd::run::level::RUN) ircd::post{[]
{
ircd::quit();
}};
if(smoketest[0] && level == ircd::run::level::RUN)
ircd::post {[] { ircd::quit(); }};
}};
// This is the sole io_context for Construct, and the ios.run() below is the
// the only place where the program actually blocks.
boost::asio::io_context ios;
// Associates libircd with our io_context and posts the initial routines
// to that io_context. Execution of IRCd will then occur during ios::run()
// note: only supports service for one hostname/origin at this time.
ircd::init(ios, origin, hostname);
// libircd does no signal handling (or at least none that you ever have to
// care about); reaction to all signals happens out here instead. Handling
// is done properly through the io_context which registers the handler for
@ -180,6 +180,10 @@ noexcept try
// platformness with windows etc.
const construct::signals signals{ios};
// Associates libircd with our io_context and posts the initial routines
// to that io_context. Execution of IRCd will then occur during ios::run()
ircd::init(ios);
// If the user wants to immediately drop to an interactive command line
// without having to send a ctrl-c for it, that is provided here. This does
// not actually take effect until it's processed in the ios.run() below.
@ -375,4 +379,7 @@ applyargs()
if(soft_assert)
ircd::soft_assert.set("true");
if(quietmode)
ircd::log::console_disable();
}

View File

@ -66,7 +66,7 @@
#include "net/net.h"
#include "server/server.h"
#include "magick.h"
#include "m/m.h"
#include "m/matrix.h"
#include "resource/resource.h"
#include "client.h"
@ -74,11 +74,8 @@
///
namespace ircd
{
seconds uptime();
void cont() noexcept;
bool quit() noexcept;
void init(boost::asio::io_context &ios, const string_view &origin, const string_view &hostname);
extern const info::versions version_api;
extern const info::versions version_abi;
extern conf::item<bool> restart;
extern conf::item<bool> debugmode;
@ -86,8 +83,13 @@ namespace ircd
extern conf::item<bool> write_avoid;
extern conf::item<bool> soft_assert;
extern const info::versions version_api;
extern const info::versions version_abi;
extern conf::item<std::string> server_name;
extern conf::item<std::string> network_name;
seconds uptime();
void init(boost::asio::io_context &ios);
void cont() noexcept;
bool quit() noexcept;
}
#endif // HAVE_IRCD_IRCD_H

35
include/ircd/m/init.h Normal file
View File

@ -0,0 +1,35 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// 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.
#pragma once
#define HAVE_IRCD_M_INIT_H
namespace ircd::m::init
{
struct modules;
struct backfill;
struct bootstrap;
}
/// Internal use only; do not call
struct ircd::m::init::modules
{
void fini_imports() noexcept;
void init_imports();
modules();
~modules() noexcept;
};
/// Internal use only; do not call
struct ircd::m::init::bootstrap
{
bootstrap();
};

View File

@ -34,7 +34,7 @@ namespace ircd::m
/// Matrix Protocol System
namespace ircd::m
{
struct init;
struct matrix;
IRCD_OVERLOAD(generate)
@ -44,6 +44,7 @@ namespace ircd::m
#include "name.h"
#include "error.h"
#include "self.h"
#include "init.h"
#include "id.h"
#include "event/event.h"
#include "get.h"
@ -83,30 +84,15 @@ namespace ircd::m
#include "media.h"
#include "search.h"
struct ircd::m::init
struct ircd::m::matrix
{
struct modules;
struct backfill;
std::string module_path
{
fs::path_string(fs::base::LIB, "libircd_matrix")
};
self::init _self;
dbs::init _dbs;
std::unique_ptr<modules> _modules;
static void bootstrap();
void close();
public:
init(const string_view &origin, const string_view &hostname);
~init() noexcept;
};
struct ircd::m::init::modules
{
void fini_imports() noexcept;
void init_imports();
void init_keys();
public:
modules();
~modules() noexcept;
ircd::module module
{
module_path
};
};

View File

@ -13,12 +13,12 @@
namespace ircd::m
{
struct room;
IRCD_M_EXCEPTION(m::error, CONFLICT, http::CONFLICT);
IRCD_M_EXCEPTION(m::error, NOT_MODIFIED, http::NOT_MODIFIED);
IRCD_M_EXCEPTION(CONFLICT, ALREADY_MEMBER, http::CONFLICT);
struct room;
// Util
bool my(const room &);
bool operator!(const room &); // room_id empty

View File

@ -51,7 +51,7 @@ struct ircd::m::self::init
static void tls_certificate();
static void keys();
init(const string_view &origin, const string_view &servername);
init();
};
inline ircd::string_view

View File

@ -32,39 +32,19 @@ AM_CPPFLAGS = \
@EXTRA_CPPFLAGS@ \
###
#TODO: split options for if LD_GOLD
AM_LDFLAGS = \
-version-info 3:1:0 \
-Wl,--warn-common \
-Wl,--warn-execstack \
-Wl,--detect-odr-violations \
-Wl,--unresolved-symbols=report-all \
-Wl,--no-undefined-version \
-Wl,--unresolved-symbols=report-all \
-Wl,--weak-unresolved-symbols \
-Wl,--icf=all \
-Wl,--rosegment \
-Wl,--gdb-index \
-Wl,-z,lazy \
-Wl,-z,now \
-Wl,-z,nodelete \
-Wl,-z,nodlopen \
-Wl,-z,noexecstack \
-Wl,-z,combreloc \
-Wl,-z,text-unlikely-segment \
$(PLATFORM_LDFLAGS) \
@EXTRA_LDFLAGS@ \
###
if GCC
AM_LDFLAGS += \
-Wl,-fuse-ld=gold \
###
endif
if CLANG
AM_LDFLAGS += \
-fuse-ld=gold \
###
endif
if MINGW
AM_LDFLAGS += \
-Wl,--enable-runtime-pseudo-reloc \
@ -176,13 +156,6 @@ libircd_la_SOURCES += resource.cc
if JS
libircd_la_SOURCES += js.cc
endif
libircd_la_SOURCES += m_name.cc
libircd_la_SOURCES += m_id.cc
libircd_la_SOURCES += m_dbs.cc
libircd_la_SOURCES += m_room.cc
libircd_la_SOURCES += m_fed.cc
libircd_la_SOURCES += m.cc
libircd_la_SOURCES += m_event.cc
libircd_la_SOURCES += ircd.cc
db_write_thread.lo: AM_CPPFLAGS += -I$(top_srcdir)/deps/rocksdb/include
@ -227,6 +200,3 @@ rfc3986.lo: CXXFLAGS += ${GUNIT_CXXFLAGS}
rfc1459.lo: AM_CPPFLAGS := -include ircd/spirit.h ${AM_CPPFLAGS}
rfc1459.lo: CXXFLAGS += ${GUNIT_CXXFLAGS}
m_id.lo: AM_CPPFLAGS := -include ircd/spirit.h ${AM_CPPFLAGS}
m_id.lo: CXXFLAGS += ${GUNIT_CXXFLAGS}

View File

@ -10,10 +10,7 @@
namespace ircd
{
std::string _origin; // user's supplied param
std::string _servername; // user's supplied param
ctx::ctx *main_context; // Main program loop
extern ctx::ctx *main_context;
static void main() noexcept;
}
@ -69,6 +66,45 @@ ircd::restart
{ "persist", false },
};
decltype(ircd::server_name)
ircd::server_name
{
{
{ "name", "ircd.name.server" },
{ "default", "localhost" },
{ "persist", false },
}, []
{
if(!rfc3986::valid_remote(std::nothrow, ircd::server_name))
throw user_error
{
"The 'ircd.name.server' conf \"%s\" is not a valid hostname.",
string_view(server_name),
};
}
};
decltype(ircd::network_name)
ircd::network_name
{
{
{ "name", "ircd.name.network" },
{ "default", "localhost" },
{ "persist", false },
}, []
{
if(!rfc3986::valid_remote(std::nothrow, ircd::network_name))
throw user_error
{
"The 'ircd.name.network' conf \"%s\" is not a valid hostname.",
string_view(network_name),
};
}
};
decltype(ircd::main_context)
ircd::main_context;
/// Sets up the IRCd and its main context, then returns without blocking.
//
/// Pass your io_context instance, it will share it with the rest of your program.
@ -79,9 +115,7 @@ ircd::restart
///
/// init() can only be called from a run::level::HALT state
void
ircd::init(boost::asio::io_context &user_ios,
const string_view &origin,
const string_view &servername)
ircd::init(boost::asio::io_context &user_ios)
try
{
// This function must only be called from a HALT state.
@ -91,24 +125,6 @@ try
"Cannot init() IRCd from runlevel %s", reflect(run::level)
};
// Check that the supplied origin string is properly formatted.
if(!rfc3986::valid_remote(std::nothrow, origin))
throw user_error
{
"The 'origin' argument \"%s\" is not a valid hostname.", origin
};
// Check that the supplied servername string is properly formatted.
if(!rfc3986::valid_remote(std::nothrow, servername))
throw user_error
{
"The 'servername' argument \"%s\" is not a valid hostname.", servername
};
// Save the params used for m::init later.
_origin = std::string{origin};
_servername = std::string{servername};
// Setup the core event loop system starting with the user's supplied ios.
ios::init(user_ios);
@ -299,23 +315,7 @@ noexcept try
server::init _server_; // Server related
client::init _client_; // Client related
js::init _js_; // SpiderMonkey
m::init _matrix_ // Matrix
{
string_view{_origin},
string_view{_servername}
};
// Any deinits which have to be done with all subsystems intact
const unwind shutdown{[&]
{
_matrix_.close();
server::interrupt_all();
client::terminate_all();
client::close_all();
server::close_all();
server::wait_all();
client::wait_all();
}};
m::matrix _matrix_; // Matrix
// IRCd will now transition to the RUN state indicating full functionality.
run::set(run::level::RUN);

View File

@ -481,6 +481,9 @@ ircd::mods::available()
std::string
ircd::mods::fullpath(const string_view &name)
{
if(fs::is_absolute(name))
return postfixed(name);
std::vector<std::string> why;
const auto path
{

View File

@ -1444,11 +1444,11 @@ ircd::server::peer::open_links()
try
{
if(unlikely(is_loop(open_opts.ipport)))
if(!my_host(server_name(open_opts)))
if(!my_host(net::server_name(open_opts)))
throw unavailable
{
"Won't open loopback for remote host '%s'",
server_name(open_opts),
net::server_name(open_opts),
};
// The hostname in open_opts should still reference this object's string.

86
matrix/Makefile.am Normal file
View File

@ -0,0 +1,86 @@
AUTOMAKE_OPTIONS = foreign
DEFS += \
-DIRCD_UNIT \
-DIRCD_MATRIX_UNIT \
###
AM_CXXFLAGS = \
-ftls-model=global-dynamic \
@EXTRA_CXXFLAGS@ \
###
if DEBUG
if GCC
AM_CXXFLAGS += -fmax-errors=2
endif
endif
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-include ircd/ircd.pic.h \
-include ircd/mods/mapi.h \
@EXTRA_CPPFLAGS@ \
###
#TODO: split options for if LD_GOLD
AM_LDFLAGS = \
-version-info 0:1:0 \
-Wl,--no-undefined-version \
-Wl,--unresolved-symbols=report-all \
-Wl,--allow-shlib-undefined \
-Wl,--weak-unresolved-symbols \
-Wl,-z,now \
-L$(top_srcdir)/ircd \
$(PLATFORM_LDFLAGS) \
@EXTRA_LDFLAGS@ \
###
if MINGW
AM_LDFLAGS += \
-Wl,--enable-runtime-pseudo-reloc \
###
endif
libircd_matrixdir = @libdir@
libircd_matrix_LTLIBRARIES = libircd_matrix.la
libircd_matrix_LIBADD =#
libircd_matrix_LIBADD += -lircd
libircd_matrix_la_SOURCES =#
libircd_matrix_la_SOURCES += name.cc
libircd_matrix_la_SOURCES += id.cc
libircd_matrix_la_SOURCES += dbs.cc
libircd_matrix_la_SOURCES += room.cc
libircd_matrix_la_SOURCES += fed.cc
libircd_matrix_la_SOURCES += init_bootstrap.cc
libircd_matrix_la_SOURCES += matrix.cc
libircd_matrix_la_SOURCES += event.cc
### TODO: dedup with ircd/Makefile.am
# Units containing a spirit grammar have some special needs to mitigate
# larger-than-normal compile time, compile memory, and output objects.
# A composite of CXXFLAGS is used specifically on units with grammars.
GUNIT_CXXFLAGS = ###
# Grammar templates can generate a huge number of individual debug symbols
# for each template instantiation deep within spirit; we try to reduce...
GUNIT_CXXFLAGS += -fno-var-tracking
if GCC
GUNIT_CXXFLAGS += -fno-var-tracking-assignments
GUNIT_CXXFLAGS += -femit-struct-debug-baseonly
endif
# The recursive grammars can consume a large amount of RAM when compiling
# (>= 2 GiB) which can thrash small systems and even sometimes crash GCC.
# This option reduces memory consumption at the cost of compilation speed.
if GCC
if LOWMEM_COMPILE
GUNIT_CXXFLAGS += --param ggc-min-expand=1
endif
endif
id.lo: AM_CPPFLAGS := -include ircd/spirit.h ${AM_CPPFLAGS}
id.lo: CXXFLAGS += ${GUNIT_CXXFLAGS}

View File

@ -8,15 +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.
ircd::mapi::header
IRCD_MODULE
{
"Matrix initial bootstrap support."
};
void
IRCD_MODULE_EXPORT
ircd::m::init::bootstrap()
ircd::m::init::bootstrap::bootstrap()
try
{
assert(dbs::events);

View File

@ -8,6 +8,25 @@
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
namespace ircd::m
{
std::unique_ptr<self::init> _self;
std::unique_ptr<dbs::init> _dbs;
std::unique_ptr<init::modules> _modules;
static void on_load();
static void on_unload() noexcept;
}
ircd::mapi::header
IRCD_MODULE
{
"Matrix Chat Protocol",
ircd::m::on_load,
ircd::m::on_unload,
};
IRCD_MODULE_EXPORT_DATA
decltype(ircd::m::log)
ircd::m::log
{
@ -32,26 +51,14 @@ me_offline_status_msg
{ "default", "Catch ya on the flip side..." }
};
//
// init::init
//
ircd::m::init::init(const string_view &origin,
const string_view &servername)
void
ircd::m::on_load()
try
:_self
{
origin, servername
}
,_dbs
{
self::servername, std::string{}
}
,_modules
{
std::make_unique<modules>()
}
{
_self = std::make_unique<self::init>();
_dbs = std::make_unique<dbs::init>(ircd::server_name, std::string{});
_modules = std::make_unique<init::modules>();
if(!ircd::write_avoid && vm::sequence::retired != 0)
presence::set(me, "online", me_online_status_msg);
}
@ -78,14 +85,29 @@ catch(const std::exception &e)
throw;
}
ircd::m::init::~init()
void
ircd::m::on_unload()
noexcept try
{
mods::imports.erase("m_listen"s);
if(m::sync::pool.size())
m::sync::pool.join();
if(!std::uncaught_exceptions() && !ircd::write_avoid)
presence::set(me, "offline", me_offline_status_msg);
_modules.reset(nullptr);
_dbs.reset(nullptr);
_self.reset(nullptr);
//TODO: remove this for non-interfering shutdown
server::interrupt_all();
client::terminate_all();
client::close_all();
server::close_all();
server::wait_all();
client::wait_all();
}
catch(const m::error &e)
{
@ -97,12 +119,6 @@ catch(const m::error &e)
ircd::terminate();
}
void
ircd::m::init::close()
{
mods::imports.erase("m_listen"s);
}
//
// init::modules
//
@ -164,17 +180,7 @@ ircd::m::init::modules::init_imports()
"database is empty. I will be bootstrapping it with initial events now..."
};
const module m_init_bootstrap
{
"m_init_bootstrap"
};
const mods::import<void ()> bootstrap
{
m_init_bootstrap, "ircd::m::init::bootstrap"
};
bootstrap();
m::init::bootstrap{};
}
}
@ -483,18 +489,18 @@ ircd::m::self::host()
extern ircd::m::room::id::buf users_room_id;
extern ircd::m::room::id::buf tokens_room_id;
ircd::m::self::init::init(const string_view &origin,
const string_view &servername)
ircd::m::self::init::init()
try
{
self::origin = string_view{ircd::network_name};
self::servername = string_view{ircd::server_name};
// Sanity check that these are valid hostname strings. This was likely
// already checked, so these validators will simply throw without very
// useful error messages if invalid strings ever make it this far.
rfc3986::valid_host(origin);
rfc3986::valid_host(servername);
self::origin = origin;
self::servername = servername;
m::my_node = string_view{strlcpy
{
ircd_node_id, origin
@ -521,6 +527,17 @@ ircd::m::self::init::init(const string_view &origin,
assert(ircd::run::level == run::level::START);
mods::imports.emplace("m_keys"s, "m_keys"s);
}
catch(const std::exception &e)
{
log::critical
{
m::log, "Failed to init self origin[%s] servername[%s]",
origin,
servername,
};
throw;
}
///////////////////////////////////////////////////////////////////////////////
//

View File

@ -20,36 +20,18 @@ AM_CPPFLAGS = \
@EXTRA_CPPFLAGS@ \
###
#TODO: split options for if LD_GOLD
AM_LDFLAGS = \
-module \
-avoid-version \
-Wl,--warn-common \
-Wl,--warn-execstack \
-Wl,--detect-odr-violations \
-Wl,--allow-shlib-undefined \
-Wl,--icf=all \
-Wl,--gdb-index \
-Wl,-z,lazy \
-Wl,-z,noexecstack \
-Wl,-z,combreloc \
-Wl,-z,text-unlikely-segment \
-L$(top_srcdir)/ircd \
-L$(top_srcdir)/matrix \
$(PLATFORM_LDFLAGS) \
@EXTRA_LDFLAGS@ \
###
if GCC
AM_LDFLAGS += \
-Wl,-fuse-ld=gold \
###
endif
if CLANG
AM_LDFLAGS += \
-fuse-ld=gold \
###
endif
###############################################################################
#
# /
@ -161,7 +143,6 @@ m_event_append_la_SOURCES = m_event_append.cc
m_event_horizon_la_SOURCES = m_event_pretty.cc
m_event_pretty_la_SOURCES = m_event_horizon.cc
m_init_bootstrap_la_SOURCES = m_init_bootstrap.cc
m_init_backfill_la_SOURCES = m_init_backfill.cc
m_listen_la_SOURCES = m_listen.cc
@ -225,7 +206,6 @@ m_module_LTLIBRARIES = \
m_room_server_acl.la \
m_room_bootstrap.la \
m_room_name.la \
m_init_bootstrap.la \
m_init_backfill.la \
m_listen.la \
m_users.la \

View File

@ -10,6 +10,19 @@
#include "net_dns.h"
namespace ircd::net::dns
{
template<class T> static rfc1035::record *new_record(mutable_buffer &, const rfc1035::answer &);
static void handle_resolved(std::exception_ptr, const tag &, const answers &);
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
{

View File

@ -21,34 +21,24 @@ namespace ircd::net::dns
using answers_callback = std::function<void (std::exception_ptr, const tag &, const answers &)>;
constexpr const size_t MAX_COUNT {64};
template<class T> static rfc1035::record *new_record(mutable_buffer &, const rfc1035::answer &);
static void handle_resolved(std::exception_ptr, const tag &, const answers &);
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();
}
namespace ircd::net::dns::cache
{
struct waiter;
static bool operator==(const waiter &, const waiter &);
static bool operator!=(const waiter &, const waiter &);
bool operator==(const waiter &, const waiter &);
bool operator!=(const waiter &, const waiter &);
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 &);
bool call_waiter(const string_view &, const string_view &, const json::array &, waiter &);
size_t call_waiters(const string_view &, const string_view &, const json::array &);
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 uint &code, const string_view &msg);
bool put(const string_view &type, const string_view &state_key, const records &rrs);
bool put(const string_view &type, const string_view &state_key, const uint &code, const string_view &msg);
static void fini();
static void init();
void fini();
void init();
extern conf::item<seconds> min_ttl IRCD_MODULE_EXPORT_DATA;
extern conf::item<seconds> error_ttl IRCD_MODULE_EXPORT_DATA;