feat(transport): add websocket transport (#290)

This commit is contained in:
I Putu Ariyasa 2023-10-01 13:43:03 +07:00 committed by GitHub
parent d2fe586f7b
commit 5946a18370
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 731 additions and 94 deletions

328
Cargo.lock generated
View File

@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
@ -90,7 +99,7 @@ checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.103",
]
[[package]]
@ -101,7 +110,7 @@ checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.103",
]
[[package]]
@ -180,6 +189,21 @@ dependencies = [
"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]]
name = "base64"
version = "0.13.1"
@ -310,7 +334,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
"syn 1.0.103",
]
[[package]]
@ -444,6 +468,12 @@ dependencies = [
"zeroize",
]
[[package]]
name = "data-encoding"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
[[package]]
name = "digest"
version = "0.10.5"
@ -478,7 +508,7 @@ checksum = "828de45d0ca18782232dfb8f3ea9cc428e8ced380eb26a520baaacfc70de39ce"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.103",
]
[[package]]
@ -518,7 +548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
dependencies = [
"crc32fast",
"miniz_oxide",
"miniz_oxide 0.5.4",
]
[[package]]
@ -586,9 +616,9 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.25"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
[[package]]
name = "futures-io"
@ -598,32 +628,32 @@ checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
[[package]]
name = "futures-macro"
version = "0.3.25"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.37",
]
[[package]]
name = "futures-sink"
version = "0.3.25"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
[[package]]
name = "futures-task"
version = "0.3.25"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
[[package]]
name = "futures-util"
version = "0.3.25"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
dependencies = [
"futures-core",
"futures-macro",
@ -664,7 +694,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
"syn 1.0.103",
]
[[package]]
@ -677,6 +707,12 @@ dependencies = [
"polyval",
]
[[package]]
name = "gimli"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
[[package]]
name = "git2"
version = "0.14.4"
@ -797,9 +833,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hyper"
version = "0.14.22"
version = "0.14.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abfba89e19b959ca163c7752ba59d737c1ceea53a5d31a149c805446fc958064"
checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
dependencies = [
"bytes",
"futures-channel",
@ -812,7 +848,7 @@ dependencies = [
"httpdate",
"itoa",
"pin-project-lite",
"socket2",
"socket2 0.4.7",
"tokio",
"tower-service",
"tracing",
@ -932,9 +968,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.137"
version = "0.2.148"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
[[package]]
name = "libgit2-sys"
@ -1022,15 +1058,24 @@ dependencies = [
]
[[package]]
name = "mio"
version = "0.8.5"
name = "miniz_oxide"
version = "0.7.1"
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 = [
"libc",
"log",
"wasi",
"windows-sys 0.42.0",
"windows-sys 0.48.0",
]
[[package]]
@ -1117,6 +1162,15 @@ dependencies = [
"libc",
]
[[package]]
name = "object"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.16.0"
@ -1152,7 +1206,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.103",
]
[[package]]
@ -1257,14 +1311,14 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.103",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
[[package]]
name = "pin-utils"
@ -1316,7 +1370,7 @@ dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"syn 1.0.103",
"version_check",
]
@ -1333,9 +1387,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.47"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
dependencies = [
"unicode-ident",
]
@ -1360,7 +1414,7 @@ dependencies = [
"itertools",
"proc-macro2",
"quote",
"syn",
"syn 1.0.103",
]
[[package]]
@ -1375,9 +1429,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.21"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
@ -1428,6 +1482,8 @@ dependencies = [
"clap",
"console-subscriber",
"fdlimit",
"futures-core",
"futures-sink",
"hex",
"lazy_static",
"notify",
@ -1435,9 +1491,11 @@ dependencies = [
"serde",
"sha2",
"snowstorm",
"socket2",
"socket2 0.4.7",
"tokio",
"tokio-native-tls",
"tokio-tungstenite",
"tokio-util",
"toml",
"tracing",
"tracing-subscriber",
@ -1487,6 +1545,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "rustc-demangle"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc_version"
version = "0.4.0"
@ -1564,22 +1628,22 @@ checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
[[package]]
name = "serde"
version = "1.0.147"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.147"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.37",
]
[[package]]
@ -1593,6 +1657,17 @@ dependencies = [
"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]]
name = "sha2"
version = "0.10.6"
@ -1677,6 +1752,16 @@ dependencies = [
"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]]
name = "strsim"
version = "0.10.0"
@ -1701,10 +1786,21 @@ dependencies = [
]
[[package]]
name = "sync_wrapper"
version = "0.1.1"
name = "syn"
version = "2.0.37"
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]]
name = "tempfile"
@ -1737,22 +1833,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
[[package]]
name = "thiserror"
version = "1.0.37"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.37"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.37",
]
[[package]]
@ -1810,23 +1906,22 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.24.2"
version = "1.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb"
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
dependencies = [
"autocfg",
"backtrace",
"bytes",
"libc",
"memchr",
"mio",
"num_cpus",
"parking_lot 0.12.1",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"socket2 0.5.4",
"tokio-macros",
"tracing",
"windows-sys 0.42.0",
"windows-sys 0.48.0",
]
[[package]]
@ -1841,13 +1936,13 @@ dependencies = [
[[package]]
name = "tokio-macros"
version = "1.8.0"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.37",
]
[[package]]
@ -1872,10 +1967,22 @@ dependencies = [
]
[[package]]
name = "tokio-util"
version = "0.7.4"
name = "tokio-tungstenite"
version = "0.20.1"
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 = [
"bytes",
"futures-core",
@ -1998,7 +2105,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.103",
]
[[package]]
@ -2057,6 +2164,25 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "typenum"
version = "1.15.0"
@ -2106,6 +2232,12 @@ dependencies = [
"serde",
]
[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "valuable"
version = "0.1.0"
@ -2217,21 +2349,51 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_gnullvm 0.42.0",
"windows_aarch64_msvc 0.42.0",
"windows_i686_gnu 0.42.0",
"windows_i686_msvc 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",
]
[[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]]
name = "windows_aarch64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
@ -2244,6 +2406,12 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
@ -2256,6 +2424,12 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
@ -2268,6 +2442,12 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
@ -2280,12 +2460,24 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "windows_x86_64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "windows_x86_64_msvc"
version = "0.36.1"
@ -2298,6 +2490,12 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "zeroize"
version = "1.3.0"

View File

@ -11,7 +11,7 @@ build = "build.rs"
include = ["src/**/*", "LICENSE", "README.md", "build.rs"]
[features]
default = ["server", "client", "tls", "noise", "hot-reload"]
default = ["server", "client", "tls", "noise", "websocket", "hot-reload"]
# Run as a server
server = []
@ -21,6 +21,8 @@ client = []
tls = ["tokio-native-tls"]
# Noise support
noise = ["snowstorm", "base64"]
# Websocket support
websocket = ["tokio-tungstenite", "tokio-util", "futures-core", "futures-sink", "tls"]
# Configuration hot-reload support
hot-reload = ["notify"]
@ -74,6 +76,10 @@ atty = "0.2"
async-http-proxy = { version = "1.2", features = ["runtime-tokio", "basic-auth"] }
async-socks5 = "0.5"
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]
vergen = { version = "7.4.2", default-features = false, features = ["build", "git", "cargo"] }

View File

@ -1,12 +1,15 @@
FROM rust:alpine as builder
RUN apk add --no-cache musl-dev openssl openssl-dev pkgconfig
FROM rust:bookworm as builder
RUN apt update && apt install -y libssl-dev
WORKDIR /home/rust/src
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 cp target/release/rathole build-out/
FROM scratch
FROM gcr.io/distroless/cc-debian12
WORKDIR /app
COPY --from=builder /home/rust/src/build-out/rathole .
USER 1000:1000

View File

@ -17,20 +17,20 @@ rathole类似于 [frp](https://github.com/fatedier/frp) 和 [ngrok](https://g
<!-- TOC -->
- [rathole](#rathole)
- [Features](#features)
- [Quickstart](#quickstart)
- [Configuration](#configuration)
- [Logging](#logging)
- [Tuning](#tuning)
- [Benchmark](#benchmark)
- [Development Status](#development-status)
- [Features](#features)
- [Quickstart](#quickstart)
- [Configuration](#configuration)
- [Logging](#logging)
- [Tuning](#tuning)
- [Benchmark](#benchmark)
- [Development Status](#development-status)
<!-- /TOC -->
## Features
- **高性能** 具有更高的吞吐量,高并发下更稳定。见[Benchmark](#Benchmark)
- **低资源消耗** 内存占用远低于同类工具。见[Benchmark](#Benchmark)。[二进制文件最小](docs/build-guide.md)可以到 **~500KiB**,可以部署在嵌入式设备如路由器上。
- **高性能** 具有更高的吞吐量,高并发下更稳定。见[Benchmark](#benchmark)
- **低资源消耗** 内存占用远低于同类工具。见[Benchmark](#benchmark)。[二进制文件最小](docs/build-guide.md)可以到 **~500KiB**,可以部署在嵌入式设备如路由器上。
- **安全性** 每个服务单独强制鉴权。Server 和 Client 负责各自的配置。使用 Noise Protocol 可以简单地配置传输加密,而不需要自签证书。同时也支持 TLS。
- **热重载** 支持配置文件热重载动态修改端口转发服务。HTTP API 正在开发中。
@ -91,7 +91,7 @@ local_addr = "127.0.0.1:22" # 需要被转发的服务的地址
## Configuration
如果只有一个 `[server]``[client]` 块存在的话,`rathole` 可以根据配置文件的内容自动决定在服务器模式或客户端模式下运行,就像 [Quickstart](#Quickstart) 中的例子。
如果只有一个 `[server]``[client]` 块存在的话,`rathole` 可以根据配置文件的内容自动决定在服务器模式或客户端模式下运行,就像 [Quickstart](#quickstart) 中的例子。
`[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
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
type = "tcp" # Optional. The protocol that needs forwarding. Possible values: ["tcp", "udp"]. Default: "tcp"
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"
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
type = "tcp" # Optional. Same as the client `[client.services.X.type]
token = "whatever" # Necessary if `server.default_token` not set

View File

@ -18,20 +18,20 @@ rathole, like [frp](https://github.com/fatedier/frp) and [ngrok](https://github.
<!-- TOC -->
- [rathole](#rathole)
- [Features](#features)
- [Quickstart](#quickstart)
- [Configuration](#configuration)
- [Logging](#logging)
- [Tuning](#tuning)
- [Benchmark](#benchmark)
- [Features](#features)
- [Quickstart](#quickstart)
- [Configuration](#configuration)
- [Logging](#logging)
- [Tuning](#tuning)
- [Benchmark](#benchmark)
- [Planning](#planning)
<!-- /TOC -->
## Features
- **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.
- **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.
- **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.
@ -93,7 +93,7 @@ To run `rathole` run as a background service on Linux, checkout the [systemd exa
## 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.
@ -128,6 +128,9 @@ pattern = "Noise_NK_25519_ChaChaPoly_BLAKE2s" # Optional. Default value as shown
local_private_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
type = "tcp" # Optional. The protocol that needs forwarding. Possible values: ["tcp", "udp"]. Default: "tcp"
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"
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
type = "tcp" # Optional. Same as the client `[client.services.X.type]
token = "whatever" # Necessary if `server.default_token` not set

View File

@ -24,6 +24,8 @@ use tracing::{debug, error, info, instrument, trace, warn, Instrument, Span};
use crate::transport::NoiseTransport;
#[cfg(feature = "tls")]
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};
@ -62,6 +64,15 @@ pub async fn run_client(
#[cfg(not(feature = "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")
}
}
}

View File

@ -49,6 +49,8 @@ pub enum TransportType {
Tls,
#[serde(rename = "noise")]
Noise,
#[serde(rename = "websocket")]
Websocket,
}
/// Per service config
@ -75,8 +77,7 @@ impl ClientServiceConfig {
}
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
#[derive(Default)]
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default)]
pub enum ServiceType {
#[serde(rename = "tcp")]
#[default]
@ -85,8 +86,6 @@ pub enum ServiceType {
Udp,
}
fn default_service_type() -> ServiceType {
Default::default()
}
@ -136,6 +135,12 @@ pub struct NoiseConfig {
// 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 {
DEFAULT_NODELAY
}
@ -180,6 +185,7 @@ pub struct TransportConfig {
pub tcp: TcpConfig,
pub tls: Option<TlsConfig>,
pub noise: Option<NoiseConfig>,
pub websocket: Option<WebsocketConfig>,
}
fn default_heartbeat_timeout() -> u64 {
@ -313,6 +319,7 @@ impl Config {
// The check is done in transport
Ok(())
}
TransportType::Websocket => Ok(()),
}
}

View File

@ -27,6 +27,8 @@ use tracing::{debug, error, info, info_span, instrument, warn, Instrument, Span}
use crate::transport::NoiseTransport;
#[cfg(feature = "tls")]
use crate::transport::TlsTransport;
#[cfg(feature = "websocket")]
use crate::transport::WebsocketTransport;
type ServiceDigest = protocol::Digest; // SHA256 of a service name
type Nonce = protocol::Digest; // Also called `session_key`
@ -72,6 +74,15 @@ pub async fn run_server(
#[cfg(not(feature = "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(())

View File

@ -79,6 +79,11 @@ mod noise;
#[cfg(feature = "noise")]
pub use noise::NoiseTransport;
#[cfg(feature = "websocket")]
mod websocket;
#[cfg(feature = "websocket")]
pub use websocket::WebsocketTransport;
#[derive(Debug, Clone, Copy)]
struct Keepalive {
// tcp_keepalive_time if the underlying protocol is TCP

View File

@ -46,7 +46,7 @@ impl Transport for TlsTransport {
// if no trusted_root is specified, allow TlsConnector to use system default
let connector = native_tls::TlsConnector::builder().build()?;
Some(TlsConnector::from(connector))
},
}
};
let tls_acceptor = match config.pkcs12.as_ref() {

250
src/transport/websocket.rs Normal file
View File

@ -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)
}
}

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -59,6 +59,9 @@ async fn tcp() -> Result<()> {
#[cfg(not(target_os = "macos"))]
test("tests/for_tcp/tls_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(())
}
@ -86,6 +89,9 @@ async fn udp() -> Result<()> {
#[cfg(not(target_os = "macos"))]
test("tests/for_udp/tls_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(())
}