diff --git a/construct/Makefile.am b/construct/Makefile.am index 5e4c63a53..e10372225 100644 --- a/construct/Makefile.am +++ b/construct/Makefile.am @@ -68,7 +68,6 @@ construct_LDADD = \ construct_SOURCES = \ construct.cc \ - matrix.cc \ signals.cc \ console.cc \ lgetopt.cc \ diff --git a/construct/construct.cc b/construct/construct.cc index 60f89168b..85a980b62 100644 --- a/construct/construct.cc +++ b/construct/construct.cc @@ -13,7 +13,6 @@ #include #include "lgetopt.h" #include "construct.h" -#include "matrix.h" #include "signals.h" #include "console.h" @@ -120,8 +119,13 @@ noexcept try if(printversion) return print_version(); - // The matrix origin is the first positional argument after any switched - // arguments. The matrix origin is the hostpart of MXID's for the server. + // Sets various other conf items based on the program options captured into + // the globals preceding this frame. + applyargs(); + + // The network name (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 { argc > 0? @@ -129,46 +133,42 @@ noexcept try nullptr }; - // The hostname is the unique name for this specific server. This is + // The server_name is the unique name for this specific server. This is // generally the same as origin; but if origin is example.org with an - // SRV record redirecting to matrix.example.org then hostname is + // SRV record redirecting to matrix.example.org then server_name is // matrix.example.org. In clusters serving a single origin, all - // hostnames must be different. - const ircd::string_view hostname + // server_names must be different. + const ircd::string_view server_name { - argc > 1? // hostname given on command line + argc > 1? // server_name given on command line argv[1]: - argc > 0? // hostname matches origin + argc > 0? // server_name matches origin argv[0]: nullptr }; - // at least one hostname argument is required for now. - if(!hostname) + // at least one server_name argument is required for now. + if(!server_name) throw ircd::user_error { "usage :%s [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. The - // smoketest is inert unless the -smoketest program option is used. - const ircd::run::changed smoketester{[](const auto &level) + // smoketest is inert unless the -smoketest program option is used. Note + // the special case for run::level::RUN, which initiates the transition + // to QUIT; the ircd::post allows any operations queued in the io_context + // to run in case the smoketest isn't the only callback being invoked. + const ircd::run::changed smoketester { - smoketest.at(size_t(level) + 1) = true; - if(smoketest[0] && level == ircd::run::level::RUN) - ircd::post {[] { ircd::quit(); }}; - }}; + [](const auto &level) + { + smoketest.at(size_t(level) + 1) = true; + 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. @@ -187,9 +187,88 @@ noexcept try // to that io_context. Execution of IRCd will then occur during ios::run() ircd::init(ios); - // Start matrix application. - if(likely(!nomatrix)) - construct::matrix::init(); + // Setup synchronization primitives on this stack for starting and stopping + // the application (matrix homeserver). Note this stack cannot actually use + // these; they'll be used to synchronize the closures below running in + // different contexts. + ircd::ctx::latch start(2), quit(2); + + // Setup the matrix homeserver application. This will be executed on an + // ircd::context (dedicated stack). We construct several objects on the + // stack which are the basis for our matrix homeserver. When the stack + // unwinds, the homeserver will go out of service. + const auto homeserver{[&origin, &server_name, &start, &quit] + { + // 5 + struct ircd::m::homeserver::opts opts; + opts.origin = origin; + opts.server_name = server_name; + + // 6 + // Load the matrix library dynamic shared object + ircd::matrix matrix; + + // 7 + // Run a primary homeserver based on the program options given. + const ircd::custom_ptr homeserver + { + // 7.1 + matrix.init(&opts), [&matrix] + (ircd::m::homeserver *const homeserver) + { + // 13.1 + matrix.fini(homeserver); + } + }; + + // 8 + // Notify the loader the homeserver is ready for service. + start.count_down_and_wait(); + + // 9 + // Yield until the loader notifies us; this stack will then unwind. + quit.count_down_and_wait(); + + // 13 + }}; + + // This object registers a callback for a specific event in libircd; the + // closure is called from the main context (#1) running ircd::main(). + // after libircd is ready for service in runlevel START but before entering + // runlevel RUN. It is called again immediately after entering runlevel + // QUIT, but before any functionality of libircd destructs. This cues us + // to start and stop the homeserver. + const decltype(ircd::run::main)::callback loader + { + ircd::run::main, [&homeserver, &start, &quit] + { + static ircd::context context; + + // 2 This branch is taken the first time this function is called, + // and not taken the second time. + if(!context) + { + // 3 Launch the homeserver context (asynchronous). + context = { "matrix", homeserver }; + + // 4 Yield until the homeserver function notifies `start`; waiting + // here prevents ircd::main() from entering runlevel RUN. + start.count_down_and_wait(); + + // 10 + return; + } + + // 11 + // Notify the waiting homeserver context to quit; this will + // start shutting down the homeserver. + quit.count_down_and_wait(); + + // 12 + // Wait for the homeserver context to finish before we return. + context.join(); + } + }; // 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 @@ -207,10 +286,12 @@ noexcept try if(norun) return EXIT_SUCCESS; + // 1 // Execution. // Blocks until a clean exit from a quit() or an exception comes out of it. ios.run(); + // 14 // The smoketest is enabled if the first value is true; then all of the // values must be true for the smoketest to pass. if(smoketest[0]) @@ -331,6 +412,8 @@ enable_coredumps() } #endif +/// These operations are safe to call before ircd::init() and anytime after +/// static initialization. void applyargs() { diff --git a/construct/matrix.cc b/construct/matrix.cc deleted file mode 100644 index 02ce1be6b..000000000 --- a/construct/matrix.cc +++ /dev/null @@ -1,116 +0,0 @@ -// Matrix Construct -// -// Copyright (C) Matrix Construct Developers, Authors & Contributors -// Copyright (C) 2016-2019 Jason Volk -// -// 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 -#include "construct.h" -#include "matrix.h" - -decltype(construct::matrix) -construct::matrix; - -void -construct::matrix::init() -{ - assert(construct::matrix == nullptr); - construct::matrix = new matrix{}; -} - -void -construct::matrix::quit() -{ - if(!construct::matrix) - return; - - construct::matrix->context.terminate(); -} - -construct::matrix::matrix() -:context -{ - "matrix", - 1048576, - std::bind(&matrix::main, this), - ircd::context::DISPATCH, -} -{ -} - -construct::matrix::~matrix() -noexcept -{ -} - -void -construct::matrix::main() -noexcept try -{ - ircd::run::changed::dock.wait([] - { - return ircd::run::level != ircd::run::level::READY; - }); - - if(ircd::run::level != ircd::run::level::START || ircd::run::level != ircd::run::level::RUN) - return; - - ircd::matrix instance - { - - }; - - const ircd::scope_restore this_instance - { - this->instance, std::addressof(instance) - }; - - ircd::mods::import log - { - instance.module, "ircd::m::log" - }; - - ircd::log::notice - { - log, "Matrix Constructed" - }; - - dock.notify_all(); - ircd::run::changed::dock.wait([] - { - return false - || ircd::run::level == ircd::run::level::QUIT - || ircd::run::level == ircd::run::level::HALT - ; - }); - - ircd::log::notice - { - log, "Matrix Shutdown..." - }; -} -catch(const ircd::ctx::interrupted &e) -{ - ircd::log::debug - { - "construct::matrix :%s", e.what() - }; -} -catch(const ircd::ctx::terminated &e) -{ - ircd::log::debug - { - "construct::matrix: terminated." - }; -} -catch(const std::exception &e) -{ - ircd::log::error - { - "construct::matrix :%s", e.what() - }; -} diff --git a/construct/matrix.h b/construct/matrix.h deleted file mode 100644 index 9d7c79469..000000000 --- a/construct/matrix.h +++ /dev/null @@ -1,34 +0,0 @@ -// Matrix Construct -// -// Copyright (C) Matrix Construct Developers, Authors & Contributors -// Copyright (C) 2016-2018 Jason Volk -// -// 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. - -namespace ircd -{ - struct matrix; -} - -namespace construct -{ - struct matrix; -} - -struct construct::matrix -{ - ircd::ctx::dock dock; - ircd::context context; - ircd::matrix *instance {nullptr}; - - void main() noexcept; - - matrix(); - ~matrix() noexcept; - - static void init(); - static void quit(); -}; diff --git a/construct/signals.cc b/construct/signals.cc index ebd40e434..e0c813ead 100644 --- a/construct/signals.cc +++ b/construct/signals.cc @@ -13,7 +13,6 @@ #include "construct.h" #include "signals.h" #include "console.h" -#include "matrix.h" namespace construct { diff --git a/include/ircd/ircd.h b/include/ircd/ircd.h index aaee00022..e9715de5e 100644 --- a/include/ircd/ircd.h +++ b/include/ircd/ircd.h @@ -82,9 +82,6 @@ namespace ircd extern conf::item write_avoid; extern conf::item soft_assert; - extern conf::item server_name; - extern conf::item network_name; - seconds uptime(); void init(boost::asio::io_context &ios); void cont() noexcept; diff --git a/include/ircd/m/event/append.h b/include/ircd/m/event/append.h index 940ba81c2..430a039ea 100644 --- a/include/ircd/m/event/append.h +++ b/include/ircd/m/event/append.h @@ -11,6 +11,12 @@ #pragma once #define HAVE_IRCD_M_EVENT_APPEND +//XXX fwd decl +namespace ircd::m +{ + struct room; +}; + /// Used when transmitting events to clients. This tries to hide and provide /// as much boilerplate as possible which we abstracted from all of the /// different locations where an event may be revealed to a client. This device diff --git a/include/ircd/m/homeserver.h b/include/ircd/m/homeserver.h new file mode 100644 index 000000000..cead22156 --- /dev/null +++ b/include/ircd/m/homeserver.h @@ -0,0 +1,115 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2018 Jason Volk +// +// 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_HOMESERVER_H + +namespace ircd::m +{ + struct homeserver; + + IRCD_M_EXCEPTION(error, NOT_MY_HOMESERVER, http::NOT_FOUND) + IRCD_M_EXCEPTION(error, NOT_A_HOMESERVER, http::SERVICE_UNAVAILABLE) + + string_view origin(const homeserver &); + string_view server_name(const homeserver &); + + bool origin(const homeserver &, const string_view &); + bool server_name(const homeserver &, const string_view &); + + string_view public_key_id(const homeserver &); + const ed25519::sk &secret_key(const homeserver &); + + bool for_each(const std::function &); + + homeserver &my(const string_view &origin); + homeserver &my(); // primary + + user::id me(const string_view &origin); + user::id me(); // primary +} + +///NOTE: instance_multimap is used because there is no instance_map yet. +struct ircd::m::homeserver +:instance_multimap> +{ + struct key; + struct cert; + struct opts; + + /// Internal state; use m::my(). + static homeserver *primary; + + /// Options from the user. + const struct opts *opts; + + /// Federation key related. + std::unique_ptr key; + + /// Database + std::shared_ptr database; + + /// List of special room specific to this homeserver. This includes the + /// fundamental !ircd room, !conf room, etc. This list generally doesn't + /// change after construction, but it's mutable to allow modules to add + /// new rooms to the list. + std::set rooms; + + /// An inscription of @ircd:network.name to root various references to + /// a user representing the server. + m::user::id::buf self; + + /// Loaded modules. + std::list modules; + + homeserver(const struct opts *const &); + ~homeserver() noexcept; + + /// Factory to create homeserver with single procedure for shlib purposes. + static homeserver *init(const struct opts *); + static void fini(homeserver *) noexcept; +}; + +struct ircd::m::homeserver::key +{ + /// Current federation secret key instance + ed25519::sk secret_key; + + /// Current federation public key instance + ed25519::pk public_key; + + /// Current federation public key base64 + std::string public_key_b64; + + /// Current ed25519:ident string + std::string public_key_id; + + key(const string_view &origin); + key() = default; +}; + +struct ircd::m::homeserver::cert +{ + std::string tls_private_key_path; + std::string tls_public_key_path; + std::string tls_cert_path; +}; + +struct ircd::m::homeserver::opts +{ + /// Network name. This is the mxid hostpart (i.e @user:origin). + string_view origin; + + /// This server's name. This is the unique domain-name of this server + /// participating in the cluster to serve the origin. The servername may + /// be the origin itself; otherwise, SRV/well-known indirection is required + /// to reach the servername starting from the origin. + string_view server_name; +}; diff --git a/include/ircd/m/m.h b/include/ircd/m/m.h index 1e072550c..1bdb386b1 100644 --- a/include/ircd/m/m.h +++ b/include/ircd/m/m.h @@ -35,6 +35,7 @@ namespace ircd::m namespace ircd::m { struct matrix; + struct homeserver; IRCD_OVERLOAD(generate) @@ -48,9 +49,8 @@ namespace ircd #include "name.h" #include "error.h" -#include "self.h" -#include "init.h" #include "id.h" +#include "self.h" #include "event/event.h" #include "get.h" #include "query.h" @@ -89,9 +89,13 @@ namespace ircd #include "media.h" #include "search.h" #include "resource.h" +#include "homeserver.h" struct ircd::m::matrix { + static const std::vector module_names; + static const std::vector module_names_optional; + std::string module_path { fs::path_string(fs::base::LIB, "libircd_matrix") @@ -101,4 +105,16 @@ struct ircd::m::matrix { module_path }; + + using init_proto = m::homeserver *(const struct m::homeserver::opts *); + mods::import init + { + module, "ircd::m::homeserver::init" + }; + + using fini_proto = void (m::homeserver *) noexcept; + mods::import fini + { + module, "ircd::m::homeserver::fini" + }; }; diff --git a/include/ircd/m/self.h b/include/ircd/m/self.h index e27ace16b..e399876c4 100644 --- a/include/ircd/m/self.h +++ b/include/ircd/m/self.h @@ -13,56 +13,27 @@ namespace ircd::m::self { - struct init; + // Test if provided string is one of my homeserver's network_name()'s. + bool my_host(const string_view &); - extern std::string origin; - extern std::string servername; - extern ed25519::sk secret_key; - extern ed25519::pk public_key; - extern std::string public_key_b64; - extern std::string public_key_id; - extern std::string tls_cert_der; - extern std::string tls_cert_der_sha256_b64; - - string_view host(); + // Similar to my_host(), but the comparison is relaxed to allow port + // numbers to be a factor: myself.com:8448 input will match if a homeserver + // here has a network_name of myself.com. OTOH, myself.com:1234 (i.e some + // non-canonical port) can only match a homeserver here with the explicit + // name of myself.com:1234. bool host(const string_view &); - void create_my_key(); - void signon(), signoff(); + // Alias for origin(my()); primary homeserver's network name + string_view my_host(); //__attribute__((deprecated)); } namespace ircd::m { - extern struct user me; - extern struct room my_room; - extern struct node my_node; - - string_view my_host(); - bool my_host(const string_view &); + using self::my_host; + using self::host; } namespace ircd { using m::my_host; } - -struct ircd::m::self::init -{ - static void federation_ed25519(); - static void tls_certificate(); - static void keys(); - - init(); -}; - -inline ircd::string_view -ircd::m::my_host() -{ - return self::host(); -} - -inline bool -ircd::m::my_host(const string_view &host) -{ - return self::host(host); -} diff --git a/include/ircd/m/user/user.h b/include/ircd/m/user/user.h index c1219a5a0..3c0612bd0 100644 --- a/include/ircd/m/user/user.h +++ b/include/ircd/m/user/user.h @@ -48,8 +48,6 @@ struct ircd::m::user using closure = std::function; using closure_bool = std::function; - static m::room tokens; - id user_id; operator const id &() const; diff --git a/ircd/ircd.cc b/ircd/ircd.cc index 21755fb60..ac8f5b74c 100644 --- a/ircd/ircd.cc +++ b/ircd/ircd.cc @@ -88,42 +88,6 @@ 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; diff --git a/matrix/Makefile.am b/matrix/Makefile.am index 2ecb67c92..244d1e7f0 100644 --- a/matrix/Makefile.am +++ b/matrix/Makefile.am @@ -57,7 +57,6 @@ 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 += self.cc libircd_matrix_la_SOURCES += hook.cc libircd_matrix_la_SOURCES += event.cc libircd_matrix_la_SOURCES += event_cached.cc @@ -127,7 +126,7 @@ libircd_matrix_la_SOURCES += filter.cc libircd_matrix_la_SOURCES += txn.cc libircd_matrix_la_SOURCES += vm.cc libircd_matrix_la_SOURCES += init_backfill.cc -libircd_matrix_la_SOURCES += init_bootstrap.cc +libircd_matrix_la_SOURCES += homeserver.cc libircd_matrix_la_SOURCES += resource.cc libircd_matrix_la_SOURCES += matrix.cc diff --git a/matrix/conf.cc b/matrix/conf.cc index 6451a29e3..be12711e4 100644 --- a/matrix/conf.cc +++ b/matrix/conf.cc @@ -259,7 +259,7 @@ try item.get(vbuf) }; - return set_conf_item(m::me.user_id, key, val); + return set_conf_item(m::me(), key, val); } catch(const std::exception &e) { @@ -278,7 +278,7 @@ create_conf_room(const m::event &, m::vm::eval &) { const m::conf_room conf_room; - m::create(conf_room.room_id, m::me.user_id); + m::create(conf_room.room_id, m::me()); //rehash_conf({}, true); } diff --git a/matrix/device.cc b/matrix/device.cc index 747773cc0..141b8383e 100644 --- a/matrix/device.cc +++ b/matrix/device.cc @@ -302,7 +302,16 @@ IRCD_MODULE_EXPORT ircd::m::device::access_token_to_id(const string_view &token, const closure &closure) { - const m::room::state &state{m::user::tokens}; + const m::room::id::buf tokens + { + "tokens", origin(my()) + }; + + const m::room::state &state + { + tokens + }; + const m::event::idx &event_idx { state.get(std::nothrow, "ircd.access_token", token) diff --git a/matrix/event.cc b/matrix/event.cc index 3bd436012..9348f22c7 100644 --- a/matrix/event.cc +++ b/matrix/event.cc @@ -182,20 +182,30 @@ ircd::m::event::signatures(const mutable_buffer &out, json::iov &event, const json::iov &content) { + const string_view &origin + { + event.at("origin") + }; + const ed25519::sig sig { sign(event, content) }; + const string_view public_key_id + { + m::public_key_id(my(origin)) + }; + thread_local char sigb64buf[b64encode_size(sizeof(sig))]; const json::members sigb64 { - { self::public_key_id, b64encode_unpadded(sigb64buf, sig) } + { public_key_id, b64encode_unpadded(sigb64buf, sig) } }; const json::members sigs { - { event.at("origin"), sigb64 } + { origin, sigb64 } }; return json::stringify(mutable_buffer{out}, sigs); @@ -222,19 +232,22 @@ ircd::m::signatures(const mutable_buffer &out_, sign(preimage) }; - const auto sig_host + const auto &origin { - my_host(json::get<"origin"_>(event))? - json::get<"origin"_>(event): - my_host() + json::at<"origin"_>(event) + }; + + const string_view public_key_id + { + m::public_key_id(my(origin)) }; thread_local char sigb64buf[b64encode_size(sizeof(sig))]; const json::member my_sig { - sig_host, json::members + origin, json::members { - { self::public_key_id, b64encode_unpadded(sigb64buf, sig) } + { public_key_id, b64encode_unpadded(sigb64buf, sig) } } }; @@ -257,7 +270,17 @@ ircd::ed25519::sig ircd::m::event::sign(json::iov &event, const json::iov &contents) { - return sign(event, contents, self::secret_key); + const string_view &origin + { + event.at("origin") + }; + + const auto &secret_key + { + m::secret_key(my(origin)) + }; + + return sign(event, contents, secret_key); } ircd::ed25519::sig @@ -278,7 +301,17 @@ ircd::m::event::sign(json::iov &event, ircd::ed25519::sig ircd::m::sign(const event &event) { - return sign(event, self::secret_key); + const string_view &origin + { + json::at<"origin"_>(event) + }; + + const auto &secret_key + { + m::secret_key(my(origin)) + }; + + return sign(event, secret_key); } ircd::ed25519::sig @@ -297,7 +330,17 @@ ircd::m::sign(const event &event, ircd::ed25519::sig ircd::m::event::sign(const json::object &event) { - return sign(event, self::secret_key); + const json::string &origin + { + event.at("origin") + }; + + const auto &secret_key + { + m::secret_key(my(origin)) + }; + + return sign(event, secret_key); } ircd::ed25519::sig @@ -317,7 +360,17 @@ ircd::m::event::sign(const json::object &event, ircd::ed25519::sig ircd::m::event::sign(const string_view &event) { - return sign(event, self::secret_key); + const json::string &origin + { + json::object(event).at("origin") + }; + + const auto &secret_key + { + m::secret_key(my(origin)) + }; + + return sign(event, secret_key); } ircd::ed25519::sig @@ -766,7 +819,7 @@ ircd::m::make_id(const event &event, { const id::event ret { - buf, b64tob64url(readable, b64encode_unpadded(readable, hash)), my_host() + buf, b64tob64url(readable, b64encode_unpadded(readable, hash)), at<"origin"_>(event) }; buf.assigned(ret); diff --git a/matrix/event_conforms.cc b/matrix/event_conforms.cc index af2fd6e8d..eea381e19 100644 --- a/matrix/event_conforms.cc +++ b/matrix/event_conforms.cc @@ -87,7 +87,6 @@ ircd::m::vm::conform_check_size { { { "_site", "vm.conform" }, - { "origin", my_host() } }, [](const m::event &event, eval &eval) { diff --git a/matrix/homeserver.cc b/matrix/homeserver.cc new file mode 100644 index 000000000..c44aa38ed --- /dev/null +++ b/matrix/homeserver.cc @@ -0,0 +1,559 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2018 Jason Volk +// +// 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. + +namespace ircd::m +{ + static void bootstrap(homeserver &); +} + +// Linkage for the container of all active clients for iteration purposes. +template<> +decltype(ircd::util::instance_multimap>::map) +ircd::util::instance_multimap>::map +{}; + +[[gnu::hot]] +ircd::m::user::id +ircd::m::me() +{ + auto &my + { + m::my() + }; + + return my.self; +} + +[[gnu::hot]] +ircd::m::user::id +ircd::m::me(const string_view &origin) +{ + auto &my + { + m::my(origin) + }; + + return my.self; +} + +[[gnu::hot]] +ircd::m::homeserver & +ircd::m::my() +{ + if(unlikely(!homeserver::primary)) + throw m::NOT_A_HOMESERVER + { + "I do not host any homeserver here." + }; + + return *homeserver::primary; +} + +[[gnu::hot]] +ircd::m::homeserver & +ircd::m::my(const string_view &name) +{ + const auto &it + { + homeserver::map.find(name) + }; + + if(unlikely(it == end(homeserver::map))) + throw m::NOT_MY_HOMESERVER + { + "I do not host any '%s' homeserver here.", + name, + }; + + const auto &ptr + { + it->second + }; + + assert(ptr); + return *ptr; +} + +bool +ircd::m::for_each(const std::function &closure) +{ + for(auto &[name, hs_p] : homeserver::map) + if(!closure(*hs_p)) + return false; + + return true; +} + +const ircd::ed25519::sk & +ircd::m::secret_key(const homeserver &homeserver) +{ + assert(homeserver.key); + return homeserver.key->secret_key; +} + +ircd::string_view +ircd::m::public_key_id(const homeserver &homeserver) +{ + assert(homeserver.key); + return homeserver.key->public_key_id; +} + +bool +ircd::m::server_name(const homeserver &homeserver, + const string_view &server_name) +{ + return server_name == m::server_name(homeserver); +} + +bool +ircd::m::origin(const homeserver &homeserver, + const string_view &origin) +{ + return origin == m::origin(homeserver); +} + +ircd::string_view +ircd::m::server_name(const homeserver &homeserver) +{ + assert(homeserver.opts); + return homeserver.opts->server_name; +} + +ircd::string_view +ircd::m::origin(const homeserver &homeserver) +{ + assert(homeserver.opts); + return homeserver.opts->origin; +} + +// +// homeserver::homeserver +// + +decltype(ircd::m::homeserver::primary) +ircd::m::homeserver::primary; + +ircd::m::homeserver * +IRCD_MODULE_EXPORT +ircd::m::homeserver::init(const struct opts *const opts) +{ + return new homeserver + { + opts + }; +} + +void +IRCD_MODULE_EXPORT +ircd::m::homeserver::fini(homeserver *const homeserver) +noexcept +{ + delete homeserver; +} + +// +// homeserver::homeserver::homeserver +// + +IRCD_MODULE_EXPORT +ircd::m::homeserver::homeserver(const struct opts *const &opts) +:instance_multimap +{ + string_view{opts->origin} +} +,opts +{ + opts +} +,key +{ + std::make_unique(opts->origin) +} +,database +{ + std::make_shared(opts->server_name, std::string{}) +} +,rooms +{ + { "ircd", opts->origin }, +} +,self +{ + "ircd", opts->origin +} +{ + primary = primary?: this; + + modules = + { + begin(matrix::module_names), end(matrix::module_names) + }; + + if(primary == this && dbs::events && sequence(*dbs::events) == 0) + bootstrap(*this); +} + +ircd::m::homeserver::~homeserver() +noexcept +{ + while(!modules.empty()) + modules.pop_back(); +} + +// +// homeserver::keys +// + +/* +namespace ircd::m +{ + extern conf::item ed25519_key_dir; +} + +decltype(ircd::m::ed25519_key_dir) +ircd::m::ed25519_key_dir +{ + { "name", "ircd.keys.ed25519_key_dir" }, + { "default", fs::cwd() }, +}; + +void +IRCD_MODULE_EXPORT +ircd::m::self::init::federation_ed25519() +{ + if(empty(m::self::origin)) + throw error + { + "The m::self::origin must be set to init my ed25519 key." + }; + + const std::string path_parts[] + { + std::string{ed25519_key_dir}, + m::self::origin + ".ed25519", + }; + + const std::string sk_file + { + ircd::string(fs::PATH_MAX_LEN, [&](const mutable_buffer &buf) + { + return fs::path(buf, path_parts); + }) + }; + + if(fs::exists(sk_file) || ircd::write_avoid) + log::info + { + m::log, "Using ed25519 secret key @ `%s'", sk_file + }; + else + log::notice + { + m::log, "Creating ed25519 secret key @ `%s'", sk_file + }; + + m::self::secret_key = ed25519::sk + { + sk_file, &m::self::public_key + }; + + m::self::public_key_b64 = b64encode_unpadded(m::self::public_key); + const fixed_buffer hash + { + sha256{m::self::public_key} + }; + + const auto public_key_hash_b58 + { + b58encode(hash) + }; + + static const auto trunc_size{8}; + m::self::public_key_id = fmt::snstringf + { + 32, "ed25519:%s", trunc(public_key_hash_b58, trunc_size) + }; + + log::info + { + m::log, "Current key is '%s' and the public key is: %s", + m::self::public_key_id, + m::self::public_key_b64 + }; +} +*/ + +// +// create_my_key +// + +ircd::m::homeserver::key::key(const string_view &origin) +{ +/* + const json::members verify_keys_ + {{ + string_view{m::self::public_key_id}, + { + { "key", m::self::public_key_b64 } + } + }}; + + m::keys my_key; + json::get<"server_name"_>(my_key) = my_host(); + json::get<"old_verify_keys"_>(my_key) = "{}"; + + //TODO: conf + json::get<"valid_until_ts"_>(my_key) = + ircd::time() + milliseconds(1000UL * 60 * 60 * 24 * 180).count(); + + const json::strung verify_keys{verify_keys_}; // must be on stack until my_keys serialized. + json::get<"verify_keys"_>(my_key) = verify_keys; + + const json::strung presig + { + my_key + }; + + const ed25519::sig sig + { + m::self::secret_key.sign(const_buffer{presig}) + }; + + char signature[256]; + const json::strung signatures{json::members + { + { my_host(), + { + { string_view{m::self::public_key_id}, b64encode_unpadded(signature, sig) } + }} + }}; + + json::get<"signatures"_>(my_key) = signatures; + keys::cache::set(json::strung{my_key}); +*/ +} + +/////////////////////////////////////////////////////////////////////////////// +// +// m/self.h +// + +ircd::string_view +ircd::m::self::my_host() +{ + return origin(my()); +} + +bool +ircd::m::self::host(const string_view &other) +{ + const net::hostport other_host{other}; + for(const auto &[my_network, hs_p] : homeserver::map) + { + // port() is 0 when the origin has no port (and implies 8448) + const auto port + { + net::port(net::hostport(my_network)) + }; + + // If my_host has a port number, then the argument must also have the + // same port number. + if(port && my_network == other) + return true; + else if(port) + continue; + + /// If my_host has no port number, then the argument can have port + /// 8448 or no port number, which will initialize net::hostport.port to + /// the "canon_port" of 8448. + assert(net::canon_port == 8448); + if(net::port(other_host) != net::canon_port) + continue; + + /// Both myself and input are using 8448; now the name has to match. + if(my_network != host(other_host)) + continue; + + return true; + } + + return false; +} + +bool +ircd::m::self::my_host(const string_view &name) +{ + const auto it + { + homeserver::map.find(name) + }; + + return it != end(homeserver::map); +} + +// +// signon/signoff greetings +// + +/* +namespace ircd::m::self +{ + void signon(), signoff(); +} + +ircd::conf::item +me_online_status_msg +{ + { "name", "ircd.me.online.status_msg" }, + { "default", "Wanna chat? IRCd at your service!" } +}; + +ircd::conf::item +me_offline_status_msg +{ + { "name", "ircd.me.offline.status_msg" }, + { "default", "Catch ya on the flip side..." } +}; + +void +ircd::m::self::signon() +{ + if(!ircd::write_avoid && vm::sequence::retired != 0) + presence::set(me, "online", me_online_status_msg); +} + +void +ircd::m::self::signoff() +{ + if(!std::uncaught_exceptions() && !ircd::write_avoid) + presence::set(me, "offline", me_offline_status_msg); +} + +// +// init +// + +ircd::m::self::init::init() +try +{ + // 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); + + ircd_user_id = {"ircd", origin}; + m::me = {ircd_user_id}; + + ircd_room_id = {"ircd", origin}; + m::my_room = {ircd_room_id}; + + if(origin == "localhost") + log::warning + { + "The origin is configured or has defaulted to 'localhost'" + }; +} +catch(const std::exception &e) +{ + log::critical + { + m::log, "Failed to init self origin[%s] servername[%s]", + origin, + servername, + }; + + throw; +} + +static const auto self_init{[] +{ + ircd::m::self::init(); + return true; +}()}; +*/ + +void +ircd::m::bootstrap(homeserver &homeserver) +try +{ + assert(dbs::events); + assert(db::sequence(*dbs::events) == 0); + if(homeserver.self.hostname() == "localhost") + log::warning + { + "The server's name is configured to localhost. This is probably not what you want." + }; + + if(!exists(homeserver.self)) + { + create(homeserver.self); + user(homeserver.self).activate(); + } + + const m::room::id::buf node_room_id + { + node(origin(homeserver)).room_id() + }; + + if(!exists(node_room_id)) + create(room(node_room_id)); + + const m::room::id::buf my_room + { + "ircd", origin(homeserver) + }; + + if(!exists(my_room)) + create(my_room, homeserver.self, "internal"); + + if(!membership(my_room, homeserver.self, "join")) + join(room(my_room), user(homeserver.self)); + + if(!room(my_room).has("m.room.name", "")) + send(my_room, homeserver.self, "m.room.name", "", + { + { "name", "IRCd's Room" } + }); + + if(!room(my_room).has("m.room.topic", "")) + send(my_room, homeserver.self, "m.room.topic", "", + { + { "topic", "The daemon's den." } + }); + + const m::room::id::buf tokens_room + { + "tokens", origin(homeserver) + }; + + if(!exists(tokens_room)) + create(tokens_room, homeserver.self); + + if(!room(tokens_room).has("m.room.name","")) + send(tokens_room, homeserver.self, "m.room.name", "", + { + { "name", "User Tokens" } + }); + + log::info + { + log, "Bootstrap event generation completed nominally." + }; +} +catch(const std::exception &e) +{ + throw ircd::panic + { + "bootstrap %s error :%s", + server_name(homeserver), + e.what() + }; +} diff --git a/matrix/hook.cc b/matrix/hook.cc index e9146bf15..e8ed87dc9 100644 --- a/matrix/hook.cc +++ b/matrix/hook.cc @@ -207,7 +207,7 @@ const ircd::m::hook::base::base(const json::members &members) :_feature { - _hook_make_feature(members) + members // _hook_make_feature(members) } ,feature { diff --git a/matrix/init_backfill.cc b/matrix/init_backfill.cc index b7050b3cf..2f30d2e86 100644 --- a/matrix/init_backfill.cc +++ b/matrix/init_backfill.cc @@ -8,6 +8,11 @@ // 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::init +{ + struct backfill; +} + /// This should be a namespace but we're stuck in struct m::init for now, so /// this code should be portable for a future when m::init is unstructured. struct ircd::m::init::backfill diff --git a/matrix/init_bootstrap.cc b/matrix/init_bootstrap.cc deleted file mode 100644 index 19296e217..000000000 --- a/matrix/init_bootstrap.cc +++ /dev/null @@ -1,71 +0,0 @@ -// Matrix Construct -// -// Copyright (C) Matrix Construct Developers, Authors & Contributors -// Copyright (C) 2016-2019 Jason Volk -// -// 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. - -ircd::m::init::bootstrap::bootstrap() -try -{ - assert(dbs::events); - assert(db::sequence(*dbs::events) == 0); - if(me.user_id.hostname() == "localhost") - log::warning - { - "The ircd.origin is configured to localhost. This is probably not" - " what you want. To fix this now, you will have to remove the " - " database and start over." - }; - - if(!exists(me)) - { - create(me.user_id); - me.activate(); - } - - if(!exists(my_node)) - create(my_node); - - if(!exists(my_room)) - create(my_room, me.user_id, "internal"); - - if(!membership(my_room, me, "join")) - join(my_room, me.user_id); - - if(!my_room.has("m.room.name", "")) - send(my_room, me.user_id, "m.room.name", "", - { - { "name", "IRCd's Room" } - }); - - if(!my_room.has("m.room.topic", "")) - send(my_room, me.user_id, "m.room.topic", "", - { - { "topic", "The daemon's den." } - }); - - if(!exists(user::tokens)) - create(user::tokens, me.user_id); - - if(!user::tokens.has("m.room.name","")) - send(user::tokens, me.user_id, "m.room.name", "", - { - { "name", "User Tokens" } - }); - - log::info - { - log, "Bootstrap event generation completed nominally." - }; -} -catch(const std::exception &e) -{ - throw ircd::panic - { - "bootstrap error :%s", e.what() - }; -} diff --git a/matrix/keys.cc b/matrix/keys.cc index 83afd794b..d2a7d021e 100644 --- a/matrix/keys.cc +++ b/matrix/keys.cc @@ -476,7 +476,7 @@ ircd::m::keys::cache::set(const json::object &keys) }; if(!exists(node_room.room_id)) - create(node_room, m::me.user_id); + create(node_room, me()); const json::object &vks { @@ -490,7 +490,7 @@ ircd::m::keys::cache::set(const json::object &keys) return ret; const auto &key_id(unquote(member.first)); - send(node_room, m::me.user_id, "ircd.key", key_id, keys); + send(node_room, me(), "ircd.key", key_id, keys); ++ret; } diff --git a/matrix/matrix.cc b/matrix/matrix.cc index 18b7a1675..39f13756d 100644 --- a/matrix/matrix.cc +++ b/matrix/matrix.cc @@ -28,169 +28,12 @@ ircd::m::log "m", 'm' }; -// -// init -// - -/// --- tmp --- - -extern "C" void -reload_conf(); - -namespace ircd::m -{ - std::unique_ptr _dbs; - std::unique_ptr _fetch; - std::unique_ptr _modules; -} - -/// --- /tmp --- - -void -ircd::m::on_load() -try -{ - assert(ircd::run::level == run::level::START); - m::self::init::keys(); - _dbs = std::make_unique(ircd::server_name, std::string{}); - reload_conf(); - _fetch = std::make_unique(); - _modules = std::make_unique(); - self::signon(); -} -catch(const m::error &e) -{ - log::error - { - log, "Failed to start matrix (%u) %s :%s :%s", - uint(e.code), - http::status(e.code), - e.errcode(), - e.errstr(), - }; - - throw; -} -catch(const std::exception &e) -{ - log::error - { - log, "Failed to start matrix :%s", e.what() - }; - - throw; -} - -void -ircd::m::on_unload() -noexcept try -{ - mods::imports.erase("m_listen"s); - - if(m::sync::pool.size()) - m::sync::pool.join(); - - self::signoff(); - _fetch.reset(nullptr); - _modules.reset(nullptr); - _dbs.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) -{ - log::critical - { - log, "%s %s", e.what(), e.content - }; - - ircd::terminate(); -} - -// -// init::modules -// - -namespace ircd::m -{ - extern const std::vector module_names; - extern const std::vector module_names_optional; -} - -ircd::m::init::modules::modules() -{ - const unwind::exceptional unload{[this] - { - this->fini_imports(); - }}; - - init_imports(); -} - -ircd::m::init::modules::~modules() -noexcept -{ - fini_imports(); -} - -void -ircd::m::init::modules::init_imports() -{ - if(!bool(ircd::mods::autoload)) - { - log::warning - { - "Not loading modules because noautomod flag is set. " - "You may still load modules manually." - }; - - return; - } - - for(const auto &name : module_names) try - { - mods::imports.emplace(name, name); - } - catch(...) - { - const auto &optional(module_names_optional); - if(std::count(begin(optional), end(optional), name)) - continue; - - throw; - } - - if(vm::sequence::retired == 0) - { - log::notice - { - log, "This appears to be your first time running IRCd because the events " - "database is empty. I will be bootstrapping it with initial events now..." - }; - - m::init::bootstrap{}; - } -} - -void -ircd::m::init::modules::fini_imports() -noexcept -{ - for(auto it(module_names.rbegin()); it != module_names.rend(); ++it) - mods::imports.erase(*it); -} - /// This is an ordered list for loading and unloading modules. This is not the /// solution I really want at all so consider it temporary. Modules are loaded /// in the order of the lines and unloaded in reverse order. -decltype(ircd::m::module_names) -ircd::m::module_names +IRCD_MODULE_EXPORT_DATA +decltype(ircd::m::matrix::module_names) +ircd::m::matrix::module_names { "m_noop", "m_breadcrumb_rooms", @@ -313,8 +156,165 @@ ircd::m::module_names /// This is a list of modules that are considered "optional" and any loading /// error for them will not propagate and interrupt m::init. -decltype(ircd::m::module_names_optional) -ircd::m::module_names_optional +IRCD_MODULE_EXPORT_DATA +decltype(ircd::m::matrix::module_names_optional) +ircd::m::matrix::module_names_optional { "web_hook", }; + +// +// init +// + +/// --- tmp --- + +extern "C" void +reload_conf(); + +namespace ircd::m::init +{ + struct modules; +} + +namespace ircd::m +{ + std::unique_ptr _dbs; + std::unique_ptr _fetch; + //std::unique_ptr _modules; +} + +/// --- /tmp --- + +void +ircd::m::on_load() +try +{ + assert(ircd::run::level == run::level::START); + //reload_conf(); + _fetch = std::make_unique(); + //_modules = std::make_unique(); + //self::signon(); +} +catch(const m::error &e) +{ + log::error + { + log, "Failed to start matrix (%u) %s :%s :%s", + uint(e.code), + http::status(e.code), + e.errcode(), + e.errstr(), + }; + + throw; +} +catch(const std::exception &e) +{ + log::error + { + log, "Failed to start matrix :%s", e.what() + }; + + throw; +} + +void +ircd::m::on_unload() +noexcept try +{ + //mods::imports.erase("m_listen"s); + + if(m::sync::pool.size()) + m::sync::pool.join(); + + //self::signoff(); + _fetch.reset(nullptr); + //_modules.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) +{ + log::critical + { + log, "%s %s", e.what(), e.content + }; + + ircd::terminate(); +} + +// +// init::modules +// + +/* +ircd::m::init::modules::modules() +{ + const unwind::exceptional unload{[this] + { + this->fini_imports(); + }}; + + init_imports(); +} + +ircd::m::init::modules::~modules() +noexcept +{ + fini_imports(); +} + +void +ircd::m::init::modules::init_imports() +{ + if(!bool(ircd::mods::autoload)) + { + log::warning + { + "Not loading modules because noautomod flag is set. " + "You may still load modules manually." + }; + + return; + } + + for(const auto &name : module_names) try + { + mods::imports.emplace(name, name); + } + catch(...) + { + const auto &optional(module_names_optional); + if(std::count(begin(optional), end(optional), name)) + continue; + + throw; + } + + if(vm::sequence::retired == 0) + { + log::notice + { + log, "This appears to be your first time running IRCd because the events " + "database is empty. I will be bootstrapping it with initial events now..." + }; + + m::init::bootstrap{}; + } +} + +void +ircd::m::init::modules::fini_imports() +noexcept +{ + for(auto it(module_names.rbegin()); it != module_names.rend(); ++it) + mods::imports.erase(*it); +} +*/ diff --git a/matrix/node.cc b/matrix/node.cc index 36f03ed72..8bdbb49c9 100644 --- a/matrix/node.cc +++ b/matrix/node.cc @@ -123,7 +123,7 @@ ircd::m::create(const node &node, node.room_id() }; - create(room_id, m::me.user_id); + create(room_id, me()); return node; } diff --git a/matrix/request.cc b/matrix/request.cc index caba5e2c1..845c4c08a 100644 --- a/matrix/request.cc +++ b/matrix/request.cc @@ -99,11 +99,29 @@ const thread_local char x_matrix[2_KiB]; if(startswith(json::at<"uri"_>(*this), "/_matrix/federation")) { - const auto &sk{self::secret_key}; - const auto &pkid{self::public_key_id}; + const json::string &origin + { + json::at<"origin"_>(*this) + }; + + const auto &my + { + m::my(origin) + }; + + const auto &secret_key + { + m::secret_key(my) + }; + + const auto &public_key_id + { + m::public_key_id(my) + }; + header[headers++] = { - "Authorization", generate(x_matrix, sk, pkid) + "Authorization", generate(x_matrix, secret_key, public_key_id) }; } @@ -169,14 +187,19 @@ const stringify(mutable_buffer{buf}, *this) }; - const ed25519::sig sig + const json::string &origin { - self::secret_key.sign(object) + json::at<"origin"_>(*this) }; - const auto &origin + const auto &secret_key { - unquote(string_view{json::at<"origin"_>(*this)}) + m::secret_key(my(origin)) + }; + + const ed25519::sig sig + { + secret_key.sign(object) }; thread_local char sigb64[1_KiB]; diff --git a/matrix/resource.cc b/matrix/resource.cc index 9219dc988..b21def6d4 100644 --- a/matrix/resource.cc +++ b/matrix/resource.cc @@ -212,9 +212,14 @@ ircd::m::authenticate_user(const resource::method &method, m::event::keys::include {"sender"} }; + const m::room::id::buf tokens_room + { + "tokens", origin(my()) + }; + const m::room::state tokens { - m::user::tokens, &fopts + tokens_room, &fopts }; tokens.get(std::nothrow, "ircd.access_token", request.access_token, [&request] diff --git a/matrix/room.cc b/matrix/room.cc index b080f527a..7e6d92c26 100644 --- a/matrix/room.cc +++ b/matrix/room.cc @@ -107,7 +107,7 @@ ircd::m::event::id::buf ircd::m::notice(const room &room, const string_view &body) { - return message(room, me.user_id, body, "m.notice"); + return message(room, me(), body, "m.notice"); } ircd::m::event::id::buf @@ -744,7 +744,12 @@ ircd::m::local_joined(const room &room) room }; - return !members.empty("join", my_host()); + return !for_each([&members] + (const homeserver &homeserver) + { + // return false to break and return false; true to continue + return members.empty("join", origin(homeserver)); + }); } /// Member(s) from another server are presently joined to the room. For example @@ -848,7 +853,7 @@ ircd::m::internal(const id::room &room_id) if(!exists(room)) return false; - if(!creator(room, m::me)) + if(!creator(room, me())) return false; return true; @@ -868,7 +873,7 @@ ircd::m::exists(const id::room &room_id) if(likely(it.depth() < 2UL)) return true; - if(my_host(room_id.host()) && creator(room_id, m::me)) + if(my_host(room_id.host()) && creator(room_id, me())) return true; return false; diff --git a/matrix/room_aliases.cc b/matrix/room_aliases.cc index beff19a26..469e44243 100644 --- a/matrix/room_aliases.cc +++ b/matrix/room_aliases.cc @@ -12,22 +12,8 @@ namespace ircd::m { extern conf::item alias_fetch_timeout; extern conf::item alias_cache_ttl; - extern const room::id::buf alias_room_id; - extern const room alias_room; } -decltype(ircd::m::alias_room_id) -ircd::m::alias_room_id -{ - "alias", ircd::my_host() -}; - -decltype(ircd::m::alias_room) -ircd::m::alias_room -{ - alias_room_id -}; - decltype(ircd::m::alias_cache_ttl) ircd::m::alias_cache_ttl { @@ -168,6 +154,16 @@ ircd::m::room::aliases::cache::del(const alias &alias) make_key(buf, alias) }; + const m::room::id::buf alias_room_id + { + "alias", origin(my()) + }; + + const m::room alias_room + { + alias_room_id + }; + const auto &event_idx { alias_room.get(std::nothrow, "ircd.room.alias", key) @@ -186,7 +182,7 @@ ircd::m::room::aliases::cache::del(const alias &alias) const auto ret { - redact(alias_room, m::me.user_id, event_id, "deleted") + redact(alias_room, me(), event_id, "deleted") }; return true; @@ -203,9 +199,19 @@ ircd::m::room::aliases::cache::set(const alias &alias, make_key(buf, alias) }; + const m::room::id::buf alias_room_id + { + "alias", origin(my()) + }; + + const m::room alias_room + { + alias_room_id + }; + const auto ret { - send(alias_room, m::me.user_id, "ircd.room.alias", key, + send(alias_room, me(), "ircd.room.alias", key, { { "room_id", id } }) @@ -427,9 +433,14 @@ IRCD_MODULE_EXPORT ircd::m::room::aliases::cache::for_each(const string_view &server, const closure_bool &closure) { + const m::room::id::buf alias_room_id + { + "alias", origin(my()) + }; + const m::room::state state { - alias_room + alias_room_id }; bool ret{true}; @@ -574,6 +585,16 @@ ircd::m::room::aliases::cache::getidx(const alias &alias) tolower(buf, swapped) }; + const m::room::id::buf alias_room_id + { + "alias", origin(my()) + }; + + const m::room alias_room + { + alias_room_id + }; + const auto &event_idx { alias_room.get(std::nothrow, "ircd.room.alias", key) diff --git a/matrix/rooms_summary.cc b/matrix/rooms_summary.cc index a2d55a4cb..7b6afa29b 100644 --- a/matrix/rooms_summary.cc +++ b/matrix/rooms_summary.cc @@ -13,16 +13,9 @@ namespace ircd::m::rooms::summary static void chunk_remote(const room &, json::stack::object &o); static void chunk_local(const room &, json::stack::object &o); - extern const room::id::buf public_room_id; extern hookfn create_public_room; } -decltype(ircd::m::rooms::summary::public_room_id) -ircd::m::rooms::summary::public_room_id -{ - "public", ircd::my_host() -}; - /// Create the public rooms room during initial database bootstrap. /// This hooks the creation of the !ircd room which is a fundamental /// event indicating the database has just been created. @@ -34,9 +27,19 @@ ircd::m::rooms::summary::create_public_room { "room_id", "!ircd" }, { "type", "m.room.create" }, }, - [](const m::event &, m::vm::eval &) + [](const m::event &event, m::vm::eval &) { - m::create(public_room_id, m::me.user_id); + auto &my + { + m::my(at<"origin"_>(event)) + }; + + const auto &public_room_id + { + *my.rooms.emplace("public", origin(my)).first + }; + + m::create(public_room_id, me()); } }; @@ -140,6 +143,11 @@ IRCD_MODULE_EXPORT ircd::m::rooms::summary::del(const m::room &room, const string_view &origin) { + const m::room::id::buf public_room_id + { + "public", my_host() + }; + const m::room::state state { public_room_id @@ -164,7 +172,7 @@ ircd::m::rooms::summary::del(const m::room &room, m::event_id(event_idx) }; - return redact(public_room_id, m::me, event_id, "delisted"); + return redact(public_room_id, me(), event_id, "delisted"); } ircd::m::event::id::buf @@ -197,13 +205,19 @@ ircd::m::rooms::summary::set(const m::room::id &room_id, const string_view &origin, const json::object &summary) { + const m::room::id::buf public_room_id + { + "public", my_host() + }; + + char state_key_buf[event::STATE_KEY_MAX_SIZE]; const auto state_key { make_state_key(state_key_buf, room_id, origin) }; - return send(public_room_id, m::me, "ircd.rooms.summary", state_key, summary); + return send(public_room_id, me(), "ircd.rooms.summary", state_key, summary); } ircd::json::object @@ -275,6 +289,11 @@ IRCD_MODULE_EXPORT ircd::m::rooms::summary::for_each(const room::id &room_id, const closure_idx &closure) { + const m::room::id::buf public_room_id + { + "public", my_host() + }; + const m::room::state state { public_room_id diff --git a/matrix/self.cc b/matrix/self.cc deleted file mode 100644 index 03936c0b8..000000000 --- a/matrix/self.cc +++ /dev/null @@ -1,215 +0,0 @@ -// Matrix Construct -// -// Copyright (C) Matrix Construct Developers, Authors & Contributors -// Copyright (C) 2016-2018 Jason Volk -// -// 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. - -std::string -ircd::m::self::origin -{ - ircd::string_view{ircd::network_name} -}; - -std::string -ircd::m::self::servername -{ - ircd::string_view{ircd::server_name} -}; - -ircd::ed25519::sk -ircd::m::self::secret_key -{}; - -ircd::ed25519::pk -ircd::m::self::public_key -{}; - -std::string -ircd::m::self::public_key_b64 -{}; - -std::string -ircd::m::self::public_key_id -{}; - -std::string -ircd::m::self::tls_cert_der -{}; - -std::string -ircd::m::self::tls_cert_der_sha256_b64 -{}; - -// -// my user -// - -ircd::m::user::id::buf -ircd_user_id -{ - "ircd", ircd::my_host() -}; - -ircd::m::user -ircd::m::me -{ - ircd_user_id -}; - -// -// my room -// - -ircd::m::room::id::buf -ircd_room_id -{ - "ircd", ircd::my_host() -}; - -ircd::m::room -ircd::m::my_room -{ - ircd_room_id -}; - -// -// my node -// - -ircd::m::node -ircd::m::my_node -{ - ircd::my_host() -}; - -// -// signon/signoff greetings -// - -ircd::conf::item -me_online_status_msg -{ - { "name", "ircd.me.online.status_msg" }, - { "default", "Wanna chat? IRCd at your service!" } -}; - -ircd::conf::item -me_offline_status_msg -{ - { "name", "ircd.me.offline.status_msg" }, - { "default", "Catch ya on the flip side..." } -}; - -void -ircd::m::self::signon() -{ - if(!ircd::write_avoid && vm::sequence::retired != 0) - presence::set(me, "online", me_online_status_msg); -} - -void -ircd::m::self::signoff() -{ - if(!std::uncaught_exceptions() && !ircd::write_avoid) - presence::set(me, "offline", me_offline_status_msg); -} - -bool -ircd::m::self::host(const string_view &other) -{ - // port() is 0 when the origin has no port (and implies 8448) - const auto port - { - net::port(hostport(origin)) - }; - - // If my_host has a port number, then the argument must also have the - // same port number. - if(port) - return host() == other; - - /// If my_host has no port number, then the argument can have port - /// 8448 or no port number, which will initialize net::hostport.port to - /// the "canon_port" of 8448. - assert(net::canon_port == 8448); - const net::hostport _other{other}; - if(net::port(_other) != net::canon_port) - return false; - - if(host() != host(_other)) - return false; - - return true; -} - -ircd::string_view -ircd::m::self::host() -{ - return m::self::origin; -} - -// -// init -// - -/// ID of the room which stores ephemeral tokens (an instance of the room is -/// provided below). -ircd::m::room::id::buf -tokens_room_id -{ - "tokens", ircd::my_host() -}; - -/// The tokens room serves as a key-value lookup for various tokens to -/// users, etc. It primarily serves to store access tokens for users. This -/// is a separate room from the users room because in the future it may -/// have an optimized configuration as well as being more easily cleared. -/// -ircd::m::room -ircd::m::user::tokens -{ - tokens_room_id -}; - -ircd::m::self::init::init() -try -{ - // 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); - - ircd_user_id = {"ircd", origin}; - m::me = {ircd_user_id}; - - ircd_room_id = {"ircd", origin}; - m::my_room = {ircd_room_id}; - - if(origin == "localhost") - log::warning - { - "The origin is configured or has defaulted to 'localhost'" - }; -} -catch(const std::exception &e) -{ - log::critical - { - m::log, "Failed to init self origin[%s] servername[%s]", - origin, - servername, - }; - - throw; -} - -static const auto self_init{[] -{ - ircd::m::self::init(); - return true; -}()}; diff --git a/matrix/user.cc b/matrix/user.cc index 396d146bc..e03b0fdcf 100644 --- a/matrix/user.cc +++ b/matrix/user.cc @@ -67,7 +67,7 @@ ircd::m::create_user_room(const user::id &user_id, const json::members &contents) try { - return create(room_id, m::me.user_id, "user"); + return create(room_id, me(), "user"); } catch(const std::exception &e) { @@ -115,16 +115,26 @@ const char b58[size(hash) * 2]; return { - buf, b58encode(b58, hash), my_host() + buf, b58encode(b58, hash), origin(my()) }; } ircd::m::device::id::buf ircd::m::user::get_device_from_access_token(const string_view &token) { + const m::room::id::buf tokens_room_id + { + "tokens", origin(my()) + }; + + const m::room tokens + { + tokens_room_id + }; + const event::idx event_idx { - user::tokens.get("ircd.access_token", token) + tokens.get("ircd.access_token", token) }; device::id::buf ret; diff --git a/matrix/user_register.cc b/matrix/user_register.cc index b6e7172e0..3750b1bad 100644 --- a/matrix/user_register.cc +++ b/matrix/user_register.cc @@ -45,7 +45,7 @@ const // specified. TODO: isn't that guest reg? const m::id::user::buf user_id { - username, my_host() + username, origin(my()) }; // Check if the the user_id is acceptably formed for this server or throws @@ -155,9 +155,14 @@ const json::STRING }; + const m::room::id::buf user_tokens + { + "tokens", user_id.host() + }; + const m::event::id::buf access_token_id { - m::send(m::user::tokens, user_id, "ircd.access_token", access_token, json::members + m::send(user_tokens, user_id, "ircd.access_token", access_token, json::members { { "ip", last_seen_ip }, { "device_id", device_id }, diff --git a/modules/app/app.cc b/modules/app/app.cc index d2332555f..abc7e9977 100644 --- a/modules/app/app.cc +++ b/modules/app/app.cc @@ -43,7 +43,7 @@ void ircd::m::app::init() { if(!m::exists(app_room_id)) - m::create(app_room_id, m::me, "internal"); + m::create(app_room_id, me(), "internal"); init_apps(); } diff --git a/modules/client/account/account.cc b/modules/client/account/account.cc index 2d39e916b..1503b0b43 100644 --- a/modules/client/account/account.cc +++ b/modules/client/account/account.cc @@ -39,7 +39,7 @@ activate__user(const m::user &user) user }; - return send(user_room, m::me.user_id, "ircd.account", "active", json::members + return send(user_room, m::me(), "ircd.account", "active", json::members { { "value", true } }); diff --git a/modules/client/account/deactivate.cc b/modules/client/account/deactivate.cc index a9cfbeb85..7928a3a97 100644 --- a/modules/client/account/deactivate.cc +++ b/modules/client/account/deactivate.cc @@ -74,7 +74,7 @@ deactivate__user(const m::user &user, user }; - return send(user_room, m::me.user_id, "ircd.account", "active", json::members + return send(user_room, m::me(), "ircd.account", "active", json::members { { "value", false } }); diff --git a/modules/client/login.cc b/modules/client/login.cc index 874471a2f..94de56ec8 100644 --- a/modules/client/login.cc +++ b/modules/client/login.cc @@ -110,12 +110,17 @@ post__login_password(client &client, string(remote_buf, remote(client)), json::STRING }; + const m::room::id::buf tokens_room + { + "tokens", origin(m::my()) + }; + // Log the user in by issuing an event in the tokens room containing // the generated token. When this call completes without throwing the // access_token will be committed and the user will be logged in. const m::event::id::buf access_token_id { - m::send(m::user::tokens, user_id, "ircd.access_token", access_token, + m::send(tokens_room, user_id, "ircd.access_token", access_token, { { "ip", last_seen_ip }, { "device_id", device_id }, diff --git a/modules/client/logout.cc b/modules/client/logout.cc index 66235f58b..efeab6c5c 100644 --- a/modules/client/logout.cc +++ b/modules/client/logout.cc @@ -76,9 +76,14 @@ post__logout(client &client, request.access_token }; + const m::room::id::buf tokens_room_id + { + "tokens", origin(m::my()) + }; + const m::room::state tokens { - m::user::tokens + tokens_room_id }; const auto token_event_idx @@ -98,9 +103,14 @@ m::resource::response post__logout_all(client &client, const m::resource::request &request) { + const m::room::id::buf tokens_room_id + { + "tokens", origin(m::my()) + }; + const m::room::state tokens { - m::user::tokens + tokens_room_id }; long count(0); @@ -145,9 +155,14 @@ try m::event_id(token_event_idx) }; + const m::room::id::buf tokens_room_id + { + "tokens", origin(m::my()) + }; + const auto redaction_event_id { - m::redact(m::user::tokens, user_id, token_event_id, reason) + m::redact(tokens_room_id, user_id, token_event_id, reason) }; return true; diff --git a/modules/client/rooms/report.cc b/modules/client/rooms/report.cc index b544880e4..59790a596 100644 --- a/modules/client/rooms/report.cc +++ b/modules/client/rooms/report.cc @@ -14,12 +14,6 @@ using namespace ircd; static void create_report_room(const m::event &, m::vm::eval &); -const m::room::id::buf -report_room_id -{ - "abuse", m::my_host() -}; - conf::item reason_max { @@ -78,6 +72,11 @@ post__report(client &client, request.at("reason") }; + const m::room::id::buf report_room_id + { + "abuse", request.user_id.host() + }; + const m::room room { report_room_id @@ -104,16 +103,26 @@ post__report(client &client, } void -create_report_room(const m::event &, +create_report_room(const m::event &event, m::vm::eval &) try { + const auto &origin + { + at<"origin"_>(event) + }; + + const m::room::id::buf report_room_id + { + "abuse", origin + }; + if(m::exists(report_room_id)) return; const m::room room { - m::create(report_room_id, m::me, "internal") + m::create(report_room_id, m::my(origin).self, "internal") }; log::debug @@ -126,8 +135,7 @@ catch(const std::exception &e) { log::critical { - m::log, "Creating the '%s' room failed :%s", - string_view{report_room_id}, + m::log, "Creating the !abuse room failed :%s", e.what() }; } diff --git a/modules/client/sync/rooms/timeline.cc b/modules/client/sync/rooms/timeline.cc index 3ab531df9..5448aab6b 100644 --- a/modules/client/sync/rooms/timeline.cc +++ b/modules/client/sync/rooms/timeline.cc @@ -67,7 +67,7 @@ ircd::m::sync::room_timeline_linear(data &data) { *data.room == data.user_room && startswith(json::get<"type"_>(*data.event), "ircd.cmd") && - (json::get<"sender"_>(*data.event) == m::me.user_id || + (json::get<"sender"_>(*data.event) == me() || json::get<"sender"_>(*data.event) == data.user.user_id) }; diff --git a/modules/console.cc b/modules/console.cc index d77253b53..b031ea757 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -1688,7 +1688,7 @@ console_cmd__conf__set(opt &out, const string_view &line) const auto event_id { - set_conf_item(m::me, key, val) + set_conf_item(m::me(), key, val) }; out << event_id << " <- " << key << " = " << val << std::endl; @@ -5506,9 +5506,14 @@ console_cmd__net__listen(opt &out, const string_view &line) for(const auto &[name, prop] : addl) opts = insert(opts, json::member(name, prop)); + const m::room::id::buf my_room + { + "ircd", origin(m::my()) + }; + const auto eid { - m::send(m::my_room, m::me, "ircd.listen", token.at("name"), opts) + m::send(my_room, m::me(), "ircd.listen", token.at("name"), opts) }; out << eid << std::endl; @@ -5523,9 +5528,19 @@ console_cmd__net__listen__del(opt &out, const string_view &line) "name" }}; + const m::room::id::buf my_room_id + { + "ircd", origin(m::my()) + }; + + const m::room my_room + { + my_room_id + }; + const auto event_idx { - m::my_room.get("ircd.listen", token.at("name")) + my_room.get("ircd.listen", token.at("name")) }; const auto event_id @@ -5535,7 +5550,7 @@ console_cmd__net__listen__del(opt &out, const string_view &line) const auto redact_id { - m::redact(m::my_room, m::me, event_id, "deleted") + m::redact(my_room, m::me(), event_id, "deleted") }; out << "Removed listener '" << token.at("name") << "' configuration. " << std::endl @@ -5890,8 +5905,8 @@ console_cmd__key(opt &out, const string_view &line) if(!server_name) { out << "origin: " << m::my_host() << std::endl; - out << "public key ID: " << m::self::public_key_id << std::endl; - out << "public key base64: " << m::self::public_key_b64 << std::endl; + out << "public key ID: " << m::public_key_id(m::my()) << std::endl; + //out << "public key base64: " << m::self::public_key_b64 << std::endl; return true; } @@ -5950,14 +5965,6 @@ console_cmd__key__get(opt &out, const string_view &line) return true; } -bool -console_cmd__key__create(opt &out, const string_view &line) -{ - m::self::create_my_key(); - out << "done" << std::endl; - return true; -} - // // stage // @@ -6008,6 +6015,11 @@ console_cmd__stage(opt &out, const string_view &line) key? tokens_after(line, ' ', 1) : string_view{} }; + const m::room::id::buf my_room + { + "ircd", origin(m::my()) + }; + if(stage.size() == id) { m::event base_event{json::members @@ -6015,8 +6027,8 @@ console_cmd__stage(opt &out, const string_view &line) { "depth", json::undefined_number }, { "origin", my_host() }, { "origin_server_ts", time() }, - { "sender", m::me.user_id }, - { "room_id", m::my_room.room_id }, + { "sender", m::me() }, + { "room_id", my_room }, { "type", "m.room.message" }, { "prev_state", "[]" }, }}; @@ -10332,7 +10344,7 @@ console_cmd__room__create(opt &out, const string_view &line) const m::user::id creator { - param.at(1, m::me.user_id) + param.at(1, m::me()) }; const string_view type @@ -10976,7 +10988,7 @@ console_cmd__user__read__ignore(opt &out, const string_view &line) const auto eid { - send(user_room, m::me.user_id, "ircd.read.ignore", target, json::object{}) + send(user_room, m::me(), "ircd.read.ignore", target, json::object{}) }; out << "User " << my_user.user_id << " will not send receipts for" @@ -11170,9 +11182,14 @@ console_cmd__user__tokens(opt &out, const string_view &line) param["clear"] == "clear" }; + const m::room::id::buf tokens_room + { + "tokens", origin(m::my()) + }; + const m::room::state &tokens { - m::user::tokens + tokens_room }; tokens.for_each("ircd.access_token", m::event::closure_idx{[&out, &user, &clear] @@ -11216,12 +11233,16 @@ console_cmd__user__tokens(opt &out, const string_view &line) << " " << string_view{event.event_id}; - if(clear) { + const m::room::id::buf tokens_room + { + "tokens", origin(m::my()) + }; + const auto eid { - m::redact(m::user::tokens, user.user_id, event.event_id, "cleared") + m::redact(tokens_room, user.user_id, event.event_id, "cleared") }; out << " - cleared by " << eid; @@ -12079,7 +12100,7 @@ console_cmd__feds__heads(opt &out, const string_view &line) const m::user::id &user_id { - param.at(1, m::me.user_id) + param.at(1, m::me()) }; using closure_prototype = bool (const string_view &, @@ -13863,7 +13884,7 @@ console_cmd__file__download(opt &out, const string_view &line) const auto room_id { - m::media::file::download(mxc, m::me.user_id, remote) + m::media::file::download(mxc, m::me(), remote) }; out << room_id << std::endl; diff --git a/modules/m_command.cc b/modules/m_command.cc index a54dd122d..6f2939122 100644 --- a/modules/m_command.cc +++ b/modules/m_command.cc @@ -113,7 +113,7 @@ try const auto &response_sender { - public_response? user : m::me + public_response? user : m::user(m::me()) }; const auto &response_room diff --git a/modules/m_control.cc b/modules/m_control.cc index 6d91612f0..a432da55c 100644 --- a/modules/m_control.cc +++ b/modules/m_control.cc @@ -100,7 +100,7 @@ noexcept try "no alt text" }; - msghtml(control_room, m::me.user_id, str, alt, "m.notice"); + msghtml(control_room, m::me(), str, alt, "m.notice"); } catch(const std::exception &e) { @@ -127,15 +127,15 @@ static void create_control_room(const m::event &, m::vm::eval &) { - create(control_room_id, m::me.user_id); - join(control_room, m::me.user_id); - send(control_room, m::me.user_id, "m.room.name", "", + create(control_room_id, m::me()); + join(control_room, m::me()); + send(control_room, m::me(), "m.room.name", "", { { "name", "Control Room" } }); - notice(control_room, m::me.user_id, "Welcome to the control room."); - notice(control_room, m::me.user_id, "I am the daemon. You can talk to me in this room by highlighting me."); + notice(control_room, m::me(), "Welcome to the control room."); + notice(control_room, m::me(), "I am the daemon. You can talk to me in this room by highlighting me."); } m::hookfn diff --git a/modules/m_device.cc b/modules/m_device.cc index 83a4c8e95..cce902115 100644 --- a/modules/m_device.cc +++ b/modules/m_device.cc @@ -56,6 +56,11 @@ ircd::m::_access_token_delete(const m::event &event, unquote(content.at("")) }; - m::redact(m::user::tokens, at<"sender"_>(event), token_event_id, "device deleted"); + const m::room::id::buf tokens_room + { + "tokens", origin(m::my()) + }; + + m::redact(tokens_room, at<"sender"_>(event), token_event_id, "device deleted"); }); }; diff --git a/modules/m_listen.cc b/modules/m_listen.cc index 9f7a07f6a..c9f6dcac3 100644 --- a/modules/m_listen.cc +++ b/modules/m_listen.cc @@ -104,8 +104,17 @@ on_quit() void init_listeners() { - m::room::state{m::my_room}.for_each("ircd.listen", [] - (const m::event &event) + const m::room::id::buf my_room + { + "ircd", m::origin(m::my()) + }; + + const m::room::state state + { + my_room + }; + + state.for_each("ircd.listen", [](const m::event &event) { load_listener(event); }); @@ -150,7 +159,16 @@ load_listener(const string_view &name) try { bool ret{false}; - const m::room::state state{m::my_room}; + const m::room::id::buf my_room + { + "ircd", m::origin(m::my()) + }; + + const m::room::state state + { + my_room + }; + state.get("ircd.listen", name, [&ret] (const m::event &event) { diff --git a/modules/m_room_aliases.cc b/modules/m_room_aliases.cc index b94fc2e4b..de6b00755 100644 --- a/modules/m_room_aliases.cc +++ b/modules/m_room_aliases.cc @@ -28,18 +28,6 @@ IRCD_MODULE "Matrix m.room.aliases" }; -decltype(ircd::m::alias_room_id) -ircd::m::alias_room_id -{ - "alias", ircd::my_host() -}; - -decltype(ircd::m::alias_room) -ircd::m::alias_room -{ - alias_room_id -}; - // // create the alias room as an effect of !ircd created on bootstrap // @@ -53,9 +41,19 @@ ircd::m::create_alias_room_hookfn { "type", "m.room.create" }, }, - [](const m::event &, m::vm::eval &) + [](const m::event &event, m::vm::eval &) { - create(alias_room_id, m::me.user_id); + auto &my + { + m::my(at<"origin"_>(event)) + }; + + const auto &alias_room_id + { + *my.rooms.emplace("alias", origin(my)).first + }; + + create(alias_room_id, my.self); } }; diff --git a/modules/m_room_create.cc b/modules/m_room_create.cc index b9c45e066..f2654f3d5 100644 --- a/modules/m_room_create.cc +++ b/modules/m_room_create.cc @@ -49,7 +49,7 @@ try const auto &level { - my(sender) && sender != m::me? + my(sender) && sender != me()? log::INFO: log::DEBUG }; diff --git a/modules/m_vm.cc b/modules/m_vm.cc index 6bc6923e0..d10592826 100644 --- a/modules/m_vm.cc +++ b/modules/m_vm.cc @@ -135,7 +135,7 @@ ircd::m::vm::init() log::info { log, "BOOT %s @%lu [%s] db:%lu", - string_view{m::my_node.node_id}, + server_name(my()), sequence::retired, sequence::retired? string_view{event_id} : "NO EVENTS"_sv, @@ -175,7 +175,7 @@ ircd::m::vm::fini() log::info { log, "HALT '%s' @%lu [%s] vm:%lu:%lu:%lu db:%lu", - string_view{m::my_node.node_id}, + server_name(my()), retired, retired? string_view{event_id} : "NO EVENTS"_sv, diff --git a/modules/media/download.cc b/modules/media/download.cc index 0bda149cb..537d1d65b 100644 --- a/modules/media/download.cc +++ b/modules/media/download.cc @@ -65,7 +65,7 @@ get__download(client &client, { request.user_id? m::user::id{request.user_id}: - m::me.user_id + m::me() }; const bool allow_remote diff --git a/modules/media/thumbnail.cc b/modules/media/thumbnail.cc index 09d2b3941..8a3eede21 100644 --- a/modules/media/thumbnail.cc +++ b/modules/media/thumbnail.cc @@ -122,7 +122,7 @@ get__thumbnail(client &client, { request.user_id? m::user::id{request.user_id}: - m::me.user_id + m::me() }; if(!m::media::thumbnail::enable_remote) diff --git a/modules/net_dns_cache.cc b/modules/net_dns_cache.cc index 8912674dc..260ee48e4 100644 --- a/modules/net_dns_cache.cc +++ b/modules/net_dns_cache.cc @@ -172,7 +172,7 @@ try rr0.~object(); array.~array(); content.~object(); - send(room_id, m::me, type, state_key, json::object(out.completed())); + send(room_id, m::me(), type, state_key, json::object(out.completed())); return true; } catch(const http::error &e) @@ -297,7 +297,7 @@ try array.~array(); content.~object(); - send(room_id, m::me, type, state_key, json::object{out.completed()}); + send(room_id, m::me(), type, state_key, json::object{out.completed()}); return true; } catch(const http::error &e) @@ -695,7 +695,7 @@ try { const m::room room { - m::create(room_id, m::me, "internal") + m::create(room_id, m::me(), "internal") }; log::debug diff --git a/modules/well_known.cc b/modules/well_known.cc index 545f3b9a5..33c01870c 100644 --- a/modules/well_known.cc +++ b/modules/well_known.cc @@ -80,7 +80,7 @@ handle_matrix_server(client &client, { client, json::members { - { "m.server", m::self::servername } + { "m.server", m::server_name(m::my()) } } }; }