forked from lavina/lavina
				
			
							parent
							
								
									0944c449ca
								
							
						
					
					
						commit
						57b6af8732
					
				|  | @ -9,6 +9,7 @@ server_name = "irc.localhost" | ||||||
| listen_on = "127.0.0.1:5222" | listen_on = "127.0.0.1:5222" | ||||||
| cert = "./certs/xmpp.pem" | cert = "./certs/xmpp.pem" | ||||||
| key = "./certs/xmpp.key" | key = "./certs/xmpp.key" | ||||||
|  | hostname = "localhost" | ||||||
| 
 | 
 | ||||||
| [storage] | [storage] | ||||||
| db_path = "db.sqlite" | db_path = "db.sqlite" | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ impl<'a> XmppConnection<'a> { | ||||||
|                     r#type: IqType::Result, |                     r#type: IqType::Result, | ||||||
|                     body: BindResponse(Jid { |                     body: BindResponse(Jid { | ||||||
|                         name: Some(self.user.xmpp_name.clone()), |                         name: Some(self.user.xmpp_name.clone()), | ||||||
|                         server: Server("localhost".into()), |                         server: Server(self.hostname.clone()), | ||||||
|                         resource: Some(self.user.xmpp_resource.clone()), |                         resource: Some(self.user.xmpp_resource.clone()), | ||||||
|                     }), |                     }), | ||||||
|                 }; |                 }; | ||||||
|  | @ -52,7 +52,7 @@ impl<'a> XmppConnection<'a> { | ||||||
|                 req.serialize(output); |                 req.serialize(output); | ||||||
|             } |             } | ||||||
|             IqClientBody::DiscoInfo(info) => { |             IqClientBody::DiscoInfo(info) => { | ||||||
|                 let response = disco_info(iq.to.as_deref(), &info); |                 let response = self.disco_info(iq.to.as_deref(), &info); | ||||||
|                 let req = Iq { |                 let req = Iq { | ||||||
|                     from: iq.to, |                     from: iq.to, | ||||||
|                     id: iq.id, |                     id: iq.id, | ||||||
|  | @ -63,7 +63,7 @@ impl<'a> XmppConnection<'a> { | ||||||
|                 req.serialize(output); |                 req.serialize(output); | ||||||
|             } |             } | ||||||
|             IqClientBody::DiscoItem(item) => { |             IqClientBody::DiscoItem(item) => { | ||||||
|                 let response = disco_items(iq.to.as_deref(), &item, self.rooms).await; |                 let response = self.disco_items(iq.to.as_deref(), &item, self.rooms).await; | ||||||
|                 let req = Iq { |                 let req = Iq { | ||||||
|                     from: iq.to, |                     from: iq.to, | ||||||
|                     id: iq.id, |                     id: iq.id, | ||||||
|  | @ -87,13 +87,13 @@ impl<'a> XmppConnection<'a> { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| fn disco_info(to: Option<&str>, req: &InfoQuery) -> InfoQuery { |     fn disco_info(&self, to: Option<&str>, req: &InfoQuery) -> InfoQuery { | ||||||
|         let identity; |         let identity; | ||||||
|         let feature; |         let feature; | ||||||
|  | 
 | ||||||
|         match to { |         match to { | ||||||
|         Some("localhost") => { |             Some(r) if r == &*self.hostname => { | ||||||
|                 identity = vec![Identity { |                 identity = vec![Identity { | ||||||
|                     category: "server".into(), |                     category: "server".into(), | ||||||
|                     name: None, |                     name: None, | ||||||
|  | @ -106,7 +106,7 @@ fn disco_info(to: Option<&str>, req: &InfoQuery) -> InfoQuery { | ||||||
|                     Feature::new("presence"), |                     Feature::new("presence"), | ||||||
|                 ] |                 ] | ||||||
|             } |             } | ||||||
|         Some("rooms.localhost") => { |             Some(r) if r == &*self.hostname_rooms => { | ||||||
|                 identity = vec![Identity { |                 identity = vec![Identity { | ||||||
|                     category: "conference".into(), |                     category: "conference".into(), | ||||||
|                     name: Some("Chat rooms".into()), |                     name: Some("Chat rooms".into()), | ||||||
|  | @ -128,29 +128,29 @@ fn disco_info(to: Option<&str>, req: &InfoQuery) -> InfoQuery { | ||||||
|             identity, |             identity, | ||||||
|             feature, |             feature, | ||||||
|         } |         } | ||||||
| } |     } | ||||||
| 
 | 
 | ||||||
| async fn disco_items(to: Option<&str>, req: &ItemQuery, rooms: &RoomRegistry) -> ItemQuery { |     async fn disco_items(&self, to: Option<&str>, req: &ItemQuery, rooms: &RoomRegistry) -> ItemQuery { | ||||||
|         let item = match to { |         let item = match to { | ||||||
|         Some("localhost") => { |             Some(r) if r == &*self.hostname => { | ||||||
|                 vec![Item { |                 vec![Item { | ||||||
|                     jid: Jid { |                     jid: Jid { | ||||||
|                         name: None, |                         name: None, | ||||||
|                     server: Server("rooms.localhost".into()), |                         server: Server(self.hostname_rooms.clone()), | ||||||
|                         resource: None, |                         resource: None, | ||||||
|                     }, |                     }, | ||||||
|                     name: None, |                     name: None, | ||||||
|                     node: None, |                     node: None, | ||||||
|                 }] |                 }] | ||||||
|             } |             } | ||||||
|         Some("rooms.localhost") => { |             Some(r) if r == &*self.hostname_rooms => { | ||||||
|                 let room_list = rooms.get_all_rooms().await; |                 let room_list = rooms.get_all_rooms().await; | ||||||
|                 room_list |                 room_list | ||||||
|                     .into_iter() |                     .into_iter() | ||||||
|                     .map(|room_info| Item { |                     .map(|room_info| Item { | ||||||
|                         jid: Jid { |                         jid: Jid { | ||||||
|                             name: Some(Name(room_info.id.into_inner())), |                             name: Some(Name(room_info.id.into_inner())), | ||||||
|                         server: Server("rooms.localhost".into()), |                             server: Server(self.hostname_rooms.clone()), | ||||||
|                             resource: None, |                             resource: None, | ||||||
|                         }, |                         }, | ||||||
|                         name: None, |                         name: None, | ||||||
|  | @ -161,4 +161,5 @@ async fn disco_items(to: Option<&str>, req: &ItemQuery, rooms: &RoomRegistry) -> | ||||||
|             _ => vec![], |             _ => vec![], | ||||||
|         }; |         }; | ||||||
|         ItemQuery { item } |         ItemQuery { item } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -9,7 +9,6 @@ use std::net::SocketAddr; | ||||||
| use std::path::PathBuf; | use std::path::PathBuf; | ||||||
| use std::sync::Arc; | use std::sync::Arc; | ||||||
| 
 | 
 | ||||||
| use anyhow::anyhow; |  | ||||||
| use futures_util::future::join_all; | use futures_util::future::join_all; | ||||||
| use prometheus::Registry as MetricsRegistry; | use prometheus::Registry as MetricsRegistry; | ||||||
| use quick_xml::events::{BytesDecl, Event}; | use quick_xml::events::{BytesDecl, Event}; | ||||||
|  | @ -44,6 +43,7 @@ pub struct ServerConfig { | ||||||
|     pub listen_on: SocketAddr, |     pub listen_on: SocketAddr, | ||||||
|     pub cert: PathBuf, |     pub cert: PathBuf, | ||||||
|     pub key: PathBuf, |     pub key: PathBuf, | ||||||
|  |     pub hostname: Str, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct LoadedConfig { | struct LoadedConfig { | ||||||
|  | @ -125,11 +125,12 @@ pub async fn launch( | ||||||
|                             let players = players.clone(); |                             let players = players.clone(); | ||||||
|                             let rooms = rooms.clone(); |                             let rooms = rooms.clone(); | ||||||
|                             let storage = storage.clone(); |                             let storage = storage.clone(); | ||||||
|  |                             let hostname = config.hostname.clone(); | ||||||
|                             let terminator = Terminator::spawn(|termination| { |                             let terminator = Terminator::spawn(|termination| { | ||||||
|                                 let stopped_tx = stopped_tx.clone(); |                                 let stopped_tx = stopped_tx.clone(); | ||||||
|                                 let loaded_config = loaded_config.clone(); |                                 let loaded_config = loaded_config.clone(); | ||||||
|                                 async move { |                                 async move { | ||||||
|                                     match handle_socket(loaded_config, stream, &socket_addr, players, rooms, storage, termination).await { |                                     match handle_socket(loaded_config, stream, &socket_addr, players, rooms, storage, hostname, termination).await { | ||||||
|                                         Ok(_) => log::info!("Connection terminated"), |                                         Ok(_) => log::info!("Connection terminated"), | ||||||
|                                         Err(err) => log::warn!("Connection failed: {err}"), |                                         Err(err) => log::warn!("Connection failed: {err}"), | ||||||
|                                     } |                                     } | ||||||
|  | @ -164,12 +165,13 @@ pub async fn launch( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async fn handle_socket( | async fn handle_socket( | ||||||
|     config: Arc<LoadedConfig>, |     cert_config: Arc<LoadedConfig>, | ||||||
|     mut stream: TcpStream, |     mut stream: TcpStream, | ||||||
|     socket_addr: &SocketAddr, |     socket_addr: &SocketAddr, | ||||||
|     mut players: PlayerRegistry, |     mut players: PlayerRegistry, | ||||||
|     rooms: RoomRegistry, |     rooms: RoomRegistry, | ||||||
|     mut storage: Storage, |     mut storage: Storage, | ||||||
|  |     hostname: Str, | ||||||
|     termination: Deferred<()>, // TODO use it to stop the connection gracefully
 |     termination: Deferred<()>, // TODO use it to stop the connection gracefully
 | ||||||
| ) -> Result<()> { | ) -> Result<()> { | ||||||
|     log::info!("Received an XMPP connection from {socket_addr}"); |     log::info!("Received an XMPP connection from {socket_addr}"); | ||||||
|  | @ -178,12 +180,12 @@ async fn handle_socket( | ||||||
|     let mut buf_reader = BufReader::new(reader); |     let mut buf_reader = BufReader::new(reader); | ||||||
|     let mut buf_writer = BufWriter::new(writer); |     let mut buf_writer = BufWriter::new(writer); | ||||||
| 
 | 
 | ||||||
|     socket_force_tls(&mut buf_reader, &mut buf_writer, &mut reader_buf).await?; |     socket_force_tls(&mut buf_reader, &mut buf_writer, &mut reader_buf, &hostname).await?; | ||||||
| 
 | 
 | ||||||
|     let mut config = tokio_rustls::rustls::ServerConfig::builder() |     let mut config = tokio_rustls::rustls::ServerConfig::builder() | ||||||
|         .with_safe_defaults() |         .with_safe_defaults() | ||||||
|         .with_no_client_auth() |         .with_no_client_auth() | ||||||
|         .with_single_cert(vec![config.cert.clone()], config.key.clone())?; |         .with_single_cert(vec![cert_config.cert.clone()], cert_config.key.clone())?; | ||||||
|     config.key_log = Arc::new(tokio_rustls::rustls::KeyLogFile::new()); |     config.key_log = Arc::new(tokio_rustls::rustls::KeyLogFile::new()); | ||||||
| 
 | 
 | ||||||
|     log::debug!("Accepting TLS connection..."); |     log::debug!("Accepting TLS connection..."); | ||||||
|  | @ -202,7 +204,7 @@ async fn handle_socket( | ||||||
|             log::info!("Socket handling was terminated"); |             log::info!("Socket handling was terminated"); | ||||||
|             return Ok(()) |             return Ok(()) | ||||||
|         }, |         }, | ||||||
|         authenticated = socket_auth(&mut xml_reader, &mut xml_writer, &mut reader_buf, &mut storage) => { |         authenticated = socket_auth(&mut xml_reader, &mut xml_writer, &mut reader_buf, &mut storage, &hostname) => { | ||||||
|             match authenticated { |             match authenticated { | ||||||
|                 Ok(authenticated) => { |                 Ok(authenticated) => { | ||||||
|                     let mut connection = players.connect_to_player(authenticated.player_id.clone()).await; |                     let mut connection = players.connect_to_player(authenticated.player_id.clone()).await; | ||||||
|  | @ -213,6 +215,7 @@ async fn handle_socket( | ||||||
|                         &authenticated, |                         &authenticated, | ||||||
|                         &mut connection, |                         &mut connection, | ||||||
|                         &rooms, |                         &rooms, | ||||||
|  |                         &hostname, | ||||||
|                     ) |                     ) | ||||||
|                     .await?; |                     .await?; | ||||||
|                 }, |                 }, | ||||||
|  | @ -233,16 +236,18 @@ async fn socket_force_tls( | ||||||
|     reader: &mut (impl AsyncBufRead + Unpin), |     reader: &mut (impl AsyncBufRead + Unpin), | ||||||
|     writer: &mut (impl AsyncWrite + Unpin), |     writer: &mut (impl AsyncWrite + Unpin), | ||||||
|     reader_buf: &mut Vec<u8>, |     reader_buf: &mut Vec<u8>, | ||||||
|  |     hostname: &Str, | ||||||
| ) -> Result<()> { | ) -> Result<()> { | ||||||
|     use proto_xmpp::tls::*; |     use proto_xmpp::tls::*; | ||||||
|     let xml_reader = &mut NsReader::from_reader(reader); |     let xml_reader = &mut NsReader::from_reader(reader); | ||||||
|     let xml_writer = &mut Writer::new(writer); |     let xml_writer = &mut Writer::new(writer); | ||||||
|  |     // TODO validate the server hostname received in the stream start
 | ||||||
|     let _ = ClientStreamStart::parse(xml_reader, reader_buf).await?; |     let _ = ClientStreamStart::parse(xml_reader, reader_buf).await?; | ||||||
| 
 | 
 | ||||||
|     let event = Event::Decl(BytesDecl::new("1.0", None, None)); |     let event = Event::Decl(BytesDecl::new("1.0", None, None)); | ||||||
|     xml_writer.write_event_async(event).await?; |     xml_writer.write_event_async(event).await?; | ||||||
|     let msg = ServerStreamStart { |     let msg = ServerStreamStart { | ||||||
|         from: "localhost".into(), |         from: hostname.to_string(), | ||||||
|         lang: "en".into(), |         lang: "en".into(), | ||||||
|         id: uuid::Uuid::new_v4().to_string(), |         id: uuid::Uuid::new_v4().to_string(), | ||||||
|         version: "1.0".into(), |         version: "1.0".into(), | ||||||
|  | @ -267,12 +272,14 @@ async fn socket_auth( | ||||||
|     xml_writer: &mut Writer<(impl AsyncWrite + Unpin)>, |     xml_writer: &mut Writer<(impl AsyncWrite + Unpin)>, | ||||||
|     reader_buf: &mut Vec<u8>, |     reader_buf: &mut Vec<u8>, | ||||||
|     storage: &mut Storage, |     storage: &mut Storage, | ||||||
|  |     hostname: &Str, | ||||||
| ) -> Result<Authenticated> { | ) -> Result<Authenticated> { | ||||||
|  |     // TODO validate the server hostname received in the stream start
 | ||||||
|     let _ = ClientStreamStart::parse(xml_reader, reader_buf).await?; |     let _ = ClientStreamStart::parse(xml_reader, reader_buf).await?; | ||||||
| 
 | 
 | ||||||
|     xml_writer.write_event_async(Event::Decl(BytesDecl::new("1.0", None, None))).await?; |     xml_writer.write_event_async(Event::Decl(BytesDecl::new("1.0", None, None))).await?; | ||||||
|     ServerStreamStart { |     ServerStreamStart { | ||||||
|         from: "localhost".into(), |         from: hostname.to_string(), | ||||||
|         lang: "en".into(), |         lang: "en".into(), | ||||||
|         id: uuid::Uuid::new_v4().to_string(), |         id: uuid::Uuid::new_v4().to_string(), | ||||||
|         version: "1.0".into(), |         version: "1.0".into(), | ||||||
|  | @ -335,12 +342,14 @@ async fn socket_final( | ||||||
|     authenticated: &Authenticated, |     authenticated: &Authenticated, | ||||||
|     user_handle: &mut PlayerConnection, |     user_handle: &mut PlayerConnection, | ||||||
|     rooms: &RoomRegistry, |     rooms: &RoomRegistry, | ||||||
|  |     hostname: &Str, | ||||||
| ) -> Result<()> { | ) -> Result<()> { | ||||||
|  |     // TODO validate the server hostname received in the stream start
 | ||||||
|     let _ = ClientStreamStart::parse(xml_reader, reader_buf).await?; |     let _ = ClientStreamStart::parse(xml_reader, reader_buf).await?; | ||||||
| 
 | 
 | ||||||
|     xml_writer.write_event_async(Event::Decl(BytesDecl::new("1.0", None, None))).await?; |     xml_writer.write_event_async(Event::Decl(BytesDecl::new("1.0", None, None))).await?; | ||||||
|     ServerStreamStart { |     ServerStreamStart { | ||||||
|         from: "localhost".into(), |         from: hostname.to_string(), | ||||||
|         lang: "en".into(), |         lang: "en".into(), | ||||||
|         id: uuid::Uuid::new_v4().to_string(), |         id: uuid::Uuid::new_v4().to_string(), | ||||||
|         version: "1.0".into(), |         version: "1.0".into(), | ||||||
|  | @ -366,6 +375,8 @@ async fn socket_final( | ||||||
|             user: authenticated, |             user: authenticated, | ||||||
|             user_handle, |             user_handle, | ||||||
|             rooms, |             rooms, | ||||||
|  |             hostname: hostname.clone(), | ||||||
|  |             hostname_rooms: format!("rooms.{}", hostname).into(), | ||||||
|         }; |         }; | ||||||
|         let should_recreate_xml_future = select! { |         let should_recreate_xml_future = select! { | ||||||
|             biased; |             biased; | ||||||
|  | @ -422,6 +433,8 @@ struct XmppConnection<'a> { | ||||||
|     user: &'a Authenticated, |     user: &'a Authenticated, | ||||||
|     user_handle: &'a mut PlayerConnection, |     user_handle: &'a mut PlayerConnection, | ||||||
|     rooms: &'a RoomRegistry, |     rooms: &'a RoomRegistry, | ||||||
|  |     hostname: Str, | ||||||
|  |     hostname_rooms: Str, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'a> XmppConnection<'a> { | impl<'a> XmppConnection<'a> { | ||||||
|  |  | ||||||
|  | @ -18,17 +18,17 @@ impl<'a> XmppConnection<'a> { | ||||||
|             resource: _, |             resource: _, | ||||||
|         }) = m.to |         }) = m.to | ||||||
|         { |         { | ||||||
|             if server.0.as_ref() == "rooms.localhost" && m.r#type == MessageType::Groupchat { |             if server.0.as_ref() == &*self.hostname_rooms && m.r#type == MessageType::Groupchat { | ||||||
|                 self.user_handle.send_message(RoomId::from(name.0.clone())?, m.body.clone().into()).await?; |                 self.user_handle.send_message(RoomId::from(name.0.clone())?, m.body.clone().into()).await?; | ||||||
|                 Message::<()> { |                 Message::<()> { | ||||||
|                     to: Some(Jid { |                     to: Some(Jid { | ||||||
|                         name: Some(self.user.xmpp_name.clone()), |                         name: Some(self.user.xmpp_name.clone()), | ||||||
|                         server: Server("localhost".into()), |                         server: Server(self.hostname.clone()), | ||||||
|                         resource: Some(self.user.xmpp_resource.clone()), |                         resource: Some(self.user.xmpp_resource.clone()), | ||||||
|                     }), |                     }), | ||||||
|                     from: Some(Jid { |                     from: Some(Jid { | ||||||
|                         name: Some(name), |                         name: Some(name), | ||||||
|                         server: Server("rooms.localhost".into()), |                         server: Server(self.hostname_rooms.clone()), | ||||||
|                         resource: Some(self.user.xmpp_muc_name.clone()), |                         resource: Some(self.user.xmpp_muc_name.clone()), | ||||||
|                     }), |                     }), | ||||||
|                     id: m.id, |                     id: m.id, | ||||||
|  |  | ||||||
|  | @ -16,12 +16,12 @@ impl<'a> XmppConnection<'a> { | ||||||
|             Presence::<()> { |             Presence::<()> { | ||||||
|                 to: Some(Jid { |                 to: Some(Jid { | ||||||
|                     name: Some(self.user.xmpp_name.clone()), |                     name: Some(self.user.xmpp_name.clone()), | ||||||
|                     server: Server("localhost".into()), |                     server: Server(self.hostname.clone()), | ||||||
|                     resource: Some(self.user.xmpp_resource.clone()), |                     resource: Some(self.user.xmpp_resource.clone()), | ||||||
|                 }), |                 }), | ||||||
|                 from: Some(Jid { |                 from: Some(Jid { | ||||||
|                     name: Some(self.user.xmpp_name.clone()), |                     name: Some(self.user.xmpp_name.clone()), | ||||||
|                     server: Server("localhost".into()), |                     server: Server(self.hostname.clone()), | ||||||
|                     resource: Some(self.user.xmpp_resource.clone()), |                     resource: Some(self.user.xmpp_resource.clone()), | ||||||
|                 }), |                 }), | ||||||
|                 ..Default::default() |                 ..Default::default() | ||||||
|  | @ -36,12 +36,12 @@ impl<'a> XmppConnection<'a> { | ||||||
|             Presence::<()> { |             Presence::<()> { | ||||||
|                 to: Some(Jid { |                 to: Some(Jid { | ||||||
|                     name: Some(self.user.xmpp_name.clone()), |                     name: Some(self.user.xmpp_name.clone()), | ||||||
|                     server: Server("localhost".into()), |                     server: Server(self.hostname.clone()), | ||||||
|                     resource: Some(self.user.xmpp_resource.clone()), |                     resource: Some(self.user.xmpp_resource.clone()), | ||||||
|                 }), |                 }), | ||||||
|                 from: Some(Jid { |                 from: Some(Jid { | ||||||
|                     name: Some(name.clone()), |                     name: Some(name.clone()), | ||||||
|                     server: Server("rooms.localhost".into()), |                     server: Server(self.hostname_rooms.clone()), | ||||||
|                     resource: Some(self.user.xmpp_muc_name.clone()), |                     resource: Some(self.user.xmpp_muc_name.clone()), | ||||||
|                 }), |                 }), | ||||||
|                 ..Default::default() |                 ..Default::default() | ||||||
|  |  | ||||||
|  | @ -21,12 +21,12 @@ impl<'a> XmppConnection<'a> { | ||||||
|                 Message::<()> { |                 Message::<()> { | ||||||
|                     to: Some(Jid { |                     to: Some(Jid { | ||||||
|                         name: Some(self.user.xmpp_name.clone()), |                         name: Some(self.user.xmpp_name.clone()), | ||||||
|                         server: Server("localhost".into()), |                         server: Server(self.hostname.clone()), | ||||||
|                         resource: Some(self.user.xmpp_resource.clone()), |                         resource: Some(self.user.xmpp_resource.clone()), | ||||||
|                     }), |                     }), | ||||||
|                     from: Some(Jid { |                     from: Some(Jid { | ||||||
|                         name: Some(Name(room_id.into_inner().into())), |                         name: Some(Name(room_id.into_inner().into())), | ||||||
|                         server: Server("rooms.localhost".into()), |                         server: Server(self.hostname_rooms.clone()), | ||||||
|                         resource: Some(Resource(author_id.into_inner().into())), |                         resource: Some(Resource(author_id.into_inner().into())), | ||||||
|                     }), |                     }), | ||||||
|                     id: None, |                     id: None, | ||||||
|  |  | ||||||
|  | @ -135,6 +135,7 @@ impl TestServer { | ||||||
|             listen_on: "127.0.0.1:0".parse().unwrap(), |             listen_on: "127.0.0.1:0".parse().unwrap(), | ||||||
|             cert: "tests/certs/xmpp.pem".parse().unwrap(), |             cert: "tests/certs/xmpp.pem".parse().unwrap(), | ||||||
|             key: "tests/certs/xmpp.key".parse().unwrap(), |             key: "tests/certs/xmpp.key".parse().unwrap(), | ||||||
|  |             hostname: "localhost".into(), | ||||||
|         }; |         }; | ||||||
|         let mut metrics = MetricsRegistry::new(); |         let mut metrics = MetricsRegistry::new(); | ||||||
|         let mut storage = Storage::open(StorageConfig { |         let mut storage = Storage::open(StorageConfig { | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ server_name = "irc.localhost" | ||||||
| listen_on = "127.0.0.1:5222" | listen_on = "127.0.0.1:5222" | ||||||
| cert = "./certs/xmpp.pem" | cert = "./certs/xmpp.pem" | ||||||
| key = "./certs/xmpp.key" | key = "./certs/xmpp.key" | ||||||
|  | hostname = "localhost" | ||||||
| 
 | 
 | ||||||
| [storage] | [storage] | ||||||
| db_path = "db.sqlite" | db_path = "db.sqlite" | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue