mod acl_check; mod fetch_and_handle_outliers; mod fetch_prev; mod fetch_state; mod handle_incoming_pdu; mod handle_outlier_pdu; mod handle_prev_pdu; mod parse_incoming_pdu; mod policy_server; mod resolve_state; mod state_at_incoming; mod upgrade_outlier_pdu; use std::{collections::HashMap, fmt::Write, sync::Arc, time::Instant}; use async_trait::async_trait; use conduwuit::{Err, Event, PduEvent, Result, RoomVersion, Server, SyncRwLock, utils::MutexMap}; use ruma::{ OwnedEventId, OwnedRoomId, RoomId, RoomVersionId, events::room::create::RoomCreateEventContent, }; use crate::{Dep, globals, rooms, sending, server_keys}; pub struct Service { pub mutex_federation: RoomMutexMap, pub federation_handletime: SyncRwLock, services: Services, } struct Services { globals: Dep, sending: Dep, auth_chain: Dep, metadata: Dep, outlier: Dep, pdu_metadata: Dep, server_keys: Dep, short: Dep, state: Dep, state_cache: Dep, state_accessor: Dep, state_compressor: Dep, timeline: Dep, server: Arc, } type RoomMutexMap = MutexMap; type HandleTimeMap = HashMap; #[async_trait] impl crate::Service for Service { fn build(args: crate::Args<'_>) -> Result> { Ok(Arc::new(Self { mutex_federation: RoomMutexMap::new(), federation_handletime: HandleTimeMap::new().into(), services: Services { globals: args.depend::("globals"), sending: args.depend::("sending"), auth_chain: args.depend::("rooms::auth_chain"), metadata: args.depend::("rooms::metadata"), outlier: args.depend::("rooms::outlier"), server_keys: args.depend::("server_keys"), pdu_metadata: args.depend::("rooms::pdu_metadata"), short: args.depend::("rooms::short"), state: args.depend::("rooms::state"), state_cache: args.depend::("rooms::state_cache"), state_accessor: args .depend::("rooms::state_accessor"), state_compressor: args .depend::("rooms::state_compressor"), timeline: args.depend::("rooms::timeline"), server: args.server.clone(), }, })) } async fn memory_usage(&self, out: &mut (dyn Write + Send)) -> Result { let mutex_federation = self.mutex_federation.len(); writeln!(out, "federation_mutex: {mutex_federation}")?; let federation_handletime = self.federation_handletime.read().len(); writeln!(out, "federation_handletime: {federation_handletime}")?; Ok(()) } fn name(&self) -> &str { crate::service::make_name(std::module_path!()) } } impl Service { async fn event_exists(&self, event_id: OwnedEventId) -> bool { self.services.timeline.pdu_exists(&event_id).await } async fn event_fetch(&self, event_id: OwnedEventId) -> Option { self.services.timeline.get_pdu(&event_id).await.ok() } } fn check_room_id(room_id: &RoomId, pdu: &Pdu) -> Result { if pdu .room_id() .is_some_and(|claimed_room_id| claimed_room_id != room_id) { return Err!(Request(InvalidParam(error!( pdu_event_id = ?pdu.event_id(), pdu_room_id = ?pdu.room_id(), ?room_id, "Found event from room in room", )))); } Ok(()) } fn get_room_version_id(create_event: &Pdu) -> Result { let content: RoomCreateEventContent = create_event.get_content()?; let room_version = content.room_version; Ok(room_version) } #[inline] fn to_room_version(room_version_id: &RoomVersionId) -> RoomVersion { RoomVersion::new(room_version_id).expect("room version is supported") }