From dcfb83fb2069bfcf4642b03453253e35479bf3da Mon Sep 17 00:00:00 2001 From: fx Date: Tue, 24 Oct 2023 01:15:22 +0200 Subject: first ping impl baseline, doesnt work --- Cargo.lock | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +- src/auth.rs | 21 +++++---- src/error.rs | 37 +++++++++++++--- src/main.rs | 19 ++++++++- src/routes/device.rs | 8 ++-- src/routes/start.rs | 21 +++++---- src/services/mod.rs | 1 + src/services/ping.rs | 53 +++++++++++++++++++++++ src/wol.rs | 17 ++++---- 10 files changed, 260 insertions(+), 37 deletions(-) create mode 100644 src/services/mod.rs create mode 100644 src/services/ping.rs diff --git a/Cargo.lock b/Cargo.lock index 09f5744..bf813bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -89,6 +89,7 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", + "base64 0.21.4", "bitflags 1.3.2", "bytes", "futures-util", @@ -107,8 +108,10 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", + "sha1", "sync_wrapper", "tokio", + "tokio-tungstenite", "tower", "tower-layer", "tower-service", @@ -293,6 +296,12 @@ dependencies = [ "typenum", ] +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + [[package]] name = "der" version = "0.7.8" @@ -516,6 +525,12 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "hashbrown" version = "0.12.3" @@ -842,6 +857,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + [[package]] name = "nom" version = "7.1.3" @@ -1114,6 +1135,48 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "pnet_base" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872e46346144ebf35219ccaa64b1dffacd9c6f188cd7d012bd6977a2a838f42e" +dependencies = [ + "no-std-net", +] + +[[package]] +name = "pnet_macros" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a780e80005c2e463ec25a6e9f928630049a10b43945fea83207207d4a7606f4" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", +] + +[[package]] +name = "pnet_macros_support" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d932134f32efd7834eb8b16d42418dac87086347d1bc7d142370ef078582bc" +dependencies = [ + "pnet_base", +] + +[[package]] +name = "pnet_packet" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bde678bbd85cb1c2d99dc9fc596e57f03aa725f84f3168b0eaf33eeccb41706" +dependencies = [ + "glob", + "pnet_base", + "pnet_macros", + "pnet_macros_support", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -1693,6 +1756,22 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +[[package]] +name = "surge-ping" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af341b2be485d647b5dc4cfb2da99efac35b5c95748a08fb7233480fedc5ead3" +dependencies = [ + "hex", + "parking_lot", + "pnet_packet", + "rand", + "socket2 0.5.5", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "syn" version = "1.0.109" @@ -1849,6 +1928,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + [[package]] name = "toml" version = "0.5.11" @@ -1955,6 +2046,25 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "typenum" version = "1.17.0" @@ -2011,6 +2121,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "valuable" version = "0.1.0" @@ -2054,6 +2170,7 @@ dependencies = [ "serde", "serde_json", "sqlx", + "surge-ping", "time", "tokio", "tracing", diff --git a/Cargo.toml b/Cargo.toml index e772810..9bdc4da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axum = { version = "0.6.20", features = ["headers"] } +axum = { version = "0.6.20", features = ["headers", "ws"] } tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] } tracing = "0.1.37" tracing-subscriber = { version = "0.3.17", features = ["env-filter", "local-time", "time"] } @@ -16,3 +16,4 @@ serde_json = "1.0.107" config = "0.13.3" once_cell = "1.18.0" sqlx = { version = "0.7.1", features = ["postgres", "runtime-tokio"]} +surge-ping = "0.8.0" diff --git a/src/auth.rs b/src/auth.rs index 0fffa60..e4b1c2f 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,8 +1,8 @@ -use std::error::Error; use axum::headers::HeaderValue; use axum::http::StatusCode; +use axum::http::header::ToStrError; use tracing::{debug, error, trace}; -use crate::auth::AuthError::{MissingSecret, ServerError, WrongSecret}; +use crate::auth::AuthError::{MissingSecret, WrongSecret}; use crate::config::SETTINGS; pub fn auth(secret: Option<&HeaderValue>) -> Result { @@ -11,8 +11,8 @@ pub fn auth(secret: Option<&HeaderValue>) -> Result { trace!("value exists"); let key = SETTINGS .get_string("apikey") - .map_err(|err| ServerError(Box::new(err)))?; - if value.to_str().map_err(|err| ServerError(Box::new(err)))? == key.as_str() { + .map_err(AuthError::Config)?; + if value.to_str().map_err(AuthError::HeaderToStr)? == key.as_str() { debug!("successful auth"); Ok(true) } else { @@ -29,15 +29,20 @@ pub fn auth(secret: Option<&HeaderValue>) -> Result { pub enum AuthError { WrongSecret, MissingSecret, - ServerError(Box), + Config(config::ConfigError), + HeaderToStr(ToStrError) } impl AuthError { pub fn get(self) -> (StatusCode, &'static str) { match self { - AuthError::WrongSecret => (StatusCode::UNAUTHORIZED, "Wrong credentials"), - AuthError::MissingSecret => (StatusCode::BAD_REQUEST, "Missing credentials"), - AuthError::ServerError(err) => { + Self::WrongSecret => (StatusCode::UNAUTHORIZED, "Wrong credentials"), + Self::MissingSecret => (StatusCode::BAD_REQUEST, "Missing credentials"), + Self::Config(err) => { + error!("server error: {}", err.to_string()); + (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") + }, + Self::HeaderToStr(err) => { error!("server error: {}", err.to_string()); (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") }, diff --git a/src/error.rs b/src/error.rs index db2fc86..f143ee9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,5 @@ use std::error::Error; +use std::io; use axum::http::StatusCode; use axum::Json; use axum::response::{IntoResponse, Response}; @@ -8,21 +9,45 @@ use crate::auth::AuthError; #[derive(Debug)] pub enum WebolError { - Auth(AuthError), Generic, - Server(Box), + Auth(AuthError), + Ping(surge_ping::SurgeError), + DB(sqlx::Error), + IpParse(::Err), + BufferParse(std::num::ParseIntError), + Broadcast(io::Error), + Axum(axum::Error) } impl IntoResponse for WebolError { fn into_response(self) -> Response { let (status, error_message) = match self { - WebolError::Auth(err) => err.get(), - WebolError::Generic => (StatusCode::INTERNAL_SERVER_ERROR, ""), - WebolError::Server(err) => { + Self::Auth(err) => err.get(), + Self::Generic => (StatusCode::INTERNAL_SERVER_ERROR, ""), + Self::Ping(err) => { + error!("Ping: {}", err.source().unwrap()); + (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") + }, + Self::IpParse(err) => { + error!("server error: {}", err.to_string()); + (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") + }, + Self::DB(err) => { + error!("server error: {}", err.to_string()); + (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") + }, + Self::Broadcast(err) => { + error!("server error: {}", err.to_string()); + (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") + }, + Self::BufferParse(err) => { + error!("server error: {}", err.to_string()); + (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") + }, + Self::Axum(err) => { error!("server error: {}", err.to_string()); (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") }, - }; let body = Json(json!({ "error": error_message, diff --git a/src/main.rs b/src/main.rs index ce12cf6..9c31ec8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,12 +4,14 @@ use axum::{Router, routing::post}; use axum::routing::{get, put}; use sqlx::PgPool; use time::util::local_offset; +use tokio::sync::mpsc::{self, Sender}; use tracing::{info, level_filters::LevelFilter}; use tracing_subscriber::{EnvFilter, fmt::{self, time::LocalTime}, prelude::*}; use crate::config::SETTINGS; use crate::db::init_db_pool; use crate::routes::device::{get_device, post_device, put_device}; use crate::routes::start::start; +use crate::services::ping::ws_ping; mod auth; mod config; @@ -17,6 +19,7 @@ mod routes; mod wol; mod db; mod error; +mod services; #[tokio::main] async fn main() { @@ -43,13 +46,23 @@ async fn main() { let db = init_db_pool().await; sqlx::migrate!().run(&db).await.unwrap(); - let shared_state = Arc::new(AppState { db }); + let (tx, mut rx) = mpsc::channel(32); + + // FIXME: once_cell? or just static mutable + tokio::spawn( async move { + while let Some(message) = rx.recv().await { + println!("GOT = {}", message); + } + }); + + let shared_state = Arc::new(AppState { db, ping_send: tx }); let app = Router::new() .route("/start", post(start)) .route("/device", get(get_device)) .route("/device", put(put_device)) .route("/device", post(post_device)) + .route("/status", get(ws_ping)) .with_state(shared_state); let addr = SETTINGS.get_string("serveraddr").unwrap_or("0.0.0.0:7229".to_string()); @@ -61,5 +74,7 @@ async fn main() { } pub struct AppState { - db: PgPool + db: PgPool, + ping_send: Sender, + // ping_receive: Receiver } diff --git a/src/routes/device.rs b/src/routes/device.rs index 025c7d0..248d1e0 100644 --- a/src/routes/device.rs +++ b/src/routes/device.rs @@ -21,7 +21,7 @@ pub async fn get_device(State(state): State>, headers: Head WHERE id = $1; "#, payload.id - ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; + ).fetch_one(&state.db).await.map_err(WebolError::DB)?; Ok(Json(json!(device))) } else { @@ -46,7 +46,7 @@ pub async fn put_device(State(state): State>, headers: Head payload.id, payload.mac, payload.broadcast_addr - ).execute(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; + ).execute(&state.db).await.map_err(WebolError::DB)?; Ok(Json(json!(PutDeviceResponse { success: true }))) } else { @@ -80,7 +80,7 @@ pub async fn post_device(State(state): State>, headers: Hea payload.mac, payload.broadcast_addr, payload.id - ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; + ).fetch_one(&state.db).await.map_err(WebolError::DB)?; Ok(Json(json!(device))) } else { @@ -93,4 +93,4 @@ pub struct PostDevicePayload { id: String, mac: String, broadcast_addr: String, -} \ No newline at end of file +} diff --git a/src/routes/start.rs b/src/routes/start.rs index 163d58c..b45fe5b 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -14,7 +14,8 @@ use crate::error::WebolError; pub async fn start(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, WebolError> { info!("POST request"); let secret = headers.get("authorization"); - if auth(secret).map_err(WebolError::Auth)? { + let authorized = auth(secret).map_err(WebolError::Auth)?; + if authorized { let device = sqlx::query_as!( Device, r#" @@ -23,7 +24,7 @@ pub async fn start(State(state): State>, headers: HeaderMap WHERE id = $1; "#, payload.id - ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; + ).fetch_one(&state.db).await.map_err(WebolError::DB)?; info!("starting {}", device.id); @@ -32,10 +33,14 @@ pub async fn start(State(state): State>, headers: HeaderMap .unwrap_or("0.0.0.0:1111".to_string()); let _ = send_packet( - &bind_addr.parse().map_err(|err| WebolError::Server(Box::new(err)))?, - &device.broadcast_addr.parse().map_err(|err| WebolError::Server(Box::new(err)))?, - create_buffer(&device.mac).map_err(|err| WebolError::Server(Box::new(err)))? - ).map_err(|err| WebolError::Server(Box::new(err))); + &bind_addr.parse().map_err(WebolError::IpParse)?, + &device.broadcast_addr.parse().map_err(WebolError::IpParse)?, + create_buffer(&device.mac)? + )?; + + if payload.ping.is_some_and(|ping| ping) { + tokio::spawn(async move {crate::services::ping::spawn(state.ping_send.clone()).await}); + } Ok(Json(json!(StartResponse { id: device.id, boot: true }))) } else { Err(WebolError::Generic) @@ -45,11 +50,11 @@ pub async fn start(State(state): State>, headers: HeaderMap #[derive(Deserialize)] pub struct StartPayload { id: String, - _test: Option, + ping: Option, } #[derive(Serialize)] struct StartResponse { id: String, boot: bool, -} \ No newline at end of file +} diff --git a/src/services/mod.rs b/src/services/mod.rs new file mode 100644 index 0000000..a766209 --- /dev/null +++ b/src/services/mod.rs @@ -0,0 +1 @@ +pub mod ping; diff --git a/src/services/ping.rs b/src/services/ping.rs new file mode 100644 index 0000000..6e710ec --- /dev/null +++ b/src/services/ping.rs @@ -0,0 +1,53 @@ +use std::sync::Arc; + +use axum::{extract::{WebSocketUpgrade, ws::WebSocket, State}, response::Response}; +use tokio::sync::mpsc::Sender; +use tracing::{debug, error}; + +use crate::{error::WebolError, AppState}; + +pub async fn spawn(tx: Sender) -> Result<(), WebolError> { + let payload = [0; 8]; + + let mut cont = true; + while cont { + let ping = surge_ping::ping( + "192.168.178.28".parse().map_err(WebolError::IpParse)?, + &payload + ).await; + + if let Err(ping) = ping { + cont = matches!(ping, surge_ping::SurgeError::Timeout { .. }); + + debug!("{}", cont); + + if !cont { + return Err(ping).map_err(WebolError::Ping) + } + + } else { + let (_, duration) = ping.unwrap(); + debug!("Ping took {:?}", duration); + cont = false; + // FIXME: remove unwrap + tx.send("Got ping".to_string()).await.unwrap(); + }; + } + + Ok(()) +} + +pub async fn ws_ping(ws: WebSocketUpgrade, State(_state): State>) -> Response { + ws.on_upgrade(handle_socket) +} + +// FIXME: Handle commands through enum +async fn handle_socket(mut socket: WebSocket) { + // TODO: Understand Cow + + // match socket.send(axum::extract::ws::Message::Close(Some(CloseFrame { code: 4000, reason: Cow::Owned("started".to_owned()) }))).await.map_err(WebolError::Axum) { + match socket.send(axum::extract::ws::Message::Text("started".to_string())).await.map_err(WebolError::Axum) { + Ok(..) => (), + Err(err) => { error!("Server Error: {:?}", err) } + }; +} diff --git a/src/wol.rs b/src/wol.rs index 80b66cd..0cdcae3 100644 --- a/src/wol.rs +++ b/src/wol.rs @@ -1,16 +1,17 @@ use std::net::{SocketAddr, UdpSocket}; -use std::num::ParseIntError; + +use crate::error::WebolError; /// Creates the magic packet from a mac address /// /// # Panics /// /// Panics if `mac_addr` is an invalid mac -pub fn create_buffer(mac_addr: &str) -> Result, ParseIntError> { +pub fn create_buffer(mac_addr: &str) -> Result, WebolError> { let mut mac = Vec::new(); let sp = mac_addr.split(':'); for f in sp { - mac.push(u8::from_str_radix(f, 16)?); + mac.push(u8::from_str_radix(f, 16).map_err(WebolError::BufferParse)?) }; let mut buf = vec![255; 6]; for _ in 0..16 { @@ -22,8 +23,8 @@ pub fn create_buffer(mac_addr: &str) -> Result, ParseIntError> { } /// Sends a buffer on UDP broadcast -pub fn send_packet(bind_addr: &SocketAddr, broadcast_addr: &SocketAddr, buffer: Vec) -> Result { - let socket = UdpSocket::bind(bind_addr)?; - socket.set_broadcast(true)?; - socket.send_to(&buffer, broadcast_addr) -} \ No newline at end of file +pub fn send_packet(bind_addr: &SocketAddr, broadcast_addr: &SocketAddr, buffer: Vec) -> Result { + let socket = UdpSocket::bind(bind_addr).map_err(WebolError::Broadcast)?; + socket.set_broadcast(true).map_err(WebolError::Broadcast)?; + socket.send_to(&buffer, broadcast_addr).map_err(WebolError::Broadcast) +} -- cgit v1.2.3 From f9224ff02e688dec819ab81893320a0611f2a198 Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Tue, 24 Oct 2023 14:56:17 +0200 Subject: Seems to work --- src/main.rs | 12 ++---------- src/routes/start.rs | 10 +++++++--- src/services/ping.rs | 28 +++++++++++++++++----------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9c31ec8..124c44e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use axum::{Router, routing::post}; use axum::routing::{get, put}; use sqlx::PgPool; use time::util::local_offset; -use tokio::sync::mpsc::{self, Sender}; +use tokio::sync::broadcast::{channel, Sender}; use tracing::{info, level_filters::LevelFilter}; use tracing_subscriber::{EnvFilter, fmt::{self, time::LocalTime}, prelude::*}; use crate::config::SETTINGS; @@ -46,15 +46,8 @@ async fn main() { let db = init_db_pool().await; sqlx::migrate!().run(&db).await.unwrap(); - let (tx, mut rx) = mpsc::channel(32); + let (tx, _) = channel(32); - // FIXME: once_cell? or just static mutable - tokio::spawn( async move { - while let Some(message) = rx.recv().await { - println!("GOT = {}", message); - } - }); - let shared_state = Arc::new(AppState { db, ping_send: tx }); let app = Router::new() @@ -76,5 +69,4 @@ async fn main() { pub struct AppState { db: PgPool, ping_send: Sender, - // ping_receive: Receiver } diff --git a/src/routes/start.rs b/src/routes/start.rs index b45fe5b..863ef16 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use std::sync::Arc; use axum::extract::State; use serde_json::{json, Value}; -use tracing::info; +use tracing::{debug, info}; use crate::auth::auth; use crate::config::SETTINGS; use crate::wol::{create_buffer, send_packet}; @@ -39,8 +39,12 @@ pub async fn start(State(state): State>, headers: HeaderMap )?; if payload.ping.is_some_and(|ping| ping) { - tokio::spawn(async move {crate::services::ping::spawn(state.ping_send.clone()).await}); - } + debug!("ping true"); + tokio::spawn(async move { + debug!("Init ping service"); + crate::services::ping::spawn(state.ping_send.clone()).await + }); + }; Ok(Json(json!(StartResponse { id: device.id, boot: true }))) } else { Err(WebolError::Generic) diff --git a/src/services/ping.rs b/src/services/ping.rs index 6e710ec..ff328a5 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -1,8 +1,9 @@ +use std::borrow::Cow; use std::sync::Arc; use axum::{extract::{WebSocketUpgrade, ws::WebSocket, State}, response::Response}; -use tokio::sync::mpsc::Sender; -use tracing::{debug, error}; +use tokio::sync::broadcast::{Sender}; +use tracing::{debug, error, trace}; use crate::{error::WebolError, AppState}; @@ -12,7 +13,7 @@ pub async fn spawn(tx: Sender) -> Result<(), WebolError> { let mut cont = true; while cont { let ping = surge_ping::ping( - "192.168.178.28".parse().map_err(WebolError::IpParse)?, + "127.0.0.1".parse().map_err(WebolError::IpParse)?, &payload ).await; @@ -30,24 +31,29 @@ pub async fn spawn(tx: Sender) -> Result<(), WebolError> { debug!("Ping took {:?}", duration); cont = false; // FIXME: remove unwrap - tx.send("Got ping".to_string()).await.unwrap(); + tx.send("Got ping".to_string()).unwrap(); }; } Ok(()) } -pub async fn ws_ping(ws: WebSocketUpgrade, State(_state): State>) -> Response { - ws.on_upgrade(handle_socket) +// TODO: Status to routes, websocket here +pub async fn ws_ping(State(state): State>, ws: WebSocketUpgrade) -> Response { + ws.on_upgrade(move |socket| handle_socket(socket, state.ping_send.clone())) } // FIXME: Handle commands through enum -async fn handle_socket(mut socket: WebSocket) { +async fn handle_socket(mut socket: WebSocket, tx: Sender) { // TODO: Understand Cow - - // match socket.send(axum::extract::ws::Message::Close(Some(CloseFrame { code: 4000, reason: Cow::Owned("started".to_owned()) }))).await.map_err(WebolError::Axum) { - match socket.send(axum::extract::ws::Message::Text("started".to_string())).await.map_err(WebolError::Axum) { + while let message = tx.subscribe().recv().await.unwrap() { + trace!("GOT = {}", message); + if &message == "Got ping" { + break; + } + }; + match socket.send(axum::extract::ws::Message::Close(Some(axum::extract::ws::CloseFrame { code: 4000, reason: Cow::Owned("started".to_owned()) }))).await.map_err(WebolError::Axum) { Ok(..) => (), Err(err) => { error!("Server Error: {:?}", err) } }; -} +} \ No newline at end of file -- cgit v1.2.3 From 00dd8a9abee6b9f0cfc37c6f20f30f0d99dfe91a Mon Sep 17 00:00:00 2001 From: fx Date: Wed, 25 Oct 2023 12:53:31 +0200 Subject: runs, no error handling --- Cargo.lock | 24 ++++++++++++++++ Cargo.toml | 2 ++ src/main.rs | 13 ++++++--- src/routes/mod.rs | 3 +- src/routes/start.rs | 24 +++++++++++----- src/routes/status.rs | 12 ++++++++ src/services/ping.rs | 79 +++++++++++++++++++++++++++++++++++++--------------- 7 files changed, 122 insertions(+), 35 deletions(-) create mode 100644 src/routes/status.rs diff --git a/Cargo.lock b/Cargo.lock index bf813bf..2650edc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,6 +134,18 @@ dependencies = [ "tower-service", ] +[[package]] +name = "axum-macros" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "backtrace" version = "0.3.69" @@ -2127,6 +2139,16 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "uuid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +dependencies = [ + "getrandom", + "rand", +] + [[package]] name = "valuable" version = "0.1.0" @@ -2165,6 +2187,7 @@ name = "webol" version = "0.1.0" dependencies = [ "axum", + "axum-macros", "config", "once_cell", "serde", @@ -2175,6 +2198,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", + "uuid", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 9bdc4da..d29a1b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,5 @@ config = "0.13.3" once_cell = "1.18.0" sqlx = { version = "0.7.1", features = ["postgres", "runtime-tokio"]} surge-ping = "0.8.0" +axum-macros = "0.3.8" +uuid = { version = "1.5.0", features = ["v4", "fast-rng"] } diff --git a/src/main.rs b/src/main.rs index 124c44e..854b59d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::env; use std::sync::Arc; use axum::{Router, routing::post}; @@ -5,13 +6,14 @@ use axum::routing::{get, put}; use sqlx::PgPool; use time::util::local_offset; use tokio::sync::broadcast::{channel, Sender}; +use tokio::sync::Mutex; use tracing::{info, level_filters::LevelFilter}; use tracing_subscriber::{EnvFilter, fmt::{self, time::LocalTime}, prelude::*}; use crate::config::SETTINGS; use crate::db::init_db_pool; use crate::routes::device::{get_device, post_device, put_device}; use crate::routes::start::start; -use crate::services::ping::ws_ping; +use crate::routes::status::status; mod auth; mod config; @@ -47,15 +49,17 @@ async fn main() { sqlx::migrate!().run(&db).await.unwrap(); let (tx, _) = channel(32); + + let ping_map: HashMap = HashMap::new(); - let shared_state = Arc::new(AppState { db, ping_send: tx }); + let shared_state = Arc::new(AppState { db, ping_send: tx, ping_map: Arc::new(Mutex::new(ping_map)) }); let app = Router::new() .route("/start", post(start)) .route("/device", get(get_device)) .route("/device", put(put_device)) .route("/device", post(post_device)) - .route("/status", get(ws_ping)) + .route("/status", get(status)) .with_state(shared_state); let addr = SETTINGS.get_string("serveraddr").unwrap_or("0.0.0.0:7229".to_string()); @@ -69,4 +73,5 @@ async fn main() { pub struct AppState { db: PgPool, ping_send: Sender, -} + ping_map: Arc>>, +} \ No newline at end of file diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 12fbfab..d5ab0d6 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1,2 +1,3 @@ pub mod start; -pub mod device; \ No newline at end of file +pub mod device; +pub mod status; \ No newline at end of file diff --git a/src/routes/start.rs b/src/routes/start.rs index 863ef16..45e7ec8 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -4,15 +4,18 @@ use serde::{Deserialize, Serialize}; use std::sync::Arc; use axum::extract::State; use serde_json::{json, Value}; -use tracing::{debug, info}; +use tracing::{debug, info, warn}; +use uuid::Uuid; use crate::auth::auth; use crate::config::SETTINGS; use crate::wol::{create_buffer, send_packet}; use crate::db::Device; use crate::error::WebolError; +#[axum_macros::debug_handler] pub async fn start(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, WebolError> { info!("POST request"); + warn!("{:?}", state.ping_map); let secret = headers.get("authorization"); let authorized = auth(secret).map_err(WebolError::Auth)?; if authorized { @@ -38,14 +41,20 @@ pub async fn start(State(state): State>, headers: HeaderMap create_buffer(&device.mac)? )?; - if payload.ping.is_some_and(|ping| ping) { - debug!("ping true"); - tokio::spawn(async move { + let uuid = if payload.ping.is_some_and(|ping| ping) { + let uuid_gen = Uuid::new_v4().to_string(); + let uuid_genc = uuid_gen.clone(); + tokio::spawn(async move{ debug!("Init ping service"); - crate::services::ping::spawn(state.ping_send.clone()).await + state.ping_map.lock().await.insert(uuid_gen, ("192.168.178.94".to_string(), false)); + + warn!("{:?}", state.ping_map); + + crate::services::ping::spawn(state.ping_send.clone(), "192.168.178.94".to_string()).await; }); - }; - Ok(Json(json!(StartResponse { id: device.id, boot: true }))) + Some(uuid_genc) + } else { None }; + Ok(Json(json!(StartResponse { id: device.id, boot: true, uuid }))) } else { Err(WebolError::Generic) } @@ -61,4 +70,5 @@ pub struct StartPayload { struct StartResponse { id: String, boot: bool, + uuid: Option, } diff --git a/src/routes/status.rs b/src/routes/status.rs new file mode 100644 index 0000000..cdecf6a --- /dev/null +++ b/src/routes/status.rs @@ -0,0 +1,12 @@ +use std::sync::Arc; +use axum::extract::{State, WebSocketUpgrade}; +use axum::response::Response; +use serde::Deserialize; +use crate::AppState; +use crate::services::ping::status_websocket; + +#[axum_macros::debug_handler] +pub async fn status(State(state): State>, ws: WebSocketUpgrade) -> Response { + // TODO: remove unwrap + ws.on_upgrade(move |socket| status_websocket(socket, state.ping_send.clone(), state.ping_map.clone())) +} \ No newline at end of file diff --git a/src/services/ping.rs b/src/services/ping.rs index ff328a5..e3d465d 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -1,26 +1,29 @@ use std::borrow::Cow; +use std::collections::HashMap; use std::sync::Arc; -use axum::{extract::{WebSocketUpgrade, ws::WebSocket, State}, response::Response}; +use axum::extract::{ws::WebSocket}; +use axum::extract::ws::Message; use tokio::sync::broadcast::{Sender}; -use tracing::{debug, error, trace}; +use tokio::sync::Mutex; +use tracing::{debug, error, trace, warn}; -use crate::{error::WebolError, AppState}; +use crate::error::WebolError; -pub async fn spawn(tx: Sender) -> Result<(), WebolError> { +pub async fn spawn(tx: Sender, ip: String) -> Result<(), WebolError> { let payload = [0; 8]; let mut cont = true; while cont { let ping = surge_ping::ping( - "127.0.0.1".parse().map_err(WebolError::IpParse)?, + ip.parse().map_err(WebolError::IpParse)?, &payload ).await; if let Err(ping) = ping { cont = matches!(ping, surge_ping::SurgeError::Timeout { .. }); - debug!("{}", cont); + // debug!("{}", cont); if !cont { return Err(ping).map_err(WebolError::Ping) @@ -31,29 +34,59 @@ pub async fn spawn(tx: Sender) -> Result<(), WebolError> { debug!("Ping took {:?}", duration); cont = false; // FIXME: remove unwrap - tx.send("Got ping".to_string()).unwrap(); + // FIXME: if error: SendError because no listener, then handle the entry directly + tx.send(ip.clone()); }; } Ok(()) } -// TODO: Status to routes, websocket here -pub async fn ws_ping(State(state): State>, ws: WebSocketUpgrade) -> Response { - ws.on_upgrade(move |socket| handle_socket(socket, state.ping_send.clone())) -} - // FIXME: Handle commands through enum -async fn handle_socket(mut socket: WebSocket, tx: Sender) { - // TODO: Understand Cow - while let message = tx.subscribe().recv().await.unwrap() { - trace!("GOT = {}", message); - if &message == "Got ping" { - break; +pub async fn status_websocket(mut socket: WebSocket, tx: Sender, ping_map: Arc>>) { + warn!("{:?}", ping_map); + + let mut uuid: Option = None; + + trace!("wait for ws message (uuid)"); + let msg = socket.recv().await; + uuid = Some(msg.unwrap().unwrap().into_text().unwrap()); + + let uuid = uuid.unwrap(); + + trace!("Search for uuid: {:?}", uuid); + + let device = ping_map.lock().await.get(&uuid).unwrap().to_owned(); + + trace!("got device: {:?}", device); + + match device.1 { + true => { + debug!("already started"); + socket.send(Message::Text(format!("start_{}", uuid))).await.unwrap(); + socket.close().await.unwrap(); + }, + false => { + let ip = device.0.to_owned(); + let mut i = 0; + loop{ + trace!("{}", i); + // TODO: Check if older than 10 minutes, close if true + trace!("wait for tx message"); + let message = tx.subscribe().recv().await.unwrap(); + trace!("GOT = {}", message); + if message == ip { + trace!("message == ip"); + break; + } + i += 1; + }; + + socket.send(Message::Text(format!("start_{}", uuid))).await.unwrap(); + socket.close().await.unwrap(); + tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; + ping_map.lock().await.remove(&uuid); + warn!("{:?}", ping_map); } - }; - match socket.send(axum::extract::ws::Message::Close(Some(axum::extract::ws::CloseFrame { code: 4000, reason: Cow::Owned("started".to_owned()) }))).await.map_err(WebolError::Axum) { - Ok(..) => (), - Err(err) => { error!("Server Error: {:?}", err) } - }; + } } \ No newline at end of file -- cgit v1.2.3 From 0cca10290d089aabac8f2e4356cfaf80f06ae194 Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Sun, 29 Oct 2023 19:55:26 +0100 Subject: does what is expected, but badly --- src/error.rs | 20 ++++++++++++---- src/main.rs | 5 ++-- src/routes/start.rs | 5 ++-- src/routes/status.rs | 2 -- src/services/ping.rs | 68 ++++++++++++++++++++++++++++++---------------------- 5 files changed, 60 insertions(+), 40 deletions(-) diff --git a/src/error.rs b/src/error.rs index f143ee9..1592a78 100644 --- a/src/error.rs +++ b/src/error.rs @@ -10,19 +10,20 @@ use crate::auth::AuthError; #[derive(Debug)] pub enum WebolError { Generic, + // User(UserError), Auth(AuthError), Ping(surge_ping::SurgeError), DB(sqlx::Error), IpParse(::Err), BufferParse(std::num::ParseIntError), Broadcast(io::Error), - Axum(axum::Error) } impl IntoResponse for WebolError { fn into_response(self) -> Response { let (status, error_message) = match self { Self::Auth(err) => err.get(), + // Self::User(err) => err.get(), Self::Generic => (StatusCode::INTERNAL_SERVER_ERROR, ""), Self::Ping(err) => { error!("Ping: {}", err.source().unwrap()); @@ -44,10 +45,6 @@ impl IntoResponse for WebolError { error!("server error: {}", err.to_string()); (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") }, - Self::Axum(err) => { - error!("server error: {}", err.to_string()); - (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") - }, }; let body = Json(json!({ "error": error_message, @@ -55,3 +52,16 @@ impl IntoResponse for WebolError { (status, body).into_response() } } + +// #[derive(Debug)] +// pub enum UserError { +// UnknownUUID, +// } +// +// impl UserError { +// pub fn get(self) -> (StatusCode, &'static str) { +// match self { +// Self::UnknownUUID => (StatusCode::UNPROCESSABLE_ENTITY, "Unknown UUID"), +// } +// } +// } diff --git a/src/main.rs b/src/main.rs index 854b59d..545d8fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ use crate::db::init_db_pool; use crate::routes::device::{get_device, post_device, put_device}; use crate::routes::start::start; use crate::routes::status::status; +use crate::services::ping::{BroadcastCommands, PingMap}; mod auth; mod config; @@ -72,6 +73,6 @@ async fn main() { pub struct AppState { db: PgPool, - ping_send: Sender, - ping_map: Arc>>, + ping_send: Sender, + ping_map: PingMap, } \ No newline at end of file diff --git a/src/routes/start.rs b/src/routes/start.rs index 45e7ec8..b1c8a73 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -44,15 +44,16 @@ pub async fn start(State(state): State>, headers: HeaderMap let uuid = if payload.ping.is_some_and(|ping| ping) { let uuid_gen = Uuid::new_v4().to_string(); let uuid_genc = uuid_gen.clone(); + let uuid_gencc = uuid_gen.clone(); tokio::spawn(async move{ debug!("Init ping service"); state.ping_map.lock().await.insert(uuid_gen, ("192.168.178.94".to_string(), false)); warn!("{:?}", state.ping_map); - crate::services::ping::spawn(state.ping_send.clone(), "192.168.178.94".to_string()).await; + crate::services::ping::spawn(state.ping_send.clone(), "192.168.178.94".to_string(), uuid_genc.clone(), state.ping_map.clone()).await }); - Some(uuid_genc) + Some(uuid_gencc) } else { None }; Ok(Json(json!(StartResponse { id: device.id, boot: true, uuid }))) } else { diff --git a/src/routes/status.rs b/src/routes/status.rs index cdecf6a..4a5ec67 100644 --- a/src/routes/status.rs +++ b/src/routes/status.rs @@ -1,12 +1,10 @@ use std::sync::Arc; use axum::extract::{State, WebSocketUpgrade}; use axum::response::Response; -use serde::Deserialize; use crate::AppState; use crate::services::ping::status_websocket; #[axum_macros::debug_handler] pub async fn status(State(state): State>, ws: WebSocketUpgrade) -> Response { - // TODO: remove unwrap ws.on_upgrade(move |socket| status_websocket(socket, state.ping_send.clone(), state.ping_map.clone())) } \ No newline at end of file diff --git a/src/services/ping.rs b/src/services/ping.rs index e3d465d..6835fc0 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -3,16 +3,19 @@ use std::collections::HashMap; use std::sync::Arc; use axum::extract::{ws::WebSocket}; -use axum::extract::ws::Message; +use axum::extract::ws::{CloseFrame, Message}; use tokio::sync::broadcast::{Sender}; use tokio::sync::Mutex; -use tracing::{debug, error, trace, warn}; +use tracing::{debug, trace, warn}; use crate::error::WebolError; -pub async fn spawn(tx: Sender, ip: String) -> Result<(), WebolError> { +pub type PingMap = Arc>>; + +pub async fn spawn(tx: Sender, ip: String, uuid: String, ping_map: PingMap) -> Result<(), WebolError> { let payload = [0; 8]; + // TODO: Better while let mut cont = true; while cont { let ping = surge_ping::ping( @@ -22,40 +25,44 @@ pub async fn spawn(tx: Sender, ip: String) -> Result<(), WebolError> { if let Err(ping) = ping { cont = matches!(ping, surge_ping::SurgeError::Timeout { .. }); - - // debug!("{}", cont); - if !cont { return Err(ping).map_err(WebolError::Ping) } - } else { let (_, duration) = ping.unwrap(); debug!("Ping took {:?}", duration); cont = false; - // FIXME: remove unwrap - // FIXME: if error: SendError because no listener, then handle the entry directly - tx.send(ip.clone()); + handle_broadcast_send(&tx, ip.clone(), ping_map.clone(), uuid.clone()).await; }; } Ok(()) } -// FIXME: Handle commands through enum -pub async fn status_websocket(mut socket: WebSocket, tx: Sender, ping_map: Arc>>) { - warn!("{:?}", ping_map); +async fn handle_broadcast_send(tx: &Sender, ip: String, ping_map: PingMap, uuid: String) { + debug!("sending pingsuccess message"); + ping_map.lock().await.insert(uuid.clone(), (ip.clone(), true)); + let _ = tx.send(BroadcastCommands::PingSuccess(ip)); + tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; + trace!("remove {} from ping_map", uuid); + ping_map.lock().await.remove(&uuid); +} - let mut uuid: Option = None; +#[derive(Clone, Debug)] +pub enum BroadcastCommands { + PingSuccess(String) +} + +pub async fn status_websocket(mut socket: WebSocket, tx: Sender, ping_map: PingMap) { + warn!("{:?}", ping_map); trace!("wait for ws message (uuid)"); let msg = socket.recv().await; - uuid = Some(msg.unwrap().unwrap().into_text().unwrap()); - - let uuid = uuid.unwrap(); + let uuid = msg.unwrap().unwrap().into_text().unwrap(); trace!("Search for uuid: {:?}", uuid); + // TODO: Handle Error let device = ping_map.lock().await.get(&uuid).unwrap().to_owned(); trace!("got device: {:?}", device); @@ -63,29 +70,32 @@ pub async fn status_websocket(mut socket: WebSocket, tx: Sender, ping_ma match device.1 { true => { debug!("already started"); - socket.send(Message::Text(format!("start_{}", uuid))).await.unwrap(); - socket.close().await.unwrap(); + // socket.send(Message::Text(format!("start_{}", uuid))).await.unwrap(); + // socket.close().await.unwrap(); + socket.send(Message::Close(Some(CloseFrame { code: 4001, reason: Cow::from(format!("start_{}", uuid)) }))).await.unwrap(); }, false => { let ip = device.0.to_owned(); - let mut i = 0; loop{ - trace!("{}", i); - // TODO: Check if older than 10 minutes, close if true trace!("wait for tx message"); let message = tx.subscribe().recv().await.unwrap(); - trace!("GOT = {}", message); - if message == ip { + trace!("GOT = {:?}", message); + // if let BroadcastCommands::PingSuccess(msg_ip) = message { + // if msg_ip == ip { + // trace!("message == ip"); + // break; + // } + // } + let BroadcastCommands::PingSuccess(msg_ip) = message; + if msg_ip == ip { trace!("message == ip"); break; } - i += 1; }; - socket.send(Message::Text(format!("start_{}", uuid))).await.unwrap(); - socket.close().await.unwrap(); - tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; - ping_map.lock().await.remove(&uuid); + socket.send(Message::Close(Some(CloseFrame { code: 4000, reason: Cow::from(format!("start_{}", uuid)) }))).await.unwrap(); + // socket.send(Message::Text(format!("start_{}", uuid))).await.unwrap(); + // socket.close().await.unwrap(); warn!("{:?}", ping_map); } } -- cgit v1.2.3 From 84c32953ae5f52be44af4b48381747f55cb04f4a Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Sun, 29 Oct 2023 20:30:01 +0100 Subject: impl dashmap --- Cargo.lock | 14 ++++++++++++++ Cargo.toml | 1 + src/main.rs | 7 +++---- src/routes/start.rs | 2 +- src/services/ping.rs | 11 +++++------ 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2650edc..a60c07d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -308,6 +308,19 @@ dependencies = [ "typenum", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.4.0" @@ -2189,6 +2202,7 @@ dependencies = [ "axum", "axum-macros", "config", + "dashmap", "once_cell", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index d29a1b3..cf38752 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,3 +19,4 @@ sqlx = { version = "0.7.1", features = ["postgres", "runtime-tokio"]} surge-ping = "0.8.0" axum-macros = "0.3.8" uuid = { version = "1.5.0", features = ["v4", "fast-rng"] } +dashmap = "5.5.3" diff --git a/src/main.rs b/src/main.rs index 545d8fe..762a817 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,11 @@ -use std::collections::HashMap; use std::env; use std::sync::Arc; use axum::{Router, routing::post}; use axum::routing::{get, put}; +use dashmap::DashMap; use sqlx::PgPool; use time::util::local_offset; use tokio::sync::broadcast::{channel, Sender}; -use tokio::sync::Mutex; use tracing::{info, level_filters::LevelFilter}; use tracing_subscriber::{EnvFilter, fmt::{self, time::LocalTime}, prelude::*}; use crate::config::SETTINGS; @@ -51,9 +50,9 @@ async fn main() { let (tx, _) = channel(32); - let ping_map: HashMap = HashMap::new(); + let ping_map: DashMap = DashMap::new(); - let shared_state = Arc::new(AppState { db, ping_send: tx, ping_map: Arc::new(Mutex::new(ping_map)) }); + let shared_state = Arc::new(AppState { db, ping_send: tx, ping_map: Arc::new(ping_map) }); let app = Router::new() .route("/start", post(start)) diff --git a/src/routes/start.rs b/src/routes/start.rs index b1c8a73..5b73281 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -47,7 +47,7 @@ pub async fn start(State(state): State>, headers: HeaderMap let uuid_gencc = uuid_gen.clone(); tokio::spawn(async move{ debug!("Init ping service"); - state.ping_map.lock().await.insert(uuid_gen, ("192.168.178.94".to_string(), false)); + state.ping_map.insert(uuid_gen, ("192.168.178.94".to_string(), false)); warn!("{:?}", state.ping_map); diff --git a/src/services/ping.rs b/src/services/ping.rs index 6835fc0..ed848fc 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -1,16 +1,15 @@ use std::borrow::Cow; -use std::collections::HashMap; use std::sync::Arc; use axum::extract::{ws::WebSocket}; use axum::extract::ws::{CloseFrame, Message}; +use dashmap::DashMap; use tokio::sync::broadcast::{Sender}; -use tokio::sync::Mutex; use tracing::{debug, trace, warn}; use crate::error::WebolError; -pub type PingMap = Arc>>; +pub type PingMap = Arc>; pub async fn spawn(tx: Sender, ip: String, uuid: String, ping_map: PingMap) -> Result<(), WebolError> { let payload = [0; 8]; @@ -41,11 +40,11 @@ pub async fn spawn(tx: Sender, ip: String, uuid: String, ping async fn handle_broadcast_send(tx: &Sender, ip: String, ping_map: PingMap, uuid: String) { debug!("sending pingsuccess message"); - ping_map.lock().await.insert(uuid.clone(), (ip.clone(), true)); + ping_map.insert(uuid.clone(), (ip.clone(), true)); let _ = tx.send(BroadcastCommands::PingSuccess(ip)); tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; trace!("remove {} from ping_map", uuid); - ping_map.lock().await.remove(&uuid); + ping_map.remove(&uuid); } #[derive(Clone, Debug)] @@ -63,7 +62,7 @@ pub async fn status_websocket(mut socket: WebSocket, tx: Sender Date: Sun, 29 Oct 2023 21:09:46 +0100 Subject: add ip to database and use for ping, remove arc from pingmap --- migrations/20231009123228_devices.sql | 7 ++++--- src/db.rs | 3 ++- src/main.rs | 2 +- src/routes/device.rs | 16 ++++++++++------ src/routes/start.rs | 11 +++++------ src/routes/status.rs | 2 +- src/services/ping.rs | 20 +++++++++++--------- 7 files changed, 34 insertions(+), 27 deletions(-) diff --git a/migrations/20231009123228_devices.sql b/migrations/20231009123228_devices.sql index 9d0c7ca..b911b19 100644 --- a/migrations/20231009123228_devices.sql +++ b/migrations/20231009123228_devices.sql @@ -1,7 +1,8 @@ -- Add migration script here CREATE TABLE IF NOT EXISTS "devices" ( - "id" TEXT PRIMARY KEY NOT NULL, - "mac" TEXT NOT NULL, - "broadcast_addr" TEXT NOT NULL + "id" VARCHAR(255) PRIMARY KEY NOT NULL, + "mac" VARCHAR(17) NOT NULL, + "broadcast_addr" VARCHAR(39) NOT NULL, + "ip" VARCHAR(39) NOT NULL ) diff --git a/src/db.rs b/src/db.rs index 3c51e2b..51ea469 100644 --- a/src/db.rs +++ b/src/db.rs @@ -12,7 +12,8 @@ use crate::config::SETTINGS; pub struct Device { pub id: String, pub mac: String, - pub broadcast_addr: String + pub broadcast_addr: String, + pub ip: String } pub async fn init_db_pool() -> PgPool { diff --git a/src/main.rs b/src/main.rs index 762a817..ee540af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,7 +52,7 @@ async fn main() { let ping_map: DashMap = DashMap::new(); - let shared_state = Arc::new(AppState { db, ping_send: tx, ping_map: Arc::new(ping_map) }); + let shared_state = Arc::new(AppState { db, ping_send: tx, ping_map }); let app = Router::new() .route("/start", post(start)) diff --git a/src/routes/device.rs b/src/routes/device.rs index 248d1e0..7353733 100644 --- a/src/routes/device.rs +++ b/src/routes/device.rs @@ -16,7 +16,7 @@ pub async fn get_device(State(state): State>, headers: Head let device = sqlx::query_as!( Device, r#" - SELECT id, mac, broadcast_addr + SELECT id, mac, broadcast_addr, ip FROM devices WHERE id = $1; "#, @@ -40,12 +40,13 @@ pub async fn put_device(State(state): State>, headers: Head if auth(secret).map_err(WebolError::Auth)? { sqlx::query!( r#" - INSERT INTO devices (id, mac, broadcast_addr) - VALUES ($1, $2, $3); + INSERT INTO devices (id, mac, broadcast_addr, ip) + VALUES ($1, $2, $3, $4); "#, payload.id, payload.mac, - payload.broadcast_addr + payload.broadcast_addr, + payload.ip ).execute(&state.db).await.map_err(WebolError::DB)?; Ok(Json(json!(PutDeviceResponse { success: true }))) @@ -59,6 +60,7 @@ pub struct PutDevicePayload { id: String, mac: String, broadcast_addr: String, + ip: String } #[derive(Serialize)] @@ -74,11 +76,12 @@ pub async fn post_device(State(state): State>, headers: Hea Device, r#" UPDATE devices - SET mac = $1, broadcast_addr = $2 WHERE id = $3 - RETURNING id, mac, broadcast_addr; + SET mac = $1, broadcast_addr = $2, ip = $3 WHERE id = $4 + RETURNING id, mac, broadcast_addr, ip; "#, payload.mac, payload.broadcast_addr, + payload.ip, payload.id ).fetch_one(&state.db).await.map_err(WebolError::DB)?; @@ -93,4 +96,5 @@ pub struct PostDevicePayload { id: String, mac: String, broadcast_addr: String, + ip: String, } diff --git a/src/routes/start.rs b/src/routes/start.rs index 5b73281..3bccb0f 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -22,7 +22,7 @@ pub async fn start(State(state): State>, headers: HeaderMap let device = sqlx::query_as!( Device, r#" - SELECT id, mac, broadcast_addr + SELECT id, mac, broadcast_addr, ip FROM devices WHERE id = $1; "#, @@ -44,16 +44,15 @@ pub async fn start(State(state): State>, headers: HeaderMap let uuid = if payload.ping.is_some_and(|ping| ping) { let uuid_gen = Uuid::new_v4().to_string(); let uuid_genc = uuid_gen.clone(); - let uuid_gencc = uuid_gen.clone(); - tokio::spawn(async move{ + tokio::spawn(async move { debug!("Init ping service"); - state.ping_map.insert(uuid_gen, ("192.168.178.94".to_string(), false)); + state.ping_map.insert(uuid_gen.clone(), (device.ip.clone(), false)); warn!("{:?}", state.ping_map); - crate::services::ping::spawn(state.ping_send.clone(), "192.168.178.94".to_string(), uuid_genc.clone(), state.ping_map.clone()).await + crate::services::ping::spawn(state.ping_send.clone(), device.ip, uuid_gen.clone(), &state.ping_map).await }); - Some(uuid_gencc) + Some(uuid_genc) } else { None }; Ok(Json(json!(StartResponse { id: device.id, boot: true, uuid }))) } else { diff --git a/src/routes/status.rs b/src/routes/status.rs index 4a5ec67..45f3e51 100644 --- a/src/routes/status.rs +++ b/src/routes/status.rs @@ -6,5 +6,5 @@ use crate::services::ping::status_websocket; #[axum_macros::debug_handler] pub async fn status(State(state): State>, ws: WebSocketUpgrade) -> Response { - ws.on_upgrade(move |socket| status_websocket(socket, state.ping_send.clone(), state.ping_map.clone())) + ws.on_upgrade(move |socket| status_websocket(socket, state)) } \ No newline at end of file diff --git a/src/services/ping.rs b/src/services/ping.rs index ed848fc..04ad511 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -6,12 +6,13 @@ use axum::extract::ws::{CloseFrame, Message}; use dashmap::DashMap; use tokio::sync::broadcast::{Sender}; use tracing::{debug, trace, warn}; +use crate::AppState; use crate::error::WebolError; -pub type PingMap = Arc>; +pub type PingMap = DashMap; -pub async fn spawn(tx: Sender, ip: String, uuid: String, ping_map: PingMap) -> Result<(), WebolError> { +pub async fn spawn(tx: Sender, ip: String, uuid: String, ping_map: &PingMap) -> Result<(), WebolError> { let payload = [0; 8]; // TODO: Better while @@ -31,14 +32,14 @@ pub async fn spawn(tx: Sender, ip: String, uuid: String, ping let (_, duration) = ping.unwrap(); debug!("Ping took {:?}", duration); cont = false; - handle_broadcast_send(&tx, ip.clone(), ping_map.clone(), uuid.clone()).await; + handle_broadcast_send(&tx, ip.clone(), &ping_map, uuid.clone()).await; }; } Ok(()) } -async fn handle_broadcast_send(tx: &Sender, ip: String, ping_map: PingMap, uuid: String) { +async fn handle_broadcast_send(tx: &Sender, ip: String, ping_map: &PingMap, uuid: String) { debug!("sending pingsuccess message"); ping_map.insert(uuid.clone(), (ip.clone(), true)); let _ = tx.send(BroadcastCommands::PingSuccess(ip)); @@ -52,8 +53,8 @@ pub enum BroadcastCommands { PingSuccess(String) } -pub async fn status_websocket(mut socket: WebSocket, tx: Sender, ping_map: PingMap) { - warn!("{:?}", ping_map); +pub async fn status_websocket(mut socket: WebSocket, state: Arc) { + warn!("{:?}", state.ping_map); trace!("wait for ws message (uuid)"); let msg = socket.recv().await; @@ -62,13 +63,14 @@ pub async fn status_websocket(mut socket: WebSocket, tx: Sender { debug!("already started"); + // TODO: What's better? // socket.send(Message::Text(format!("start_{}", uuid))).await.unwrap(); // socket.close().await.unwrap(); socket.send(Message::Close(Some(CloseFrame { code: 4001, reason: Cow::from(format!("start_{}", uuid)) }))).await.unwrap(); @@ -77,7 +79,7 @@ pub async fn status_websocket(mut socket: WebSocket, tx: Sender Date: Sun, 29 Oct 2023 21:27:34 +0100 Subject: added correct sqlx offline data --- ...49c49607520a8d09f902b996467dddf58737a3757f.json | 16 -------- ...963d5186b764ec9125d597f9fba566e280bd09d352.json | 36 ------------------ ...5b87dfcee9067933c4df892609700c0766c20fc5c5.json | 40 ++++++++++++++++++++ ...b8cf06394a302d288e91f5eedde65db6630021f737.json | 17 +++++++++ ...9b1c094959a49c6b7383f1a0b49df242e2720a9185.json | 34 ----------------- ...9dd2293fa19e5f1975ea8810526924e77683ba92c4.json | 43 ++++++++++++++++++++++ 6 files changed, 100 insertions(+), 86 deletions(-) delete mode 100644 .sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json delete mode 100644 .sqlx/query-6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352.json create mode 100644 .sqlx/query-82c11b5a47389884e4ed945b87dfcee9067933c4df892609700c0766c20fc5c5.json create mode 100644 .sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json delete mode 100644 .sqlx/query-bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185.json create mode 100644 .sqlx/query-f179f38584f97842cd41159dd2293fa19e5f1975ea8810526924e77683ba92c4.json diff --git a/.sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json b/.sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json deleted file mode 100644 index feedac8..0000000 --- a/.sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n INSERT INTO devices (id, mac, broadcast_addr)\n VALUES ($1, $2, $3);\n ", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text", - "Text" - ] - }, - "nullable": [] - }, - "hash": "3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f" -} diff --git a/.sqlx/query-6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352.json b/.sqlx/query-6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352.json deleted file mode 100644 index 89f6bbe..0000000 --- a/.sqlx/query-6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n UPDATE devices\n SET mac = $1, broadcast_addr = $2 WHERE id = $3\n RETURNING id, mac, broadcast_addr;\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "mac", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "broadcast_addr", - "type_info": "Text" - } - ], - "parameters": { - "Left": [ - "Text", - "Text", - "Text" - ] - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352" -} diff --git a/.sqlx/query-82c11b5a47389884e4ed945b87dfcee9067933c4df892609700c0766c20fc5c5.json b/.sqlx/query-82c11b5a47389884e4ed945b87dfcee9067933c4df892609700c0766c20fc5c5.json new file mode 100644 index 0000000..c0a933d --- /dev/null +++ b/.sqlx/query-82c11b5a47389884e4ed945b87dfcee9067933c4df892609700c0766c20fc5c5.json @@ -0,0 +1,40 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT id, mac, broadcast_addr, ip\n FROM devices\n WHERE id = $1;\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "mac", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "broadcast_addr", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "ip", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false, + false, + false, + false + ] + }, + "hash": "82c11b5a47389884e4ed945b87dfcee9067933c4df892609700c0766c20fc5c5" +} diff --git a/.sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json b/.sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json new file mode 100644 index 0000000..bc4bdd3 --- /dev/null +++ b/.sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO devices (id, mac, broadcast_addr, ip)\n VALUES ($1, $2, $3, $4);\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Varchar", + "Varchar", + "Varchar" + ] + }, + "nullable": [] + }, + "hash": "adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737" +} diff --git a/.sqlx/query-bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185.json b/.sqlx/query-bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185.json deleted file mode 100644 index efd2830..0000000 --- a/.sqlx/query-bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT id, mac, broadcast_addr\n FROM devices\n WHERE id = $1;\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "mac", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "broadcast_addr", - "type_info": "Text" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185" -} diff --git a/.sqlx/query-f179f38584f97842cd41159dd2293fa19e5f1975ea8810526924e77683ba92c4.json b/.sqlx/query-f179f38584f97842cd41159dd2293fa19e5f1975ea8810526924e77683ba92c4.json new file mode 100644 index 0000000..322db91 --- /dev/null +++ b/.sqlx/query-f179f38584f97842cd41159dd2293fa19e5f1975ea8810526924e77683ba92c4.json @@ -0,0 +1,43 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE devices\n SET mac = $1, broadcast_addr = $2, ip = $3 WHERE id = $4\n RETURNING id, mac, broadcast_addr, ip;\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "mac", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "broadcast_addr", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "ip", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Varchar", + "Varchar", + "Varchar", + "Text" + ] + }, + "nullable": [ + false, + false, + false, + false + ] + }, + "hash": "f179f38584f97842cd41159dd2293fa19e5f1975ea8810526924e77683ba92c4" +} -- cgit v1.2.3 From 348cf5fbe4527865e8aa5cb719fd8790f4d8953e Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Mon, 30 Oct 2023 12:22:31 +0100 Subject: changed pingmap tuple to own struct --- src/main.rs | 2 +- src/routes/start.rs | 3 ++- src/services/ping.rs | 16 +++++++++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index ee540af..e96b736 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,7 +50,7 @@ async fn main() { let (tx, _) = channel(32); - let ping_map: DashMap = DashMap::new(); + let ping_map: PingMap = DashMap::new(); let shared_state = Arc::new(AppState { db, ping_send: tx, ping_map }); diff --git a/src/routes/start.rs b/src/routes/start.rs index 3bccb0f..c2c9378 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -11,6 +11,7 @@ use crate::config::SETTINGS; use crate::wol::{create_buffer, send_packet}; use crate::db::Device; use crate::error::WebolError; +use crate::services::ping::PingValue; #[axum_macros::debug_handler] pub async fn start(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, WebolError> { @@ -46,7 +47,7 @@ pub async fn start(State(state): State>, headers: HeaderMap let uuid_genc = uuid_gen.clone(); tokio::spawn(async move { debug!("Init ping service"); - state.ping_map.insert(uuid_gen.clone(), (device.ip.clone(), false)); + state.ping_map.insert(uuid_gen.clone(), PingValue { ip: device.ip.clone(), online: false }); warn!("{:?}", state.ping_map); diff --git a/src/services/ping.rs b/src/services/ping.rs index 04ad511..f0cc4a3 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -10,7 +10,13 @@ use crate::AppState; use crate::error::WebolError; -pub type PingMap = DashMap; +pub type PingMap = DashMap; + +#[derive(Debug, Clone)] +pub struct PingValue { + pub ip: String, + pub online: bool +} pub async fn spawn(tx: Sender, ip: String, uuid: String, ping_map: &PingMap) -> Result<(), WebolError> { let payload = [0; 8]; @@ -32,7 +38,7 @@ pub async fn spawn(tx: Sender, ip: String, uuid: String, ping let (_, duration) = ping.unwrap(); debug!("Ping took {:?}", duration); cont = false; - handle_broadcast_send(&tx, ip.clone(), &ping_map, uuid.clone()).await; + handle_broadcast_send(&tx, ip.clone(), ping_map, uuid.clone()).await; }; } @@ -41,7 +47,7 @@ pub async fn spawn(tx: Sender, ip: String, uuid: String, ping async fn handle_broadcast_send(tx: &Sender, ip: String, ping_map: &PingMap, uuid: String) { debug!("sending pingsuccess message"); - ping_map.insert(uuid.clone(), (ip.clone(), true)); + ping_map.insert(uuid.clone(), PingValue { ip: ip.clone(), online: true }); let _ = tx.send(BroadcastCommands::PingSuccess(ip)); tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; trace!("remove {} from ping_map", uuid); @@ -67,7 +73,7 @@ pub async fn status_websocket(mut socket: WebSocket, state: Arc) { trace!("got device: {:?}", device); - match device.1 { + match device.online { true => { debug!("already started"); // TODO: What's better? @@ -76,7 +82,7 @@ pub async fn status_websocket(mut socket: WebSocket, state: Arc) { socket.send(Message::Close(Some(CloseFrame { code: 4001, reason: Cow::from(format!("start_{}", uuid)) }))).await.unwrap(); }, false => { - let ip = device.0.to_owned(); + let ip = device.ip.to_owned(); loop{ trace!("wait for tx message"); let message = state.ping_send.subscribe().recv().await.unwrap(); -- cgit v1.2.3 From bdbcce55ff7d4494f377fbb7045d572d47f7868c Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Mon, 30 Oct 2023 12:33:57 +0100 Subject: cargo update and use cargo directly in actions --- .github/workflows/pull_request.yml | 38 ++-------- .github/workflows/push.yml | 18 +---- Cargo.lock | 140 ++++++++++++++++++++----------------- 3 files changed, 83 insertions(+), 113 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index d7eaaf3..279e16d 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -19,21 +19,9 @@ jobs: uses: mozilla-actions/sccache-action@v0.0.3 - uses: actions/checkout@v4 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - override: true - - - name: run cargo check - uses: actions-rs/cargo@v1 - with: - command: check - - - name: run clippy - uses: actions-rs/cargo@v1 - with: - command: clippy + + - run: cargo check + - run: cargo clippy check-release: runs-on: ubuntu-latest @@ -42,20 +30,6 @@ jobs: uses: mozilla-actions/sccache-action@v0.0.3 - uses: actions/checkout@v4 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - override: true - - - name: run cargo check - uses: actions-rs/cargo@v1 - with: - command: check - args: --release - - - name: run clippy - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --release + + - run: cargo check --release + - run: cargo clippy --release \ No newline at end of file diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 93b6edb..d41941b 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -19,23 +19,9 @@ jobs: uses: mozilla-actions/sccache-action@v0.0.3 - uses: actions/checkout@v4 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - override: true - - name: Run cargo check - uses: actions-rs/cargo@v1 - with: - command: check - args: --release - - - name: Run Clippy - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --release + - run: cargo check --release + - run: cargo clippy --release build: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index a60c07d..df6537a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", @@ -30,14 +30,15 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -89,7 +90,7 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", - "base64 0.21.4", + "base64 0.21.5", "bitflags 1.3.2", "bytes", "futures-util", @@ -169,9 +170,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -257,9 +258,9 @@ checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "cpufeatures" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -453,9 +454,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -463,15 +464,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -491,27 +492,27 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-core", "futures-io", @@ -562,7 +563,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.7", ] [[package]] @@ -571,7 +572,7 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", "allocator-api2", ] @@ -590,7 +591,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "bytes", "headers-core", "http", @@ -873,9 +874,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi", @@ -1024,7 +1025,7 @@ checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall", "smallvec", "windows-targets", ] @@ -1058,9 +1059,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" dependencies = [ "memchr", "thiserror", @@ -1069,9 +1070,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8" +checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" dependencies = [ "pest", "pest_generator", @@ -1079,9 +1080,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a" +checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" dependencies = [ "pest", "pest_meta", @@ -1092,9 +1093,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d" +checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" dependencies = [ "once_cell", "pest", @@ -1262,15 +1263,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -1337,16 +1329,14 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" +checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d" dependencies = [ - "byteorder", "const-oid", "digest", "num-bigint-dig", "num-integer", - "num-iter", "num-traits", "pkcs1", "pkcs8", @@ -1375,9 +1365,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.20" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ "bitflags 2.4.1", "errno", @@ -1406,18 +1396,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.189" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", @@ -1588,7 +1578,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", "atoi", "byteorder", "bytes", @@ -1668,7 +1658,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" dependencies = [ "atoi", - "base64 0.21.4", + "base64 0.21.5", "bitflags 2.4.1", "byteorder", "bytes", @@ -1710,7 +1700,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" dependencies = [ "atoi", - "base64 0.21.4", + "base64 0.21.5", "bitflags 2.4.1", "byteorder", "crc", @@ -1827,13 +1817,13 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.3.5", + "redox_syscall", "rustix", "windows-sys", ] @@ -2037,12 +2027,12 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] @@ -2318,6 +2308,26 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "zerocopy" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd66a62464e3ffd4e37bd09950c2b9dd6c4f8767380fabba0d523f9a775bc85a" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "255c4596d41e6916ced49cfafea18727b24d67878fa180ddfd69b9df34fd1726" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "zeroize" version = "1.6.0" -- cgit v1.2.3 From 158dbf0a382289bbc68973aa1dda4213e625bd5a Mon Sep 17 00:00:00 2001 From: FxQnLr <39925636+FxQnLr@users.noreply.github.com> Date: Mon, 30 Oct 2023 13:07:21 +0100 Subject: Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8f3fb28 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 FxQnLr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. -- cgit v1.2.3 From f8f0565c42db7c612ac12b9a58155051e795639a Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Mon, 30 Oct 2023 13:12:18 +0100 Subject: update dependencies --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cf38752..7b2c22b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,15 +7,15 @@ edition = "2021" [dependencies] axum = { version = "0.6.20", features = ["headers", "ws"] } -tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] } -tracing = "0.1.37" +tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread"] } +tracing = "0.1.40" tracing-subscriber = { version = "0.3.17", features = ["env-filter", "local-time", "time"] } -time = { version = "0.3.29", features = ["macros"] } -serde = { version = "1.0.188", features = ["derive"] } +time = { version = "0.3.30", features = ["macros"] } +serde = { version = "1.0.190", features = ["derive"] } serde_json = "1.0.107" config = "0.13.3" once_cell = "1.18.0" -sqlx = { version = "0.7.1", features = ["postgres", "runtime-tokio"]} +sqlx = { version = "0.7.2", features = ["postgres", "runtime-tokio"]} surge-ping = "0.8.0" axum-macros = "0.3.8" uuid = { version = "1.5.0", features = ["v4", "fast-rng"] } -- cgit v1.2.3 From 5b7302cf9be4e0badd691203e160ca110613e34c Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Thu, 2 Nov 2023 19:44:29 +0100 Subject: ping timeout and cleanup --- Cargo.lock | 22 ++++++------- Cargo.toml | 2 +- README.md | 2 ++ src/db.rs | 2 +- src/error.rs | 27 +++------------ src/routes/device.rs | 10 +++--- src/routes/start.rs | 2 -- src/services/ping.rs | 92 +++++++++++++++++++++++++++------------------------- 8 files changed, 73 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df6537a..350c8e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -276,9 +276,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" +checksum = "4939f9ed1444bd8c896d37f3090012fa6e7834fe84ef8c9daa166109515732f9" [[package]] name = "crossbeam-queue" @@ -726,9 +726,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", "hashbrown 0.14.2", @@ -1416,9 +1416,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -2187,7 +2187,7 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "webol" -version = "0.1.0" +version = "0.2.0" dependencies = [ "axum", "axum-macros", @@ -2310,18 +2310,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.20" +version = "0.7.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd66a62464e3ffd4e37bd09950c2b9dd6c4f8767380fabba0d523f9a775bc85a" +checksum = "e50cbb27c30666a6108abd6bc7577556265b44f243e2be89a8bc4e07a528c107" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.20" +version = "0.7.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "255c4596d41e6916ced49cfafea18727b24d67878fa180ddfd69b9df34fd1726" +checksum = "a25f293fe55f0a48e7010d65552bb63704f6ceb55a1a385da10d41d8f78e4a3d" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 7b2c22b..1bf823f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "webol" -version = "0.1.0" +version = "0.2.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/README.md b/README.md index d177df2..e4a6c44 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,5 @@ WEBOL_APIKEY: `String` WEBOL_SERVERADDR: `Option` (0.0.0.0:7229) WEBOL_BINDADDR: `Option` (0.0.0.0:1111) + +WEBOL_PINGTIMEOUT: `Option` (10) \ No newline at end of file diff --git a/src/db.rs b/src/db.rs index 51ea469..c012b47 100644 --- a/src/db.rs +++ b/src/db.rs @@ -8,7 +8,7 @@ use tracing::{debug, info}; #[cfg(not(debug_assertions))] use crate::config::SETTINGS; -#[derive(Serialize)] +#[derive(Serialize, Debug)] pub struct Device { pub id: String, pub mac: String, diff --git a/src/error.rs b/src/error.rs index 1592a78..5b82534 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,3 @@ -use std::error::Error; use std::io; use axum::http::StatusCode; use axum::Json; @@ -10,9 +9,7 @@ use crate::auth::AuthError; #[derive(Debug)] pub enum WebolError { Generic, - // User(UserError), Auth(AuthError), - Ping(surge_ping::SurgeError), DB(sqlx::Error), IpParse(::Err), BufferParse(std::num::ParseIntError), @@ -22,13 +19,10 @@ pub enum WebolError { impl IntoResponse for WebolError { fn into_response(self) -> Response { let (status, error_message) = match self { - Self::Auth(err) => err.get(), - // Self::User(err) => err.get(), - Self::Generic => (StatusCode::INTERNAL_SERVER_ERROR, ""), - Self::Ping(err) => { - error!("Ping: {}", err.source().unwrap()); - (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") + Self::Auth(err) => { + err.get() }, + Self::Generic => (StatusCode::INTERNAL_SERVER_ERROR, ""), Self::IpParse(err) => { error!("server error: {}", err.to_string()); (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") @@ -51,17 +45,4 @@ impl IntoResponse for WebolError { })); (status, body).into_response() } -} - -// #[derive(Debug)] -// pub enum UserError { -// UnknownUUID, -// } -// -// impl UserError { -// pub fn get(self) -> (StatusCode, &'static str) { -// match self { -// Self::UnknownUUID => (StatusCode::UNPROCESSABLE_ENTITY, "Unknown UUID"), -// } -// } -// } +} \ No newline at end of file diff --git a/src/routes/device.rs b/src/routes/device.rs index 7353733..1eeff0b 100644 --- a/src/routes/device.rs +++ b/src/routes/device.rs @@ -4,13 +4,13 @@ use axum::headers::HeaderMap; use axum::Json; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; -use tracing::info; +use tracing::{debug, info}; use crate::auth::auth; use crate::db::Device; use crate::error::WebolError; pub async fn get_device(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, WebolError> { - info!("GET request"); + info!("add device {}", payload.id); let secret = headers.get("authorization"); if auth(secret).map_err(WebolError::Auth)? { let device = sqlx::query_as!( @@ -23,6 +23,8 @@ pub async fn get_device(State(state): State>, headers: Head payload.id ).fetch_one(&state.db).await.map_err(WebolError::DB)?; + debug!("got device {:?}", device); + Ok(Json(json!(device))) } else { Err(WebolError::Generic) @@ -35,7 +37,7 @@ pub struct GetDevicePayload { } pub async fn put_device(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, WebolError> { - info!("PUT request"); + info!("add device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip); let secret = headers.get("authorization"); if auth(secret).map_err(WebolError::Auth)? { sqlx::query!( @@ -69,7 +71,7 @@ pub struct PutDeviceResponse { } pub async fn post_device(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, WebolError> { - info!("POST request"); + info!("edit device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip); let secret = headers.get("authorization"); if auth(secret).map_err(WebolError::Auth)? { let device = sqlx::query_as!( diff --git a/src/routes/start.rs b/src/routes/start.rs index c2c9378..9cd358b 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -49,8 +49,6 @@ pub async fn start(State(state): State>, headers: HeaderMap debug!("Init ping service"); state.ping_map.insert(uuid_gen.clone(), PingValue { ip: device.ip.clone(), online: false }); - warn!("{:?}", state.ping_map); - crate::services::ping::spawn(state.ping_send.clone(), device.ip, uuid_gen.clone(), &state.ping_map).await }); Some(uuid_genc) diff --git a/src/services/ping.rs b/src/services/ping.rs index f0cc4a3..a26dacc 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -1,14 +1,13 @@ -use std::borrow::Cow; use std::sync::Arc; use axum::extract::{ws::WebSocket}; -use axum::extract::ws::{CloseFrame, Message}; +use axum::extract::ws::Message; use dashmap::DashMap; +use time::{Duration, Instant}; use tokio::sync::broadcast::{Sender}; -use tracing::{debug, trace, warn}; +use tracing::{debug, error, trace}; use crate::AppState; - -use crate::error::WebolError; +use crate::config::SETTINGS; pub type PingMap = DashMap; @@ -18,92 +17,97 @@ pub struct PingValue { pub online: bool } -pub async fn spawn(tx: Sender, ip: String, uuid: String, ping_map: &PingMap) -> Result<(), WebolError> { +pub async fn spawn(tx: Sender, ip: String, uuid: String, ping_map: &PingMap) { + let timer = Instant::now(); let payload = [0; 8]; - // TODO: Better while let mut cont = true; while cont { let ping = surge_ping::ping( - ip.parse().map_err(WebolError::IpParse)?, + ip.parse().expect("bad ip"), &payload ).await; if let Err(ping) = ping { cont = matches!(ping, surge_ping::SurgeError::Timeout { .. }); if !cont { - return Err(ping).map_err(WebolError::Ping) + error!("{}", ping.to_string()); + } + if timer.elapsed() >= Duration::minutes(SETTINGS.get_int("pingtimeout").unwrap_or(10)) { + let _ = tx.send(BroadcastCommands::PingTimeout(uuid.clone())); + trace!("remove {} from ping_map after timeout", uuid); + ping_map.remove(&uuid); + cont = false; } } else { - let (_, duration) = ping.unwrap(); + let (_, duration) = ping.map_err(|err| error!("{}", err.to_string())).expect("fatal error"); debug!("Ping took {:?}", duration); cont = false; handle_broadcast_send(&tx, ip.clone(), ping_map, uuid.clone()).await; }; } - - Ok(()) } async fn handle_broadcast_send(tx: &Sender, ip: String, ping_map: &PingMap, uuid: String) { - debug!("sending pingsuccess message"); + debug!("send pingsuccess message"); ping_map.insert(uuid.clone(), PingValue { ip: ip.clone(), online: true }); - let _ = tx.send(BroadcastCommands::PingSuccess(ip)); + let _ = tx.send(BroadcastCommands::PingSuccess(uuid.clone())); tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; - trace!("remove {} from ping_map", uuid); + trace!("remove {} from ping_map after success", uuid); ping_map.remove(&uuid); } #[derive(Clone, Debug)] pub enum BroadcastCommands { - PingSuccess(String) + PingSuccess(String), + PingTimeout(String) } pub async fn status_websocket(mut socket: WebSocket, state: Arc) { - warn!("{:?}", state.ping_map); - trace!("wait for ws message (uuid)"); let msg = socket.recv().await; let uuid = msg.unwrap().unwrap().into_text().unwrap(); trace!("Search for uuid: {:?}", uuid); - // TODO: Handle Error - let device = state.ping_map.get(&uuid).unwrap().to_owned(); + match state.ping_map.get(&uuid) { + Some(device) => { + debug!("got device: {} (online: {})", device.ip, device.online); + let _ = socket.send(process_device(state.clone(), uuid, device.to_owned()).await).await; + }, + None => { + debug!("didn't find any device"); + let _ = socket.send(Message::Text(format!("notfound_{}", uuid))).await; + }, + }; - trace!("got device: {:?}", device); + let _ = socket.close().await; +} +async fn process_device(state: Arc, uuid: String, device: PingValue) -> Message { match device.online { true => { debug!("already started"); - // TODO: What's better? - // socket.send(Message::Text(format!("start_{}", uuid))).await.unwrap(); - // socket.close().await.unwrap(); - socket.send(Message::Close(Some(CloseFrame { code: 4001, reason: Cow::from(format!("start_{}", uuid)) }))).await.unwrap(); + Message::Text(format!("start_{}", uuid)) }, false => { - let ip = device.ip.to_owned(); loop{ trace!("wait for tx message"); - let message = state.ping_send.subscribe().recv().await.unwrap(); - trace!("GOT = {:?}", message); - // if let BroadcastCommands::PingSuccess(msg_ip) = message { - // if msg_ip == ip { - // trace!("message == ip"); - // break; - // } - // } - let BroadcastCommands::PingSuccess(msg_ip) = message; - if msg_ip == ip { - trace!("message == ip"); - break; + let message = state.ping_send.subscribe().recv().await.expect("fatal error"); + trace!("got message {:?}", message); + return match message { + BroadcastCommands::PingSuccess(msg_uuid) => { + if msg_uuid != uuid { continue; } + trace!("message == uuid success"); + Message::Text(format!("start_{}", uuid)) + }, + BroadcastCommands::PingTimeout(msg_uuid) => { + if msg_uuid != uuid { continue; } + trace!("message == uuid timeout"); + Message::Text(format!("timeout_{}", uuid)) + } } - }; - - socket.send(Message::Close(Some(CloseFrame { code: 4000, reason: Cow::from(format!("start_{}", uuid)) }))).await.unwrap(); - // socket.send(Message::Text(format!("start_{}", uuid))).await.unwrap(); - // socket.close().await.unwrap(); - warn!("{:?}", state.ping_map); + } } } } \ No newline at end of file -- cgit v1.2.3 From 94104b621e2eec44dd90eb22fae2db2ce4938b87 Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Thu, 2 Nov 2023 20:57:47 +0100 Subject: update dependencies --- src/routes/start.rs | 5 ++--- src/services/ping.rs | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/routes/start.rs b/src/routes/start.rs index 9cd358b..271f924 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use std::sync::Arc; use axum::extract::State; use serde_json::{json, Value}; -use tracing::{debug, info, warn}; +use tracing::{debug, info}; use uuid::Uuid; use crate::auth::auth; use crate::config::SETTINGS; @@ -16,7 +16,6 @@ use crate::services::ping::PingValue; #[axum_macros::debug_handler] pub async fn start(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, WebolError> { info!("POST request"); - warn!("{:?}", state.ping_map); let secret = headers.get("authorization"); let authorized = auth(secret).map_err(WebolError::Auth)?; if authorized { @@ -46,7 +45,7 @@ pub async fn start(State(state): State>, headers: HeaderMap let uuid_gen = Uuid::new_v4().to_string(); let uuid_genc = uuid_gen.clone(); tokio::spawn(async move { - debug!("Init ping service"); + debug!("init ping service"); state.ping_map.insert(uuid_gen.clone(), PingValue { ip: device.ip.clone(), online: false }); crate::services::ping::spawn(state.ping_send.clone(), device.ip, uuid_gen.clone(), &state.ping_map).await diff --git a/src/services/ping.rs b/src/services/ping.rs index a26dacc..d900acb 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -41,7 +41,7 @@ pub async fn spawn(tx: Sender, ip: String, uuid: String, ping } } else { let (_, duration) = ping.map_err(|err| error!("{}", err.to_string())).expect("fatal error"); - debug!("Ping took {:?}", duration); + debug!("ping took {:?}", duration); cont = false; handle_broadcast_send(&tx, ip.clone(), ping_map, uuid.clone()).await; }; @@ -50,10 +50,12 @@ pub async fn spawn(tx: Sender, ip: String, uuid: String, ping async fn handle_broadcast_send(tx: &Sender, ip: String, ping_map: &PingMap, uuid: String) { debug!("send pingsuccess message"); - ping_map.insert(uuid.clone(), PingValue { ip: ip.clone(), online: true }); let _ = tx.send(BroadcastCommands::PingSuccess(uuid.clone())); + trace!("sent message"); + ping_map.insert(uuid.clone(), PingValue { ip: ip.clone(), online: true }); + trace!("updated ping_map"); tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; - trace!("remove {} from ping_map after success", uuid); + debug!("remove {} from ping_map after success", uuid); ping_map.remove(&uuid); } @@ -70,12 +72,12 @@ pub async fn status_websocket(mut socket: WebSocket, state: Arc) { trace!("Search for uuid: {:?}", uuid); - match state.ping_map.get(&uuid) { - Some(device) => { - debug!("got device: {} (online: {})", device.ip, device.online); - let _ = socket.send(process_device(state.clone(), uuid, device.to_owned()).await).await; + let device_exists = state.ping_map.contains_key(&uuid); + match device_exists { + true => { + let _ = socket.send(process_device(state.clone(), uuid).await).await; }, - None => { + false => { debug!("didn't find any device"); let _ = socket.send(Message::Text(format!("notfound_{}", uuid))).await; }, @@ -84,7 +86,10 @@ pub async fn status_websocket(mut socket: WebSocket, state: Arc) { let _ = socket.close().await; } -async fn process_device(state: Arc, uuid: String, device: PingValue) -> Message { +async fn process_device(state: Arc, uuid: String) -> Message { + let pm = state.ping_map.clone().into_read_only(); + let device = pm.get(&uuid).expect("fatal error"); + debug!("got device: {} (online: {})", device.ip, device.online); match device.online { true => { debug!("already started"); -- cgit v1.2.3 From 9e3afcfee276af982a1e1d11f24c9711defc124e Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Thu, 2 Nov 2023 20:58:29 +0100 Subject: Revert "update dependencies" This reverts commit 94104b621e2eec44dd90eb22fae2db2ce4938b87. --- src/routes/start.rs | 5 +++-- src/services/ping.rs | 23 +++++++++-------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/routes/start.rs b/src/routes/start.rs index 271f924..9cd358b 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use std::sync::Arc; use axum::extract::State; use serde_json::{json, Value}; -use tracing::{debug, info}; +use tracing::{debug, info, warn}; use uuid::Uuid; use crate::auth::auth; use crate::config::SETTINGS; @@ -16,6 +16,7 @@ use crate::services::ping::PingValue; #[axum_macros::debug_handler] pub async fn start(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, WebolError> { info!("POST request"); + warn!("{:?}", state.ping_map); let secret = headers.get("authorization"); let authorized = auth(secret).map_err(WebolError::Auth)?; if authorized { @@ -45,7 +46,7 @@ pub async fn start(State(state): State>, headers: HeaderMap let uuid_gen = Uuid::new_v4().to_string(); let uuid_genc = uuid_gen.clone(); tokio::spawn(async move { - debug!("init ping service"); + debug!("Init ping service"); state.ping_map.insert(uuid_gen.clone(), PingValue { ip: device.ip.clone(), online: false }); crate::services::ping::spawn(state.ping_send.clone(), device.ip, uuid_gen.clone(), &state.ping_map).await diff --git a/src/services/ping.rs b/src/services/ping.rs index d900acb..a26dacc 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -41,7 +41,7 @@ pub async fn spawn(tx: Sender, ip: String, uuid: String, ping } } else { let (_, duration) = ping.map_err(|err| error!("{}", err.to_string())).expect("fatal error"); - debug!("ping took {:?}", duration); + debug!("Ping took {:?}", duration); cont = false; handle_broadcast_send(&tx, ip.clone(), ping_map, uuid.clone()).await; }; @@ -50,12 +50,10 @@ pub async fn spawn(tx: Sender, ip: String, uuid: String, ping async fn handle_broadcast_send(tx: &Sender, ip: String, ping_map: &PingMap, uuid: String) { debug!("send pingsuccess message"); - let _ = tx.send(BroadcastCommands::PingSuccess(uuid.clone())); - trace!("sent message"); ping_map.insert(uuid.clone(), PingValue { ip: ip.clone(), online: true }); - trace!("updated ping_map"); + let _ = tx.send(BroadcastCommands::PingSuccess(uuid.clone())); tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; - debug!("remove {} from ping_map after success", uuid); + trace!("remove {} from ping_map after success", uuid); ping_map.remove(&uuid); } @@ -72,12 +70,12 @@ pub async fn status_websocket(mut socket: WebSocket, state: Arc) { trace!("Search for uuid: {:?}", uuid); - let device_exists = state.ping_map.contains_key(&uuid); - match device_exists { - true => { - let _ = socket.send(process_device(state.clone(), uuid).await).await; + match state.ping_map.get(&uuid) { + Some(device) => { + debug!("got device: {} (online: {})", device.ip, device.online); + let _ = socket.send(process_device(state.clone(), uuid, device.to_owned()).await).await; }, - false => { + None => { debug!("didn't find any device"); let _ = socket.send(Message::Text(format!("notfound_{}", uuid))).await; }, @@ -86,10 +84,7 @@ pub async fn status_websocket(mut socket: WebSocket, state: Arc) { let _ = socket.close().await; } -async fn process_device(state: Arc, uuid: String) -> Message { - let pm = state.ping_map.clone().into_read_only(); - let device = pm.get(&uuid).expect("fatal error"); - debug!("got device: {} (online: {})", device.ip, device.online); +async fn process_device(state: Arc, uuid: String, device: PingValue) -> Message { match device.online { true => { debug!("already started"); -- cgit v1.2.3 From 32561060a8dc6fc6118498da06bdd8f5b4c3f0fd Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Thu, 2 Nov 2023 20:59:36 +0100 Subject: fixed broadcast and cleanup --- src/routes/start.rs | 5 ++--- src/services/ping.rs | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/routes/start.rs b/src/routes/start.rs index 9cd358b..271f924 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use std::sync::Arc; use axum::extract::State; use serde_json::{json, Value}; -use tracing::{debug, info, warn}; +use tracing::{debug, info}; use uuid::Uuid; use crate::auth::auth; use crate::config::SETTINGS; @@ -16,7 +16,6 @@ use crate::services::ping::PingValue; #[axum_macros::debug_handler] pub async fn start(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, WebolError> { info!("POST request"); - warn!("{:?}", state.ping_map); let secret = headers.get("authorization"); let authorized = auth(secret).map_err(WebolError::Auth)?; if authorized { @@ -46,7 +45,7 @@ pub async fn start(State(state): State>, headers: HeaderMap let uuid_gen = Uuid::new_v4().to_string(); let uuid_genc = uuid_gen.clone(); tokio::spawn(async move { - debug!("Init ping service"); + debug!("init ping service"); state.ping_map.insert(uuid_gen.clone(), PingValue { ip: device.ip.clone(), online: false }); crate::services::ping::spawn(state.ping_send.clone(), device.ip, uuid_gen.clone(), &state.ping_map).await diff --git a/src/services/ping.rs b/src/services/ping.rs index a26dacc..d900acb 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -41,7 +41,7 @@ pub async fn spawn(tx: Sender, ip: String, uuid: String, ping } } else { let (_, duration) = ping.map_err(|err| error!("{}", err.to_string())).expect("fatal error"); - debug!("Ping took {:?}", duration); + debug!("ping took {:?}", duration); cont = false; handle_broadcast_send(&tx, ip.clone(), ping_map, uuid.clone()).await; }; @@ -50,10 +50,12 @@ pub async fn spawn(tx: Sender, ip: String, uuid: String, ping async fn handle_broadcast_send(tx: &Sender, ip: String, ping_map: &PingMap, uuid: String) { debug!("send pingsuccess message"); - ping_map.insert(uuid.clone(), PingValue { ip: ip.clone(), online: true }); let _ = tx.send(BroadcastCommands::PingSuccess(uuid.clone())); + trace!("sent message"); + ping_map.insert(uuid.clone(), PingValue { ip: ip.clone(), online: true }); + trace!("updated ping_map"); tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; - trace!("remove {} from ping_map after success", uuid); + debug!("remove {} from ping_map after success", uuid); ping_map.remove(&uuid); } @@ -70,12 +72,12 @@ pub async fn status_websocket(mut socket: WebSocket, state: Arc) { trace!("Search for uuid: {:?}", uuid); - match state.ping_map.get(&uuid) { - Some(device) => { - debug!("got device: {} (online: {})", device.ip, device.online); - let _ = socket.send(process_device(state.clone(), uuid, device.to_owned()).await).await; + let device_exists = state.ping_map.contains_key(&uuid); + match device_exists { + true => { + let _ = socket.send(process_device(state.clone(), uuid).await).await; }, - None => { + false => { debug!("didn't find any device"); let _ = socket.send(Message::Text(format!("notfound_{}", uuid))).await; }, @@ -84,7 +86,10 @@ pub async fn status_websocket(mut socket: WebSocket, state: Arc) { let _ = socket.close().await; } -async fn process_device(state: Arc, uuid: String, device: PingValue) -> Message { +async fn process_device(state: Arc, uuid: String) -> Message { + let pm = state.ping_map.clone().into_read_only(); + let device = pm.get(&uuid).expect("fatal error"); + debug!("got device: {} (online: {})", device.ip, device.online); match device.online { true => { debug!("already started"); -- cgit v1.2.3