diff --git a/Cargo.lock b/Cargo.lock index 20e3e9e..9da6298 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,14 +32,18 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] +dependencies = ["generic-array"] [[package]] name = "bumpalo" @@ -47,6 +51,12 @@ version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" +[[package]] +name = "bytes" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" + [[package]] name = "cc" version = "1.0.79" @@ -64,59 +74,49 @@ name = "cpufeatures" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" -dependencies = [ - "libc", -] +dependencies = ["libc"] [[package]] name = "crypto-common" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] +dependencies = ["generic-array", "typenum"] [[package]] name = "daemonize" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab8bfdaacb3c887a54d41bdf48d3af8873b3f5566469f8ba21b92057509f116e" -dependencies = [ - "libc", -] +dependencies = ["libc"] [[package]] name = "digest" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" -dependencies = [ - "block-buffer", - "crypto-common", -] +dependencies = ["block-buffer", "crypto-common"] [[package]] name = "generic-array" version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] +dependencies = ["typenum", "version_check"] [[package]] name = "getrandom" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] +dependencies = ["cfg-if", "libc", "wasi"] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = ["libc"] [[package]] name = "httparse" @@ -129,22 +129,20 @@ name = "js-sys" version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" -dependencies = [ - "wasm-bindgen", -] +dependencies = ["wasm-bindgen"] [[package]] name = "kaminari" version = "0.11.0" dependencies = [ - "lazy_static", - "lightws", - "rcgen", - "rustls-pemfile", - "tokio", - "tokio-rustls", - "udpflow", - "webpki-roots", + "lazy_static", + "lightws", + "rcgen", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "udpflow", + "webpki-roots", ] [[package]] @@ -153,24 +151,25 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a44efce1123e3bb26326f6636f1ca866bd8f37b861c3c1d3e3397e1106b5de8" dependencies = [ - "lazy_static", - "lightws", - "rcgen", - "rustls-pemfile", - "tokio", - "tokio-rustls", - "webpki-roots", + "lazy_static", + "lightws", + "rcgen", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "webpki-roots", ] [[package]] name = "kaminari-cmd" version = "0.5.7" dependencies = [ - "anyhow", - "kaminari 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "realm_io", - "realm_syscall", - "tokio", + "anyhow", + "kaminari 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "realm_io", + "realm_syscall", + "tokio", + "udpflow", ] [[package]] @@ -190,35 +189,41 @@ name = "lightws" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2d9475b8e6d54b95d6fbf2118a19eac71995f00533b5d7e186246ce0c0ee82" -dependencies = [ - "base64 0.20.0", - "cfg-if", - "httparse", - "rand", - "sha1", - "tokio", -] +dependencies = ["base64 0.20.0", "cfg-if", "httparse", "rand", "sha1", "tokio"] + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = ["autocfg", "scopeguard"] [[package]] name = "log" version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +dependencies = ["cfg-if"] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mio" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.45.0", -] +dependencies = ["libc", "log", "wasi", "windows-sys 0.45.0"] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = ["hermit-abi", "libc"] [[package]] name = "once_cell" @@ -226,14 +231,26 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = ["lock_api", "parking_lot_core"] + +[[package]] +name = "parking_lot_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +dependencies = ["cfg-if", "libc", "redox_syscall", "smallvec", "windows-sys"] + [[package]] name = "pem" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" -dependencies = [ - "base64 0.13.1", -] +dependencies = ["base64 0.13.1"] [[package]] name = "pin-project-lite" @@ -252,81 +269,63 @@ name = "proc-macro2" version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" -dependencies = [ - "unicode-ident", -] +dependencies = ["unicode-ident"] [[package]] name = "quote" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" -dependencies = [ - "proc-macro2", -] +dependencies = ["proc-macro2"] [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] +dependencies = ["libc", "rand_chacha", "rand_core"] [[package]] name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] +dependencies = ["ppv-lite86", "rand_core"] [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] +dependencies = ["getrandom"] [[package]] name = "rcgen" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" -dependencies = [ - "pem", - "ring", - "time", - "yasna", -] +dependencies = ["pem", "ring", "time", "yasna"] [[package]] name = "realm_io" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "419b106090b985e393ac20b68845ca77d5a7fc9af6126ae97fbd8825bbdbaf69" -dependencies = [ - "libc", - "tokio", -] +dependencies = ["libc", "tokio"] [[package]] name = "realm_syscall" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8edff993b2672552f1c9afd483b8704263b0a4d7d37620e5c4a7e6760f6f9868" -dependencies = [ - "daemonize", - "libc", - "socket2 0.5.2", -] +dependencies = ["daemonize", "libc", "socket2 0.5.2"] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = ["bitflags"] [[package]] name = "ring" @@ -334,13 +333,13 @@ version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", ] [[package]] @@ -348,41 +347,34 @@ name = "rustls" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07180898a28ed6a7f7ba2311594308f595e3dd2e3c3812fa0a80a47b45f17e5d" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] +dependencies = ["log", "ring", "rustls-webpki", "sct"] [[package]] name = "rustls-pemfile" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" -dependencies = [ - "base64 0.21.0", -] +dependencies = ["base64 0.21.0"] [[package]] name = "rustls-webpki" version = "0.100.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" -dependencies = [ - "ring", - "untrusted", -] +dependencies = ["ring", "untrusted"] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sct" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] +dependencies = ["ring", "untrusted"] [[package]] name = "serde" @@ -395,31 +387,34 @@ name = "sha1" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] +dependencies = ["cfg-if", "cpufeatures", "digest"] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = ["libc"] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] +dependencies = ["libc", "winapi"] [[package]] name = "socket2" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d283f86695ae989d1e18440a943880967156325ba025f05049946bff47bcc2b" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] +dependencies = ["libc", "windows-sys 0.48.0"] [[package]] name = "spin" @@ -432,32 +427,21 @@ name = "syn" version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +dependencies = ["proc-macro2", "quote", "unicode-ident"] [[package]] name = "syn" version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +dependencies = ["proc-macro2", "quote", "unicode-ident"] [[package]] name = "time" version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" -dependencies = [ - "serde", - "time-core", -] +dependencies = ["serde", "time-core"] [[package]] name = "time-core" @@ -471,13 +455,17 @@ version = "1.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" dependencies = [ - "autocfg", - "libc", - "mio", - "pin-project-lite", - "socket2 0.4.9", - "tokio-macros", - "windows-sys 0.48.0", + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "socket2 0.4.9", + "tokio-macros", + "windows-sys 0.48.0", ] [[package]] @@ -485,21 +473,14 @@ name = "tokio-macros" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.15", -] +dependencies = ["proc-macro2", "quote", "syn 2.0.15"] [[package]] name = "tokio-rustls" version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" -dependencies = [ - "rustls", - "tokio", -] +dependencies = ["rustls", "tokio"] [[package]] name = "typenum" @@ -512,9 +493,7 @@ name = "udpflow" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdcd3eb84a09ccdb41034d5d251061c6c906fc466a4589a178eaebe23c2451df" -dependencies = [ - "tokio", -] +dependencies = ["tokio"] [[package]] name = "unicode-ident" @@ -545,10 +524,7 @@ name = "wasm-bindgen" version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] +dependencies = ["cfg-if", "wasm-bindgen-macro"] [[package]] name = "wasm-bindgen-backend" @@ -556,13 +532,13 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 1.0.109", - "wasm-bindgen-shared", + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-shared", ] [[package]] @@ -570,10 +546,7 @@ name = "wasm-bindgen-macro" version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] +dependencies = ["quote", "wasm-bindgen-macro-support"] [[package]] name = "wasm-bindgen-macro-support" @@ -581,11 +554,11 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "wasm-bindgen-backend", - "wasm-bindgen-shared", + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] @@ -599,29 +572,21 @@ name = "web-sys" version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" -dependencies = [ - "js-sys", - "wasm-bindgen", -] +dependencies = ["js-sys", "wasm-bindgen"] [[package]] name = "webpki-roots" version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa54963694b65584e170cf5dc46aeb4dcaa5584e652ff5f3952e56d66aff0125" -dependencies = [ - "rustls-webpki", -] +dependencies = ["rustls-webpki"] [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] +dependencies = ["winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu"] [[package]] name = "winapi-i686-pc-windows-gnu" @@ -640,18 +605,14 @@ name = "windows-sys" version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] +dependencies = ["windows-targets 0.42.2"] [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.0", -] +dependencies = ["windows-targets 0.48.0"] [[package]] name = "windows-targets" @@ -659,13 +620,13 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -674,13 +635,13 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -772,6 +733,4 @@ name = "yasna" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" -dependencies = [ - "time", -] +dependencies = ["time"] diff --git a/cmd/Cargo.toml b/cmd/Cargo.toml index c3e58bf..46de2b2 100644 --- a/cmd/Cargo.toml +++ b/cmd/Cargo.toml @@ -12,8 +12,9 @@ license = "GPL-3.0" anyhow = "1" realm_io = "0.4.0" realm_syscall = "0.1.6" -kaminari = { version = "0.11", features = ["ws"] } -tokio = { version = "1.9", features = ["rt", "net", "macros"] } +kaminari = { path = "../kaminari", features = ["all"] } +tokio = { version = "1.0", features = ["full"] } +udpflow = "0.1" [[bin]] name = "kaminaric" @@ -22,8 +23,3 @@ path = "src/client.rs" [[bin]] name = "kaminaris" path = "src/server.rs" - -[features] -default = ["tls-rustls"] -tls-rustls = ["kaminari/tls"] -tls-openssl = [] diff --git a/cmd/README.md b/cmd/README.md index b8f038f..a10911c 100644 --- a/cmd/README.md +++ b/cmd/README.md @@ -5,18 +5,18 @@ [![downloads](https://img.shields.io/github/downloads/zephyrchien/kaminari/total?color=green)](https://github.com/zephyrchien/kaminari/releases) [![telegram](https://img.shields.io/badge/-telegram-blue?style=flat&color=grey&logo=telegram)](https://t.me/+zKbZTvQE2XtiYmIx) -Blazing-fast websocket tunnel built on top of [lightws](https://github.com/zephyrchien/lightws). +A blazing fast TCP, TLS and WebSocket tunnel. ## Intro -- Client side receives tcp then sends [tcp/ws/tls/wss]. +- Client side listens on tcp or udp and sends traffics through [tcp/ws/tls/wss] to server side. -- Server side receives [tcp/ws/tls/wss] then sends tcp. +- Server side receives the traffics then sends them to desginated remote through tcp or udp . - Compatible with shadowsocks [SIP003 plugin](https://shadowsocks.org/guide/sip003.html). ```text - tcp ws/tls/wss tcp + tcp/udp ws/tls/wss/tcp tcp/udp === ============ === +-------------------+ +-------------------+ | | | | @@ -24,7 +24,7 @@ Blazing-fast websocket tunnel built on top of [lightws](https://github.com/zephy | kaminaric | | kaminaris | <-------+ <--------------+ <-------+ | | | | - +-------------------+ +-------------------+ + +-------------------+ +-------------------+ ``` ## Usage @@ -57,9 +57,9 @@ use `ws` to enable websocket. Client or server side options: -- `host=`* : set http host. +- `host=`\* : set http host. -- `path=`* : set http path. +- `path=`\* : set http path. Client side extra options: @@ -79,7 +79,7 @@ use `tls` to enable tls. Client side options: -- `sni=`* : set sni. +- `sni=`\* : set sni. - `alpn=`: set alpn. e.g.: `h2,http/1.1`. @@ -91,11 +91,11 @@ Server side options: Requires either `cert+key` or `servername`. -- `key=`* : private key path. +- `key=`\* : private key path. -- `cert=`* : certificate path. +- `cert=`\* : certificate path. -- `servername=`* : generate self signed cert/key, use $name as CN. +- `servername=`\* : generate self signed cert/key, use $name as CN. - `ocsp=`: der-encoded OCSP response. @@ -113,6 +113,10 @@ openssl ocsp -issuer \ -respout -noverify -no_nonce ``` +#### UDP Over TCP Options + +use `uot` to enable udp over tcp feature. + ### Examples tcp ⇋ ws --- ws ⇋ tcp: @@ -147,6 +151,26 @@ kaminaris 127.0.0.1:20000 127.0.0.1:30000 'ws;host=example.com;path=/ws;tls;cert kaminaris 127.0.0.1:20000 127.0.0.1:30000 'ws;host=example.com;path=/ws;tls;servername=example.com' ``` +udp ⇋ tcp --- tcp ⇋ udp: + +```shell +kaminaric 127.0.0.1:10000 127.0.0.1:20000 'uot' + +kaminaris 127.0.0.1:20000 127.0.0.1:30000 'uot' +``` + +udp ⇋ tls --- tls ⇋ udp: + +```shell +kaminaric 127.0.0.1:10000 127.0.0.1:20000 'uot;tls;sni=example.com' + +# use cert + key +kaminaris 127.0.0.1:20000 127.0.0.1:30000 'uot;tls;cert=example.com.crt;key=example.com.key' + +# or generate self signed cert/key +kaminaris 127.0.0.1:20000 127.0.0.1:30000 'uot;tls;servername=example.com' +``` + shadowsocks plugin: ```shell @@ -161,7 +185,7 @@ sslocal -b "127.0.0.1:1080" -s "example.com:8080" -m "aes-128-gcm" -k "123456" \ --plugin-opts "ws;host=example.com;path=/chat" ``` -*To use `v2ray-plugin` on client side, add `mux=0` to disable multiplex, so that it sends standard websocket stream which can be handled by `kaminari` or any other middlewares. +\*To use `v2ray-plugin` on client side, add `mux=0` to disable multiplex, so that it sends standard websocket stream which can be handled by `kaminari` or any other middlewares. ```shell sslocal -b "127.0.0.1:1080" -s "example.com:8080" -m "aes-128-gcm" -k "123456" \ diff --git a/cmd/src/client.rs b/cmd/src/client.rs index f2bb36b..cf66fb0 100644 --- a/cmd/src/client.rs +++ b/cmd/src/client.rs @@ -2,127 +2,126 @@ use std::net::SocketAddr; use anyhow::Result; use tokio::net::{TcpListener, TcpStream}; -use realm_io::{CopyBuffer, bidi_copy_buf}; +use realm_io::{CopyBuffer, bidi_copy_buf, buf_size}; use kaminari::opt; -use kaminari::trick::Ref; use kaminari::AsyncConnect; -use kaminari::nop::NopConnect; -use kaminari::ws::WsConnect; -#[cfg(any(feature = "tls-rustls", feature = "tls-openssl"))] -use kaminari::tls::TlsConnect; - -use kaminari_cmd::{Endpoint, parse_cmd, parse_env}; +use kaminari::uot::UotConnect; +use kaminari::mix::{MixConnect, MixClientConf}; +use tokio::net::UdpSocket; +use udpflow::{UdpListener, UdpStreamLocal}; +use kaminari_cmd::{Endpoint, parse_cmd, parse_env, UDP_MAX_BUF_LENGTH}; + +enum Listener { + TcpListener(TcpListener), + UdpListener(UdpListener), +} -#[tokio::main(flavor = "current_thread")] +#[tokio::main] async fn main() -> Result<()> { let (Endpoint { local, remote }, options) = parse_env().or_else(|_| parse_cmd())?; let ws = opt::get_ws_conf(&options); - #[cfg(any(feature = "tls-rustls", feature = "tls-openssl"))] let tls = opt::get_tls_client_conf(&options); eprintln!("listen: {}", &local); eprintln!("remote: {}", &remote); - if let Some(ws) = &ws { - eprintln!("ws: {}", ws) + if let Some(ref ws) = ws { + eprintln!("ws: {ws}") } - #[cfg(any(feature = "tls-rustls", feature = "tls-openssl"))] - if let Some(tls) = &tls { + if let Some(ref tls) = tls { eprintln!("tls: {}", &tls); } - let lis = TcpListener::bind(local).await?; + let connector = MixConnect::new_shared(MixClientConf { ws, tls }); + + let uot = opt::get_uot_conf(&options); + if uot.is_some() { + eprintln!("UDP over TCP enabled."); + } + + let lis = match uot { + Some(_) => { + let socket = UdpSocket::bind(local).await.unwrap(); + Listener::UdpListener(UdpListener::new(socket)) + } + None => Listener::TcpListener(TcpListener::bind(local).await.unwrap()), + }; #[cfg(all(unix, not(target_os = "android")))] let _ = realm_syscall::bump_nofile_limit(); - macro_rules! run { - ($cc: expr) => { - println!("connect: {}", $cc.as_ref()); - loop { - match lis.accept().await { + // let connector = Ref::new(&connector); + println!("connect: {}", &connector); + loop { + match lis { + Listener::TcpListener(ref lis) => match lis.accept().await { + Ok((stream, _)) => { + tokio::spawn(relay_tcp(stream, remote, connector.clone())); + } + Err(e) => { + eprintln!("accept error: {e}"); + break; + } + }, + Listener::UdpListener(ref lis) => { + let mut buf = vec![0u8; UDP_MAX_BUF_LENGTH]; + match lis.accept(&mut buf).await { Ok((stream, _)) => { - tokio::spawn(relay(stream, remote, $cc)); + tokio::spawn(relay_uot(stream, remote, connector.clone(), buf)); } Err(e) => { - eprintln!("accept error: {}", e); + eprintln!("accept error: {e}"); break; } } } - }; - } - - macro_rules! run_ws_each { - ($client: expr) => { - let ws_mask_mode = opt::get_opt!(&options => "mask"); - match ws_mask_mode { - Some("standard") => { - eprintln!("mask: standard"); - let client = $client.standard(); - run!(Ref::new(&client)); - }, - Some("fixed") => { - let client = $client.fixed(); - eprintln!("mask: fixed"); - run!(Ref::new(&client)); - }, - _ => { - eprintln!("mask: skip"); - run!(Ref::new(&$client)); - } - }; } } - #[cfg(any(feature = "tls-rustls", feature = "tls-openssl"))] - match (ws, tls) { - (None, None) => { - let client = NopConnect {}; - run!(Ref::new(&client)); - } - (Some(ws), None) => { - let client = WsConnect::new(NopConnect {}, ws); - run_ws_each!(client); - } - (None, Some(tls)) => { - let client = TlsConnect::new(NopConnect {}, tls); - run!(Ref::new(&client)); - } - (Some(ws), Some(tls)) => { - let client = WsConnect::new(TlsConnect::new(NopConnect {}, tls), ws); - run_ws_each!(client); - } - }; + Ok(()) +} - #[cfg(not(any(feature = "tls-rustls", feature = "tls-openssl")))] - if let Some(ws) = ws { - let client = WsConnect::new(NopConnect {}, ws); - run_ws_each!(client); - } else { - let client = NopConnect {}; - run!(Ref::new(&client)); - } +async fn relay_tcp(mut local: TcpStream, remote: SocketAddr, client: T) -> std::io::Result<()> +where + T: AsyncConnect, +{ + let mut buf1 = vec![0u8; buf_size()]; + let buf2 = vec![0u8; buf_size()]; - Ok(()) + let remote = TcpStream::connect(remote).await?; + let mut remote = client.connect(remote, &mut buf1).await?; + + let buf1 = CopyBuffer::new(buf1.into_boxed_slice()); + let buf2 = CopyBuffer::new(buf2.into_boxed_slice()); + + bidi_copy_buf(&mut local, &mut remote, buf1, buf2) + .await + .map(|_| ()) } -#[rustfmt::skip] -async fn relay(mut local: TcpStream, remote: SocketAddr, client: Ref) -> std::io::Result<()> +async fn relay_uot( + mut local: UdpStreamLocal, + remote: SocketAddr, + client: T, + mut buf1: Vec, +) -> std::io::Result<()> where T: AsyncConnect, { - let mut buf1 = vec![0u8; 0x2000]; - let buf2 = vec![0u8; 0x2000]; + println!("{} -> {remote}", local.peer_addr()); + let buf2 = vec![0u8; UDP_MAX_BUF_LENGTH]; let remote = TcpStream::connect(remote).await?; + let client = UotConnect::new(client); let mut remote = client.connect(remote, &mut buf1).await?; let buf1 = CopyBuffer::new(buf1.into_boxed_slice()); let buf2 = CopyBuffer::new(buf2.into_boxed_slice()); - bidi_copy_buf(&mut local, &mut remote, buf1, buf2).await.map(|_| ()) + bidi_copy_buf(&mut local, &mut remote, buf1, buf2) + .await + .map(|_| ()) } diff --git a/cmd/src/lib.rs b/cmd/src/lib.rs index 7382916..d60244e 100644 --- a/cmd/src/lib.rs +++ b/cmd/src/lib.rs @@ -2,6 +2,8 @@ use std::env; use std::net::{SocketAddr, ToSocketAddrs}; use anyhow::Result; +pub const UDP_MAX_BUF_LENGTH: usize = 0xffff; + pub struct Endpoint { pub local: SocketAddr, pub remote: SocketAddr, @@ -14,12 +16,12 @@ pub fn parse_env() -> Result<(Endpoint, String)> { let remote_port = env::var("SS_REMOTE_PORT")?; let plugin_opts = env::var("SS_PLUGIN_OPTIONS")?; - let local = format!("{}:{}", local_host, local_port) + let local = format!("{local_host}:{local_port}") .to_socket_addrs()? .next() .unwrap(); - let remote = format!("{}:{}", remote_host, remote_port) + let remote = format!("{remote_host}:{remote_port}") .to_socket_addrs()? .next() .unwrap(); diff --git a/cmd/src/server.rs b/cmd/src/server.rs index d71d869..b1245f8 100644 --- a/cmd/src/server.rs +++ b/cmd/src/server.rs @@ -2,19 +2,24 @@ use std::net::SocketAddr; use anyhow::Result; use tokio::net::{TcpListener, TcpStream}; -use realm_io::{CopyBuffer, bidi_copy_buf}; +use realm_io::{CopyBuffer, bidi_copy_buf, buf_size}; use kaminari::opt; -use kaminari::trick::Ref; use kaminari::AsyncAccept; -use kaminari::nop::NopAccept; -use kaminari::ws::WsAccept; -#[cfg(any(feature = "tls-rustls", feature = "tls-openssl"))] -use kaminari::tls::TlsAccept; +use kaminari::uot::UotAccept; +use kaminari::mix::{MixAccept, MixServerConf}; +use tokio::net::UdpSocket; +use udpflow::UdpStreamRemote; -use kaminari_cmd::{Endpoint, parse_cmd, parse_env}; +use kaminari_cmd::{Endpoint, parse_cmd, parse_env, UDP_MAX_BUF_LENGTH}; -#[tokio::main(flavor = "current_thread")] +#[derive(Clone)] +enum Streamer { + TcpStream(SocketAddr), + UdpStream(SocketAddr), +} + +#[tokio::main] async fn main() -> Result<()> { let (Endpoint { local, remote }, options) = parse_env() .map(|(Endpoint { local, remote }, opt)| { @@ -29,89 +34,88 @@ async fn main() -> Result<()> { .or_else(|_| parse_cmd())?; let ws = opt::get_ws_conf(&options); - - #[cfg(any(feature = "tls-rustls", feature = "tls-openssl"))] let tls = opt::get_tls_server_conf(&options); eprintln!("listen: {}", &local); eprintln!("remote: {}", &remote); if let Some(ws) = &ws { - eprintln!("ws: {}", ws) + eprintln!("ws: {ws}") } - #[cfg(any(feature = "tls-rustls", feature = "tls-openssl"))] if let Some(tls) = &tls { eprintln!("tls: {}", &tls); } + let uot = opt::get_uot_conf(&options); + if uot.is_some() { + eprintln!("UDP over TCP enabled."); + } + + let acceptor = MixAccept::new_shared(MixServerConf { ws, tls }); + + let uot = opt::get_uot_conf(&options); + + let remote = match uot { + Some(_) => Streamer::UdpStream(remote), + None => Streamer::TcpStream(remote), + }; + let lis = TcpListener::bind(local).await?; #[cfg(all(unix, not(target_os = "android")))] let _ = realm_syscall::bump_nofile_limit(); - macro_rules! run { - ($ac: expr) => { - println!("accept: {}", $ac.as_ref()); - loop { - match lis.accept().await { - Ok((stream, _)) => { - tokio::spawn(relay(stream, remote, $ac)); - } - Err(e) => { - eprintln!("accept error: {}", e); - break; - } - } + println!("accept: {}", &acceptor); + loop { + match lis.accept().await { + Ok((stream, _)) => { + tokio::spawn(relay(stream, remote.clone(), acceptor.clone())); + } + Err(e) => { + eprintln!("accept error: {e}"); + break; } - }; - } - - #[cfg(any(feature = "tls-rustls", feature = "tls-openssl"))] - match (ws, tls) { - (None, None) => { - let server = NopAccept {}; - run!(Ref::new(&server)); - } - (Some(ws), None) => { - let server = WsAccept::new(NopAccept {}, ws); - run!(Ref::new(&server)); - } - (None, Some(tls)) => { - let server = TlsAccept::new(NopAccept {}, tls); - run!(Ref::new(&server)); - } - (Some(ws), Some(tls)) => { - let server = WsAccept::new(TlsAccept::new(NopAccept {}, tls), ws); - run!(Ref::new(&server)); } - }; - - #[cfg(not(any(feature = "tls-rustls", feature = "tls-openssl")))] - if let Some(ws) = ws { - let server = WsAccept::new(NopAccept {}, ws); - run!(Ref::new(&server)); - } else { - let server = NopAccept {}; - run!(Ref::new(&server)); } Ok(()) } -#[rustfmt::skip] -async fn relay(local: TcpStream, remote: SocketAddr, server: Ref) -> std::io::Result<()> +async fn relay(local: TcpStream, remote: Streamer, server: T) -> std::io::Result<()> where T: AsyncAccept, { - let mut buf1 = vec![0u8; 0x2000]; - let buf2 = vec![0u8; 0x2000]; - - let mut local = server.accept(local, &mut buf1).await?; - let mut remote = TcpStream::connect(remote).await?; - - let buf1 = CopyBuffer::new(buf1.into_boxed_slice()); - let buf2 = CopyBuffer::new(buf2.into_boxed_slice()); - - bidi_copy_buf(&mut local, &mut remote, buf1, buf2).await.map(|_| ()) + match remote { + Streamer::TcpStream(remote) => { + let mut buf1 = vec![0u8; buf_size()]; + let buf2 = vec![0u8; buf_size()]; + let mut local = server.accept(local, &mut buf1).await?; + let mut remote = TcpStream::connect(remote).await?; + + let buf1 = CopyBuffer::new(buf1); + let buf2 = CopyBuffer::new(buf2); + + bidi_copy_buf(&mut local, &mut remote, buf1, buf2) + .await + .map(|_| ()) + } + Streamer::UdpStream(remote) => { + println!("{} -> {remote}", local.peer_addr()?); + let mut buf1 = vec![0u8; UDP_MAX_BUF_LENGTH]; + let buf2 = vec![0u8; UDP_MAX_BUF_LENGTH]; + let server = UotAccept::new(server); + let mut local = server.accept(local, &mut buf1).await?; + + let socket = UdpSocket::bind("127.0.0.1:0").await?; + let mut remote = UdpStreamRemote::new(socket, remote); + + let buf1 = CopyBuffer::new(buf1.into_boxed_slice()); + let buf2 = CopyBuffer::new(buf2.into_boxed_slice()); + + bidi_copy_buf(&mut local, &mut remote, buf1, buf2) + .await + .map(|_| ()) + } + } } diff --git a/kaminari/Cargo.toml b/kaminari/Cargo.toml index c92ad37..0c558d7 100644 --- a/kaminari/Cargo.toml +++ b/kaminari/Cargo.toml @@ -26,16 +26,21 @@ tokio = "1.9" lazy_static = "1" # ws -lightws = { version = "0.6", features = ["unsafe_auto_mask_write"], optional = true } +lightws = { version = "0.6", features = [ + "unsafe_auto_mask_write", +], optional = true } # uot -udpflow = { version = "0.1.0", optional = true } +udpflow = { version = "0.1", optional = true } # tls -tokio-rustls = { version = "0.24", features = ["early-data", "dangerous_configuration"], optional = true } +tokio-rustls = { version = "0.24", features = [ + "early-data", + "dangerous_configuration", +], optional = true } webpki-roots = { version = "0.23", optional = true } rustls-pemfile = { version = "1", optional = true } -rcgen = {version = "0.10", optional = true } +rcgen = { version = "0.10", optional = true } [package.metadata.docs.rs] all-features = true diff --git a/kaminari/src/mix.rs b/kaminari/src/mix.rs index 4bafe76..df7c6cd 100644 --- a/kaminari/src/mix.rs +++ b/kaminari/src/mix.rs @@ -2,6 +2,8 @@ use std::io::Result; use std::future::Future; use std::fmt::{Display, Formatter}; +use crate::ws; + use super::{IOStream, AsyncAccept, AsyncConnect}; use super::nop::{NopAccept, NopConnect}; use super::ws::{WsConf, WsAccept, WsConnect}; @@ -18,8 +20,12 @@ pub struct MixClientConf { pub enum MixConnect { Plain(NopConnect), Ws(WsConnect), + WsFixed(WsConnect), + WsStandard(WsConnect), Tls(TlsConnect), Wss(WsConnect>), + WssFixed(WsConnect, ws::Fixed>), + WssStandard(WsConnect, ws::Standard>), } impl MixConnect { @@ -28,9 +34,21 @@ impl MixConnect { let MixClientConf { ws, tls } = conf; match (ws, tls) { (None, None) => Plain(NopConnect {}), - (Some(ws), None) => Ws(WsConnect::new(NopConnect {}, ws)), + (Some(ws), None) => match ws.mask_mode { + ws::MaskMode::Skip => Ws(WsConnect::new(NopConnect {}, ws)), + ws::MaskMode::Fixed => WsFixed(WsConnect::new(NopConnect {}, ws)), + ws::MaskMode::Standard => WsStandard(WsConnect::new(NopConnect {}, ws)), + }, (None, Some(tls)) => Tls(TlsConnect::new(NopConnect {}, tls)), - (Some(ws), Some(tls)) => Wss(WsConnect::new(TlsConnect::new(NopConnect {}, tls), ws)), + (Some(ws), Some(tls)) => match ws.mask_mode { + ws::MaskMode::Skip => Wss(WsConnect::new(TlsConnect::new(NopConnect {}, tls), ws)), + ws::MaskMode::Fixed => { + WssFixed(WsConnect::new(TlsConnect::new(NopConnect {}, tls), ws)) + } + ws::MaskMode::Standard => { + WssStandard(WsConnect::new(TlsConnect::new(NopConnect {}, tls), ws)) + } + }, } } @@ -39,12 +57,26 @@ impl MixConnect { let MixClientConf { ws, tls } = conf; match (ws, tls) { (None, None) => Plain(NopConnect {}), - (Some(ws), None) => Ws(WsConnect::new(NopConnect {}, ws)), + (Some(ws), None) => match ws.mask_mode { + ws::MaskMode::Skip => Ws(WsConnect::new(NopConnect {}, ws)), + ws::MaskMode::Fixed => WsFixed(WsConnect::new(NopConnect {}, ws)), + ws::MaskMode::Standard => WsStandard(WsConnect::new(NopConnect {}, ws)), + }, (None, Some(tls)) => Tls(TlsConnect::new_shared(NopConnect {}, tls)), - (Some(ws), Some(tls)) => Wss(WsConnect::new( - TlsConnect::new_shared(NopConnect {}, tls), - ws, - )), + (Some(ws), Some(tls)) => match ws.mask_mode { + ws::MaskMode::Skip => Wss(WsConnect::new( + TlsConnect::new_shared(NopConnect {}, tls), + ws, + )), + ws::MaskMode::Fixed => WssFixed(WsConnect::new( + TlsConnect::new_shared(NopConnect {}, tls), + ws, + )), + ws::MaskMode::Standard => WssStandard(WsConnect::new( + TlsConnect::new_shared(NopConnect {}, tls), + ws, + )), + }, } } } @@ -62,8 +94,12 @@ impl AsyncConnect for MixConnect { match self { Plain(cc) => cc.connect(stream, buf).await.map(MixS::Plain), Ws(cc) => cc.connect(stream, buf).await.map(MixS::Ws), + WsFixed(cc) => cc.connect(stream, buf).await.map(MixS::WsFixed), + WsStandard(cc) => cc.connect(stream, buf).await.map(MixS::WsStandard), Tls(cc) => cc.connect(stream, buf).await.map(MixS::Tls), Wss(cc) => cc.connect(stream, buf).await.map(MixS::Wss), + WssFixed(cc) => cc.connect(stream, buf).await.map(MixS::WssFixed), + WssStandard(cc) => cc.connect(stream, buf).await.map(MixS::WssStandard), } } } @@ -138,15 +174,19 @@ mod stream { use std::pin::Pin; use std::task::{Poll, Context}; use tokio::io::{ReadBuf, AsyncRead, AsyncWrite}; - use crate::ws::{WsClientStream, WsServerStream}; + use crate::ws::{WsClientStream, WsServerStream, WsStandardClientStream, WsFixedClientStream}; use crate::tls::{TlsClientStream, TlsServerStream}; #[derive(Debug)] pub enum MixClientStream { Plain(T), Ws(WsClientStream), + WsFixed(WsFixedClientStream), + WsStandard(WsStandardClientStream), Tls(TlsClientStream), Wss(WsClientStream>), + WssFixed(WsFixedClientStream>), + WssStandard(WsStandardClientStream>), } #[derive(Debug)] @@ -174,7 +214,7 @@ mod stream { }; } - macro_rules! impl_async_read { + macro_rules! impl_async_read_server { ($stream: ident) => { impl AsyncRead for $stream { fn poll_read( @@ -189,7 +229,7 @@ mod stream { }; } - macro_rules! impl_async_write { + macro_rules! impl_async_write_server { ($stream: ident) => { impl AsyncWrite for $stream { fn poll_write( @@ -214,10 +254,96 @@ mod stream { }; } - impl_async_read!(MixClientStream); - impl_async_write!(MixClientStream); - impl_async_read!(MixServerStream); - impl_async_write!(MixServerStream); + macro_rules! impl_async_read_client { + ($stream: ident) => { + impl AsyncRead for $stream { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + use $stream::*; + call_each!( + self || Plain, + Ws, + WsFixed, + WsStandard, + Tls, + Wss, + WssFixed, + WssStandard, + || poll_read, + cx, + buf + ) + } + } + }; + } + + macro_rules! impl_async_write_client { + ($stream: ident) => { + impl AsyncWrite for $stream { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + use $stream::*; + call_each!( + self || Plain, + Ws, + WsFixed, + WsStandard, + Tls, + Wss, + WssFixed, + WssStandard, + || poll_write, + cx, + buf + ) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + use $stream::*; + call_each!( + self || Plain, + Ws, + WsFixed, + WsStandard, + Tls, + Wss, + WssFixed, + WssStandard, + || poll_flush, + cx + ) + } + + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + use $stream::*; + call_each!( + self || Plain, + Ws, + WsFixed, + WsStandard, + Tls, + Wss, + WssFixed, + WssStandard, + || poll_shutdown, + cx + ) + } + } + }; + } + + impl_async_read_client!(MixClientStream); + impl_async_write_client!(MixClientStream); + impl_async_read_server!(MixServerStream); + impl_async_write_server!(MixServerStream); } // ========== type cast ========== @@ -272,7 +398,16 @@ macro_rules! impl_display { }; } -impl_display!(MixConnect || Plain, Ws, Tls, Wss,); +impl_display!( + MixConnect || Plain, + Ws, + WsFixed, + WsStandard, + Tls, + Wss, + WssFixed, + WssStandard, +); impl_display!(MixAccept || Plain, Ws, Tls, Wss,); #[cfg(test)] @@ -285,6 +420,7 @@ mod test { ws: Some(WsConf { host: String::from("abc"), path: String::from("chat"), + mask_mode: ws::MaskMode::Skip, }), tls: Some(TlsClientConf { sni: String::from("abc"), @@ -299,7 +435,7 @@ mod test { let conn = MixConnect::new(conf); - println!("{}", conn); + println!("{conn}"); } #[test] @@ -308,6 +444,7 @@ mod test { ws: Some(WsConf { host: String::from("abc"), path: String::from("chat"), + mask_mode: ws::MaskMode::Skip, }), tls: Some(TlsServerConf { crt: String::new(), @@ -322,6 +459,6 @@ mod test { let lis = MixAccept::new(conf); - println!("{}", lis); + println!("{lis}"); } } diff --git a/kaminari/src/opt.rs b/kaminari/src/opt.rs index c0a30b8..1693b2e 100644 --- a/kaminari/src/opt.rs +++ b/kaminari/src/opt.rs @@ -33,6 +33,17 @@ macro_rules! get_opt { pub use has_opt; pub use get_opt; +#[cfg(feature = "uot")] +pub fn get_uot_conf(s: &str) -> Option<()> { + let it = s.split(';').map(|x| x.trim()); + + if !has_opt!(it.clone(), "uot") { + return None; + } + + Some(()) +} + #[cfg(feature = "ws")] pub fn get_ws_conf(s: &str) -> Option { let it = s.split(';').map(|x| x.trim()); @@ -41,6 +52,8 @@ pub fn get_ws_conf(s: &str) -> Option { return None; } + let mask_mode = get_opt!(it.clone(), "mask"); + let host = get_opt!(it.clone(), "host"); let path = get_opt!(it.clone(), "path"); @@ -48,6 +61,7 @@ pub fn get_ws_conf(s: &str) -> Option { Some(WsConf { host: String::from(host), path: String::from(path), + mask_mode: mask_mode.into(), }) } else { panic!("ws: require host and path") @@ -119,22 +133,24 @@ mod test { #[test] #[cfg(feature = "ws")] fn ws_conf() { + use crate::ws::MaskMode; macro_rules! y { - ( $( ($s:expr, $host: expr, $path: expr); )+ )=> { + ( $( ($s:expr, $host: expr, $path: expr, $mask: expr); )+ )=> { $( assert_eq!(get_ws_conf($s), Some(WsConf{ host: String::from($host), path: String::from($path), + mask_mode: $mask, })); )+ } } y![ - ("ws;host=a.b.c;path=/", "a.b.c", "/"); - ("ws;host=a.b.c;path=/abc", "a.b.c", "/abc"); - ("ws;path=/abc;host=a.b.c", "a.b.c", "/abc"); - ("ws;path=/abc;host=a.b.c;", "a.b.c", "/abc"); + ("ws;host=a.b.c;path=/", "a.b.c", "/", MaskMode::Skip); + ("ws;host=a.b.c;path=/abc;mask=standard", "a.b.c", "/abc", MaskMode::Standard); + ("ws;path=/abc;host=a.b.c;mask=fixed", "a.b.c", "/abc", MaskMode::Fixed); + ("ws;path=/abc;host=a.b.c;", "a.b.c", "/abc", MaskMode::Skip); ]; } diff --git a/kaminari/src/ws.rs b/kaminari/src/ws.rs index 9d748fc..794eafc 100644 --- a/kaminari/src/ws.rs +++ b/kaminari/src/ws.rs @@ -15,15 +15,61 @@ pub type WsClientStream = WsStream; pub type WsStandardClientStream = WsStream; pub type WsFixedClientStream = WsStream; +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum MaskMode { + Skip, + Fixed, + Standard, +} + +impl From> for MaskMode { + fn from(item: Option<&str>) -> Self { + match item { + Some(item) => match item { + "skip" => Self::Skip, + "fixed" => Self::Fixed, + "standard" => Self::Standard, + _ => panic!("{item} mask mode is not supported."), + }, + None => Self::Skip, + } + } +} + +impl Display for MaskMode { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Self::Skip => "skip", + Self::Fixed => "fixed", + Self::Standard => "standard", + } + ) + } +} + +impl Default for MaskMode { + fn default() -> Self { + Self::Skip + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct WsConf { pub host: String, pub path: String, + pub mask_mode: MaskMode, } impl Display for WsConf { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "host: {}, path: {}", self.host, self.path) + write!( + f, + "host: {}, path: {}, mask: {}", + self.host, self.path, self.mask_mode + ) } } @@ -64,10 +110,12 @@ impl Display for WsConnect where T: Display, { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "[ws]{}", self.conn) } + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "[ws]{}", self.conn) + } } -impl WsConnect { +impl WsConnect { #[inline] pub const fn new(conn: T, conf: WsConf) -> Self { Self { @@ -76,24 +124,6 @@ impl WsConnect { _marker: PhantomData, } } - - #[inline] - pub fn standard(self) -> WsConnect { - WsConnect { - conn: self.conn, - conf: self.conf, - _marker: PhantomData, - } - } - - #[inline] - pub fn fixed(self) -> WsConnect { - WsConnect { - conn: self.conn, - conf: self.conf, - _marker: PhantomData, - } - } } impl AsyncConnect for WsConnect @@ -133,12 +163,16 @@ impl Display for WsAccept where T: Display, { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "[ws]{}", self.lis) } + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "[ws]{}", self.lis) + } } impl WsAccept { #[inline] - pub const fn new(lis: T, conf: WsConf) -> Self { Self { lis, conf } } + pub const fn new(lis: T, conf: WsConf) -> Self { + Self { lis, conf } + } } impl AsyncAccept for WsAccept