Expand Shadowsocks runtime compatibility
This commit is contained in:
parent
d1638726ca
commit
4d1f589280
167 changed files with 57173 additions and 1640 deletions
523
third_party/tokio-rustls-fork-shadow-tls/Cargo.lock
generated
vendored
Normal file
523
third_party/tokio-rustls-fork-shadow-tls/Cargo.lock
generated
vendored
Normal file
|
|
@ -0,0 +1,523 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[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",
|
||||
]
|
||||
|
||||
[[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",
|
||||
]
|
||||
|
||||
[[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"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||
|
||||
[[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.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[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"
|
||||
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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-fork-shadow-tls"
|
||||
version = "0.20.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "227b89ca93267855a168e5293f66c74d43afabcdf2239947d3b5904928388161"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
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.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls-fork-shadow-tls"
|
||||
version = "0.0.8"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"rustls-fork-shadow-tls",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
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",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.22.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
|
||||
dependencies = [
|
||||
"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",
|
||||
]
|
||||
|
||||
[[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.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||
57
third_party/tokio-rustls-fork-shadow-tls/Cargo.toml
vendored
Normal file
57
third_party/tokio-rustls-fork-shadow-tls/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "tokio-rustls-fork-shadow-tls"
|
||||
version = "0.0.8"
|
||||
authors = ["ChiHai <ihciah@gmail.com>"]
|
||||
description = "Asynchronous TLS streams wrapper for Tokio based on Rustls."
|
||||
homepage = "https://github.com/compdzwio/tokio-tls"
|
||||
readme = "README.md"
|
||||
categories = [
|
||||
"asynchronous",
|
||||
"cryptography",
|
||||
"network-programming",
|
||||
]
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/compdzwio/tokio-tls"
|
||||
resolver = "1"
|
||||
|
||||
[dependencies.bytes]
|
||||
version = "1"
|
||||
|
||||
[dependencies.rustls-fork-shadow-tls]
|
||||
version = "0.20.8"
|
||||
default-features = false
|
||||
|
||||
[dependencies.thiserror]
|
||||
version = "1"
|
||||
|
||||
[dependencies.tokio]
|
||||
version = "1.25.0"
|
||||
features = ["full"]
|
||||
|
||||
[dev-dependencies.tokio]
|
||||
version = "1.25.0"
|
||||
|
||||
[dev-dependencies.webpki-roots]
|
||||
version = "0.22"
|
||||
|
||||
[features]
|
||||
dangerous_configuration = ["rustls-fork-shadow-tls/dangerous_configuration"]
|
||||
default = [
|
||||
"logging",
|
||||
"tls12",
|
||||
]
|
||||
logging = ["rustls-fork-shadow-tls/logging"]
|
||||
tls12 = ["rustls-fork-shadow-tls/tls12"]
|
||||
unsafe_io = []
|
||||
30
third_party/tokio-rustls-fork-shadow-tls/Cargo.toml.orig
generated
vendored
Normal file
30
third_party/tokio-rustls-fork-shadow-tls/Cargo.toml.orig
generated
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
[package]
|
||||
authors = ["ChiHai <ihciah@gmail.com>"]
|
||||
categories = ["asynchronous", "cryptography", "network-programming"]
|
||||
description = "Asynchronous TLS streams wrapper for Tokio based on Rustls."
|
||||
edition = "2021"
|
||||
homepage = "https://github.com/compdzwio/tokio-tls"
|
||||
license = "MIT/Apache-2.0"
|
||||
name = "tokio-rustls-fork-shadow-tls"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/compdzwio/tokio-tls"
|
||||
version = "0.0.8"
|
||||
|
||||
[dependencies]
|
||||
bytes = {version = "1"}
|
||||
tokio = {version = "1.25.0", features = ["full"]}
|
||||
rustls-fork-shadow-tls = {version = "0.20.8", default-features = false}
|
||||
thiserror = {version = "1"}
|
||||
|
||||
[features]
|
||||
dangerous_configuration = ["rustls-fork-shadow-tls/dangerous_configuration"]
|
||||
default = ["logging", "tls12"]
|
||||
logging = ["rustls-fork-shadow-tls/logging"]
|
||||
tls12 = ["rustls-fork-shadow-tls/tls12"]
|
||||
# Once unsafe_io is enabled, you may not drop the future before it returns ready.
|
||||
# It saves one buffer copy than disabled.
|
||||
unsafe_io = []
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = {version = "1.25.0"}
|
||||
webpki-roots = "0.22"
|
||||
1
third_party/tokio-rustls-fork-shadow-tls/README.md
vendored
Normal file
1
third_party/tokio-rustls-fork-shadow-tls/README.md
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Tokio-rustls
|
||||
42
third_party/tokio-rustls-fork-shadow-tls/examples/connect.rs
vendored
Normal file
42
third_party/tokio-rustls-fork-shadow-tls/examples/connect.rs
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use tokio::{
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
net::TcpStream,
|
||||
};
|
||||
|
||||
use tokio_rustls_fork_shadow_tls::TlsConnector;
|
||||
use rustls_fork_shadow_tls::{OwnedTrustAnchor, RootCertStore};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let mut root_store = RootCertStore::empty();
|
||||
root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
|
||||
OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
ta.subject,
|
||||
ta.spki,
|
||||
ta.name_constraints,
|
||||
)
|
||||
}));
|
||||
let config = rustls_fork_shadow_tls::ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
|
||||
let connector = TlsConnector::from(Arc::new(config));
|
||||
let stream = TcpStream::connect("rsproxy.cn:443").await.unwrap();
|
||||
println!("rsproxy.cn:443 connected");
|
||||
|
||||
let domain = rustls_fork_shadow_tls::ServerName::try_from("rsproxy.cn").unwrap();
|
||||
let mut stream = connector.connect(domain, stream).await.unwrap();
|
||||
println!("handshake success");
|
||||
|
||||
let content = b"GET / HTTP/1.0\r\nHost: rsproxy.cn\r\n\r\n";
|
||||
stream.write_all(content).await?;
|
||||
println!("http request sent");
|
||||
|
||||
let buf = vec![0_u8; 64];
|
||||
let n = stream.read(buf).await?;
|
||||
let resp = String::from_utf8(buf).unwrap();
|
||||
println!("http response recv: \n\n{resp}");
|
||||
}
|
||||
86
third_party/tokio-rustls-fork-shadow-tls/src/client.rs
vendored
Normal file
86
third_party/tokio-rustls-fork-shadow-tls/src/client.rs
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use rustls_fork_shadow_tls::{ClientConfig, ClientConnection, ClientSessionIdGenerators};
|
||||
|
||||
use crate::{
|
||||
split::{ReadHalf, WriteHalf},
|
||||
stream::Stream,
|
||||
TlsError,
|
||||
};
|
||||
|
||||
/// A wrapper around an underlying raw stream which implements the TLS protocol.
|
||||
pub type TlsStream<IO> = Stream<IO, ClientConnection>;
|
||||
/// TlsStream for read only.
|
||||
pub type TlsStreamReadHalf<IO> = ReadHalf<IO, ClientConnection>;
|
||||
/// TlsStream for write only.
|
||||
pub type TlsStreamWriteHalf<IO> = WriteHalf<IO, ClientConnection>;
|
||||
|
||||
/// A wrapper around a `rustls::ClientConfig`, providing an async `connect` method.
|
||||
#[derive(Clone)]
|
||||
pub struct TlsConnector {
|
||||
inner: Arc<ClientConfig>,
|
||||
}
|
||||
|
||||
impl From<Arc<ClientConfig>> for TlsConnector {
|
||||
fn from(inner: Arc<ClientConfig>) -> TlsConnector {
|
||||
TlsConnector { inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ClientConfig> for TlsConnector {
|
||||
fn from(inner: ClientConfig) -> TlsConnector {
|
||||
TlsConnector {
|
||||
inner: Arc::new(inner),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TlsConnector {
|
||||
pub async fn connect<IO>(
|
||||
&self,
|
||||
domain: rustls_fork_shadow_tls::ServerName,
|
||||
stream: IO,
|
||||
) -> Result<TlsStream<IO>, TlsError>
|
||||
where
|
||||
IO: AsyncRead + AsyncWrite + Unpin,
|
||||
{
|
||||
let session = ClientConnection::new(self.inner.clone(), domain)?;
|
||||
let mut stream = Stream::new(stream, session);
|
||||
stream.handshake().await?;
|
||||
Ok(stream)
|
||||
}
|
||||
|
||||
pub async fn connect_with_session_id_generator<IO, F>(
|
||||
&self,
|
||||
domain: rustls_fork_shadow_tls::ServerName,
|
||||
stream: IO,
|
||||
generator: F,
|
||||
) -> Result<TlsStream<IO>, TlsError>
|
||||
where
|
||||
IO: AsyncRead + AsyncWrite + Unpin,
|
||||
F: Fn(&[u8]) -> [u8; 32] + Send + Sync + 'static,
|
||||
{
|
||||
let session =
|
||||
ClientConnection::new_with_session_id_generator(self.inner.clone(), domain, generator)?;
|
||||
let mut stream = Stream::new(stream, session);
|
||||
stream.handshake().await?;
|
||||
Ok(stream)
|
||||
}
|
||||
|
||||
pub async fn connect_with_session_id_generators<IO>(
|
||||
&self,
|
||||
domain: rustls_fork_shadow_tls::ServerName,
|
||||
stream: IO,
|
||||
generators: ClientSessionIdGenerators,
|
||||
) -> Result<TlsStream<IO>, TlsError>
|
||||
where
|
||||
IO: AsyncRead + AsyncWrite + Unpin,
|
||||
{
|
||||
let session =
|
||||
ClientConnection::new_with_session_id_generators(self.inner.clone(), domain, generators)?;
|
||||
let mut stream = Stream::new(stream, session);
|
||||
stream.handshake().await?;
|
||||
Ok(stream)
|
||||
}
|
||||
}
|
||||
20
third_party/tokio-rustls-fork-shadow-tls/src/error.rs
vendored
Normal file
20
third_party/tokio-rustls-fork-shadow-tls/src/error.rs
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
use std::io;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum TlsError {
|
||||
#[error("io error")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error("rustls error")]
|
||||
Rustls(#[from] rustls_fork_shadow_tls::Error),
|
||||
}
|
||||
|
||||
impl From<TlsError> for io::Error {
|
||||
fn from(e: TlsError) -> Self {
|
||||
match e {
|
||||
TlsError::Io(e) => e,
|
||||
TlsError::Rustls(e) => io::Error::new(io::ErrorKind::Other, e),
|
||||
}
|
||||
}
|
||||
}
|
||||
21
third_party/tokio-rustls-fork-shadow-tls/src/lib.rs
vendored
Normal file
21
third_party/tokio-rustls-fork-shadow-tls/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#![allow(stable_features)]
|
||||
|
||||
mod client;
|
||||
mod error;
|
||||
#[cfg(not(feature = "unsafe_io"))]
|
||||
mod safe_io;
|
||||
mod server;
|
||||
mod split;
|
||||
mod stream;
|
||||
#[cfg(feature = "unsafe_io")]
|
||||
mod unsafe_io;
|
||||
|
||||
pub use client::{
|
||||
TlsConnector, TlsStream as ClientTlsStream, TlsStreamReadHalf as ClientTlsStreamReadHalf,
|
||||
TlsStreamWriteHalf as ClientTlsStreamWriteHalf,
|
||||
};
|
||||
pub use error::TlsError;
|
||||
pub use server::{
|
||||
TlsAcceptor, TlsStream as ServerTlsStream, TlsStreamReadHalf as ServerTlsStreamReadHalf,
|
||||
TlsStreamWriteHalf as ServerTlsStreamWriteHalf,
|
||||
};
|
||||
227
third_party/tokio-rustls-fork-shadow-tls/src/safe_io.rs
vendored
Normal file
227
third_party/tokio-rustls-fork-shadow-tls/src/safe_io.rs
vendored
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
use std::{
|
||||
fmt::Debug, hint::unreachable_unchecked, io
|
||||
};
|
||||
|
||||
use tokio::{
|
||||
io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}
|
||||
};
|
||||
|
||||
const BUFFER_SIZE: usize = 16 * 1024;
|
||||
|
||||
struct Buffer {
|
||||
read: usize,
|
||||
write: usize,
|
||||
buf: Box<[u8]>,
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
read: 0,
|
||||
write: 0,
|
||||
buf: vec![0; BUFFER_SIZE].into_boxed_slice(),
|
||||
}
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.write - self.read
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
fn available(&self) -> usize {
|
||||
self.buf.len() - self.write
|
||||
}
|
||||
|
||||
fn is_full(&self) -> bool {
|
||||
self.available() == 0
|
||||
}
|
||||
|
||||
fn advance(&mut self, n: usize) {
|
||||
assert!(self.write - self.read >= n);
|
||||
self.read += n;
|
||||
if self.read == self.write {
|
||||
self.read = 0;
|
||||
self.write = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct SafeRead {
|
||||
// the option is only meant for temporary take, it always should be some
|
||||
buffer: Option<Buffer>,
|
||||
status: ReadStatus,
|
||||
}
|
||||
|
||||
impl Debug for SafeRead {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("SafeRead")
|
||||
.field("status", &self.status)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ReadStatus {
|
||||
Eof,
|
||||
Err(io::Error),
|
||||
Ok,
|
||||
}
|
||||
|
||||
impl Default for SafeRead {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
buffer: Some(Buffer::new()),
|
||||
status: ReadStatus::Ok,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SafeRead {
|
||||
pub(crate) async fn do_io<IO: AsyncRead + Unpin>(&mut self, mut io: IO) -> io::Result<usize> {
|
||||
// if there are some data inside the buffer, just return.
|
||||
let buffer = self.buffer.as_ref().expect("buffer ref expected");
|
||||
if !buffer.is_empty() {
|
||||
return Ok(buffer.len());
|
||||
}
|
||||
|
||||
// read from raw io
|
||||
let buffer = self.buffer.as_mut().expect("buffer ownership expected");
|
||||
let buf = &mut buffer.buf.as_mut()[buffer.write..];
|
||||
let result = io.read(buf).await;
|
||||
match result {
|
||||
Ok(0) => {
|
||||
self.status = ReadStatus::Eof;
|
||||
result
|
||||
}
|
||||
Ok(n) => {
|
||||
buffer.write += n;
|
||||
self.status = ReadStatus::Ok;
|
||||
result
|
||||
}
|
||||
Err(e) => {
|
||||
let rerr = e.kind().into();
|
||||
self.status = ReadStatus::Err(e);
|
||||
Err(rerr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for SafeRead {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
// if buffer is empty, return WoundBlock.
|
||||
let buffer = self.buffer.as_mut().expect("buffer mut expected");
|
||||
if buffer.is_empty() {
|
||||
if !matches!(self.status, ReadStatus::Ok) {
|
||||
match std::mem::replace(&mut self.status, ReadStatus::Ok) {
|
||||
ReadStatus::Eof => return Ok(0),
|
||||
ReadStatus::Err(e) => return Err(e),
|
||||
ReadStatus::Ok => unsafe { unreachable_unchecked() },
|
||||
}
|
||||
}
|
||||
return Err(io::ErrorKind::WouldBlock.into());
|
||||
}
|
||||
|
||||
// now buffer is not empty. copy it.
|
||||
let to_copy = buffer.len().min(buf.len());
|
||||
unsafe { std::ptr::copy_nonoverlapping(buffer.buf.as_ptr().add(buffer.read), buf.as_mut_ptr(), to_copy) };
|
||||
buffer.advance(to_copy);
|
||||
|
||||
Ok(to_copy)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct SafeWrite {
|
||||
// the option is only meant for temporary take, it always should be some
|
||||
buffer: Option<Buffer>,
|
||||
status: WriteStatus,
|
||||
}
|
||||
|
||||
impl Debug for SafeWrite {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("SafeWrite")
|
||||
.field("status", &self.status)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum WriteStatus {
|
||||
Err(io::Error),
|
||||
Ok,
|
||||
}
|
||||
|
||||
impl Default for SafeWrite {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
buffer: Some(Buffer::new()),
|
||||
status: WriteStatus::Ok,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SafeWrite {
|
||||
pub(crate) async fn do_io<IO: AsyncWrite + Unpin>(&mut self, mut io: IO) -> io::Result<usize> {
|
||||
// if the buffer is empty, just return.
|
||||
let buffer = self.buffer.as_ref().expect("buffer ref expected");
|
||||
if buffer.is_empty() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
// buffer is not empty now. write it.
|
||||
let buffer = self.buffer.as_mut().expect("buffer ownership expected");
|
||||
let buf = &buffer.buf.as_ref()[buffer.read..buffer.write];
|
||||
let result = io.write_all(buf).await;
|
||||
match result {
|
||||
Ok(_) => {
|
||||
let n = buffer.write - buffer.read;
|
||||
buffer.advance(n);
|
||||
Ok(n)
|
||||
}
|
||||
Err(e) => {
|
||||
let rerr = e.kind().into();
|
||||
self.status = WriteStatus::Err(e);
|
||||
Err(rerr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for SafeWrite {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
// if there is too much data inside the buffer, return WoundBlock
|
||||
let buffer = self.buffer.as_mut().expect("buffer mut expected");
|
||||
if !matches!(self.status, WriteStatus::Ok) {
|
||||
match std::mem::replace(&mut self.status, WriteStatus::Ok) {
|
||||
WriteStatus::Err(e) => return Err(e),
|
||||
WriteStatus::Ok => unsafe { unreachable_unchecked() },
|
||||
}
|
||||
}
|
||||
if buffer.is_full() {
|
||||
return Err(io::ErrorKind::WouldBlock.into());
|
||||
}
|
||||
|
||||
// there is space inside the buffer, copy to it.
|
||||
let to_copy = buf.len().min(buffer.available());
|
||||
unsafe { std::ptr::copy_nonoverlapping(buf.as_ptr(), buffer.buf.as_mut_ptr().add(buffer.write), to_copy); }
|
||||
buffer.write += to_copy;
|
||||
Ok(to_copy)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
let buffer = self.buffer.as_mut().expect("buffer mut expected");
|
||||
if !matches!(self.status, WriteStatus::Ok) {
|
||||
match std::mem::replace(&mut self.status, WriteStatus::Ok) {
|
||||
WriteStatus::Err(e) => return Err(e),
|
||||
WriteStatus::Ok => unsafe { unreachable_unchecked() },
|
||||
}
|
||||
}
|
||||
if !buffer.is_empty() {
|
||||
return Err(io::ErrorKind::WouldBlock.into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
49
third_party/tokio-rustls-fork-shadow-tls/src/server.rs
vendored
Normal file
49
third_party/tokio-rustls-fork-shadow-tls/src/server.rs
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use rustls_fork_shadow_tls::{ServerConfig, ServerConnection};
|
||||
|
||||
use crate::{
|
||||
split::{ReadHalf, WriteHalf},
|
||||
stream::Stream,
|
||||
TlsError,
|
||||
};
|
||||
|
||||
/// A wrapper around an underlying raw stream which implements the TLS protocol.
|
||||
pub type TlsStream<IO> = Stream<IO, ServerConnection>;
|
||||
/// TlsStream for read only.
|
||||
pub type TlsStreamReadHalf<IO> = ReadHalf<IO, ServerConnection>;
|
||||
/// TlsStream for write only.
|
||||
pub type TlsStreamWriteHalf<IO> = WriteHalf<IO, ServerConnection>;
|
||||
|
||||
/// A wrapper around a `rustls::ServerConfig`, providing an async `accept` method.
|
||||
#[derive(Clone)]
|
||||
pub struct TlsAcceptor {
|
||||
inner: Arc<ServerConfig>,
|
||||
}
|
||||
|
||||
impl From<Arc<ServerConfig>> for TlsAcceptor {
|
||||
fn from(inner: Arc<ServerConfig>) -> TlsAcceptor {
|
||||
TlsAcceptor { inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ServerConfig> for TlsAcceptor {
|
||||
fn from(inner: ServerConfig) -> TlsAcceptor {
|
||||
TlsAcceptor {
|
||||
inner: Arc::new(inner),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TlsAcceptor {
|
||||
pub async fn accept<IO>(&self, stream: IO) -> Result<TlsStream<IO>, TlsError>
|
||||
where
|
||||
IO: AsyncRead + AsyncWrite + Unpin,
|
||||
{
|
||||
let session = ServerConnection::new(self.inner.clone())?;
|
||||
let mut stream = Stream::new(stream, session);
|
||||
stream.handshake().await?;
|
||||
Ok(stream)
|
||||
}
|
||||
}
|
||||
139
third_party/tokio-rustls-fork-shadow-tls/src/split.rs
vendored
Normal file
139
third_party/tokio-rustls-fork-shadow-tls/src/split.rs
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
//! Split implement for TlsStream.
|
||||
//! Note: Here we depends on the behavior of monoio TcpStream.
|
||||
//! Though it is not a good assumption, it can really make it
|
||||
//! more efficient with less code. The read and write will not
|
||||
//! interfere each other.
|
||||
use std::{
|
||||
cell::UnsafeCell,
|
||||
future::Future,
|
||||
io::IoSlice,
|
||||
ops::{Deref, DerefMut},
|
||||
pin::Pin,
|
||||
rc::Rc,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use tokio::{
|
||||
pin,
|
||||
io::{AsyncRead, AsyncWrite, ReadBuf}
|
||||
};
|
||||
|
||||
use rustls_fork_shadow_tls::{ConnectionCommon, SideData};
|
||||
|
||||
use crate::stream::Stream;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReadHalf<IO, C> {
|
||||
pub(crate) inner: Rc<UnsafeCell<Stream<IO, C>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WriteHalf<IO, C> {
|
||||
pub(crate) inner: Rc<UnsafeCell<Stream<IO, C>>>,
|
||||
}
|
||||
|
||||
impl<IO: AsyncRead + AsyncWrite + Unpin, C, SD: SideData + 'static> AsyncRead
|
||||
for ReadHalf<IO, C>
|
||||
where
|
||||
C: DerefMut + Deref<Target = ConnectionCommon<SD>>,
|
||||
{
|
||||
fn poll_read(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &mut ReadBuf<'_>
|
||||
) -> Poll<std::io::Result<()>> {
|
||||
let inner = unsafe { &mut *self.inner.get() };
|
||||
let ex = inner.read_inner(buf, true);
|
||||
pin!(ex);
|
||||
ex.poll(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<IO, C> ReadHalf<IO, C> {
|
||||
pub fn reunite(self, other: WriteHalf<IO, C>) -> Result<Stream<IO, C>, ReuniteError<IO, C>> {
|
||||
reunite(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<IO: AsyncRead + AsyncWrite + Unpin, C: Unpin, SD: SideData + 'static> AsyncWrite
|
||||
for WriteHalf<IO, C>
|
||||
where
|
||||
C: DerefMut + Deref<Target = ConnectionCommon<SD>>,
|
||||
{
|
||||
fn poll_write(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8]
|
||||
) -> Poll<std::io::Result<usize>> {
|
||||
let inner = unsafe { &mut *self.inner.get() };
|
||||
Pin::new(inner).poll_write(cx, buf)
|
||||
}
|
||||
|
||||
fn poll_write_vectored(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
bufs: &[IoSlice<'_>]
|
||||
) -> Poll<std::io::Result<usize>> {
|
||||
let inner = unsafe { &mut *self.inner.get() };
|
||||
Pin::new(inner).poll_write_vectored(cx, bufs)
|
||||
}
|
||||
|
||||
fn poll_flush(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>
|
||||
) -> Poll<std::io::Result<()>> {
|
||||
let inner = unsafe { &mut *self.inner.get() };
|
||||
Pin::new(inner).poll_flush(cx)
|
||||
}
|
||||
|
||||
fn poll_shutdown(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>
|
||||
) -> Poll<std::io::Result<()>> {
|
||||
let inner = unsafe { &mut *self.inner.get() };
|
||||
Pin::new(inner).poll_shutdown(cx)
|
||||
}
|
||||
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
let inner = unsafe { &mut *self.inner.get() };
|
||||
Pin::new(inner).is_write_vectored()
|
||||
}
|
||||
}
|
||||
|
||||
impl<IO, C> WriteHalf<IO, C> {
|
||||
pub fn reunite(self, other: ReadHalf<IO, C>) -> Result<Stream<IO, C>, ReuniteError<IO, C>> {
|
||||
reunite(other, self)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn reunite<IO, C>(
|
||||
read: ReadHalf<IO, C>,
|
||||
write: WriteHalf<IO, C>,
|
||||
) -> Result<Stream<IO, C>, ReuniteError<IO, C>> {
|
||||
if Rc::ptr_eq(&read.inner, &write.inner) {
|
||||
drop(write);
|
||||
// This unwrap cannot fail as the api does not allow creating more than two Rcs,
|
||||
// and we just dropped the other half.
|
||||
Ok(Rc::try_unwrap(read.inner)
|
||||
.expect("TlsStream: try_unwrap failed in reunite")
|
||||
.into_inner())
|
||||
} else {
|
||||
Err(ReuniteError(read, write))
|
||||
}
|
||||
}
|
||||
|
||||
/// Error indicating that two halves were not from the same socket, and thus could
|
||||
/// not be reunited.
|
||||
#[derive(Debug)]
|
||||
pub struct ReuniteError<IO, C>(pub ReadHalf<IO, C>, pub WriteHalf<IO, C>);
|
||||
|
||||
impl<IO: std::fmt::Debug, C: std::fmt::Debug> std::fmt::Display for ReuniteError<IO, C> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"tried to reunite halves that are not from the same socket"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<IO: std::fmt::Debug, C: std::fmt::Debug> std::error::Error for ReuniteError<IO, C> {}
|
||||
297
third_party/tokio-rustls-fork-shadow-tls/src/stream.rs
vendored
Normal file
297
third_party/tokio-rustls-fork-shadow-tls/src/stream.rs
vendored
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
use std::{
|
||||
cell::UnsafeCell,
|
||||
future::Future,
|
||||
io::{IoSlice, Read, self, Write},
|
||||
ops::{Deref, DerefMut},
|
||||
pin::Pin,
|
||||
rc::Rc,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use tokio::{
|
||||
pin,
|
||||
io::{AsyncRead, AsyncWrite, ReadBuf}
|
||||
};
|
||||
|
||||
use rustls_fork_shadow_tls::{ConnectionCommon, SideData};
|
||||
|
||||
use crate::split::{ReadHalf, WriteHalf};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Stream<IO, C> {
|
||||
pub(crate) io: IO,
|
||||
pub(crate) session: C,
|
||||
#[cfg(not(feature = "unsafe_io"))]
|
||||
r_buffer: crate::safe_io::SafeRead,
|
||||
#[cfg(not(feature = "unsafe_io"))]
|
||||
w_buffer: crate::safe_io::SafeWrite,
|
||||
#[cfg(feature = "unsafe_io")]
|
||||
r_buffer: crate::unsafe_io::UnsafeRead,
|
||||
#[cfg(feature = "unsafe_io")]
|
||||
w_buffer: crate::unsafe_io::UnsafeWrite,
|
||||
}
|
||||
|
||||
impl<IO, C> Stream<IO, C> {
|
||||
pub fn new(io: IO, session: C) -> Self {
|
||||
Self {
|
||||
io,
|
||||
session,
|
||||
r_buffer: Default::default(),
|
||||
w_buffer: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn split(self) -> (ReadHalf<IO, C>, WriteHalf<IO, C>) {
|
||||
let shared = Rc::new(UnsafeCell::new(self));
|
||||
(
|
||||
ReadHalf {
|
||||
inner: shared.clone(),
|
||||
},
|
||||
WriteHalf { inner: shared },
|
||||
)
|
||||
}
|
||||
|
||||
pub fn into_parts(self) -> (IO, C) {
|
||||
(self.io, self.session)
|
||||
}
|
||||
}
|
||||
|
||||
impl<IO: AsyncRead + AsyncWrite + Unpin, C, SD: SideData> Stream<IO, C>
|
||||
where
|
||||
C: DerefMut + Deref<Target = ConnectionCommon<SD>>,
|
||||
{
|
||||
pub(crate) async fn read_io(&mut self, splitted: bool) -> io::Result<usize> {
|
||||
let n = loop {
|
||||
match self.session.read_tls(&mut self.r_buffer) {
|
||||
Ok(n) => {
|
||||
break n;
|
||||
}
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => (),
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe {
|
||||
self.r_buffer.do_io(&mut self.io).await?
|
||||
};
|
||||
};
|
||||
|
||||
let state = match self.session.process_new_packets() {
|
||||
Ok(state) => state,
|
||||
Err(err) => {
|
||||
// When to write_io? If we do this in read call, the UnsafeWrite may crash
|
||||
// when we impl split in an UnsafeCell way.
|
||||
// Here we choose not to do write when read.
|
||||
// User should manually shutdown it on error.
|
||||
if !splitted {
|
||||
let _ = self.write_io().await;
|
||||
}
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData, err));
|
||||
}
|
||||
};
|
||||
|
||||
if state.peer_has_closed() && self.session.is_handshaking() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::UnexpectedEof,
|
||||
"tls handshake alert",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
pub(crate) async fn write_io(&mut self) -> io::Result<usize> {
|
||||
let n = loop {
|
||||
match self.session.write_tls(&mut self.w_buffer) {
|
||||
Ok(n) => {
|
||||
break n;
|
||||
}
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => (),
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe {
|
||||
self.w_buffer.do_io(&mut self.io).await?
|
||||
};
|
||||
};
|
||||
// Flush buffered data, only needed for safe_io.
|
||||
#[cfg(not(feature = "unsafe_io"))]
|
||||
self.w_buffer.do_io(&mut self.io).await?;
|
||||
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
pub(crate) async fn handshake(&mut self) -> io::Result<(usize, usize)> {
|
||||
let mut wrlen = 0;
|
||||
let mut rdlen = 0;
|
||||
let mut eof = false;
|
||||
|
||||
loop {
|
||||
while self.session.wants_write() && self.session.is_handshaking() {
|
||||
wrlen += self.write_io().await?;
|
||||
}
|
||||
while !eof && self.session.wants_read() && self.session.is_handshaking() {
|
||||
let n = self.read_io(false).await?;
|
||||
rdlen += n;
|
||||
if n == 0 {
|
||||
eof = true;
|
||||
}
|
||||
}
|
||||
|
||||
match (eof, self.session.is_handshaking()) {
|
||||
(true, true) => {
|
||||
let err = io::Error::new(io::ErrorKind::UnexpectedEof, "tls handshake eof");
|
||||
return Err(err);
|
||||
}
|
||||
(false, true) => (),
|
||||
(_, false) => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// flush buffer
|
||||
while self.session.wants_write() {
|
||||
wrlen += self.write_io().await?;
|
||||
}
|
||||
|
||||
Ok((rdlen, wrlen))
|
||||
}
|
||||
|
||||
pub(crate) async fn read_inner(
|
||||
&mut self,
|
||||
buf: &mut ReadBuf<'_>,
|
||||
splitted: bool,
|
||||
) -> std::io::Result<()> {
|
||||
if buf.remaining() == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
let slice = buf.initialize_unfilled();
|
||||
loop {
|
||||
// read from rustls to buffer
|
||||
match self.session.reader().read(slice) {
|
||||
Ok(n) => {
|
||||
buf.advance(n);
|
||||
return Ok(());
|
||||
}
|
||||
// we need more data, read something.
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => (),
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
|
||||
// now we need data, read something into rustls
|
||||
match self.read_io(splitted).await {
|
||||
Ok(0) => {
|
||||
return
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::UnexpectedEof,
|
||||
"tls raw stream eof",
|
||||
),
|
||||
);
|
||||
}
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<IO: AsyncRead + AsyncWrite + Unpin, C, SD: SideData + 'static> AsyncRead for Stream<IO, C>
|
||||
where
|
||||
C: DerefMut + Deref<Target = ConnectionCommon<SD>> + Unpin,
|
||||
{
|
||||
fn poll_read(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &mut ReadBuf<'_>
|
||||
) -> Poll<std::io::Result<()>> {
|
||||
let ex = self.read_inner(buf, false);
|
||||
pin!(ex);
|
||||
ex.poll(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<IO: AsyncRead + AsyncWrite + Unpin, C, SD: SideData + 'static> AsyncWrite for Stream<IO, C>
|
||||
where
|
||||
C: DerefMut + Deref<Target = ConnectionCommon<SD>> + Unpin,
|
||||
{
|
||||
fn poll_write(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8]
|
||||
) -> Poll<std::io::Result<usize>> {
|
||||
// write buf to rustls
|
||||
let n = match self.session.writer().write(buf) {
|
||||
Ok(n) => n,
|
||||
Err(e) => return Poll::Ready(Err(e)),
|
||||
};
|
||||
|
||||
// write from rustls to connection
|
||||
while self.session.wants_write() {
|
||||
let ex = self.write_io();
|
||||
pin!(ex);
|
||||
match ex.poll(cx) {
|
||||
Poll::Ready(Ok(0)) => {
|
||||
break;
|
||||
}
|
||||
Poll::Ready(Ok(_)) => (),
|
||||
Poll::Pending => return Poll::Pending,
|
||||
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
|
||||
}
|
||||
}
|
||||
Poll::Ready(Ok(n))
|
||||
}
|
||||
|
||||
fn poll_write_vectored(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
bufs: &[IoSlice<'_>]
|
||||
) -> Poll<std::io::Result<usize>> {
|
||||
let buf = bufs
|
||||
.iter()
|
||||
.find(|b| !b.is_empty())
|
||||
.map_or(&[][..], |b| &**b);
|
||||
self.poll_write(cx, buf)
|
||||
}
|
||||
|
||||
fn poll_flush(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>
|
||||
) -> Poll<std::io::Result<()>> {
|
||||
self.session.writer().flush()?;
|
||||
while self.session.wants_write() {
|
||||
let ex = self.write_io();
|
||||
pin!(ex);
|
||||
match ex.poll(cx) {
|
||||
Poll::Ready(Ok(_)) => (),
|
||||
Poll::Pending => return Poll::Pending,
|
||||
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
|
||||
}
|
||||
}
|
||||
Pin::new(&mut self.io).poll_flush(cx)
|
||||
}
|
||||
|
||||
fn poll_shutdown(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>
|
||||
) -> Poll<std::io::Result<()>> {
|
||||
self.session.send_close_notify();
|
||||
while self.session.wants_write() {
|
||||
let ex = self.write_io();
|
||||
pin!(ex);
|
||||
match ex.poll(cx) {
|
||||
Poll::Ready(Ok(_)) => (),
|
||||
Poll::Pending => return Poll::Pending,
|
||||
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
|
||||
}
|
||||
}
|
||||
Pin::new(&mut self.io).poll_shutdown(cx)
|
||||
}
|
||||
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
Pin::new(&self.io).is_write_vectored()
|
||||
}
|
||||
}
|
||||
124
third_party/tokio-rustls-fork-shadow-tls/src/unsafe_io.rs
vendored
Normal file
124
third_party/tokio-rustls-fork-shadow-tls/src/unsafe_io.rs
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
use std::{
|
||||
io,
|
||||
slice::{from_raw_parts, from_raw_parts_mut}
|
||||
};
|
||||
|
||||
use tokio::{
|
||||
io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}
|
||||
};
|
||||
|
||||
/// Used by both UnsafeRead and UnsafeWrite.
|
||||
#[derive(Debug)]
|
||||
enum Status {
|
||||
/// We haven't do real io, and maybe the dest is recorded.
|
||||
WaitFill(Option<(*const u8, usize)>),
|
||||
/// We have already do real io. The length maybe zero or non-zero.
|
||||
Filled(usize),
|
||||
}
|
||||
|
||||
impl Default for Status {
|
||||
fn default() -> Self {
|
||||
Status::WaitFill(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// UnsafeRead is a wrapper of some meta data.
|
||||
/// It implements std::io::Read trait. But it do real io in an async way.
|
||||
/// On the first read, it may returns WouldBlock error, which means the
|
||||
/// `fullfill` should be called to do real io.
|
||||
/// The data is read directly into the dest that last std read passes.
|
||||
/// Note that this action is an unsafe hack to avoid data copy.
|
||||
/// You can only use this wrapper when you make sure the read dest is always
|
||||
/// a valid buffer.
|
||||
#[derive(Default, Debug)]
|
||||
pub(crate) struct UnsafeRead {
|
||||
status: Status,
|
||||
}
|
||||
|
||||
impl UnsafeRead {
|
||||
/// `do_io` must be called after calling to io::Read::read.
|
||||
pub(crate) async unsafe fn do_io<IO: AsyncRead + Unpin>(
|
||||
&mut self,
|
||||
mut io: IO,
|
||||
) -> io::Result<usize> {
|
||||
match self.status {
|
||||
Status::WaitFill(Some((ptr, len))) => {
|
||||
let buf = unsafe { from_raw_parts_mut(ptr as *mut u8, len) };
|
||||
let n = io.read(buf).await?;
|
||||
self.status = Status::Filled(n);
|
||||
Ok(n)
|
||||
}
|
||||
Status::Filled(len) => Ok(len),
|
||||
Status::WaitFill(None) => Err(io::ErrorKind::WouldBlock.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for UnsafeRead {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
match self.status {
|
||||
Status::WaitFill(_) => {
|
||||
let ptr = buf.as_ptr();
|
||||
let len = buf.len();
|
||||
self.status = Status::WaitFill(Some((ptr, len)));
|
||||
Err(io::ErrorKind::WouldBlock.into())
|
||||
}
|
||||
Status::Filled(len) => {
|
||||
if len != 0 {
|
||||
// reset only when not eof
|
||||
self.status = Status::WaitFill(None);
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// UnsafeWrite behaves like `UnsafeRead`.
|
||||
#[derive(Default, Debug)]
|
||||
pub(crate) struct UnsafeWrite {
|
||||
status: Status,
|
||||
}
|
||||
|
||||
impl UnsafeWrite {
|
||||
/// `do_io` must be called after calling to io::Write::write.
|
||||
pub(crate) async unsafe fn do_io<IO: AsyncWrite + Unpin>(
|
||||
&mut self,
|
||||
mut io: IO,
|
||||
) -> io::Result<usize> {
|
||||
match self.status {
|
||||
Status::WaitFill(Some((ptr, len))) => {
|
||||
let buf = unsafe { from_raw_parts(ptr, len) };
|
||||
let n = io.write(buf).await?;
|
||||
self.status = Status::Filled(n);
|
||||
Ok(n)
|
||||
}
|
||||
Status::Filled(len) => Ok(len),
|
||||
Status::WaitFill(None) => Err(io::ErrorKind::WouldBlock.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for UnsafeWrite {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
match self.status {
|
||||
Status::WaitFill(_) => {
|
||||
let ptr = buf.as_ptr();
|
||||
let len = buf.len();
|
||||
self.status = Status::WaitFill(Some((ptr, len)));
|
||||
Err(io::ErrorKind::WouldBlock.into())
|
||||
}
|
||||
Status::Filled(len) => {
|
||||
if len != 0 {
|
||||
// reset only when not eof
|
||||
self.status = Status::WaitFill(None);
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue