v0.2.0: switch to quic
This commit is contained in:
parent
0ce3bd5ded
commit
bbabd34156
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
/target
|
||||
*.conf
|
||||
*.der
|
||||
|
|
673
Cargo.lock
generated
673
Cargo.lock
generated
|
@ -17,42 +17,6 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aead"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-shared-timeout"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bf0ee472a0062fe47df725a586b833aa99b7e3b000176ce1b2c608a3c0535cb"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"portable-atomic 0.3.20",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
|
@ -74,6 +38,12 @@ dependencies = [
|
|||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -108,52 +78,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chacha20"
|
||||
version = "0.9.1"
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chacha20poly1305"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"chacha20",
|
||||
"cipher",
|
||||
"poly1305",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"inout",
|
||||
"zeroize",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -163,59 +94,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.12"
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
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",
|
||||
"rand_core",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fckrkn"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"async-shared-timeout",
|
||||
"bytes",
|
||||
"chacha20poly1305",
|
||||
"chrono",
|
||||
"dashmap",
|
||||
"quinn",
|
||||
"rcgen",
|
||||
"rustls",
|
||||
"rustls-native-certs 0.7.0",
|
||||
"rustls-pemfile 2.0.0",
|
||||
"tokio",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -235,50 +132,12 @@ version = "0.28.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inout"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.67"
|
||||
|
@ -294,16 +153,6 @@ version = "0.2.152"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
|
@ -333,16 +182,7 @@ checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
|
|||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -371,22 +211,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.9"
|
||||
name = "pem"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
|
||||
checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.48.5",
|
||||
"base64",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -396,30 +233,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
|
||||
[[package]]
|
||||
name = "poly1305"
|
||||
version = "0.8.0"
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
|
||||
dependencies = [
|
||||
"cpufeatures",
|
||||
"opaque-debug",
|
||||
"universal-hash",
|
||||
]
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "0.3.20"
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e30165d31df606f5726b090ec7592c308a0eaf61721ff64c9a3018e344a8753e"
|
||||
dependencies = [
|
||||
"portable-atomic 1.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
|
@ -430,6 +253,54 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-proto"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"rand",
|
||||
"ring 0.16.20",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
"rustls-native-certs 0.6.3",
|
||||
"slab",
|
||||
"thiserror",
|
||||
"tinyvec",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-udp"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
|
@ -439,6 +310,27 @@ 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",
|
||||
]
|
||||
|
||||
[[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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
|
@ -449,12 +341,44 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
name = "rcgen"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
checksum = "48406db8ac1f3cbc7dcdb56ec355343817958a356ff430259bb07baf7607e1e1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"pem",
|
||||
"ring 0.17.7",
|
||||
"time",
|
||||
"yasna",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin 0.5.2",
|
||||
"untrusted 0.7.1",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"spin 0.9.8",
|
||||
"untrusted 0.9.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -464,16 +388,153 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.1"
|
||||
name = "rustls"
|
||||
version = "0.21.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring 0.17.7",
|
||||
"rustls-webpki",
|
||||
"sct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
|
||||
dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls-pemfile 1.0.4",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792"
|
||||
dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls-pemfile 2.0.0",
|
||||
"rustls-pki-types",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
|
||||
dependencies = [
|
||||
"base64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e9d979b3ce68192e42760c7810125eb6cf2ea10efae545a156063e61f314e2a"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.101.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
|
||||
dependencies = [
|
||||
"ring 0.17.7",
|
||||
"untrusted 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
|
||||
dependencies = [
|
||||
"ring 0.17.7",
|
||||
"untrusted 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
|
@ -482,14 +543,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.5.0"
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
|
@ -502,6 +569,59 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.35.1"
|
||||
|
@ -515,7 +635,7 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -530,10 +650,36 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
name = "tracing"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
|
@ -542,20 +688,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "universal-hash"
|
||||
version = "0.5.1"
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
|
@ -618,14 +760,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
name = "web-sys"
|
||||
version = "0.3.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.0",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
|
@ -635,6 +800,15 @@ dependencies = [
|
|||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
|
@ -750,7 +924,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.7.0"
|
||||
name = "yasna"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
|
||||
checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
|
||||
dependencies = [
|
||||
"time",
|
||||
]
|
||||
|
|
12
Cargo.toml
12
Cargo.toml
|
@ -1,15 +1,15 @@
|
|||
[package]
|
||||
name = "fckrkn"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-shared-timeout = "0.2.0"
|
||||
bytes = "1.5.0"
|
||||
chacha20poly1305 = "0.10.1"
|
||||
chrono = "0.4.33"
|
||||
dashmap = "5.5.3"
|
||||
quinn = "0.10.2"
|
||||
rcgen = "0.12.1"
|
||||
rustls = "0.21.0"
|
||||
rustls-native-certs = "0.7.0"
|
||||
rustls-pemfile = "2.0.0"
|
||||
tokio = { version = "1.35.1", features = ["rt-multi-thread", "macros", "net", "sync", "time"] }
|
||||
typenum = "1.17.0"
|
||||
|
|
443
src/main.rs
443
src/main.rs
|
@ -1,176 +1,19 @@
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
mem,
|
||||
fs, io,
|
||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||
sync::{
|
||||
atomic::{AtomicU32, Ordering},
|
||||
Arc,
|
||||
},
|
||||
path::PathBuf,
|
||||
str,
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use async_shared_timeout::Timeout;
|
||||
use bytes::BytesMut;
|
||||
use chacha20poly1305::{aead::Buffer, AeadCore, AeadInPlace, ChaCha20Poly1305, KeyInit};
|
||||
use dashmap::DashMap;
|
||||
use tokio::{net::UdpSocket, sync::mpsc};
|
||||
use typenum::Unsigned;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum BMut<'a> {
|
||||
Bytes(BytesMut),
|
||||
Vec(&'a mut Vec<u8>),
|
||||
}
|
||||
|
||||
impl<'a> Buffer for BMut<'a> {
|
||||
fn extend_from_slice(&mut self, other: &[u8]) -> chacha20poly1305::aead::Result<()> {
|
||||
match self {
|
||||
Self::Bytes(x) => x.extend_from_slice(other),
|
||||
Self::Vec(x) => x.extend_from_slice(other),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn truncate(&mut self, len: usize) {
|
||||
match self {
|
||||
Self::Bytes(x) => x.truncate(len),
|
||||
Self::Vec(x) => x.truncate(len),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a> AsRef<[u8]> for BMut<'a> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
match self {
|
||||
Self::Bytes(x) => x.as_ref(),
|
||||
Self::Vec(x) => x.as_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a> AsMut<[u8]> for BMut<'a> {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
match self {
|
||||
Self::Bytes(x) => x.as_mut(),
|
||||
Self::Vec(x) => x.as_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ChanOrSock {
|
||||
Chan(mpsc::Receiver<BytesMut>),
|
||||
Sock(Arc<UdpSocket>, Vec<u8>),
|
||||
}
|
||||
|
||||
impl ChanOrSock {
|
||||
async fn recv(&mut self) -> Option<BMut<'_>> {
|
||||
match self {
|
||||
Self::Chan(x) => x.recv().await.map(BMut::Bytes),
|
||||
Self::Sock(sock, buf) => {
|
||||
buf.resize(65536, 0);
|
||||
let len = sock.recv(buf).await.ok()?;
|
||||
buf.truncate(len);
|
||||
Some(BMut::Vec(buf))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SESSION_ID: AtomicU32 = AtomicU32::new(0);
|
||||
static PROTOCOL_VERSION: u8 = 0;
|
||||
|
||||
async fn thread(
|
||||
(mut rx_enc, sock_enc, enc_addr): (ChanOrSock, Arc<UdpSocket>, SocketAddr),
|
||||
(mut rx_dec, sock_dec, dec_addr): (ChanOrSock, Arc<UdpSocket>, SocketAddr),
|
||||
server: bool,
|
||||
chans: Arc<DashMap<SocketAddr, mpsc::Sender<BytesMut>>>,
|
||||
cipher_remote: ChaCha20Poly1305,
|
||||
cipher_local: ChaCha20Poly1305,
|
||||
) {
|
||||
let timeout = Timeout::new(
|
||||
async_shared_timeout::runtime::Tokio::new(),
|
||||
Duration::from_secs(1),
|
||||
);
|
||||
let session_id = SESSION_ID.fetch_add(1, Ordering::SeqCst).to_be_bytes();
|
||||
let remote_to_local = async {
|
||||
let mut timeout_set = false;
|
||||
while let Some(mut buf) = rx_enc.recv().await {
|
||||
if buf.len() < 12 {
|
||||
continue;
|
||||
}
|
||||
let nonce = <[u8; 12]>::try_from(&buf.as_ref()[buf.len() - 12..]).unwrap();
|
||||
let time = chrono::Utc::now().timestamp_nanos_opt().unwrap();
|
||||
let nonce1 = [
|
||||
nonce[4], nonce[5], nonce[6], nonce[7], nonce[8], nonce[9], nonce[10], nonce[11],
|
||||
];
|
||||
if i64::from_be_bytes(nonce1).abs_diff(time) > 10_000_000_000 {
|
||||
eprintln!("got invalid nonce");
|
||||
continue;
|
||||
}
|
||||
buf.truncate(buf.len() - 12);
|
||||
if let Err(err) = cipher_remote.decrypt_in_place((&nonce).into(), b"", &mut buf) {
|
||||
eprintln!("decrypt error: {err}");
|
||||
continue;
|
||||
}
|
||||
if server {
|
||||
if !timeout_set {
|
||||
timeout_set = true;
|
||||
timeout.set_default_timeout(Duration::from_secs(90));
|
||||
}
|
||||
timeout.reset();
|
||||
}
|
||||
|
||||
if let Err(err) = sock_dec.as_ref().send_to(buf.as_ref(), dec_addr).await {
|
||||
eprintln!("decrypted send error: {err}");
|
||||
}
|
||||
}
|
||||
};
|
||||
let local_to_remote = async {
|
||||
let mut timeout_set = false;
|
||||
while let Some(mut buf) = rx_dec.recv().await {
|
||||
let time = chrono::Utc::now()
|
||||
.timestamp_nanos_opt()
|
||||
.unwrap()
|
||||
.to_be_bytes();
|
||||
let nonce = [
|
||||
PROTOCOL_VERSION,
|
||||
session_id[0],
|
||||
session_id[1],
|
||||
session_id[2],
|
||||
time[0],
|
||||
time[1],
|
||||
time[2],
|
||||
time[3],
|
||||
time[4],
|
||||
time[5],
|
||||
time[6],
|
||||
time[7],
|
||||
];
|
||||
if let Err(err) = cipher_local.encrypt_in_place((&nonce).into(), b"", &mut buf) {
|
||||
eprintln!("encrypt error: {err}");
|
||||
continue;
|
||||
}
|
||||
buf.extend_from_slice(&nonce).unwrap();
|
||||
if !server {
|
||||
if !timeout_set {
|
||||
timeout_set = true;
|
||||
timeout.set_default_timeout(Duration::from_secs(90));
|
||||
}
|
||||
timeout.reset();
|
||||
}
|
||||
if let Err(err) = sock_enc.as_ref().send_to(buf.as_ref(), enc_addr).await {
|
||||
eprintln!("encrypted send error: {err}");
|
||||
}
|
||||
}
|
||||
};
|
||||
tokio::select! {
|
||||
_ = timeout.wait() => {}
|
||||
_ = remote_to_local => {}
|
||||
_ = local_to_remote => {}
|
||||
}
|
||||
chans.remove(&enc_addr);
|
||||
}
|
||||
use quinn::{IdleTimeout, TransportConfig, VarInt};
|
||||
use tokio::{net::UdpSocket, time::Instant};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
assert_eq!(<ChaCha20Poly1305 as AeadCore>::NonceSize::to_usize(), 12);
|
||||
async fn main() -> Result<(), io::Error> {
|
||||
let mut args = std::env::args().skip(1);
|
||||
let data = std::fs::read_to_string(args.next().unwrap())
|
||||
.unwrap()
|
||||
|
@ -190,38 +33,107 @@ async fn main() {
|
|||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
let ver: u8 = data.get("version").unwrap().parse().unwrap();
|
||||
assert!(matches!(ver, 0));
|
||||
assert!(matches!(ver, 1));
|
||||
|
||||
let server = data.contains_key("server");
|
||||
let src: SocketAddr = data.get("bind").unwrap().parse().unwrap();
|
||||
let dst: SocketAddr = data.get("connect").unwrap().parse().unwrap();
|
||||
let h2b = |x: &str| {
|
||||
x.as_bytes()
|
||||
.chunks_exact(2)
|
||||
.map(|x| u8::from_str_radix(std::str::from_utf8(x).unwrap(), 16).unwrap())
|
||||
.collect::<Box<[u8]>>()
|
||||
};
|
||||
let key_local = h2b(data.get("key_local").unwrap());
|
||||
let key_remote = h2b(data.get("key_remote").unwrap());
|
||||
let server = data.contains_key("server");
|
||||
let cipher_local = ChaCha20Poly1305::new_from_slice(&key_local).unwrap();
|
||||
let cipher_remote = ChaCha20Poly1305::new_from_slice(&key_remote).unwrap();
|
||||
let sock = Arc::new(UdpSocket::bind(src).await.unwrap());
|
||||
let chans = Arc::new(DashMap::<SocketAddr, mpsc::Sender<_>>::new());
|
||||
let mut buf = BytesMut::with_capacity(65536);
|
||||
loop {
|
||||
buf.resize(65536, 0);
|
||||
let Ok((len, addr)) = sock.recv_from(&mut buf).await else {
|
||||
continue;
|
||||
let proxy_key = Box::leak(h2b(data.get("key").unwrap()));
|
||||
|
||||
if server {
|
||||
let dst: SocketAddr = data.get("connect").unwrap().parse().unwrap();
|
||||
let (certs, key) = if let (Some(key_path), Some(cert_path)) = (
|
||||
data.get("ssl_key").map(PathBuf::from),
|
||||
data.get("ssl_cert").map(PathBuf::from),
|
||||
) {
|
||||
let key = fs::read(&key_path).unwrap();
|
||||
let key = if key_path.extension().map_or(false, |x| x == "der") {
|
||||
rustls::PrivateKey(key)
|
||||
} else {
|
||||
rustls::PrivateKey(
|
||||
match rustls_pemfile::read_one_from_slice(&key)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.0
|
||||
{
|
||||
rustls_pemfile::Item::Sec1Key(x) => x.secret_sec1_der().to_owned(),
|
||||
rustls_pemfile::Item::Pkcs1Key(x) => x.secret_pkcs1_der().to_owned(),
|
||||
rustls_pemfile::Item::Pkcs8Key(x) => x.secret_pkcs8_der().to_owned(),
|
||||
rustls_pemfile::Item::X509Certificate(x) => x.as_ref().to_owned(),
|
||||
_ => panic!(),
|
||||
},
|
||||
)
|
||||
};
|
||||
if let Some(ch) = chans.get(&addr) {
|
||||
if ch.send(buf.split_to(len)).await.is_ok() {
|
||||
continue;
|
||||
let cert_chain = fs::read(&cert_path).unwrap();
|
||||
let cert_chain = if cert_path.extension().map_or(false, |x| x == "der") {
|
||||
vec![rustls::Certificate(cert_chain)]
|
||||
} else {
|
||||
rustls_pemfile::certs(&mut &*cert_chain)
|
||||
.map(|x| rustls::Certificate(x.unwrap().to_vec()))
|
||||
.collect()
|
||||
};
|
||||
|
||||
(cert_chain, key)
|
||||
} else {
|
||||
let cert_path = "cert.der";
|
||||
let key_path = "key.der";
|
||||
let (cert, key) = match fs::read(cert_path).and_then(|x| Ok((x, fs::read(key_path)?))) {
|
||||
Ok(x) => x,
|
||||
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
|
||||
let cert =
|
||||
rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
|
||||
let key = cert.serialize_private_key_der();
|
||||
let cert = cert.serialize_der().unwrap();
|
||||
fs::write(cert_path, &cert).unwrap();
|
||||
fs::write(key_path, &key).unwrap();
|
||||
(cert, key)
|
||||
}
|
||||
Err(e) => {
|
||||
panic!("failed to read certificate: {}", e);
|
||||
}
|
||||
let (tx, rx) = mpsc::channel(128);
|
||||
tx.send(buf.split_to(len)).await.unwrap();
|
||||
chans.insert(addr, tx);
|
||||
let sock2 = Arc::new(
|
||||
UdpSocket::bind((
|
||||
};
|
||||
|
||||
let key = rustls::PrivateKey(key);
|
||||
let cert = rustls::Certificate(cert);
|
||||
(vec![cert], key)
|
||||
};
|
||||
|
||||
let mut server_crypto = rustls::ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_no_client_auth()
|
||||
.with_single_cert(certs, key)
|
||||
.unwrap();
|
||||
server_crypto.alpn_protocols = vec![b"hq-29".to_vec()];
|
||||
|
||||
let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(server_crypto));
|
||||
let transport_config = Arc::get_mut(&mut server_config.transport).unwrap();
|
||||
transport_config.max_concurrent_uni_streams(0_u8.into());
|
||||
transport_config.max_concurrent_bidi_streams(0_u8.into());
|
||||
// milliseconds
|
||||
transport_config.max_idle_timeout(Some(IdleTimeout::from(VarInt::from(90_000u32))));
|
||||
|
||||
let endpoint = quinn::Endpoint::server(server_config, src)?;
|
||||
println!("listening on {:?}", endpoint.local_addr());
|
||||
|
||||
while let Some(conn) = endpoint.accept().await {
|
||||
let proxy_key = &*proxy_key;
|
||||
tokio::spawn(async move {
|
||||
let Ok(connection) = conn.await else {
|
||||
return;
|
||||
};
|
||||
let Ok(dgram) = connection.read_datagram().await else {
|
||||
return;
|
||||
};
|
||||
if dgram != proxy_key {
|
||||
eprintln!("invalid key");
|
||||
return;
|
||||
}
|
||||
let Ok(sock) = UdpSocket::bind((
|
||||
if dst.is_ipv6() {
|
||||
IpAddr::V6(Ipv6Addr::UNSPECIFIED)
|
||||
} else {
|
||||
|
@ -230,23 +142,148 @@ async fn main() {
|
|||
0,
|
||||
))
|
||||
.await
|
||||
.unwrap(),
|
||||
);
|
||||
sock2.connect(dst).await.unwrap();
|
||||
let (mut enc, mut dec) = (
|
||||
(ChanOrSock::Sock(sock2.clone(), vec![]), sock2, dst),
|
||||
(ChanOrSock::Chan(rx), sock.clone(), addr),
|
||||
);
|
||||
if server {
|
||||
mem::swap(&mut enc, &mut dec);
|
||||
else {
|
||||
return;
|
||||
};
|
||||
sock.connect(dst).await.unwrap();
|
||||
let remote_to_local = async {
|
||||
while let Ok(dgram) = connection.read_datagram().await {
|
||||
let _ = sock.send(&dgram).await;
|
||||
}
|
||||
tokio::spawn(thread(
|
||||
enc,
|
||||
dec,
|
||||
server,
|
||||
chans.clone(),
|
||||
cipher_remote.clone(),
|
||||
cipher_local.clone(),
|
||||
));
|
||||
};
|
||||
let local_to_remote = async {
|
||||
let mut buf = BytesMut::with_capacity(65536);
|
||||
while let Ok(len) = {
|
||||
buf.resize(65536, 0);
|
||||
sock.recv(&mut buf).await
|
||||
} {
|
||||
let _ = connection.send_datagram(buf.split_to(len).into());
|
||||
}
|
||||
};
|
||||
tokio::select! {
|
||||
_ = local_to_remote => {}
|
||||
_ = remote_to_local => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let dst = data.get("connect").unwrap();
|
||||
let (hostname, port) = {
|
||||
let tmp = dst.chars().rev().collect::<String>();
|
||||
let (port, hostname) = tmp.split_once(':').unwrap();
|
||||
let port: u16 = port.chars().rev().collect::<String>().parse().unwrap();
|
||||
let hostname = hostname.chars().rev().collect::<String>();
|
||||
(hostname, port)
|
||||
};
|
||||
let resolved = if let Some(ip) = data.get("connect_ip") {
|
||||
SocketAddr::new(ip.parse().unwrap(), port)
|
||||
} else {
|
||||
let mut resolved = tokio::net::lookup_host(dst)
|
||||
.await
|
||||
.unwrap()
|
||||
.collect::<Vec<_>>();
|
||||
resolved.sort_by_key(|x| x.is_ipv6());
|
||||
resolved.into_iter().next().unwrap()
|
||||
};
|
||||
let mut client_crypto = rustls::ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates({
|
||||
let mut roots = rustls::RootCertStore::empty();
|
||||
for cert in rustls_native_certs::load_native_certs().unwrap() {
|
||||
roots
|
||||
.add(&rustls::Certificate(cert.as_ref().to_vec()))
|
||||
.unwrap();
|
||||
}
|
||||
if let Some(ssl_cert) = data.get("ssl_cert") {
|
||||
roots
|
||||
.add(&rustls::Certificate(fs::read(ssl_cert).unwrap()))
|
||||
.unwrap();
|
||||
}
|
||||
Arc::new(roots)
|
||||
})
|
||||
.with_no_client_auth();
|
||||
|
||||
client_crypto.alpn_protocols = vec![b"hq-29".to_vec()];
|
||||
|
||||
let mut client_config = quinn::ClientConfig::new(Arc::new(client_crypto));
|
||||
client_config.transport_config(Arc::new({
|
||||
let mut cfg = TransportConfig::default();
|
||||
cfg.keep_alive_interval(Some(Duration::from_secs(30)))
|
||||
.max_concurrent_bidi_streams(0u8.into())
|
||||
.max_concurrent_uni_streams(0u8.into())
|
||||
.max_idle_timeout(Some(Duration::from_secs(90).try_into().unwrap()));
|
||||
cfg
|
||||
}));
|
||||
let mut endpoint = quinn::Endpoint::client(
|
||||
(
|
||||
if resolved.is_ipv6() {
|
||||
IpAddr::V6(Ipv6Addr::UNSPECIFIED)
|
||||
} else {
|
||||
IpAddr::V4(Ipv4Addr::UNSPECIFIED)
|
||||
},
|
||||
0,
|
||||
)
|
||||
.into(),
|
||||
)?;
|
||||
endpoint.set_default_client_config(client_config);
|
||||
let endpoint = Arc::new(endpoint);
|
||||
|
||||
loop {
|
||||
let proxy_key = &*proxy_key;
|
||||
let endpoint = endpoint.clone();
|
||||
let hostname = hostname.clone();
|
||||
let _ = tokio::spawn(async move {
|
||||
let conn = endpoint
|
||||
.connect(resolved, &hostname)
|
||||
.unwrap()
|
||||
.await
|
||||
.unwrap();
|
||||
println!("connected");
|
||||
let sock = Arc::new(UdpSocket::bind(src).await.unwrap());
|
||||
conn.send_datagram(proxy_key.into()).unwrap();
|
||||
|
||||
let local_to_remote = async {
|
||||
let mut buf = BytesMut::with_capacity(65536);
|
||||
buf.resize(65536, 0);
|
||||
let mut chosen_addr = None;
|
||||
let mut chosen_time = Instant::now();
|
||||
loop {
|
||||
buf.resize(65536, 0);
|
||||
let Ok((len, addr)) = sock.recv_from(&mut buf).await else {
|
||||
continue;
|
||||
};
|
||||
if Some(addr) != chosen_addr {
|
||||
if chosen_addr.is_none()
|
||||
|| chosen_time + Duration::from_secs(10) > Instant::now()
|
||||
{
|
||||
chosen_addr = Some(addr);
|
||||
let _ = sock.connect(addr).await;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
chosen_time = Instant::now();
|
||||
if let Err(err) = conn.send_datagram(buf.split_to(len).into()) {
|
||||
eprintln!("send failed: {err}");
|
||||
}
|
||||
}
|
||||
};
|
||||
let remote_to_local = async {
|
||||
loop {
|
||||
let dgram = conn.read_datagram().await.unwrap();
|
||||
let _ = sock.send(&dgram).await;
|
||||
}
|
||||
};
|
||||
tokio::select! {
|
||||
_ = local_to_remote => {}
|
||||
_ = remote_to_local => {}
|
||||
}
|
||||
})
|
||||
.await;
|
||||
eprintln!("sleeping for 10 seconds...");
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue