Skip to content
Snippets Groups Projects
Commit 8a767c4b authored by 🥺's avatar 🥺 :transgender_flag: Committed by 🥺
Browse files

on room alias joins, attempt to find the room ID through *more* servers if available

parent 8ad42a85
No related branches found
No related tags found
No related merge requests found
...@@ -10,8 +10,9 @@ ...@@ -10,8 +10,9 @@
}, },
OwnedRoomAliasId, OwnedServerName, OwnedRoomAliasId, OwnedServerName,
}; };
use tracing::{debug, info};
use crate::{services, Error, Result, Ruma}; use crate::{debug_info, services, Error, Result, Ruma};
/// # `PUT /_matrix/client/v3/directory/room/{roomAlias}` /// # `PUT /_matrix/client/v3/directory/room/{roomAlias}`
/// ///
...@@ -118,12 +119,19 @@ pub async fn delete_alias_route(body: Ruma<delete_alias::v3::Request>) -> Result ...@@ -118,12 +119,19 @@ pub async fn delete_alias_route(body: Ruma<delete_alias::v3::Request>) -> Result
/// ///
/// Resolve an alias locally or over federation. /// Resolve an alias locally or over federation.
pub async fn get_alias_route(body: Ruma<get_alias::v3::Request>) -> Result<get_alias::v3::Response> { pub async fn get_alias_route(body: Ruma<get_alias::v3::Request>) -> Result<get_alias::v3::Response> {
get_alias_helper(body.body.room_alias).await get_alias_helper(body.body.room_alias, None).await
} }
pub(crate) async fn get_alias_helper(room_alias: OwnedRoomAliasId) -> Result<get_alias::v3::Response> { pub(crate) async fn get_alias_helper(
if room_alias.server_name() != services().globals.server_name() { room_alias: OwnedRoomAliasId, servers: Option<Vec<OwnedServerName>>,
let response = services() ) -> Result<get_alias::v3::Response> {
if room_alias.server_name() != services().globals.server_name()
&& (!servers
.as_ref()
.is_some_and(|servers| servers.contains(&services().globals.server_name().to_owned()))
|| servers.as_ref().is_none())
{
let mut response = services()
.sending .sending
.send_federation_request( .send_federation_request(
room_alias.server_name(), room_alias.server_name(),
...@@ -131,47 +139,83 @@ pub(crate) async fn get_alias_helper(room_alias: OwnedRoomAliasId) -> Result<get ...@@ -131,47 +139,83 @@ pub(crate) async fn get_alias_helper(room_alias: OwnedRoomAliasId) -> Result<get
room_alias: room_alias.clone(), room_alias: room_alias.clone(),
}, },
) )
.await?; .await;
let room_id = response.room_id; if let Err(ref e) = response {
debug_info!(
let mut servers = response.servers; "Server {} of the original room alias failed to assist in resolving room alias: {e}",
room_alias.server_name()
// since the room alias server_name responded, insert it into the list );
servers.push(room_alias.server_name().into());
// find active servers in room state cache to suggest
servers.extend(
services()
.rooms
.state_cache
.room_servers(&room_id)
.filter_map(Result::ok),
);
servers.sort_unstable();
servers.dedup();
// shuffle list of servers randomly after sort and dedupe
servers.shuffle(&mut rand::thread_rng());
// prefer the very first server to be ourselves if available, else prefer the
// room alias server first
if let Some(server_index) = servers
.iter()
.position(|server| server == services().globals.server_name())
{
servers.remove(server_index);
servers.insert(0, services().globals.server_name().to_owned());
} else if let Some(alias_server_index) = servers
.iter()
.position(|server| server == room_alias.server_name())
{
servers.remove(alias_server_index);
servers.insert(0, room_alias.server_name().into());
} }
return Ok(get_alias::v3::Response::new(room_id, servers)); if let Some(servers) = servers {
if !servers.is_empty() {
for server in servers {
response = services()
.sending
.send_federation_request(
&server,
federation::query::get_room_information::v1::Request {
room_alias: room_alias.clone(),
},
)
.await;
if response.is_err() {
continue;
}
break;
}
}
}
if let Ok(response) = response {
let room_id = response.room_id;
let mut servers = response.servers;
// since the room alias server_name responded, insert it into the list
servers.push(room_alias.server_name().into());
// find active servers in room state cache to suggest
servers.extend(
services()
.rooms
.state_cache
.room_servers(&room_id)
.filter_map(Result::ok),
);
servers.sort_unstable();
servers.dedup();
// shuffle list of servers randomly after sort and dedupe
servers.shuffle(&mut rand::thread_rng());
// prefer the very first server to be ourselves if available, else prefer the
// room alias server first
if let Some(server_index) = servers
.iter()
.position(|server| server == services().globals.server_name())
{
servers.remove(server_index);
servers.insert(0, services().globals.server_name().to_owned());
} else if let Some(alias_server_index) = servers
.iter()
.position(|server| server == room_alias.server_name())
{
servers.remove(alias_server_index);
servers.insert(0, room_alias.server_name().into());
}
return Ok(get_alias::v3::Response::new(room_id, servers));
}
return Err(Error::BadRequest(
ErrorKind::Unknown,
"No servers could assist in resolving the room alias",
));
} }
let mut room_id = None; let mut room_id = None;
......
...@@ -198,7 +198,7 @@ pub async fn join_room_by_id_or_alias_route( ...@@ -198,7 +198,7 @@ pub async fn join_room_by_id_or_alias_route(
)); ));
} }
let response = get_alias_helper(room_alias.clone()).await?; let response = get_alias_helper(room_alias.clone(), Some(body.server_name.clone())).await?;
if services().rooms.metadata.is_banned(&response.room_id)? && !services().users.is_admin(sender_user)? { if services().rooms.metadata.is_banned(&response.room_id)? && !services().users.is_admin(sender_user)? {
return Err(Error::BadRequest( return Err(Error::BadRequest(
......
...@@ -71,7 +71,7 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) -> ...@@ -71,7 +71,7 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) ->
federation" federation"
); );
match get_alias_helper(room_alias).await { match get_alias_helper(room_alias, None).await {
Ok(response) => { Ok(response) => {
debug!("Got federation response fetching room ID for room {room}: {:?}", response); debug!("Got federation response fetching room ID for room {room}: {:?}", response);
response.room_id response.room_id
...@@ -233,7 +233,7 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) -> ...@@ -233,7 +233,7 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) ->
fetch room ID over federation" fetch room ID over federation"
); );
match get_alias_helper(room_alias).await { match get_alias_helper(room_alias, None).await {
Ok(response) => { Ok(response) => {
debug!( debug!(
"Got federation response fetching room ID for room {room}: \ "Got federation response fetching room ID for room {room}: \
...@@ -432,7 +432,7 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) -> ...@@ -432,7 +432,7 @@ pub(crate) async fn process(command: RoomModerationCommand, body: Vec<&str>) ->
federation" federation"
); );
match get_alias_helper(room_alias).await { match get_alias_helper(room_alias, None).await {
Ok(response) => { Ok(response) => {
debug!("Got federation response fetching room ID for room {room}: {:?}", response); debug!("Got federation response fetching room ID for room {room}: {:?}", response);
response.room_id response.room_id
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment