From 42cb010236e5998a82093228242d6815db9a39ec Mon Sep 17 00:00:00 2001 From: Reverier-Xu Date: Tue, 15 Aug 2023 22:19:14 +0800 Subject: [PATCH] :sparkles: update dependencies & various fixes --- README.md | 6 ---- cli/Cargo.toml | 6 ++-- cli/src/connection.rs | 12 +++++-- cli/src/main.rs | 11 ++++-- desktop/package.json | 2 +- desktop/src-tauri/Cargo.toml | 7 ++-- desktop/src-tauri/src/connection.rs | 52 +++++++++++++++++++++------ desktop/src-tauri/tauri.conf.json | 2 +- desktop/src/views/ConnectionsView.vue | 7 ++-- lib/Cargo.toml | 6 ++-- 10 files changed, 76 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 1b1bd6a..fb81ac8 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,6 @@ Controlled TCP-over-WebSocket forwarding tunnel. -## Project Status - -This tool is rewriting with Rust, maybe unavailable for a long time now. - -You can find previous version in GitHub Releases and tags, it's written in go and could work as expected. - ## Desktop App WebSocket Reflector X provides a simple desktop app written in Tauri. diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 48ff6c7..3ea8228 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,19 +1,19 @@ [package] name = "wsrx-cli" -version = "0.1.4" +version = "0.1.5" edition = "2021" authors = ["Reverier-Xu "] description = "Controlled TCP-over-WebSocket forwarding tunnel." [dependencies] wsrx = { version = "*", path = "../lib" } -tokio = { version = "1.29", features = ["full"] } +tokio = { version = "1.31", features = ["full"] } clap = {version = "4.3", features = ["cargo"]} serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" tokio-util = "0.7" tokio-stream = "0.1" -tokio-tungstenite = { version = "0.18", features = ["rustls-tls-native-roots"] } +tokio-tungstenite = { version = "0.20", features = ["rustls-tls-native-roots"] } thiserror = "1.0" anyhow = "1.0" once_cell = "1.18" diff --git a/cli/src/connection.rs b/cli/src/connection.rs index cbe49b0..d0cc6c2 100644 --- a/cli/src/connection.rs +++ b/cli/src/connection.rs @@ -2,9 +2,14 @@ use tokio::net::TcpListener; use tokio::net::TcpStream; use url::Url; -pub async fn connect(url: impl AsRef, port: Option) -> anyhow::Result<()> { +pub async fn connect(url: impl AsRef, port: Option, bind_global: bool) -> anyhow::Result<()> { let port = port.unwrap_or(0); - let listener = TcpListener::bind(format!("127.0.0.1:{port}")).await?; + let interface = if bind_global { + "0.0.0.0" + } else { + "127.0.0.1" + }; + let listener = TcpListener::bind(format!("{interface}:{port}")).await?; let port = listener.local_addr()?.port(); let url = Url::parse(url.as_ref())?; if url.scheme() != "ws" && url.scheme() != "wss" { @@ -12,6 +17,9 @@ pub async fn connect(url: impl AsRef, port: Option) -> anyhow::Result< } let url = url.as_ref().to_string(); log::info!("Hi, I am not RX, RX is here -> 127.0.0.1:{port}"); + if bind_global { + log::info!("This proxy is bound to 0.0.0.0, access it from other device is supported."); + } loop { let (tcp, _) = listener.accept().await.expect("Failed to accept tcp connection"); let url = url.clone(); diff --git a/cli/src/main.rs b/cli/src/main.rs index 43fa38c..1642822 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -17,20 +17,27 @@ async fn main() { ) .required(false).value_parser(value_parser!(u16)), ) + .arg( + arg!( + -g --global "Listen on all interfaces" + ) + .required(false).value_parser(value_parser!(bool)), + ) .get_matches(); let url = matches .get_one::("url") .expect("The aim WebSocket URL is required") .to_string(); + let bind_global = matches.get_one::("global").unwrap_or(&false).to_owned(); match matches.get_one::("port") { Some(port) => { - connection::connect(url, Some(port.to_owned())) + connection::connect(url, Some(port.to_owned()), bind_global) .await .expect("Failed to connect to WebSocket server"); } None => { - connection::connect(url, None) + connection::connect(url, None, bind_global) .await .expect("Failed to connect to WebSocket server"); } diff --git a/desktop/package.json b/desktop/package.json index 02b6113..ae787ae 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -1,7 +1,7 @@ { "name": "desktop", "private": true, - "version": "0.1.4", + "version": "0.1.5", "type": "module", "scripts": { "dev": "vite", diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index 03d4e62..844268d 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wsrx-desktop" -version = "0.1.4" +version = "0.1.5" description = "WSRX Desktop Frontend" authors = ["Reverier-Xu "] edition = "2021" @@ -15,15 +15,16 @@ tauri = { version = "1.4", features = ["dialog-all", "fs-all", "protocol-all", " serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" wsrx = { version = "0.1", path = "../../lib" } -tokio = { version = "1.29", features = ["full"] } +tokio = { version = "1.31", features = ["full"] } tokio-util = "0.7" tokio-stream = "0.1" -tokio-tungstenite = { version = "0.18", features = ["rustls-tls-native-roots"] } +tokio-tungstenite = { version = "0.20", features = ["rustls-tls-native-roots"] } thiserror = "1.0" anyhow = "1.0" once_cell = "1.18" url = "2.4" log = "0.4" +reqwest = "0.11" [features] # this feature is used for production builds or when `devPath` points to the filesystem diff --git a/desktop/src-tauri/src/connection.rs b/desktop/src-tauri/src/connection.rs index 348c35a..be80803 100644 --- a/desktop/src-tauri/src/connection.rs +++ b/desktop/src-tauri/src/connection.rs @@ -43,11 +43,19 @@ pub struct Log { static RUNTIME_LOG: Lazy>>> = Lazy::new(|| Arc::new(RwLock::new(Vec::new()))); -pub async fn add_ws_connection(target_addr: impl AsRef, bind_addr: impl AsRef) -> anyhow::Result<()> { - let listener = TcpListener::bind(bind_addr.as_ref().to_owned() + ":0").await.unwrap(); - let port = listener.local_addr().unwrap().port(); - let url = Url::parse(target_addr.as_ref()).unwrap(); - let id = format!("{}#{}", url.host_str().unwrap(), port); +pub async fn add_ws_connection( + target_addr: impl AsRef, + bind_addr: impl AsRef, +) -> anyhow::Result<()> { + let listener = TcpListener::bind(bind_addr.as_ref().trim().to_owned() + ":0").await?; + let port = listener.local_addr()?.port(); + let url = Url::parse(target_addr.as_ref().trim())?; + let id = format!( + "{}#{}", + url.host_str() + .ok_or_else(|| anyhow::anyhow!("extract URL host failed"))?, + port + ); let conn = Connection { id: id.clone(), url: target_addr.as_ref().to_string(), @@ -135,20 +143,42 @@ pub async fn refresh_latency() -> anyhow::Result<()> { let mut dead_conns = Vec::new(); for (_, conn) in cm.connections.iter_mut() { let start = std::time::Instant::now(); - let (mut ws, _) = match tokio_tungstenite::connect_async(conn.url.as_str()).await { - Ok(tup) => tup, - Err(_) => { + match reqwest::get( + conn.url + .as_str() + .replace("wss://", "https://") + .replace("ws://", "http://"), + ) + .await + { + Ok(resp) => { + if !resp.status().is_success() { + let mut logs = RUNTIME_LOG.write().await; + logs.push(Log { + level: "warning".to_owned(), + message: format!( + "Remote server returned non-200 status code: {}, removing link.", + resp.status() + ), + addr: conn.url.clone(), + }); + dead_conns.push(conn.id.clone()); + continue; + } + } + Err(err) => { let mut logs = RUNTIME_LOG.write().await; logs.push(Log { - level: "warning".to_owned(), - message: format!("Dead link detected from remote server, removed."), + level: "error".to_owned(), + message: format!( + "Can not connect to remote server with reason: {err}, removing link." + ), addr: conn.url.clone(), }); dead_conns.push(conn.id.clone()); continue; } }; - let _ = ws.close(None).await; conn.latency = start.elapsed().as_millis() as u32; } for id in dead_conns { diff --git a/desktop/src-tauri/tauri.conf.json b/desktop/src-tauri/tauri.conf.json index ea6fe12..3beb405 100644 --- a/desktop/src-tauri/tauri.conf.json +++ b/desktop/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "WSRX Desktop", - "version": "0.1.4" + "version": "0.1.5" }, "tauri": { "allowlist": { diff --git a/desktop/src/views/ConnectionsView.vue b/desktop/src/views/ConnectionsView.vue index 93098ea..f85ba31 100644 --- a/desktop/src/views/ConnectionsView.vue +++ b/desktop/src/views/ConnectionsView.vue @@ -17,7 +17,7 @@ {{ connection.id }} -> localhost:{{ connection.port }} - {{ connection.latency }} ms + {{ connection.latency === 0 ? "--" : connection.latency }} ms @@ -44,12 +44,13 @@

{{ connection.id }} - {{ connection.latency }} ms + {{ connection.latency === 0 ? "--" : connection.latency }} ms

{{ connection.url }}

- diff --git a/lib/Cargo.toml b/lib/Cargo.toml index b977af2..f39f557 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wsrx" -version = "0.1.4" +version = "0.1.5" edition = "2021" authors = ["Reverier-Xu "] description = "Controlled TCP-over-WebSocket forwarding tunnel." @@ -11,7 +11,7 @@ readme = "README.md" license = "MPL-2.0" [dependencies] -tokio = { version = "1.29", features = ["full"] } +tokio = { version = "1.31", features = ["full"] } axum = { version = "0.6", features = [ "headers", "ws", @@ -29,6 +29,6 @@ anyhow = "1.0" toml = "0.7" uuid = "1.4" base64 = "0.21" -tokio-tungstenite = { version = "0.18", features = ["rustls-tls-native-roots"] } +tokio-tungstenite = { version = "0.20", features = ["rustls-tls-native-roots"] } tracing = "0.1" futures-util = "0.3"