编译websocket

This commit is contained in:
lbl8603
2024-07-02 21:18:08 +08:00
parent 98c394c993
commit 7e218355f2
10 changed files with 216 additions and 65 deletions

View File

@@ -44,40 +44,40 @@ jobs:
FEATURES: default
- TARGET: x86_64-unknown-linux-musl # test in an alpine container on a mac
OS: ubuntu-latest
FEATURES: ring-cipher,openssl-vendored
FEATURES: ring-cipher,wss
- TARGET: aarch64-unknown-linux-musl # tested on aws t4g.nano in alpine container
OS: ubuntu-latest
FEATURES: ring-cipher,openssl-vendored
FEATURES: ring-cipher,wss
- TARGET: armv7-unknown-linux-musleabihf # raspberry pi 2-3-4, not tested
OS: ubuntu-latest
FEATURES: openssl-vendored
FEATURES: ring-cipher,wss
- TARGET: armv7-unknown-linux-musleabi # raspberry pi 2-3-4, not tested
OS: ubuntu-latest
FEATURES: openssl-vendored
FEATURES: ring-cipher,wss
- TARGET: arm-unknown-linux-musleabihf # raspberry pi 0-1, not tested
OS: ubuntu-latest
FEATURES: ring-cipher,openssl-vendored
FEATURES: ring-cipher,wss
- TARGET: arm-unknown-linux-musleabi # raspberry pi 0-1, not tested
OS: ubuntu-latest
FEATURES: ring-cipher,openssl-vendored
FEATURES: ring-cipher,wss
- TARGET: x86_64-apple-darwin # tested on a mac, is not properly signed so there are security warnings
OS: macos-latest
FEATURES: ring-cipher,openssl-vendored
FEATURES: ring-cipher,wss
- TARGET: aarch64-apple-darwin # tested on a mac, is not properly signed so there are security warnings
OS: macos-latest
FEATURES: ring-cipher,openssl-vendored
FEATURES: ring-cipher,wss
- TARGET: i686-pc-windows-msvc # tested on a windows machine
OS: windows-2019
FEATURES: ring-cipher,openssl-vendored
FEATURES: ring-cipher,wss
- TARGET: x86_64-pc-windows-msvc # tested on a windows machine
OS: windows-latest
FEATURES: ring-cipher,openssl-vendored
FEATURES: ring-cipher,wss
- TARGET: mipsel-unknown-linux-musl # openwrt
OS: ubuntu-latest
FEATURES: openssl-vendored,ring-cipher
FEATURES: ring-cipher,wss
- TARGET: mips-unknown-linux-musl # openwrt
OS: ubuntu-latest
FEATURES: openssl-vendored
FEATURES: ring-cipher,wss
# needs: test
runs-on: ${{ matrix.OS }}
env:

160
Cargo.lock generated
View File

@@ -121,6 +121,12 @@ dependencies = [
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
version = "1.6.0"
@@ -336,6 +342,16 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
@@ -982,22 +998,10 @@ version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"wasi",
"windows-sys 0.48.0",
]
[[package]]
name = "mio"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4929e1f84c5e54c3ec6141cd5d8b5a5c055f031f80cf78f2072920173cb4d880"
dependencies = [
"hermit-abi",
"libc",
"log",
"wasi",
"windows-sys 0.52.0",
"windows-sys 0.48.0",
]
[[package]]
@@ -1099,6 +1103,12 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-src"
version = "300.1.3+3.1.2"
@@ -1262,9 +1272,9 @@ dependencies = [
[[package]]
name = "protobuf"
version = "3.4.0"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58678a64de2fced2bdec6bca052a6716a0efe692d6e3f53d1bda6a1def64cfc0"
checksum = "b55bad9126f378a853655831eb7363b7b01b81d19f8cb1218861086ca4a1a61e"
dependencies = [
"once_cell",
"protobuf-support",
@@ -1273,9 +1283,9 @@ dependencies = [
[[package]]
name = "protobuf-codegen"
version = "3.4.0"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32777b0b3f6538d9d2e012b3fad85c7e4b9244b5958d04a6415f4333782b7a77"
checksum = "0dd418ac3c91caa4032d37cb80ff0d44e2ebe637b2fb243b6234bf89cdac4901"
dependencies = [
"anyhow",
"once_cell",
@@ -1288,9 +1298,9 @@ dependencies = [
[[package]]
name = "protobuf-parse"
version = "3.4.0"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96cb37955261126624a25b5e6bda40ae34cf3989d52a783087ca6091b29b5642"
checksum = "9d39b14605eaa1f6a340aec7f320b34064feb26c93aec35d6a9a2272a8ddfa49"
dependencies = [
"anyhow",
"indexmap 1.9.3",
@@ -1304,9 +1314,9 @@ dependencies = [
[[package]]
name = "protobuf-support"
version = "3.4.0"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1ed294a835b0f30810e13616b1cd34943c6d1e84a8f3b0dcfe466d256c3e7e7"
checksum = "a5d4d7b8601c814cfb36bcebb79f0e61e45e1e93640cf778837833bbed05c372"
dependencies = [
"thiserror",
]
@@ -1510,18 +1520,104 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "rustls"
version = "0.23.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402"
dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792"
dependencies = [
"openssl-probe",
"rustls-pemfile",
"rustls-pki-types",
"schannel",
"security-framework",
]
[[package]]
name = "rustls-pemfile"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
dependencies = [
"base64",
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
[[package]]
name = "rustls-webpki"
version = "0.102.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "ryu"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]]
name = "schannel"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "security-framework"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0"
dependencies = [
"bitflags 2.5.0",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "serde"
version = "1.0.198"
@@ -1804,7 +1900,7 @@ dependencies = [
"backtrace",
"bytes",
"libc",
"mio 0.8.11",
"mio",
"num_cpus",
"parking_lot",
"pin-project-lite",
@@ -1825,6 +1921,17 @@ dependencies = [
"syn 2.0.60",
]
[[package]]
name = "tokio-rustls"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
dependencies = [
"rustls",
"rustls-pki-types",
"tokio",
]
[[package]]
name = "tokio-tungstenite"
version = "0.23.1"
@@ -1833,7 +1940,11 @@ checksum = "c6989540ced10490aaf14e6bad2e3d33728a2813310a0c71d1574304c49631cd"
dependencies = [
"futures-util",
"log",
"rustls",
"rustls-native-certs",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tungstenite",
]
@@ -1863,6 +1974,8 @@ dependencies = [
"httparse",
"log",
"rand",
"rustls",
"rustls-pki-types",
"sha1",
"thiserror",
"utf-8",
@@ -2027,7 +2140,7 @@ dependencies = [
"libsm",
"log",
"lz4_flex",
"mio 1.0.0",
"mio",
"openssl-sys",
"packet",
"parking_lot",
@@ -2037,6 +2150,7 @@ dependencies = [
"rand",
"ring",
"rsa",
"rustls",
"sha2",
"socket2",
"spki",

View File

@@ -33,7 +33,8 @@ port_mapping = ["vnt/port_mapping"]
lz4 = ["vnt/lz4_compress"]
zstd = ["vnt/zstd_compress"]
upnp = ["vnt/upnp"]
websocket = ["vnt/websocket"]
ws = ["vnt/ws"]
wss = ["vnt/wss"]
command = []
file_config = []
log = ["log4rs"]

View File

@@ -11,6 +11,8 @@ log = "0.4.17"
[features]
default = ["default-feature"]
default-feature = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "port_mapping", "log", "command", "file_config", "lz4"]
openssl = ["vn-link/openssl", "common/openssl"]
openssl-vendored = ["vn-link/openssl-vendored", "common/openssl-vendored"]
ring-cipher = ["vn-link/ring-cipher", "common/ring-cipher"]
@@ -24,9 +26,9 @@ port_mapping = ["vn-link/port_mapping", "common/port_mapping"]
lz4 = ["vn-link/lz4_compress", "common/lz4"]
zstd = ["vn-link/zstd_compress", "common/zstd"]
upnp = ["vn-link/upnp", "common/upnp"]
websocket = ["vn-link/websocket", "common/websocket"]
ws = ["vn-link/ws", "common/ws"]
wss = ["vn-link/wss", "common/wss"]
log = ["common/log"]
command = ["common/command"]
file_config = ["common/file_config"]
default-feature = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "port_mapping", "log", "command", "file_config", "lz4"]

View File

@@ -28,4 +28,5 @@ port_mapping = ["vnt/port_mapping"]
lz4_compress = ["vnt/lz4_compress"]
zstd_compress = ["vnt/zstd_compress"]
upnp = ["vnt/upnp"]
websocket = ["vnt/websocket"]
ws = ["vnt/ws"]
wss = ["vnt/wss"]

View File

@@ -21,7 +21,7 @@ winapi = { version = "0.3.9", features = ["handleapi", "processthreadsapi", "win
[features]
default = ["default-feature"]
default-feature = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "log", "command", "file_config", "lz4"]
default-feature = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "log", "command", "file_config", "lz4", "ws"]
openssl = ["vnt/openssl", "common/openssl"]
openssl-vendored = ["vnt/openssl-vendored", "common/openssl-vendored"]
@@ -36,12 +36,12 @@ port_mapping = ["vnt/port_mapping", "common/port_mapping"]
lz4 = ["vnt/lz4_compress", "common/lz4"]
zstd = ["vnt/zstd_compress", "common/zstd"]
ip_proxy = ["vnt/ip_proxy", "common/ip_proxy"]
upnp = ["vnt/upnp", "common/upnp"]
ws = ["vnt/ws", "common/ws"]
wss = ["vnt/wss", "common/wss"]
log = ["common/log"]
command = ["common/command"]
file_config = ["common/file_config"]
upnp = ["common/upnp"]
websocket = ["common/websocket"]
[build-dependencies]
rand = "0.8.5"
chrono = "0.4.23"

View File

@@ -17,7 +17,7 @@ parking_lot = "0.12.1"
rand = "0.8.5"
sha2 = { version = "0.10.6", features = ["oid"] }
thiserror = "1.0.37"
protobuf = "3.2.0"
protobuf = "=3.2.0"
socket2 = { version = "0.5.2", features = ["all"] }
aes-gcm = { version = "0.10.2", optional = true }
ring = { version = "0.17.0", optional = true }
@@ -32,7 +32,7 @@ spki = { version = "0.7.2", features = ["fingerprint", "alloc", "base64"], optio
openssl-sys = { git = "https://github.com/lbl8603/rust-openssl", optional = true }
libsm = { git = "https://github.com/lbl8603/libsm", optional = true }
mio = { version = "1.0.0", features = ["os-poll", "net", "os-ext"] }
mio = { version = "=0.8.11", features = ["os-poll", "net", "os-ext"] }
crossbeam-queue = "0.3.11"
anyhow = "1.0.82"
dns-parser = "0.8.0"
@@ -45,18 +45,19 @@ zstd = { version = "0.13.1", optional = true }
fnv = "1.0.7"
igd = { version = "0.12.1", optional = true }
tokio-tungstenite = { version = "0.23.1", optional = true }
rustls = { version = "0.23.0", features = ["ring"], default-features = false, optional = true }
futures-util = "0.3.30"
[target.'cfg(target_os = "windows")'.dependencies]
libloading = "0.8.0"
[build-dependencies]
protobuf-codegen = "3.2.0"
protobuf-codegen = "=3.2.0"
protoc-bin-vendored = "3.0.0"
cfg_aliases = "0.2.1"
[features]
default = ["websocket", "server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "lz4_compress", "zstd_compress", "integrated_tun"]
default = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "lz4_compress", "zstd_compress", "integrated_tun"]
openssl = ["openssl-sys"]
# 从源码编译
openssl-vendored = ["openssl-sys/vendored"]
@@ -73,4 +74,5 @@ lz4_compress = ["lz4_flex"]
zstd_compress = ["zstd"]
integrated_tun = ["tun"]
upnp = ["igd"]
websocket = ["tokio-tungstenite"]
ws = ["tokio-tungstenite"]
wss = ["ws", "tokio-tungstenite/rustls-tls-native-roots", "rustls"]

View File

@@ -8,7 +8,7 @@ use crate::channel::handler::RecvChannelHandler;
use crate::channel::sender::{AcceptSocketSender, ConnectUtil};
use crate::channel::tcp_channel::tcp_listen;
use crate::channel::udp_channel::udp_listen;
#[cfg(feature = "websocket")]
#[cfg(feature = "ws")]
use crate::channel::ws_channel::ws_connect_accept;
use crate::util::StopManager;
@@ -20,7 +20,7 @@ pub mod punch;
pub mod sender;
pub mod tcp_channel;
pub mod udp_channel;
#[cfg(feature = "websocket")]
#[cfg(feature = "ws")]
pub mod ws_channel;
pub const BUFFER_SIZE: usize = 1024 * 64;
@@ -308,7 +308,7 @@ where
context.clone(),
stop_manager.clone(),
)?;
#[cfg(feature = "websocket")]
#[cfg(feature = "ws")]
ws_connect_accept(_ws_connect_r, recv_handler, context.clone(), stop_manager)?;
Ok((udp_socket_sender, connect_util))

View File

@@ -8,7 +8,8 @@ use std::thread;
use std::time::Duration;
use tokio::net::TcpStream;
use tokio::sync::mpsc::{channel, Receiver};
use tokio_tungstenite::tungstenite::Message;
use tokio_tungstenite::tungstenite::http::StatusCode;
use tokio_tungstenite::tungstenite::{Error, Message};
use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream};
use crate::channel::context::ChannelContext;
@@ -71,15 +72,44 @@ const WS_ADDR: SocketAddr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFI
async fn connect_ws<H>(
data: Vec<u8>,
url: String,
mut url: String,
recv_handler: H,
context: ChannelContext,
) -> anyhow::Result<()>
where
H: RecvChannelHandler,
{
let (mut ws, response) =
tokio::time::timeout(Duration::from_secs(3), connect_async(url)).await??;
let mut count = 0;
log::info!("尝试建立连接 {:?}", url);
let (mut ws, response) = loop {
count += 1;
if count > 3 {
Err(anyhow::anyhow!("发生多次重定向,链接终止"))?
}
match tokio::time::timeout(Duration::from_secs(3), connect_async(url)).await? {
Ok(rs) => break rs,
Err(e) => {
if let Error::Http(res) = &e {
if res.status() == StatusCode::MOVED_PERMANENTLY
|| res.status() == StatusCode::FOUND
|| res.status() == StatusCode::SEE_OTHER
|| res.status() == StatusCode::TEMPORARY_REDIRECT
|| res.status() == StatusCode::PERMANENT_REDIRECT
{
if let Some(v) = res.headers().get("Location") {
if let Ok(redirect) = v.to_str() {
log::info!("url重定向响应头 {:?}", res.headers());
log::info!("url重定向地址 {}", redirect);
url = redirect.to_string();
continue;
}
}
}
}
return Err(e)?;
}
}
};
log::info!("ws协议握手 {:?}", response);
ws.send(Message::Binary(data)).await?;
let (mut ws_write, ws_read) = ws.split();

View File

@@ -111,16 +111,17 @@ impl Config {
let mut server_address_str = server_address_str.to_lowercase();
let mut _query_dns = true;
let mut protocol = ConnectProtocol::UDP;
#[cfg(feature = "websocket")]
{
if server_address_str.starts_with("ws://") {
protocol = ConnectProtocol::WS;
_query_dns = false;
}
if server_address_str.starts_with("wss://") {
protocol = ConnectProtocol::WSS;
_query_dns = false;
}
if server_address_str.starts_with("ws://") {
#[cfg(not(feature = "ws"))]
Err(anyhow!("Ws not supported"))?;
protocol = ConnectProtocol::WS;
_query_dns = false;
}
if server_address_str.starts_with("wss://") {
#[cfg(not(feature = "wss"))]
Err(anyhow!("Wss not supported"))?;
protocol = ConnectProtocol::WSS;
_query_dns = false;
}
let mut server_address = "0.0.0.0:0".parse().unwrap();