admin debug command to fetch a server's true destination
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
1cbf2bdc6b
commit
450f15df4f
11 changed files with 329 additions and 42 deletions
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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}"
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
|
@ -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?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue