diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 75 |
1 files changed, 57 insertions, 18 deletions
diff --git a/src/main.rs b/src/main.rs index 220c4c9..16006cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,15 +12,18 @@ use azalea_protocol::{ }; use bytes::BytesMut; use config::Config; +use inotify::{EventMask, Inotify, WatchMask}; use log::{error, info, warn}; -use std::{fs::read_to_string, sync::Arc}; +use std::{ + fs::read_to_string, + sync::{Arc, RwLock}, +}; use tokio::{ io::{AsyncReadExt, AsyncWriteExt}, net::{ tcp::{OwnedReadHalf, OwnedWriteHalf}, TcpListener, TcpStream, }, - sync::RwLock, }; #[tokio::main] @@ -30,17 +33,49 @@ async fn main() { .parse_env("LOG") .init(); - let config = RwLock::new(Arc::new( + let config = Arc::new(RwLock::new(Arc::new( serde_yaml::from_str::<Config>(&read_to_string("proxy.yaml").unwrap()).unwrap(), - )); + ))); + + { + let config = config.clone(); + std::thread::spawn(move || { + let mut inotify = Inotify::init().unwrap(); + inotify + .add_watch( + ".", + WatchMask::MODIFY | WatchMask::CREATE | WatchMask::DELETE, + ) + .unwrap(); + let mut buffer = [0u8; 4096]; + loop { + let events = inotify + .read_events_blocking(&mut buffer) + .expect("Failed to read inotify events"); - let listener = TcpListener::bind(config.read().await.bind).await.unwrap(); + for event in events { + if event.mask.contains(EventMask::MODIFY) { + info!("reloading config"); + match serde_yaml::from_str::<Config>(&read_to_string("proxy.yaml").unwrap()) + { + Ok(conf) => *config.write().unwrap() = Arc::new(conf), + Err(e) => error!("config has errors: {e}"), + } + } + } + } + }); + } + + let listener = TcpListener::bind(config.read().unwrap().bind) + .await + .unwrap(); info!("listening"); loop { match listener.accept().await { Ok((sock, addr)) => { info!("connected: {addr}"); - let config = config.read().await.clone(); + let config = config.read().unwrap().clone(); tokio::spawn(async move { match handle_client(config, sock).await { Ok(()) => info!("disconnected: {addr}"), @@ -72,7 +107,7 @@ async fn handle_client(config: Arc<Config>, sock: TcpStream) -> Result<(), anyho "new client (version={}, intent={:?})", p.protocol_version, p.intention ); - if p.protocol_version == config.protocol { + if p.protocol_version != config.protocol { bail!("protocol version unsupported") } match p.intention { @@ -101,7 +136,7 @@ async fn handle_client(config: Arc<Config>, sock: TcpStream) -> Result<(), anyho match profile { Some(profile) => { - info!("auth as {}", profile.username); + info!("login as {:?}", profile.username); p.username = profile.username.clone(); } None => bail!("no profile found, disconnecting client"), @@ -131,11 +166,13 @@ async fn handle_client(config: Arc<Config>, sock: TcpStream) -> Result<(), anyho ) .await?; - tokio::spawn(async move { - connect(downstream_writer, upstream_reader).await.unwrap(); - }); - - connect(upstream_writer, downstream_reader).await?; + let task_res = tokio::spawn(async move { connect(downstream_writer, upstream_reader).await }); + let res = connect(upstream_writer, downstream_reader).await; + task_res.abort(); + res?; + if let Ok(r) = task_res.await { + r?; + } Ok(()) } @@ -174,11 +211,13 @@ async fn handle_status_intent( ) .await?; - tokio::spawn(async move { - connect(writer, upstream_reader).await.unwrap(); - }); - - connect(upstream_writer, reader).await?; + let task_res = tokio::spawn(async move { connect(writer, upstream_reader).await }); + let res = connect(upstream_writer, reader).await; + task_res.abort(); + res?; + if let Ok(r) = task_res.await { + r?; + } return Ok(()); } |