stop sending make_join if 15 servers responded with unsupported/invalid room version

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-03-31 14:25:50 -04:00 committed by June
parent ce414023a4
commit af6c72fa84
2 changed files with 47 additions and 4 deletions

View file

@ -30,7 +30,7 @@ use ruma::{
};
use serde_json::value::{to_raw_value, RawValue as RawJsonValue};
use tokio::sync::RwLock;
use tracing::{debug, error, info, warn};
use tracing::{debug, error, info, trace, warn};
use super::get_alias_helper;
use crate::{
@ -1144,11 +1144,14 @@ async fn make_join_request(
) -> Result<(federation::membership::prepare_join_event::v1::Response, OwnedServerName)> {
let mut make_join_response_and_server = Err(Error::BadServerResponse("No server available to assist in joining."));
let mut make_join_counter = 0;
let mut incompatible_room_version_count = 0;
for remote_server in servers {
if remote_server == services().globals.server_name() {
continue;
}
info!("Asking {remote_server} for make_join");
info!("Asking {remote_server} for make_join ({make_join_counter})");
let make_join_response = services()
.sending
.send_federation_request(
@ -1161,6 +1164,34 @@ async fn make_join_request(
)
.await;
trace!("make_join response: {:?}", make_join_response);
make_join_counter += 1;
if let Err(ref e) = make_join_response {
trace!("make_join ErrorKind string: {:?}", e.error_code().to_string());
// converting to a string is necessary (i think) because ruma is forcing us to
// fill in the struct for M_INCOMPATIBLE_ROOM_VERSION
if e.error_code()
.to_string()
.contains("M_INCOMPATIBLE_ROOM_VERSION")
|| e.error_code()
.to_string()
.contains("M_UNSUPPORTED_ROOM_VERSION")
{
incompatible_room_version_count += 1;
}
if incompatible_room_version_count > 15 {
info!(
"15 servers have responded with M_INCOMPATIBLE_ROOM_VERSION or M_UNSUPPORTED_ROOM_VERSION, \
assuming that Conduwuit does not support the room {room_id}: {e}"
);
make_join_response_and_server =
Err(Error::BadServerResponse("Room version is not supported by Conduwuit"));
return make_join_response_and_server;
}
}
make_join_response_and_server = make_join_response.map(|r| (r, remote_server.clone()));
if make_join_response_and_server.is_ok() {

View file

@ -101,7 +101,7 @@ impl Error {
if let Self::FederationError(origin, error) = self {
let mut error = error.clone();
error.body = ErrorBody::Standard {
kind: Unknown,
kind: error.error_kind().unwrap_or(&Unknown).clone(),
message: format!("Answer from {origin}: {error}"),
};
return RumaResponse(UiaaResponse::MatrixError(error));
@ -138,7 +138,7 @@ impl Error {
_ => (Unknown, StatusCode::INTERNAL_SERVER_ERROR),
};
info!("Returning an error: {}: {}", status_code, message);
info!("Returning an error: {status_code}: {message}");
RumaResponse(UiaaResponse::MatrixError(RumaError {
body: ErrorBody::Standard {
@ -149,6 +149,18 @@ impl Error {
}))
}
/// Returns the Matrix error code / error kind
pub fn error_code(&self) -> ErrorKind {
if let Self::FederationError(_, error) = self {
return error.error_kind().unwrap_or(&Unknown).clone();
}
match self {
Self::BadRequest(kind, _) => kind.clone(),
_ => Unknown,
}
}
/// Sanitizes public-facing errors that can leak sensitive information.
pub fn sanitized_error(&self) -> String {
let db_error = String::from("Database or I/O error occurred.");