admin debug command to fetch a server's true destination

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-04-26 23:36:23 -04:00 committed by June
parent 1cbf2bdc6b
commit 450f15df4f
11 changed files with 329 additions and 42 deletions

View file

@ -294,7 +294,8 @@ pub(crate) async fn register_route(body: Ruma<register::v3::Request>) -> Result<
.admin .admin
.send_message(RoomMessageEventContent::notice_plain(format!( .send_message(RoomMessageEventContent::notice_plain(format!(
"New user \"{user_id}\" registered on this server." "New user \"{user_id}\" registered on this server."
))); )))
.await;
} }
// log in conduit admin channel if a guest registered // log in conduit admin channel if a guest registered
@ -310,27 +311,30 @@ pub(crate) async fn register_route(body: Ruma<register::v3::Request>) -> Result<
.send_message(RoomMessageEventContent::notice_plain(format!( .send_message(RoomMessageEventContent::notice_plain(format!(
"Guest user \"{user_id}\" with device display name `{device_display_name}` registered on this \ "Guest user \"{user_id}\" with device display name `{device_display_name}` registered on this \
server." server."
))); )))
.await;
} else { } else {
services() services()
.admin .admin
.send_message(RoomMessageEventContent::notice_plain(format!( .send_message(RoomMessageEventContent::notice_plain(format!(
"Guest user \"{user_id}\" with no device display name registered on this server.", "Guest user \"{user_id}\" with no device display name registered on this server.",
))); )))
.await;
} }
} else { } else {
services() services()
.admin .admin
.send_message(RoomMessageEventContent::notice_plain(format!( .send_message(RoomMessageEventContent::notice_plain(format!(
"Guest user \"{user_id}\" with no device display name registered on this server.", "Guest user \"{user_id}\" with no device display name registered on this server.",
))); )))
.await;
} }
} }
// If this is the first real user, grant them admin privileges except for guest // If this is the first real user, grant them admin privileges except for guest
// users Note: the server user, @conduit:servername, is generated first // users Note: the server user, @conduit:servername, is generated first
if !is_guest { if !is_guest {
if let Some(admin_room) = service::admin::Service::get_admin_room()? { if let Some(admin_room) = service::admin::Service::get_admin_room().await? {
if services() if services()
.rooms .rooms
.state_cache .state_cache
@ -461,7 +465,8 @@ pub(crate) async fn change_password_route(
.admin .admin
.send_message(RoomMessageEventContent::notice_plain(format!( .send_message(RoomMessageEventContent::notice_plain(format!(
"User {sender_user} changed their password." "User {sender_user} changed their password."
))); )))
.await;
Ok(change_password::v3::Response {}) Ok(change_password::v3::Response {})
} }
@ -536,7 +541,8 @@ pub(crate) async fn deactivate_route(body: Ruma<deactivate::v3::Request>) -> Res
.admin .admin
.send_message(RoomMessageEventContent::notice_plain(format!( .send_message(RoomMessageEventContent::notice_plain(format!(
"User {sender_user} deactivated their account." "User {sender_user} deactivated their account."
))); )))
.await;
Ok(deactivate::v3::Response { Ok(deactivate::v3::Response {
id_server_unbind_result: ThirdPartyIdRemovalStatus::NoSupport, id_server_unbind_result: ThirdPartyIdRemovalStatus::NoSupport,

View file

@ -97,7 +97,8 @@ pub(crate) async fn report_event_route(
body.score.unwrap_or_else(|| ruma::Int::from(0)), body.score.unwrap_or_else(|| ruma::Int::from(0)),
HtmlEscape(body.reason.as_deref().unwrap_or("")) HtmlEscape(body.reason.as_deref().unwrap_or(""))
), ),
)); ))
.await;
// even though this is kinda security by obscurity, let's still make a small // even though this is kinda security by obscurity, let's still make a small
// random delay sending a successful response per spec suggestion regarding // random delay sending a successful response per spec suggestion regarding

View file

@ -239,7 +239,7 @@ async fn send_state_event_for_key_helper(
}, },
// admin room is a sensitive room, it should not ever be made public // admin room is a sensitive room, it should not ever be made public
StateEventType::RoomJoinRules => { StateEventType::RoomJoinRules => {
if let Some(admin_room_id) = service::admin::Service::get_admin_room()? { if let Some(admin_room_id) = service::admin::Service::get_admin_room().await? {
if admin_room_id == room_id { if admin_room_id == room_id {
if let Ok(join_rule) = serde_json::from_str::<RoomJoinRulesEventContent>(json.json().get()) { if let Ok(join_rule) = serde_json::from_str::<RoomJoinRulesEventContent>(json.json().get()) {
if join_rule.join_rule == JoinRule::Public { if join_rule.join_rule == JoinRule::Public {
@ -254,7 +254,7 @@ async fn send_state_event_for_key_helper(
}, },
// admin room is a sensitive room, it should not ever be made world readable // admin room is a sensitive room, it should not ever be made world readable
StateEventType::RoomHistoryVisibility => { StateEventType::RoomHistoryVisibility => {
if let Some(admin_room_id) = service::admin::Service::get_admin_room()? { if let Some(admin_room_id) = service::admin::Service::get_admin_room().await? {
if admin_room_id == room_id { if admin_room_id == room_id {
if let Ok(visibility_content) = if let Ok(visibility_content) =
serde_json::from_str::<RoomHistoryVisibilityEventContent>(json.json().get()) serde_json::from_str::<RoomHistoryVisibilityEventContent>(json.json().get())

View file

@ -372,7 +372,8 @@ impl KeyValueDatabase {
.send_message(RoomMessageEventContent::text_plain( .send_message(RoomMessageEventContent::text_plain(
"The Conduit account emergency password is set! Please unset it as soon as you finish \ "The Conduit account emergency password is set! Please unset it as soon as you finish \
admin account recovery!", admin account recovery!",
)); ))
.await;
} }
}, },
Err(e) => { Err(e) => {
@ -473,7 +474,8 @@ impl KeyValueDatabase {
.send_message(RoomMessageEventContent::text_plain(format!( .send_message(RoomMessageEventContent::text_plain(format!(
"@room: the following is a message from the conduwuit puppy. it was sent on '{}':\n\n{}", "@room: the following is a message from the conduwuit puppy. it was sent on '{}':\n\n{}",
update.date, update.message update.date, update.message
))); )))
.await;
} }
} }
services() services()

View file

@ -8,7 +8,10 @@ use tokio::sync::RwLock;
use tracing::{debug, info, warn}; use tracing::{debug, info, warn};
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
use crate::{api::server_server::parse_incoming_pdu, services, utils::HtmlEscape, Error, PduEvent, Result}; use crate::{
api::server_server::parse_incoming_pdu, service::sending::send::resolve_actual_dest, services, utils::HtmlEscape,
Error, PduEvent, Result,
};
pub(crate) async fn get_auth_chain(_body: Vec<&str>, event_id: Box<EventId>) -> Result<RoomMessageEventContent> { pub(crate) async fn get_auth_chain(_body: Vec<&str>, event_id: Box<EventId>) -> Result<RoomMessageEventContent> {
let event_id = Arc::<EventId>::from(event_id); let event_id = Arc::<EventId>::from(event_id);
@ -428,3 +431,25 @@ pub(crate) async fn verify_json(body: Vec<&str>) -> Result<RoomMessageEventConte
)) ))
} }
} }
pub(crate) async fn resolve_true_destination(
_body: Vec<&str>, server_name: Box<ServerName>, no_cache: bool,
) -> Result<RoomMessageEventContent> {
if !services().globals.config.allow_federation {
return Ok(RoomMessageEventContent::text_plain(
"Federation is disabled on this homeserver.",
));
}
if server_name == services().globals.config.server_name {
return Ok(RoomMessageEventContent::text_plain(
"Not allowed to send federation requests to ourselves. Please use `get-pdu` for fetching local PDUs.",
));
}
let (actual_dest, hostname_uri) = resolve_actual_dest(&server_name, no_cache, true).await?;
Ok(RoomMessageEventContent::text_plain(format!(
"Actual destination: {actual_dest:?} | Hostname URI: {hostname_uri}"
)))
}

View file

@ -3,7 +3,7 @@ use ruma::{events::room::message::RoomMessageEventContent, EventId, RoomId, Serv
use self::debug_commands::{ use self::debug_commands::{
change_log_level, force_device_list_updates, get_auth_chain, get_pdu, get_remote_pdu, get_remote_pdu_list, change_log_level, force_device_list_updates, get_auth_chain, get_pdu, get_remote_pdu, get_remote_pdu_list,
get_room_state, parse_pdu, ping, sign_json, verify_json, get_room_state, parse_pdu, ping, resolve_true_destination, sign_json, verify_json,
}; };
use crate::Result; use crate::Result;
@ -106,6 +106,17 @@ pub(crate) enum DebugCommand {
/// This command needs a JSON blob provided in a Markdown code block below /// This command needs a JSON blob provided in a Markdown code block below
/// the command. /// the command.
VerifyJson, VerifyJson,
/// - Runs a server name through conduwuit's true destination resolution
/// process
///
/// Useful for debugging well-known issues
ResolveTrueDestination {
server_name: Box<ServerName>,
#[arg(short, long)]
no_cache: bool,
},
} }
pub(crate) async fn process(command: DebugCommand, body: Vec<&str>) -> Result<RoomMessageEventContent> { pub(crate) async fn process(command: DebugCommand, body: Vec<&str>) -> Result<RoomMessageEventContent> {
@ -138,5 +149,9 @@ pub(crate) async fn process(command: DebugCommand, body: Vec<&str>) -> Result<Ro
server, server,
force, force,
} => get_remote_pdu_list(body, server, force).await?, } => get_remote_pdu_list(body, server, force).await?,
DebugCommand::ResolveTrueDestination {
server_name,
no_cache,
} => resolve_true_destination(body, server_name, no_cache).await?,
}) })
} }

View file

@ -127,7 +127,7 @@ impl Service {
let conduit_user = UserId::parse(format!("@conduit:{}", services().globals.server_name())) let conduit_user = UserId::parse(format!("@conduit:{}", services().globals.server_name()))
.expect("@conduit:server_name is valid"); .expect("@conduit:server_name is valid");
if let Ok(Some(conduit_room)) = Self::get_admin_room() { if let Ok(Some(conduit_room)) = Self::get_admin_room().await {
loop { loop {
tokio::select! { tokio::select! {
event = receiver.recv_async() => { event = receiver.recv_async() => {
@ -201,15 +201,17 @@ impl Service {
Ok(()) Ok(())
} }
pub(crate) fn process_message(&self, room_message: String, event_id: Arc<EventId>) { pub(crate) async fn process_message(&self, room_message: String, event_id: Arc<EventId>) {
self.sender self.sender
.send(AdminRoomEvent::ProcessMessage(room_message, event_id)) .send_async(AdminRoomEvent::ProcessMessage(room_message, event_id))
.await
.unwrap(); .unwrap();
} }
pub(crate) fn send_message(&self, message_content: RoomMessageEventContent) { pub(crate) async fn send_message(&self, message_content: RoomMessageEventContent) {
self.sender self.sender
.send(AdminRoomEvent::SendMessage(message_content)) .send_async(AdminRoomEvent::SendMessage(message_content))
.await
.unwrap(); .unwrap();
} }
@ -621,7 +623,7 @@ impl Service {
/// ///
/// Errors are propagated from the database, and will have None if there is /// Errors are propagated from the database, and will have None if there is
/// no admin room /// no admin room
pub(crate) fn get_admin_room() -> Result<Option<OwnedRoomId>> { pub(crate) async fn get_admin_room() -> Result<Option<OwnedRoomId>> {
let admin_room_alias: Box<RoomAliasId> = format!("#admins:{}", services().globals.server_name()) let admin_room_alias: Box<RoomAliasId> = format!("#admins:{}", services().globals.server_name())
.try_into() .try_into()
.expect("#admins:server_name is a valid alias name"); .expect("#admins:server_name is a valid alias name");
@ -636,7 +638,7 @@ impl Service {
/// ///
/// In conduit, this is equivalent to granting admin privileges. /// In conduit, this is equivalent to granting admin privileges.
pub(crate) async fn make_user_admin(&self, user_id: &UserId, displayname: String) -> Result<()> { pub(crate) async fn make_user_admin(&self, user_id: &UserId, displayname: String) -> Result<()> {
if let Some(room_id) = Self::get_admin_room()? { if let Some(room_id) = Self::get_admin_room().await? {
let mutex_state = Arc::clone( let mutex_state = Arc::clone(
services() services()
.globals .globals

View file

@ -25,7 +25,7 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) ->
.try_into() .try_into()
.expect("#admins:server_name is a valid alias name"); .expect("#admins:server_name is a valid alias name");
if let Some(admin_room_id) = Service::get_admin_room()? { if let Some(admin_room_id) = Service::get_admin_room().await? {
if room.to_string().eq(&admin_room_id) || room.to_string().eq(&admin_room_alias) { if room.to_string().eq(&admin_room_id) || room.to_string().eq(&admin_room_alias) {
return Ok(RoomMessageEventContent::text_plain("Not allowed to ban the admin room.")); return Ok(RoomMessageEventContent::text_plain("Not allowed to ban the admin room."));
} }
@ -190,7 +190,7 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) ->
for &room in &rooms_s { for &room in &rooms_s {
match <&RoomOrAliasId>::try_from(room) { match <&RoomOrAliasId>::try_from(room) {
Ok(room_alias_or_id) => { Ok(room_alias_or_id) => {
if let Some(admin_room_id) = Service::get_admin_room()? { if let Some(admin_room_id) = Service::get_admin_room().await? {
if room.to_owned().eq(&admin_room_id) || room.to_owned().eq(&admin_room_alias) { if room.to_owned().eq(&admin_room_id) || room.to_owned().eq(&admin_room_alias) {
info!("User specified admin room in bulk ban list, ignoring"); info!("User specified admin room in bulk ban list, ignoring");
continue; continue;

View file

@ -512,9 +512,12 @@ impl Service {
// the administrator can execute commands as conduit // the administrator can execute commands as conduit
let from_conduit = pdu.sender == server_user && services().globals.emergency_password().is_none(); let from_conduit = pdu.sender == server_user && services().globals.emergency_password().is_none();
if let Some(admin_room) = service::admin::Service::get_admin_room()? { if let Some(admin_room) = service::admin::Service::get_admin_room().await? {
if to_conduit && !from_conduit && admin_room == pdu.room_id { if to_conduit && !from_conduit && admin_room == pdu.room_id {
services().admin.process_message(body, pdu.event_id.clone()); services()
.admin
.process_message(body, pdu.event_id.clone())
.await;
} }
} }
} }
@ -815,7 +818,7 @@ impl Service {
) -> Result<Arc<EventId>> { ) -> Result<Arc<EventId>> {
let (pdu, pdu_json) = self.create_hash_and_sign_event(pdu_builder, sender, room_id, state_lock)?; let (pdu, pdu_json) = self.create_hash_and_sign_event(pdu_builder, sender, room_id, state_lock)?;
if let Some(admin_room) = service::admin::Service::get_admin_room()? { if let Some(admin_room) = service::admin::Service::get_admin_room().await? {
if admin_room == room_id { if admin_room == room_id {
match pdu.event_type() { match pdu.event_type() {
TimelineEventType::RoomEncryption => { TimelineEventType::RoomEncryption => {

View file

@ -12,8 +12,8 @@ use crate::{services, Config, Error, Result};
mod appservice; mod appservice;
mod data; mod data;
mod send; pub(crate) mod send;
mod sender; pub(crate) mod sender;
pub(crate) use send::FedDest; pub(crate) use send::FedDest;
pub(crate) struct Service { pub(crate) struct Service {

View file

@ -13,6 +13,7 @@ use ruma::{
client::error::Error as RumaError, EndpointError, IncomingResponse, MatrixVersion, OutgoingRequest, client::error::Error as RumaError, EndpointError, IncomingResponse, MatrixVersion, OutgoingRequest,
SendAccessToken, SendAccessToken,
}, },
events::room::message::RoomMessageEventContent,
OwnedServerName, ServerName, OwnedServerName, ServerName,
}; };
use tracing::{debug, error, trace}; use tracing::{debug, error, trace};
@ -194,7 +195,7 @@ async fn get_actual_dest(server_name: &ServerName) -> Result<ActualDest> {
} else { } else {
cached = false; cached = false;
validate_dest(server_name)?; validate_dest(server_name)?;
resolve_actual_dest(server_name).await? resolve_actual_dest(server_name, false, false).await?
}; };
let string = dest.clone().into_https_string(); let string = dest.clone().into_https_string();
@ -210,59 +211,220 @@ async fn get_actual_dest(server_name: &ServerName) -> Result<ActualDest> {
/// Implemented according to the specification at <https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names> /// Implemented according to the specification at <https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names>
/// Numbers in comments below refer to bullet points in linked section of /// Numbers in comments below refer to bullet points in linked section of
/// specification /// specification
async fn resolve_actual_dest(dest: &'_ ServerName) -> Result<(FedDest, String)> { pub(crate) async fn resolve_actual_dest(
dest: &'_ ServerName, no_cache_dest: bool, admin_room_caller: bool,
) -> Result<(FedDest, String)> {
trace!("Finding actual destination for {dest}"); trace!("Finding actual destination for {dest}");
let dest_str = dest.as_str().to_owned(); let dest_str = dest.as_str().to_owned();
let mut hostname = dest_str.clone(); let mut hostname = dest_str.clone();
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Checking for 1: IP literal with provided or default port"
)))
.await;
}
#[allow(clippy::single_match_else)]
let actual_dest = match get_ip_with_port(&dest_str) { let actual_dest = match get_ip_with_port(&dest_str) {
Some(host_port) => { Some(host_port) => {
debug!("1: IP literal with provided or default port"); debug!("1: IP literal with provided or default port");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"1: IP literal with provided or default port\n\nHost and Port: {host_port:?}"
)))
.await;
}
host_port host_port
}, },
None => { None => {
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(
"Checking for 2: Hostname with included port",
))
.await;
}
if let Some(pos) = dest_str.find(':') { if let Some(pos) = dest_str.find(':') {
debug!("2: Hostname with included port"); debug!("2: Hostname with included port");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain("2: Hostname with included port"))
.await;
}
let (host, port) = dest_str.split_at(pos); let (host, port) = dest_str.split_at(pos);
query_and_cache_override(host, host, port.parse::<u16>().unwrap_or(8448)).await?; if !no_cache_dest {
query_and_cache_override(host, host, port.parse::<u16>().unwrap_or(8448)).await?;
}
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!("Host: {host} | Port: {port}")))
.await;
}
FedDest::Named(host.to_owned(), port.to_owned()) FedDest::Named(host.to_owned(), port.to_owned())
} else { } else {
trace!("Requesting well known for {dest}"); trace!("Requesting well known for {dest}");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Checking for 3: A .well-known file is available. Requesting well-known for {dest}"
)))
.await;
}
if let Some(delegated_hostname) = request_well_known(dest.as_str()).await? { if let Some(delegated_hostname) = request_well_known(dest.as_str()).await? {
debug!("3: A .well-known file is available"); debug!("3: A .well-known file is available");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain("3: A .well-known file is available"))
.await;
}
hostname = add_port_to_hostname(&delegated_hostname).into_uri_string(); hostname = add_port_to_hostname(&delegated_hostname).into_uri_string();
match get_ip_with_port(&delegated_hostname) { match get_ip_with_port(&delegated_hostname) {
Some(host_and_port) => host_and_port, // 3.1: IP literal in .well-known file Some(host_and_port) => {
debug!("3.1: IP literal in .well-known file");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"3.1: IP literal in .well-known file\n\nHost and Port: {host_and_port:?}"
)))
.await;
}
host_and_port
},
None => { None => {
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Checking for 3.2: Hostname with port in .well-known file"
)))
.await;
}
if let Some(pos) = delegated_hostname.find(':') { if let Some(pos) = delegated_hostname.find(':') {
debug!("3.2: Hostname with port in .well-known file"); debug!("3.2: Hostname with port in .well-known file");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(
"3.2: Hostname with port in .well-known file",
))
.await;
}
let (host, port) = delegated_hostname.split_at(pos); let (host, port) = delegated_hostname.split_at(pos);
query_and_cache_override(host, host, port.parse::<u16>().unwrap_or(8448)).await?; if !no_cache_dest {
query_and_cache_override(host, host, port.parse::<u16>().unwrap_or(8448)).await?;
}
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Host: {host} | Port: {port}"
)))
.await;
}
FedDest::Named(host.to_owned(), port.to_owned()) FedDest::Named(host.to_owned(), port.to_owned())
} else { } else {
trace!("Delegated hostname has no port in this branch"); trace!("Delegated hostname has no port in this branch");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(
"Delegated hostname has no port specified",
))
.await;
}
if let Some(hostname_override) = query_srv_record(&delegated_hostname).await? { if let Some(hostname_override) = query_srv_record(&delegated_hostname).await? {
debug!("3.3: SRV lookup successful"); debug!("3.3: SRV lookup successful");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(
"3.3: SRV lookup successful",
))
.await;
}
let force_port = hostname_override.port(); let force_port = hostname_override.port();
query_and_cache_override( if !no_cache_dest {
&delegated_hostname, query_and_cache_override(
&hostname_override.hostname(), &delegated_hostname,
force_port.unwrap_or(8448), &hostname_override.hostname(),
) force_port.unwrap_or(8448),
.await?; )
.await?;
}
if let Some(port) = force_port { if let Some(port) = force_port {
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Host: {delegated_hostname} | Port: {port}"
)))
.await;
}
FedDest::Named(delegated_hostname, format!(":{port}")) FedDest::Named(delegated_hostname, format!(":{port}"))
} else { } else {
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Host: {delegated_hostname} | Port: 8448"
)))
.await;
}
add_port_to_hostname(&delegated_hostname) add_port_to_hostname(&delegated_hostname)
} }
} else { } else {
debug!("3.4: No SRV records, just use the hostname from .well-known"); debug!("3.4: No SRV records, just use the hostname from .well-known");
query_and_cache_override(&delegated_hostname, &delegated_hostname, 8448).await?; if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(
"3.4: No SRV records, just use the hostname from .well-known",
))
.await;
}
if !no_cache_dest {
query_and_cache_override(&delegated_hostname, &delegated_hostname, 8448)
.await?;
}
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Host: {delegated_hostname} | Port: 8448"
)))
.await;
}
add_port_to_hostname(&delegated_hostname) add_port_to_hostname(&delegated_hostname)
} }
} }
@ -270,21 +432,84 @@ async fn resolve_actual_dest(dest: &'_ ServerName) -> Result<(FedDest, String)>
} }
} else { } else {
trace!("4: No .well-known or an error occured"); trace!("4: No .well-known or an error occured");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(
"4: No .well-known or an error occured",
))
.await;
}
if let Some(hostname_override) = query_srv_record(&dest_str).await? { if let Some(hostname_override) = query_srv_record(&dest_str).await? {
debug!("4: No .well-known; SRV record found"); debug!("4: No .well-known; SRV record found");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(
"4: No .well-known; SRV record found",
))
.await;
}
let force_port = hostname_override.port(); let force_port = hostname_override.port();
query_and_cache_override(&hostname, &hostname_override.hostname(), force_port.unwrap_or(8448))
if !no_cache_dest {
query_and_cache_override(
&hostname,
&hostname_override.hostname(),
force_port.unwrap_or(8448),
)
.await?; .await?;
}
if let Some(port) = force_port { if let Some(port) = force_port {
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Host: {hostname} | Port: {port}"
)))
.await;
}
FedDest::Named(hostname.clone(), format!(":{port}")) FedDest::Named(hostname.clone(), format!(":{port}"))
} else { } else {
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Host: {hostname} | Port: 8448"
)))
.await;
}
add_port_to_hostname(&hostname) add_port_to_hostname(&hostname)
} }
} else { } else {
debug!("4: No .well-known; 5: No SRV record found"); debug!("4: No .well-known; 5: No SRV record found");
query_and_cache_override(&dest_str, &dest_str, 8448).await?; if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(
"4: No .well-known; 5: No SRV record found",
))
.await;
}
if !no_cache_dest {
query_and_cache_override(&dest_str, &dest_str, 8448).await?;
}
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Host: {dest_str} | Port: 8448"
)))
.await;
}
add_port_to_hostname(&dest_str) add_port_to_hostname(&dest_str)
} }
} }
@ -306,6 +531,14 @@ async fn resolve_actual_dest(dest: &'_ ServerName) -> Result<(FedDest, String)>
}; };
debug!("Actual destination: {actual_dest:?} hostname: {hostname:?}"); debug!("Actual destination: {actual_dest:?} hostname: {hostname:?}");
if admin_room_caller {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
"Actual destination: {actual_dest:?} | Hostname: {hostname:?}"
)))
.await;
}
Ok((actual_dest, hostname.into_uri_string())) Ok((actual_dest, hostname.into_uri_string()))
} }