mirror of https://github.com/rapiz1/rathole.git
feat(transport): add websocket transport (#290)
This commit is contained in:
parent
d2fe586f7b
commit
5946a18370
|
@ -2,6 +2,15 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.21.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler"
|
name = "adler"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -90,7 +99,7 @@ checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.103",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -101,7 +110,7 @@ checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.103",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -180,6 +189,21 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide 0.7.1",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
|
@ -310,7 +334,7 @@ dependencies = [
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.103",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -444,6 +468,12 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "data-encoding"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
|
@ -478,7 +508,7 @@ checksum = "828de45d0ca18782232dfb8f3ea9cc428e8ced380eb26a520baaacfc70de39ce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.103",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -518,7 +548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
|
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"miniz_oxide",
|
"miniz_oxide 0.5.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -586,9 +616,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.25"
|
version = "0.3.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
|
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
|
@ -598,32 +628,32 @@ checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-macro"
|
name = "futures-macro"
|
||||||
version = "0.3.25"
|
version = "0.3.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
|
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.25"
|
version = "0.3.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.25"
|
version = "0.3.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
|
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-util"
|
name = "futures-util"
|
||||||
version = "0.3.25"
|
version = "0.3.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
|
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-macro",
|
"futures-macro",
|
||||||
|
@ -664,7 +694,7 @@ dependencies = [
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.103",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -677,6 +707,12 @@ dependencies = [
|
||||||
"polyval",
|
"polyval",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "git2"
|
name = "git2"
|
||||||
version = "0.14.4"
|
version = "0.14.4"
|
||||||
|
@ -797,9 +833,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "0.14.22"
|
version = "0.14.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "abfba89e19b959ca163c7752ba59d737c1ceea53a5d31a149c805446fc958064"
|
checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
|
@ -812,7 +848,7 @@ dependencies = [
|
||||||
"httpdate",
|
"httpdate",
|
||||||
"itoa",
|
"itoa",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"socket2 0.4.7",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -932,9 +968,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.137"
|
version = "0.2.148"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libgit2-sys"
|
name = "libgit2-sys"
|
||||||
|
@ -1022,15 +1058,24 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "miniz_oxide"
|
||||||
version = "0.8.5"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
|
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
|
||||||
|
dependencies = [
|
||||||
|
"adler",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "0.8.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"wasi",
|
"wasi",
|
||||||
"windows-sys 0.42.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1117,6 +1162,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.32.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
|
@ -1152,7 +1206,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.103",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1257,14 +1311,14 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.103",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.9"
|
version = "0.2.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-utils"
|
name = "pin-utils"
|
||||||
|
@ -1316,7 +1370,7 @@ dependencies = [
|
||||||
"proc-macro-error-attr",
|
"proc-macro-error-attr",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.103",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1333,9 +1387,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.47"
|
version = "1.0.67"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
@ -1360,7 +1414,7 @@ dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.103",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1375,9 +1429,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.21"
|
version = "1.0.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -1428,6 +1482,8 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"console-subscriber",
|
"console-subscriber",
|
||||||
"fdlimit",
|
"fdlimit",
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
"hex",
|
"hex",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"notify",
|
"notify",
|
||||||
|
@ -1435,9 +1491,11 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
"snowstorm",
|
"snowstorm",
|
||||||
"socket2",
|
"socket2 0.4.7",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
|
"tokio-tungstenite",
|
||||||
|
"tokio-util",
|
||||||
"toml",
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
|
@ -1487,6 +1545,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -1564,22 +1628,22 @@ checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.147"
|
version = "1.0.188"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.147"
|
version = "1.0.188"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
|
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1593,6 +1657,17 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha1"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
|
@ -1677,6 +1752,16 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket2"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
|
@ -1701,10 +1786,21 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sync_wrapper"
|
name = "syn"
|
||||||
version = "0.1.1"
|
version = "2.0.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
|
checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sync_wrapper"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
|
@ -1737,22 +1833,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.37"
|
version = "1.0.48"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
|
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.37"
|
version = "1.0.48"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
|
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1810,23 +1906,22 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.24.2"
|
version = "1.32.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb"
|
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"parking_lot 0.12.1",
|
"parking_lot 0.12.1",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2 0.5.4",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.42.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1841,13 +1936,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "1.8.0"
|
version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
|
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1872,10 +1967,22 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-tungstenite"
|
||||||
version = "0.7.4"
|
version = "0.20.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
|
checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
|
||||||
|
dependencies = [
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"tokio",
|
||||||
|
"tungstenite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-util"
|
||||||
|
version = "0.7.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -1998,7 +2105,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.103",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2057,6 +2164,25 @@ version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
|
@ -2106,6 +2232,12 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf-8"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "valuable"
|
name = "valuable"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -2217,21 +2349,51 @@ version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm",
|
"windows_aarch64_gnullvm 0.42.0",
|
||||||
"windows_aarch64_msvc 0.42.0",
|
"windows_aarch64_msvc 0.42.0",
|
||||||
"windows_i686_gnu 0.42.0",
|
"windows_i686_gnu 0.42.0",
|
||||||
"windows_i686_msvc 0.42.0",
|
"windows_i686_msvc 0.42.0",
|
||||||
"windows_x86_64_gnu 0.42.0",
|
"windows_x86_64_gnu 0.42.0",
|
||||||
"windows_x86_64_gnullvm",
|
"windows_x86_64_gnullvm 0.42.0",
|
||||||
"windows_x86_64_msvc 0.42.0",
|
"windows_x86_64_msvc 0.42.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.48.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.48.5",
|
||||||
|
"windows_aarch64_msvc 0.48.5",
|
||||||
|
"windows_i686_gnu 0.48.5",
|
||||||
|
"windows_i686_msvc 0.48.5",
|
||||||
|
"windows_x86_64_gnu 0.48.5",
|
||||||
|
"windows_x86_64_gnullvm 0.48.5",
|
||||||
|
"windows_x86_64_msvc 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.42.0"
|
version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
|
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
|
@ -2244,6 +2406,12 @@ version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
|
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
|
@ -2256,6 +2424,12 @@ version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
|
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
|
@ -2268,6 +2442,12 @@ version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
|
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
|
@ -2280,12 +2460,24 @@ version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
|
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.42.0"
|
version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
|
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
|
@ -2298,6 +2490,12 @@ version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
|
|
@ -11,7 +11,7 @@ build = "build.rs"
|
||||||
include = ["src/**/*", "LICENSE", "README.md", "build.rs"]
|
include = ["src/**/*", "LICENSE", "README.md", "build.rs"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["server", "client", "tls", "noise", "hot-reload"]
|
default = ["server", "client", "tls", "noise", "websocket", "hot-reload"]
|
||||||
|
|
||||||
# Run as a server
|
# Run as a server
|
||||||
server = []
|
server = []
|
||||||
|
@ -21,6 +21,8 @@ client = []
|
||||||
tls = ["tokio-native-tls"]
|
tls = ["tokio-native-tls"]
|
||||||
# Noise support
|
# Noise support
|
||||||
noise = ["snowstorm", "base64"]
|
noise = ["snowstorm", "base64"]
|
||||||
|
# Websocket support
|
||||||
|
websocket = ["tokio-tungstenite", "tokio-util", "futures-core", "futures-sink", "tls"]
|
||||||
# Configuration hot-reload support
|
# Configuration hot-reload support
|
||||||
hot-reload = ["notify"]
|
hot-reload = ["notify"]
|
||||||
|
|
||||||
|
@ -74,6 +76,10 @@ atty = "0.2"
|
||||||
async-http-proxy = { version = "1.2", features = ["runtime-tokio", "basic-auth"] }
|
async-http-proxy = { version = "1.2", features = ["runtime-tokio", "basic-auth"] }
|
||||||
async-socks5 = "0.5"
|
async-socks5 = "0.5"
|
||||||
url = { version = "2.2", features = ["serde"] }
|
url = { version = "2.2", features = ["serde"] }
|
||||||
|
tokio-tungstenite = { version="0.20.1", optional = true}
|
||||||
|
tokio-util = { version="0.7.9", optional = true, features = ["io"] }
|
||||||
|
futures-core = { version="0.3.28", optional = true }
|
||||||
|
futures-sink = { version="0.3.28", optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
vergen = { version = "7.4.2", default-features = false, features = ["build", "git", "cargo"] }
|
vergen = { version = "7.4.2", default-features = false, features = ["build", "git", "cargo"] }
|
||||||
|
|
11
Dockerfile
11
Dockerfile
|
@ -1,12 +1,15 @@
|
||||||
FROM rust:alpine as builder
|
FROM rust:bookworm as builder
|
||||||
RUN apk add --no-cache musl-dev openssl openssl-dev pkgconfig
|
RUN apt update && apt install -y libssl-dev
|
||||||
WORKDIR /home/rust/src
|
WORKDIR /home/rust/src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN cargo build --locked --release --features client,server,noise,hot-reload
|
ARG FEATURES
|
||||||
|
RUN cargo build --locked --release --features ${FEATURES:-default}
|
||||||
RUN mkdir -p build-out/
|
RUN mkdir -p build-out/
|
||||||
RUN cp target/release/rathole build-out/
|
RUN cp target/release/rathole build-out/
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
|
|
||||||
|
FROM gcr.io/distroless/cc-debian12
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=builder /home/rust/src/build-out/rathole .
|
COPY --from=builder /home/rust/src/build-out/rathole .
|
||||||
USER 1000:1000
|
USER 1000:1000
|
||||||
|
|
26
README-zh.md
26
README-zh.md
|
@ -17,20 +17,20 @@ rathole,类似于 [frp](https://github.com/fatedier/frp) 和 [ngrok](https://g
|
||||||
<!-- TOC -->
|
<!-- TOC -->
|
||||||
|
|
||||||
- [rathole](#rathole)
|
- [rathole](#rathole)
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
- [Quickstart](#quickstart)
|
- [Quickstart](#quickstart)
|
||||||
- [Configuration](#configuration)
|
- [Configuration](#configuration)
|
||||||
- [Logging](#logging)
|
- [Logging](#logging)
|
||||||
- [Tuning](#tuning)
|
- [Tuning](#tuning)
|
||||||
- [Benchmark](#benchmark)
|
- [Benchmark](#benchmark)
|
||||||
- [Development Status](#development-status)
|
- [Development Status](#development-status)
|
||||||
|
|
||||||
<!-- /TOC -->
|
<!-- /TOC -->
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **高性能** 具有更高的吞吐量,高并发下更稳定。见[Benchmark](#Benchmark)
|
- **高性能** 具有更高的吞吐量,高并发下更稳定。见[Benchmark](#benchmark)
|
||||||
- **低资源消耗** 内存占用远低于同类工具。见[Benchmark](#Benchmark)。[二进制文件最小](docs/build-guide.md)可以到 **~500KiB**,可以部署在嵌入式设备如路由器上。
|
- **低资源消耗** 内存占用远低于同类工具。见[Benchmark](#benchmark)。[二进制文件最小](docs/build-guide.md)可以到 **~500KiB**,可以部署在嵌入式设备如路由器上。
|
||||||
- **安全性** 每个服务单独强制鉴权。Server 和 Client 负责各自的配置。使用 Noise Protocol 可以简单地配置传输加密,而不需要自签证书。同时也支持 TLS。
|
- **安全性** 每个服务单独强制鉴权。Server 和 Client 负责各自的配置。使用 Noise Protocol 可以简单地配置传输加密,而不需要自签证书。同时也支持 TLS。
|
||||||
- **热重载** 支持配置文件热重载,动态修改端口转发服务。HTTP API 正在开发中。
|
- **热重载** 支持配置文件热重载,动态修改端口转发服务。HTTP API 正在开发中。
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ local_addr = "127.0.0.1:22" # 需要被转发的服务的地址
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
如果只有一个 `[server]` 和 `[client]` 块存在的话,`rathole` 可以根据配置文件的内容自动决定在服务器模式或客户端模式下运行,就像 [Quickstart](#Quickstart) 中的例子。
|
如果只有一个 `[server]` 和 `[client]` 块存在的话,`rathole` 可以根据配置文件的内容自动决定在服务器模式或客户端模式下运行,就像 [Quickstart](#quickstart) 中的例子。
|
||||||
|
|
||||||
但 `[client]` 和 `[server]` 块也可以放在一个文件中。然后在服务器端,运行 `rathole --server config.toml`。在客户端,运行 `rathole --client config.toml` 来明确告诉 `rathole` 运行模式。
|
但 `[client]` 和 `[server]` 块也可以放在一个文件中。然后在服务器端,运行 `rathole --server config.toml`。在客户端,运行 `rathole --client config.toml` 来明确告诉 `rathole` 运行模式。
|
||||||
|
|
||||||
|
@ -126,6 +126,9 @@ pattern = "Noise_NK_25519_ChaChaPoly_BLAKE2s" # Optional. Default value as shown
|
||||||
local_private_key = "key_encoded_in_base64" # Optional
|
local_private_key = "key_encoded_in_base64" # Optional
|
||||||
remote_public_key = "key_encoded_in_base64" # Optional
|
remote_public_key = "key_encoded_in_base64" # Optional
|
||||||
|
|
||||||
|
[client.transport.websocket] # Necessary if `type` is "websocket"
|
||||||
|
tls = true # If `true` then it will use settings in `client.transport.tls`
|
||||||
|
|
||||||
[client.services.service1] # A service that needs forwarding. The name `service1` can change arbitrarily, as long as identical to the name in the server's configuration
|
[client.services.service1] # A service that needs forwarding. The name `service1` can change arbitrarily, as long as identical to the name in the server's configuration
|
||||||
type = "tcp" # Optional. The protocol that needs forwarding. Possible values: ["tcp", "udp"]. Default: "tcp"
|
type = "tcp" # Optional. The protocol that needs forwarding. Possible values: ["tcp", "udp"]. Default: "tcp"
|
||||||
token = "whatever" # Necessary if `client.default_token` not set
|
token = "whatever" # Necessary if `client.default_token` not set
|
||||||
|
@ -158,6 +161,9 @@ pattern = "Noise_NK_25519_ChaChaPoly_BLAKE2s"
|
||||||
local_private_key = "key_encoded_in_base64"
|
local_private_key = "key_encoded_in_base64"
|
||||||
remote_public_key = "key_encoded_in_base64"
|
remote_public_key = "key_encoded_in_base64"
|
||||||
|
|
||||||
|
[server.transport.websocket] # Necessary if `type` is "websocket"
|
||||||
|
tls = true # If `true` then it will use settings in `server.transport.tls`
|
||||||
|
|
||||||
[server.services.service1] # The service name must be identical to the client side
|
[server.services.service1] # The service name must be identical to the client side
|
||||||
type = "tcp" # Optional. Same as the client `[client.services.X.type]
|
type = "tcp" # Optional. Same as the client `[client.services.X.type]
|
||||||
token = "whatever" # Necessary if `server.default_token` not set
|
token = "whatever" # Necessary if `server.default_token` not set
|
||||||
|
|
24
README.md
24
README.md
|
@ -18,20 +18,20 @@ rathole, like [frp](https://github.com/fatedier/frp) and [ngrok](https://github.
|
||||||
<!-- TOC -->
|
<!-- TOC -->
|
||||||
|
|
||||||
- [rathole](#rathole)
|
- [rathole](#rathole)
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
- [Quickstart](#quickstart)
|
- [Quickstart](#quickstart)
|
||||||
- [Configuration](#configuration)
|
- [Configuration](#configuration)
|
||||||
- [Logging](#logging)
|
- [Logging](#logging)
|
||||||
- [Tuning](#tuning)
|
- [Tuning](#tuning)
|
||||||
- [Benchmark](#benchmark)
|
- [Benchmark](#benchmark)
|
||||||
- [Planning](#planning)
|
- [Planning](#planning)
|
||||||
|
|
||||||
<!-- /TOC -->
|
<!-- /TOC -->
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **High Performance** Much higher throughput can be achieved than frp, and more stable when handling a large volume of connections. See [Benchmark](#Benchmark)
|
- **High Performance** Much higher throughput can be achieved than frp, and more stable when handling a large volume of connections. See [Benchmark](#benchmark)
|
||||||
- **Low Resource Consumption** Consumes much fewer memory than similar tools. See [Benchmark](#Benchmark). [The binary can be](docs/build-guide.md) **as small as ~500KiB** to fit the constraints of devices, like embedded devices as routers.
|
- **Low Resource Consumption** Consumes much fewer memory than similar tools. See [Benchmark](#benchmark). [The binary can be](docs/build-guide.md) **as small as ~500KiB** to fit the constraints of devices, like embedded devices as routers.
|
||||||
- **Security** Tokens of services are mandatory and service-wise. The server and clients are responsible for their own configs. With the optional Noise Protocol, encryption can be configured at ease. No need to create a self-signed certificate! TLS is also supported.
|
- **Security** Tokens of services are mandatory and service-wise. The server and clients are responsible for their own configs. With the optional Noise Protocol, encryption can be configured at ease. No need to create a self-signed certificate! TLS is also supported.
|
||||||
- **Hot Reload** Services can be added or removed dynamically by hot-reloading the configuration file. HTTP API is WIP.
|
- **Hot Reload** Services can be added or removed dynamically by hot-reloading the configuration file. HTTP API is WIP.
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ To run `rathole` run as a background service on Linux, checkout the [systemd exa
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
`rathole` can automatically determine to run in the server mode or the client mode, according to the content of the configuration file, if only one of `[server]` and `[client]` block is present, like the example in [Quickstart](#Quickstart).
|
`rathole` can automatically determine to run in the server mode or the client mode, according to the content of the configuration file, if only one of `[server]` and `[client]` block is present, like the example in [Quickstart](#quickstart).
|
||||||
|
|
||||||
But the `[client]` and `[server]` block can also be put in one file. Then on the server side, run `rathole --server config.toml` and on the client side, run `rathole --client config.toml` to explicitly tell `rathole` the running mode.
|
But the `[client]` and `[server]` block can also be put in one file. Then on the server side, run `rathole --server config.toml` and on the client side, run `rathole --client config.toml` to explicitly tell `rathole` the running mode.
|
||||||
|
|
||||||
|
@ -128,6 +128,9 @@ pattern = "Noise_NK_25519_ChaChaPoly_BLAKE2s" # Optional. Default value as shown
|
||||||
local_private_key = "key_encoded_in_base64" # Optional
|
local_private_key = "key_encoded_in_base64" # Optional
|
||||||
remote_public_key = "key_encoded_in_base64" # Optional
|
remote_public_key = "key_encoded_in_base64" # Optional
|
||||||
|
|
||||||
|
[client.transport.websocket] # Necessary if `type` is "websocket"
|
||||||
|
tls = true # If `true` then it will use settings in `client.transport.tls`
|
||||||
|
|
||||||
[client.services.service1] # A service that needs forwarding. The name `service1` can change arbitrarily, as long as identical to the name in the server's configuration
|
[client.services.service1] # A service that needs forwarding. The name `service1` can change arbitrarily, as long as identical to the name in the server's configuration
|
||||||
type = "tcp" # Optional. The protocol that needs forwarding. Possible values: ["tcp", "udp"]. Default: "tcp"
|
type = "tcp" # Optional. The protocol that needs forwarding. Possible values: ["tcp", "udp"]. Default: "tcp"
|
||||||
token = "whatever" # Necessary if `client.default_token` not set
|
token = "whatever" # Necessary if `client.default_token` not set
|
||||||
|
@ -160,6 +163,9 @@ pattern = "Noise_NK_25519_ChaChaPoly_BLAKE2s"
|
||||||
local_private_key = "key_encoded_in_base64"
|
local_private_key = "key_encoded_in_base64"
|
||||||
remote_public_key = "key_encoded_in_base64"
|
remote_public_key = "key_encoded_in_base64"
|
||||||
|
|
||||||
|
[server.transport.websocket] # Necessary if `type` is "websocket"
|
||||||
|
tls = true # If `true` then it will use settings in `server.transport.tls`
|
||||||
|
|
||||||
[server.services.service1] # The service name must be identical to the client side
|
[server.services.service1] # The service name must be identical to the client side
|
||||||
type = "tcp" # Optional. Same as the client `[client.services.X.type]
|
type = "tcp" # Optional. Same as the client `[client.services.X.type]
|
||||||
token = "whatever" # Necessary if `server.default_token` not set
|
token = "whatever" # Necessary if `server.default_token` not set
|
||||||
|
|
|
@ -24,6 +24,8 @@ use tracing::{debug, error, info, instrument, trace, warn, Instrument, Span};
|
||||||
use crate::transport::NoiseTransport;
|
use crate::transport::NoiseTransport;
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
use crate::transport::TlsTransport;
|
use crate::transport::TlsTransport;
|
||||||
|
#[cfg(feature = "websocket")]
|
||||||
|
use crate::transport::WebsocketTransport;
|
||||||
|
|
||||||
use crate::constants::{run_control_chan_backoff, UDP_BUFFER_SIZE, UDP_SENDQ_SIZE, UDP_TIMEOUT};
|
use crate::constants::{run_control_chan_backoff, UDP_BUFFER_SIZE, UDP_SENDQ_SIZE, UDP_TIMEOUT};
|
||||||
|
|
||||||
|
@ -62,6 +64,15 @@ pub async fn run_client(
|
||||||
#[cfg(not(feature = "noise"))]
|
#[cfg(not(feature = "noise"))]
|
||||||
crate::helper::feature_not_compile("noise")
|
crate::helper::feature_not_compile("noise")
|
||||||
}
|
}
|
||||||
|
TransportType::Websocket => {
|
||||||
|
#[cfg(feature = "websocket")]
|
||||||
|
{
|
||||||
|
let mut client = Client::<WebsocketTransport>::from(config).await?;
|
||||||
|
client.run(shutdown_rx, update_rx).await
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "websocket"))]
|
||||||
|
crate::helper::feature_not_compile("websocket")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,8 @@ pub enum TransportType {
|
||||||
Tls,
|
Tls,
|
||||||
#[serde(rename = "noise")]
|
#[serde(rename = "noise")]
|
||||||
Noise,
|
Noise,
|
||||||
|
#[serde(rename = "websocket")]
|
||||||
|
Websocket,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Per service config
|
/// Per service config
|
||||||
|
@ -75,8 +77,7 @@ impl ClientServiceConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default)]
|
||||||
#[derive(Default)]
|
|
||||||
pub enum ServiceType {
|
pub enum ServiceType {
|
||||||
#[serde(rename = "tcp")]
|
#[serde(rename = "tcp")]
|
||||||
#[default]
|
#[default]
|
||||||
|
@ -85,8 +86,6 @@ pub enum ServiceType {
|
||||||
Udp,
|
Udp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn default_service_type() -> ServiceType {
|
fn default_service_type() -> ServiceType {
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
@ -136,6 +135,12 @@ pub struct NoiseConfig {
|
||||||
// TODO: Maybe psk can be added
|
// TODO: Maybe psk can be added
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct WebsocketConfig {
|
||||||
|
pub tls: bool,
|
||||||
|
}
|
||||||
|
|
||||||
fn default_nodelay() -> bool {
|
fn default_nodelay() -> bool {
|
||||||
DEFAULT_NODELAY
|
DEFAULT_NODELAY
|
||||||
}
|
}
|
||||||
|
@ -180,6 +185,7 @@ pub struct TransportConfig {
|
||||||
pub tcp: TcpConfig,
|
pub tcp: TcpConfig,
|
||||||
pub tls: Option<TlsConfig>,
|
pub tls: Option<TlsConfig>,
|
||||||
pub noise: Option<NoiseConfig>,
|
pub noise: Option<NoiseConfig>,
|
||||||
|
pub websocket: Option<WebsocketConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_heartbeat_timeout() -> u64 {
|
fn default_heartbeat_timeout() -> u64 {
|
||||||
|
@ -313,6 +319,7 @@ impl Config {
|
||||||
// The check is done in transport
|
// The check is done in transport
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
TransportType::Websocket => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ use tracing::{debug, error, info, info_span, instrument, warn, Instrument, Span}
|
||||||
use crate::transport::NoiseTransport;
|
use crate::transport::NoiseTransport;
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
use crate::transport::TlsTransport;
|
use crate::transport::TlsTransport;
|
||||||
|
#[cfg(feature = "websocket")]
|
||||||
|
use crate::transport::WebsocketTransport;
|
||||||
|
|
||||||
type ServiceDigest = protocol::Digest; // SHA256 of a service name
|
type ServiceDigest = protocol::Digest; // SHA256 of a service name
|
||||||
type Nonce = protocol::Digest; // Also called `session_key`
|
type Nonce = protocol::Digest; // Also called `session_key`
|
||||||
|
@ -72,6 +74,15 @@ pub async fn run_server(
|
||||||
#[cfg(not(feature = "noise"))]
|
#[cfg(not(feature = "noise"))]
|
||||||
crate::helper::feature_not_compile("noise")
|
crate::helper::feature_not_compile("noise")
|
||||||
}
|
}
|
||||||
|
TransportType::Websocket => {
|
||||||
|
#[cfg(feature = "websocket")]
|
||||||
|
{
|
||||||
|
let mut server = Server::<WebsocketTransport>::from(config).await?;
|
||||||
|
server.run(shutdown_rx, update_rx).await?;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "websocket"))]
|
||||||
|
crate::helper::feature_not_compile("websocket")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -79,6 +79,11 @@ mod noise;
|
||||||
#[cfg(feature = "noise")]
|
#[cfg(feature = "noise")]
|
||||||
pub use noise::NoiseTransport;
|
pub use noise::NoiseTransport;
|
||||||
|
|
||||||
|
#[cfg(feature = "websocket")]
|
||||||
|
mod websocket;
|
||||||
|
#[cfg(feature = "websocket")]
|
||||||
|
pub use websocket::WebsocketTransport;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
struct Keepalive {
|
struct Keepalive {
|
||||||
// tcp_keepalive_time if the underlying protocol is TCP
|
// tcp_keepalive_time if the underlying protocol is TCP
|
||||||
|
|
|
@ -46,7 +46,7 @@ impl Transport for TlsTransport {
|
||||||
// if no trusted_root is specified, allow TlsConnector to use system default
|
// if no trusted_root is specified, allow TlsConnector to use system default
|
||||||
let connector = native_tls::TlsConnector::builder().build()?;
|
let connector = native_tls::TlsConnector::builder().build()?;
|
||||||
Some(TlsConnector::from(connector))
|
Some(TlsConnector::from(connector))
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let tls_acceptor = match config.pkcs12.as_ref() {
|
let tls_acceptor = match config.pkcs12.as_ref() {
|
||||||
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
use core::result::Result;
|
||||||
|
use std::io::{Error, ErrorKind};
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use std::pin::Pin;
|
||||||
|
use std::task::{ready, Context, Poll};
|
||||||
|
|
||||||
|
use super::{AddrMaybeCached, SocketOpts, TcpTransport, TlsTransport, Transport};
|
||||||
|
use crate::config::TransportConfig;
|
||||||
|
use anyhow::anyhow;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use bytes::Bytes;
|
||||||
|
use futures_core::stream::Stream;
|
||||||
|
use futures_sink::Sink;
|
||||||
|
use tokio::io::{AsyncBufRead, AsyncRead, AsyncWrite, ReadBuf};
|
||||||
|
use tokio::net::{TcpListener, TcpStream, ToSocketAddrs};
|
||||||
|
use tokio_native_tls::TlsStream;
|
||||||
|
use tokio_tungstenite::tungstenite::protocol::WebSocketConfig;
|
||||||
|
use tokio_tungstenite::{accept_async_with_config, client_async_with_config};
|
||||||
|
use tokio_tungstenite::{tungstenite::protocol::Message, WebSocketStream};
|
||||||
|
use tokio_util::io::StreamReader;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum TransportStream {
|
||||||
|
Insecure(TcpStream),
|
||||||
|
Secure(TlsStream<TcpStream>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TransportStream {
|
||||||
|
fn get_tcpstream(&self) -> &TcpStream {
|
||||||
|
match self {
|
||||||
|
TransportStream::Insecure(s) => s,
|
||||||
|
TransportStream::Secure(s) => s.get_ref().get_ref().get_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncRead for TransportStream {
|
||||||
|
fn poll_read(
|
||||||
|
self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
buf: &mut ReadBuf<'_>,
|
||||||
|
) -> Poll<std::io::Result<()>> {
|
||||||
|
match self.get_mut() {
|
||||||
|
TransportStream::Insecure(s) => Pin::new(s).poll_read(cx, buf),
|
||||||
|
TransportStream::Secure(s) => Pin::new(s).poll_read(cx, buf),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncWrite for TransportStream {
|
||||||
|
fn poll_write(
|
||||||
|
self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
buf: &[u8],
|
||||||
|
) -> Poll<Result<usize, std::io::Error>> {
|
||||||
|
match self.get_mut() {
|
||||||
|
TransportStream::Insecure(s) => Pin::new(s).poll_write(cx, buf),
|
||||||
|
TransportStream::Secure(s) => Pin::new(s).poll_write(cx, buf),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {
|
||||||
|
match self.get_mut() {
|
||||||
|
TransportStream::Insecure(s) => Pin::new(s).poll_flush(cx),
|
||||||
|
TransportStream::Secure(s) => Pin::new(s).poll_flush(cx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_shutdown(
|
||||||
|
self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
) -> Poll<Result<(), std::io::Error>> {
|
||||||
|
match self.get_mut() {
|
||||||
|
TransportStream::Insecure(s) => Pin::new(s).poll_shutdown(cx),
|
||||||
|
TransportStream::Secure(s) => Pin::new(s).poll_shutdown(cx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct StreamWrapper {
|
||||||
|
inner: WebSocketStream<TransportStream>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stream for StreamWrapper {
|
||||||
|
type Item = Result<Bytes, Error>;
|
||||||
|
|
||||||
|
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||||
|
match Pin::new(&mut self.get_mut().inner).poll_next(cx) {
|
||||||
|
Poll::Pending => Poll::Pending,
|
||||||
|
Poll::Ready(None) => Poll::Ready(None),
|
||||||
|
Poll::Ready(Some(Err(err))) => {
|
||||||
|
Poll::Ready(Some(Err(Error::new(ErrorKind::Other, err))))
|
||||||
|
}
|
||||||
|
Poll::Ready(Some(Ok(res))) => {
|
||||||
|
if let Message::Binary(b) = res {
|
||||||
|
Poll::Ready(Some(Ok(Bytes::from(b))))
|
||||||
|
} else {
|
||||||
|
Poll::Ready(Some(Err(Error::new(
|
||||||
|
ErrorKind::InvalidData,
|
||||||
|
"unexpected frame",
|
||||||
|
))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.inner.size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct WebsocketTunnel {
|
||||||
|
inner: StreamReader<StreamWrapper, Bytes>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncRead for WebsocketTunnel {
|
||||||
|
fn poll_read(
|
||||||
|
self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
buf: &mut ReadBuf<'_>,
|
||||||
|
) -> Poll<std::io::Result<()>> {
|
||||||
|
Pin::new(&mut self.get_mut().inner).poll_read(cx, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncBufRead for WebsocketTunnel {
|
||||||
|
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<&[u8]>> {
|
||||||
|
Pin::new(&mut self.get_mut().inner).poll_fill_buf(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consume(self: Pin<&mut Self>, amt: usize) {
|
||||||
|
Pin::new(&mut self.get_mut().inner).consume(amt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncWrite for WebsocketTunnel {
|
||||||
|
fn poll_write(
|
||||||
|
self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
buf: &[u8],
|
||||||
|
) -> Poll<Result<usize, std::io::Error>> {
|
||||||
|
let sw = self.get_mut().inner.get_mut();
|
||||||
|
ready!(Pin::new(&mut sw.inner)
|
||||||
|
.poll_ready(cx)
|
||||||
|
.map_err(|err| Error::new(ErrorKind::Other, err)))?;
|
||||||
|
|
||||||
|
match Pin::new(&mut sw.inner).start_send(Message::Binary(buf.to_vec())) {
|
||||||
|
Ok(()) => Poll::Ready(Ok(buf.len())),
|
||||||
|
Err(e) => Poll::Ready(Err(Error::new(ErrorKind::Other, e))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
|
||||||
|
Pin::new(&mut self.get_mut().inner.get_mut().inner)
|
||||||
|
.poll_flush(cx)
|
||||||
|
.map_err(|err| Error::new(ErrorKind::Other, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
|
||||||
|
Pin::new(&mut self.get_mut().inner.get_mut().inner)
|
||||||
|
.poll_close(cx)
|
||||||
|
.map_err(|err| Error::new(ErrorKind::Other, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum SubTransport {
|
||||||
|
Secure(TlsTransport),
|
||||||
|
Insecure(TcpTransport),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct WebsocketTransport {
|
||||||
|
sub: SubTransport,
|
||||||
|
conf: WebSocketConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Transport for WebsocketTransport {
|
||||||
|
type Acceptor = TcpListener;
|
||||||
|
type RawStream = TcpStream;
|
||||||
|
type Stream = WebsocketTunnel;
|
||||||
|
|
||||||
|
fn new(config: &TransportConfig) -> anyhow::Result<Self> {
|
||||||
|
let wsconfig = config
|
||||||
|
.websocket
|
||||||
|
.as_ref()
|
||||||
|
.ok_or_else(|| anyhow!("Missing websocket config"))?;
|
||||||
|
|
||||||
|
let conf = WebSocketConfig {
|
||||||
|
write_buffer_size: 0,
|
||||||
|
..WebSocketConfig::default()
|
||||||
|
};
|
||||||
|
let sub = match wsconfig.tls {
|
||||||
|
true => SubTransport::Secure(TlsTransport::new(config)?),
|
||||||
|
false => SubTransport::Insecure(TcpTransport::new(config)?),
|
||||||
|
};
|
||||||
|
Ok(WebsocketTransport { sub, conf })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hint(conn: &Self::Stream, opt: SocketOpts) {
|
||||||
|
opt.apply(conn.inner.get_ref().inner.get_ref().get_tcpstream())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn bind<A: ToSocketAddrs + Send + Sync>(
|
||||||
|
&self,
|
||||||
|
addr: A,
|
||||||
|
) -> anyhow::Result<Self::Acceptor> {
|
||||||
|
TcpListener::bind(addr).await.map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn accept(&self, a: &Self::Acceptor) -> anyhow::Result<(Self::RawStream, SocketAddr)> {
|
||||||
|
let (s, addr) = match &self.sub {
|
||||||
|
SubTransport::Insecure(t) => t.accept(a).await?,
|
||||||
|
SubTransport::Secure(t) => t.accept(a).await?,
|
||||||
|
};
|
||||||
|
Ok((s, addr))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handshake(&self, conn: Self::RawStream) -> anyhow::Result<Self::Stream> {
|
||||||
|
let tsream = match &self.sub {
|
||||||
|
SubTransport::Insecure(t) => TransportStream::Insecure(t.handshake(conn).await?),
|
||||||
|
SubTransport::Secure(t) => TransportStream::Secure(t.handshake(conn).await?),
|
||||||
|
};
|
||||||
|
let wsstream = accept_async_with_config(tsream, Some(self.conf)).await?;
|
||||||
|
let tun = WebsocketTunnel {
|
||||||
|
inner: StreamReader::new(StreamWrapper { inner: wsstream }),
|
||||||
|
};
|
||||||
|
Ok(tun)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn connect(&self, addr: &AddrMaybeCached) -> anyhow::Result<Self::Stream> {
|
||||||
|
let u = format!("ws://{}", &addr.addr.as_str());
|
||||||
|
let url = Url::parse(&u).unwrap();
|
||||||
|
let tstream = match &self.sub {
|
||||||
|
SubTransport::Insecure(t) => TransportStream::Insecure(t.connect(addr).await?),
|
||||||
|
SubTransport::Secure(t) => TransportStream::Secure(t.connect(addr).await?),
|
||||||
|
};
|
||||||
|
let (wsstream, _) = client_async_with_config(url, tstream, Some(self.conf))
|
||||||
|
.await
|
||||||
|
.expect("failed to connect");
|
||||||
|
let tun = WebsocketTunnel {
|
||||||
|
inner: StreamReader::new(StreamWrapper { inner: wsstream }),
|
||||||
|
};
|
||||||
|
Ok(tun)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
[client]
|
||||||
|
remote_addr = "127.0.0.1:2333"
|
||||||
|
default_token = "default_token_if_not_specify"
|
||||||
|
|
||||||
|
[client.transport]
|
||||||
|
type = "websocket"
|
||||||
|
[client.transport.tls]
|
||||||
|
trusted_root = "examples/tls/rootCA.crt"
|
||||||
|
hostname = "localhost"
|
||||||
|
[client.transport.websocket]
|
||||||
|
tls = true
|
||||||
|
|
||||||
|
[client.services.echo]
|
||||||
|
local_addr = "127.0.0.1:8080"
|
||||||
|
[client.services.pingpong]
|
||||||
|
local_addr = "127.0.0.1:8081"
|
||||||
|
|
||||||
|
[server]
|
||||||
|
bind_addr = "0.0.0.0:2333"
|
||||||
|
default_token = "default_token_if_not_specify"
|
||||||
|
|
||||||
|
[server.transport]
|
||||||
|
type = "websocket"
|
||||||
|
[server.transport.tls]
|
||||||
|
pkcs12 = "examples/tls/identity.pfx"
|
||||||
|
pkcs12_password = "1234"
|
||||||
|
[server.transport.websocket]
|
||||||
|
tls = true
|
||||||
|
|
||||||
|
[server.services.echo]
|
||||||
|
bind_addr = "0.0.0.0:2334"
|
||||||
|
[server.services.pingpong]
|
||||||
|
bind_addr = "0.0.0.0:2335"
|
|
@ -0,0 +1,27 @@
|
||||||
|
[client]
|
||||||
|
remote_addr = "127.0.0.1:2333"
|
||||||
|
default_token = "default_token_if_not_specify"
|
||||||
|
|
||||||
|
[client.transport]
|
||||||
|
type = "websocket"
|
||||||
|
[client.transport.websocket]
|
||||||
|
tls = false
|
||||||
|
|
||||||
|
[client.services.echo]
|
||||||
|
local_addr = "127.0.0.1:8080"
|
||||||
|
[client.services.pingpong]
|
||||||
|
local_addr = "127.0.0.1:8081"
|
||||||
|
|
||||||
|
[server]
|
||||||
|
bind_addr = "0.0.0.0:2333"
|
||||||
|
default_token = "default_token_if_not_specify"
|
||||||
|
|
||||||
|
[server.transport]
|
||||||
|
type = "websocket"
|
||||||
|
[server.transport.websocket]
|
||||||
|
tls = false
|
||||||
|
|
||||||
|
[server.services.echo]
|
||||||
|
bind_addr = "0.0.0.0:2334"
|
||||||
|
[server.services.pingpong]
|
||||||
|
bind_addr = "0.0.0.0:2335"
|
|
@ -0,0 +1,37 @@
|
||||||
|
[client]
|
||||||
|
remote_addr = "127.0.0.1:2332"
|
||||||
|
default_token = "default_token_if_not_specify"
|
||||||
|
|
||||||
|
[client.transport]
|
||||||
|
type = "websocket"
|
||||||
|
[client.transport.tls]
|
||||||
|
trusted_root = "examples/tls/rootCA.crt"
|
||||||
|
hostname = "localhost"
|
||||||
|
[client.transport.websocket]
|
||||||
|
tls = true
|
||||||
|
|
||||||
|
[client.services.echo]
|
||||||
|
type = "udp"
|
||||||
|
local_addr = "127.0.0.1:8080"
|
||||||
|
[client.services.pingpong]
|
||||||
|
type = "udp"
|
||||||
|
local_addr = "127.0.0.1:8081"
|
||||||
|
|
||||||
|
[server]
|
||||||
|
bind_addr = "0.0.0.0:2332"
|
||||||
|
default_token = "default_token_if_not_specify"
|
||||||
|
|
||||||
|
[server.transport]
|
||||||
|
type = "websocket"
|
||||||
|
[server.transport.tls]
|
||||||
|
pkcs12 = "examples/tls/identity.pfx"
|
||||||
|
pkcs12_password = "1234"
|
||||||
|
[server.transport.websocket]
|
||||||
|
tls = true
|
||||||
|
|
||||||
|
[server.services.echo]
|
||||||
|
type = "udp"
|
||||||
|
bind_addr = "0.0.0.0:2334"
|
||||||
|
[server.services.pingpong]
|
||||||
|
type = "udp"
|
||||||
|
bind_addr = "0.0.0.0:2335"
|
|
@ -0,0 +1,31 @@
|
||||||
|
[client]
|
||||||
|
remote_addr = "127.0.0.1:2332"
|
||||||
|
default_token = "default_token_if_not_specify"
|
||||||
|
|
||||||
|
[client.transport]
|
||||||
|
type = "websocket"
|
||||||
|
[client.transport.websocket]
|
||||||
|
tls = false
|
||||||
|
|
||||||
|
[client.services.echo]
|
||||||
|
type = "udp"
|
||||||
|
local_addr = "127.0.0.1:8080"
|
||||||
|
[client.services.pingpong]
|
||||||
|
type = "udp"
|
||||||
|
local_addr = "127.0.0.1:8081"
|
||||||
|
|
||||||
|
[server]
|
||||||
|
bind_addr = "0.0.0.0:2332"
|
||||||
|
default_token = "default_token_if_not_specify"
|
||||||
|
|
||||||
|
[server.transport]
|
||||||
|
type = "websocket"
|
||||||
|
[server.transport.websocket]
|
||||||
|
tls = false
|
||||||
|
|
||||||
|
[server.services.echo]
|
||||||
|
type = "udp"
|
||||||
|
bind_addr = "0.0.0.0:2334"
|
||||||
|
[server.services.pingpong]
|
||||||
|
type = "udp"
|
||||||
|
bind_addr = "0.0.0.0:2335"
|
|
@ -59,6 +59,9 @@ async fn tcp() -> Result<()> {
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
test("tests/for_tcp/tls_transport.toml", Type::Tcp).await?;
|
test("tests/for_tcp/tls_transport.toml", Type::Tcp).await?;
|
||||||
test("tests/for_tcp/noise_transport.toml", Type::Tcp).await?;
|
test("tests/for_tcp/noise_transport.toml", Type::Tcp).await?;
|
||||||
|
test("tests/for_tcp/websocket_transport.toml", Type::Tcp).await?;
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
test("tests/for_tcp/websocket_tls_transport.toml", Type::Tcp).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -86,6 +89,9 @@ async fn udp() -> Result<()> {
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
test("tests/for_udp/tls_transport.toml", Type::Udp).await?;
|
test("tests/for_udp/tls_transport.toml", Type::Udp).await?;
|
||||||
test("tests/for_udp/noise_transport.toml", Type::Udp).await?;
|
test("tests/for_udp/noise_transport.toml", Type::Udp).await?;
|
||||||
|
test("tests/for_udp/websocket_transport.toml", Type::Udp).await?;
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
test("tests/for_udp/websocket_tls_transport.toml", Type::Udp).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue