split
This commit is contained in:
parent
dff243369c
commit
0f33feecfc
11 changed files with 197 additions and 208 deletions
46
Cargo.lock
generated
46
Cargo.lock
generated
|
@ -71,9 +71,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstyle"
|
name = "anstyle"
|
||||||
version = "1.0.7"
|
version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstyle-parse"
|
name = "anstyle-parse"
|
||||||
|
@ -318,7 +318,7 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustls 0.22.4",
|
"rustls 0.22.4",
|
||||||
"rustls-native-certs 0.7.1",
|
"rustls-native-certs 0.7.1",
|
||||||
"rustls-pemfile 2.1.2",
|
"rustls-pemfile 2.1.3",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
@ -358,9 +358,9 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.6"
|
version = "1.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"
|
checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -413,9 +413,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.13"
|
version = "4.5.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc"
|
checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
|
@ -423,9 +423,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.13"
|
version = "4.5.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99"
|
checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
|
@ -1102,9 +1102,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http-body"
|
name = "http-body"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
|
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
|
@ -1192,9 +1192,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-util"
|
name = "hyper-util"
|
||||||
version = "0.1.6"
|
version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956"
|
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
|
@ -1911,9 +1911,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.10.5"
|
version = "1.10.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -2073,7 +2073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba"
|
checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"openssl-probe",
|
"openssl-probe",
|
||||||
"rustls-pemfile 2.1.2",
|
"rustls-pemfile 2.1.3",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"schannel",
|
"schannel",
|
||||||
"security-framework",
|
"security-framework",
|
||||||
|
@ -2090,9 +2090,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pemfile"
|
name = "rustls-pemfile"
|
||||||
version = "2.1.2"
|
version = "2.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
|
checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
|
@ -2191,18 +2191,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.204"
|
version = "1.0.205"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.204"
|
version = "1.0.205"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -3149,7 +3149,7 @@ dependencies = [
|
||||||
"ppp",
|
"ppp",
|
||||||
"regex",
|
"regex",
|
||||||
"rustls-native-certs 0.7.1",
|
"rustls-native-certs 0.7.1",
|
||||||
"rustls-pemfile 2.1.2",
|
"rustls-pemfile 2.1.3",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_regex",
|
"serde_regex",
|
||||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -14,7 +14,7 @@ scopeguard = "1.2.0"
|
||||||
|
|
||||||
bb8 = { version = "0.8", features = [] }
|
bb8 = { version = "0.8", features = [] }
|
||||||
bytes = { version = "1.7.1", features = [] }
|
bytes = { version = "1.7.1", features = [] }
|
||||||
clap = { version = "4.5.13", features = ["derive", "env"] }
|
clap = { version = "4.5.15", features = ["derive", "env"] }
|
||||||
fast-socks5 = { version = "0.9.6", features = [] }
|
fast-socks5 = { version = "0.9.6", features = [] }
|
||||||
fastwebsockets = { version = "0.8.0", features = ["upgrade", "simd", "unstable-split"] }
|
fastwebsockets = { version = "0.8.0", features = ["upgrade", "simd", "unstable-split"] }
|
||||||
futures-util = { version = "0.3.30" }
|
futures-util = { version = "0.3.30" }
|
||||||
|
@ -23,13 +23,13 @@ ppp = { version = "2.2.0", features = [] }
|
||||||
async-channel = { version = "2.3.1", features = [] }
|
async-channel = { version = "2.3.1", features = [] }
|
||||||
|
|
||||||
# For config file parsing
|
# For config file parsing
|
||||||
regex = { version = "1.10.5", default-features = false, features = ["std", "perf"] }
|
regex = { version = "1.10.6", default-features = false, features = ["std", "perf"] }
|
||||||
serde_regex = "1.1.0"
|
serde_regex = "1.1.0"
|
||||||
serde_yaml = { version = "0.9.34", features = [] }
|
serde_yaml = { version = "0.9.34", features = [] }
|
||||||
ipnet = { version = "2.9.0", features = ["serde"] }
|
ipnet = { version = "2.9.0", features = ["serde"] }
|
||||||
|
|
||||||
hyper = { version = "1.4.1", features = ["client", "http1", "http2"] }
|
hyper = { version = "1.4.1", features = ["client", "http1", "http2"] }
|
||||||
hyper-util = { version = "0.1.6", features = ["tokio", "server", "server-auto"] }
|
hyper-util = { version = "0.1.7", features = ["tokio", "server", "server-auto"] }
|
||||||
http-body-util = { version = "0.1.2" }
|
http-body-util = { version = "0.1.2" }
|
||||||
jsonwebtoken = { version = "9.3.0", default-features = false }
|
jsonwebtoken = { version = "9.3.0", default-features = false }
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
|
@ -40,9 +40,9 @@ pin-project = "1"
|
||||||
notify = { version = "6.1.1", features = [] }
|
notify = { version = "6.1.1", features = [] }
|
||||||
|
|
||||||
rustls-native-certs = { version = "0.7.1", features = [] }
|
rustls-native-certs = { version = "0.7.1", features = [] }
|
||||||
rustls-pemfile = { version = "2.1.2", features = [] }
|
rustls-pemfile = { version = "2.1.3", features = [] }
|
||||||
x509-parser = "0.16.0"
|
x509-parser = "0.16.0"
|
||||||
serde = { version = "1.0.204", features = ["derive"] }
|
serde = { version = "1.0.205", features = ["derive"] }
|
||||||
socket2 = { version = "0.5.7", features = [] }
|
socket2 = { version = "0.5.7", features = [] }
|
||||||
tokio = { version = "1.39.2", features = ["full"] }
|
tokio = { version = "1.39.2", features = ["full"] }
|
||||||
tokio-stream = { version = "0.1.15", features = ["net"] }
|
tokio-stream = { version = "0.1.15", features = ["net"] }
|
||||||
|
|
|
@ -12,7 +12,8 @@ use crate::tunnel::listeners::{
|
||||||
new_stdio_listener, HttpProxyTunnelListener, Socks5TunnelListener, TcpTunnelListener, UdpTunnelListener,
|
new_stdio_listener, HttpProxyTunnelListener, Socks5TunnelListener, TcpTunnelListener, UdpTunnelListener,
|
||||||
};
|
};
|
||||||
use crate::tunnel::server::{TlsServerConfig, WsServer, WsServerConfig};
|
use crate::tunnel::server::{TlsServerConfig, WsServer, WsServerConfig};
|
||||||
use crate::tunnel::{to_host_port, LocalProtocol, RemoteAddr, TransportAddr, TransportScheme};
|
use crate::tunnel::transport::{TransportAddr, TransportScheme};
|
||||||
|
use crate::tunnel::{to_host_port, LocalProtocol, RemoteAddr};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use tokio_rustls::client::TlsStream;
|
||||||
|
|
||||||
use crate::tunnel::client::WsClientConfig;
|
use crate::tunnel::client::WsClientConfig;
|
||||||
use crate::tunnel::server::TlsServerConfig;
|
use crate::tunnel::server::TlsServerConfig;
|
||||||
use crate::tunnel::TransportAddr;
|
use crate::tunnel::transport::TransportAddr;
|
||||||
use tokio_rustls::rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
|
use tokio_rustls::rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
|
||||||
use tokio_rustls::rustls::pki_types::{CertificateDer, PrivateKeyDer, ServerName, UnixTime};
|
use tokio_rustls::rustls::pki_types::{CertificateDer, PrivateKeyDer, ServerName, UnixTime};
|
||||||
use tokio_rustls::rustls::server::WebPkiClientVerifier;
|
use tokio_rustls::rustls::server::WebPkiClientVerifier;
|
||||||
|
|
|
@ -5,8 +5,8 @@ use crate::tunnel::connectors::TunnelConnector;
|
||||||
use crate::tunnel::listeners::TunnelListener;
|
use crate::tunnel::listeners::TunnelListener;
|
||||||
use crate::tunnel::tls_reloader::TlsReloader;
|
use crate::tunnel::tls_reloader::TlsReloader;
|
||||||
use crate::tunnel::transport::io::{TunnelReader, TunnelWriter};
|
use crate::tunnel::transport::io::{TunnelReader, TunnelWriter};
|
||||||
use crate::tunnel::transport::jwt_token_to_tunnel;
|
use crate::tunnel::transport::{jwt_token_to_tunnel, TransportScheme};
|
||||||
use crate::tunnel::{RemoteAddr, TransportScheme};
|
use crate::tunnel::RemoteAddr;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use futures_util::pin_mut;
|
use futures_util::pin_mut;
|
||||||
use hyper::header::COOKIE;
|
use hyper::header::COOKIE;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::protocols::dns::DnsResolver;
|
use crate::protocols::dns::DnsResolver;
|
||||||
use crate::tunnel::TransportAddr;
|
use crate::tunnel::transport::TransportAddr;
|
||||||
use hyper::header::{HeaderName, HeaderValue};
|
use hyper::header::{HeaderName, HeaderValue};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -29,17 +29,6 @@ pub struct WsClientConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WsClientConfig {
|
impl WsClientConfig {
|
||||||
pub const fn websocket_scheme(&self) -> &'static str {
|
|
||||||
match self.remote_addr.tls().is_some() {
|
|
||||||
false => "ws",
|
|
||||||
true => "wss",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn websocket_host_url(&self) -> String {
|
|
||||||
format!("{}:{}", self.remote_addr.host(), self.remote_addr.port())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn tls_server_name(&self) -> ServerName<'static> {
|
pub fn tls_server_name(&self) -> ServerName<'static> {
|
||||||
static INVALID_DNS_NAME: Lazy<DnsName> = Lazy::new(|| DnsName::try_from("dns-name-invalid.com").unwrap());
|
static INVALID_DNS_NAME: Lazy<DnsName> = Lazy::new(|| DnsName::try_from("dns-name-invalid.com").unwrap());
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,12 @@ pub mod connectors;
|
||||||
pub mod listeners;
|
pub mod listeners;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
mod tls_reloader;
|
mod tls_reloader;
|
||||||
mod transport;
|
pub mod transport;
|
||||||
|
|
||||||
use crate::TlsClientConfig;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::Debug;
|
||||||
use std::net::{IpAddr, SocketAddr, SocketAddrV4, SocketAddrV6};
|
use std::net::{IpAddr, SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use url::Host;
|
use url::Host;
|
||||||
|
|
||||||
|
@ -72,7 +70,7 @@ impl LocalProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn is_dynamic_reverse_tunnel(&self) -> bool {
|
pub const fn is_dynamic_reverse_tunnel(&self) -> bool {
|
||||||
matches!(self, |Self::ReverseSocks5 { .. }| Self::ReverseHttpProxy { .. })
|
matches!(self, Self::ReverseSocks5 { .. } | Self::ReverseHttpProxy { .. })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,160 +81,6 @@ pub struct RemoteAddr {
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub enum TransportScheme {
|
|
||||||
Ws,
|
|
||||||
Wss,
|
|
||||||
Http,
|
|
||||||
Https,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TransportScheme {
|
|
||||||
pub const fn values() -> &'static [Self] {
|
|
||||||
&[Self::Ws, Self::Wss, Self::Http, Self::Https]
|
|
||||||
}
|
|
||||||
pub const fn to_str(self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
Self::Ws => "ws",
|
|
||||||
Self::Wss => "wss",
|
|
||||||
Self::Http => "http",
|
|
||||||
Self::Https => "https",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alpn_protocols(&self) -> Vec<Vec<u8>> {
|
|
||||||
match self {
|
|
||||||
Self::Ws => vec![],
|
|
||||||
Self::Wss => vec![b"http/1.1".to_vec()],
|
|
||||||
Self::Http => vec![],
|
|
||||||
Self::Https => vec![b"h2".to_vec()],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl FromStr for TransportScheme {
|
|
||||||
type Err = ();
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
match s {
|
|
||||||
"https" => Ok(Self::Https),
|
|
||||||
"http" => Ok(Self::Http),
|
|
||||||
"wss" => Ok(Self::Wss),
|
|
||||||
"ws" => Ok(Self::Ws),
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for TransportScheme {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.write_str(self.to_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum TransportAddr {
|
|
||||||
Wss {
|
|
||||||
tls: TlsClientConfig,
|
|
||||||
scheme: TransportScheme,
|
|
||||||
host: Host,
|
|
||||||
port: u16,
|
|
||||||
},
|
|
||||||
Ws {
|
|
||||||
scheme: TransportScheme,
|
|
||||||
host: Host,
|
|
||||||
port: u16,
|
|
||||||
},
|
|
||||||
Https {
|
|
||||||
scheme: TransportScheme,
|
|
||||||
tls: TlsClientConfig,
|
|
||||||
host: Host,
|
|
||||||
port: u16,
|
|
||||||
},
|
|
||||||
Http {
|
|
||||||
scheme: TransportScheme,
|
|
||||||
host: Host,
|
|
||||||
port: u16,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for TransportAddr {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.write_fmt(format_args!("{}://{}:{}", self.scheme(), self.host(), self.port()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TransportAddr {
|
|
||||||
pub fn new(scheme: TransportScheme, host: Host, port: u16, tls: Option<TlsClientConfig>) -> Option<Self> {
|
|
||||||
match scheme {
|
|
||||||
TransportScheme::Https => Some(Self::Https {
|
|
||||||
scheme: TransportScheme::Https,
|
|
||||||
tls: tls?,
|
|
||||||
host,
|
|
||||||
port,
|
|
||||||
}),
|
|
||||||
TransportScheme::Http => Some(Self::Http {
|
|
||||||
scheme: TransportScheme::Http,
|
|
||||||
host,
|
|
||||||
port,
|
|
||||||
}),
|
|
||||||
TransportScheme::Wss => Some(Self::Wss {
|
|
||||||
scheme: TransportScheme::Wss,
|
|
||||||
tls: tls?,
|
|
||||||
host,
|
|
||||||
port,
|
|
||||||
}),
|
|
||||||
TransportScheme::Ws => Some(Self::Ws {
|
|
||||||
scheme: TransportScheme::Ws,
|
|
||||||
host,
|
|
||||||
port,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub const fn is_websocket(&self) -> bool {
|
|
||||||
matches!(self, Self::Ws { .. } | Self::Wss { .. })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn is_http2(&self) -> bool {
|
|
||||||
matches!(self, Self::Http { .. } | Self::Https { .. })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn tls(&self) -> Option<&TlsClientConfig> {
|
|
||||||
match self {
|
|
||||||
Self::Wss { tls, .. } => Some(tls),
|
|
||||||
Self::Https { tls, .. } => Some(tls),
|
|
||||||
Self::Ws { .. } => None,
|
|
||||||
Self::Http { .. } => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn host(&self) -> &Host {
|
|
||||||
match self {
|
|
||||||
Self::Wss { host, .. } => host,
|
|
||||||
Self::Ws { host, .. } => host,
|
|
||||||
Self::Https { host, .. } => host,
|
|
||||||
Self::Http { host, .. } => host,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn port(&self) -> u16 {
|
|
||||||
match self {
|
|
||||||
Self::Wss { port, .. } => *port,
|
|
||||||
Self::Ws { port, .. } => *port,
|
|
||||||
Self::Https { port, .. } => *port,
|
|
||||||
Self::Http { port, .. } => *port,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn scheme(&self) -> &TransportScheme {
|
|
||||||
match self {
|
|
||||||
Self::Wss { scheme, .. } => scheme,
|
|
||||||
Self::Ws { scheme, .. } => scheme,
|
|
||||||
Self::Https { scheme, .. } => scheme,
|
|
||||||
Self::Http { scheme, .. } => scheme,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_host_port(addr: SocketAddr) -> (Host, u16) {
|
pub fn to_host_port(addr: SocketAddr) -> (Host, u16) {
|
||||||
match addr.ip() {
|
match addr.ip() {
|
||||||
IpAddr::V4(ip) => (Host::Ipv4(ip), addr.port()),
|
IpAddr::V4(ip) => (Host::Ipv4(ip), addr.port()),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::tunnel::listeners::TunnelListener;
|
use crate::tunnel::listeners::TunnelListener;
|
||||||
use crate::tunnel::RemoteAddr;
|
use crate::tunnel::RemoteAddr;
|
||||||
use ahash::{HashMap, HashMapExt};
|
use ahash::{AHashMap};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use futures_util::{pin_mut, StreamExt};
|
use futures_util::{pin_mut, StreamExt};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
@ -29,13 +29,13 @@ impl<T: TunnelListener> Clone for ReverseTunnelItem<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ReverseTunnelServer<T: TunnelListener> {
|
pub struct ReverseTunnelServer<T: TunnelListener> {
|
||||||
servers: Arc<Mutex<HashMap<SocketAddr, ReverseTunnelItem<T>>>>,
|
servers: Arc<Mutex<AHashMap<SocketAddr, ReverseTunnelItem<T>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TunnelListener> ReverseTunnelServer<T> {
|
impl<T: TunnelListener> ReverseTunnelServer<T> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
servers: Arc::new(Mutex::new(HashMap::with_capacity(1))),
|
servers: Arc::new(Mutex::new(AHashMap::with_capacity(1))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use super::io::{TunnelRead, TunnelWrite, MAX_PACKET_LENGTH};
|
use super::io::{TunnelRead, TunnelWrite, MAX_PACKET_LENGTH};
|
||||||
use crate::tunnel::client::WsClient;
|
use crate::tunnel::client::WsClient;
|
||||||
use crate::tunnel::transport::headers_from_file;
|
|
||||||
use crate::tunnel::transport::jwt::tunnel_to_jwt_token;
|
use crate::tunnel::transport::jwt::tunnel_to_jwt_token;
|
||||||
use crate::tunnel::{RemoteAddr, TransportScheme};
|
use crate::tunnel::transport::{headers_from_file, TransportScheme};
|
||||||
|
use crate::tunnel::RemoteAddr;
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use http_body_util::{BodyExt, BodyStream, StreamBody};
|
use http_body_util::{BodyExt, BodyStream, StreamBody};
|
||||||
|
|
|
@ -9,11 +9,15 @@ use tracing::error;
|
||||||
pub mod http2;
|
pub mod http2;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
mod jwt;
|
mod jwt;
|
||||||
|
mod types;
|
||||||
pub mod websocket;
|
pub mod websocket;
|
||||||
|
|
||||||
pub use jwt::jwt_token_to_tunnel;
|
pub use jwt::jwt_token_to_tunnel;
|
||||||
pub use jwt::tunnel_to_jwt_token;
|
pub use jwt::tunnel_to_jwt_token;
|
||||||
pub use jwt::JwtTunnelConfig;
|
pub use jwt::JwtTunnelConfig;
|
||||||
pub use jwt::JWT_HEADER_PREFIX;
|
pub use jwt::JWT_HEADER_PREFIX;
|
||||||
|
pub use types::TransportAddr;
|
||||||
|
pub use types::TransportScheme;
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
151
src/tunnel/transport/types.rs
Normal file
151
src/tunnel/transport/types.rs
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
use crate::tunnel::client::TlsClientConfig;
|
||||||
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
use std::str::FromStr;
|
||||||
|
use url::Host;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub enum TransportScheme {
|
||||||
|
Ws,
|
||||||
|
Wss,
|
||||||
|
Http,
|
||||||
|
Https,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TransportScheme {
|
||||||
|
pub const fn values() -> &'static [Self] {
|
||||||
|
&[Self::Ws, Self::Wss, Self::Http, Self::Https]
|
||||||
|
}
|
||||||
|
pub const fn to_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Ws => "ws",
|
||||||
|
Self::Wss => "wss",
|
||||||
|
Self::Http => "http",
|
||||||
|
Self::Https => "https",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alpn_protocols(&self) -> Vec<Vec<u8>> {
|
||||||
|
match self {
|
||||||
|
Self::Ws => vec![],
|
||||||
|
Self::Wss => vec![b"http/1.1".to_vec()],
|
||||||
|
Self::Http => vec![],
|
||||||
|
Self::Https => vec![b"h2".to_vec()],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl FromStr for TransportScheme {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
"https" => Ok(Self::Https),
|
||||||
|
"http" => Ok(Self::Http),
|
||||||
|
"wss" => Ok(Self::Wss),
|
||||||
|
"ws" => Ok(Self::Ws),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for TransportScheme {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str(self.to_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum TransportAddr {
|
||||||
|
Wss {
|
||||||
|
tls: TlsClientConfig,
|
||||||
|
scheme: TransportScheme,
|
||||||
|
host: Host,
|
||||||
|
port: u16,
|
||||||
|
},
|
||||||
|
Ws {
|
||||||
|
scheme: TransportScheme,
|
||||||
|
host: Host,
|
||||||
|
port: u16,
|
||||||
|
},
|
||||||
|
Https {
|
||||||
|
scheme: TransportScheme,
|
||||||
|
tls: TlsClientConfig,
|
||||||
|
host: Host,
|
||||||
|
port: u16,
|
||||||
|
},
|
||||||
|
Http {
|
||||||
|
scheme: TransportScheme,
|
||||||
|
host: Host,
|
||||||
|
port: u16,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for TransportAddr {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_fmt(format_args!("{}://{}:{}", self.scheme(), self.host(), self.port()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TransportAddr {
|
||||||
|
pub fn new(scheme: TransportScheme, host: Host, port: u16, tls: Option<TlsClientConfig>) -> Option<Self> {
|
||||||
|
match scheme {
|
||||||
|
TransportScheme::Https => Some(Self::Https {
|
||||||
|
scheme: TransportScheme::Https,
|
||||||
|
tls: tls?,
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
}),
|
||||||
|
TransportScheme::Http => Some(Self::Http {
|
||||||
|
scheme: TransportScheme::Http,
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
}),
|
||||||
|
TransportScheme::Wss => Some(Self::Wss {
|
||||||
|
scheme: TransportScheme::Wss,
|
||||||
|
tls: tls?,
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
}),
|
||||||
|
TransportScheme::Ws => Some(Self::Ws {
|
||||||
|
scheme: TransportScheme::Ws,
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn tls(&self) -> Option<&TlsClientConfig> {
|
||||||
|
match self {
|
||||||
|
Self::Wss { tls, .. } => Some(tls),
|
||||||
|
Self::Https { tls, .. } => Some(tls),
|
||||||
|
Self::Ws { .. } => None,
|
||||||
|
Self::Http { .. } => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn host(&self) -> &Host {
|
||||||
|
match self {
|
||||||
|
Self::Wss { host, .. } => host,
|
||||||
|
Self::Ws { host, .. } => host,
|
||||||
|
Self::Https { host, .. } => host,
|
||||||
|
Self::Http { host, .. } => host,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn port(&self) -> u16 {
|
||||||
|
match self {
|
||||||
|
Self::Wss { port, .. } => *port,
|
||||||
|
Self::Ws { port, .. } => *port,
|
||||||
|
Self::Https { port, .. } => *port,
|
||||||
|
Self::Http { port, .. } => *port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn scheme(&self) -> &TransportScheme {
|
||||||
|
match self {
|
||||||
|
Self::Wss { scheme, .. } => scheme,
|
||||||
|
Self::Ws { scheme, .. } => scheme,
|
||||||
|
Self::Https { scheme, .. } => scheme,
|
||||||
|
Self::Http { scheme, .. } => scheme,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue