aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs75
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(());
}