Browse Source

Add async feature implemented with tokio and rustls, make it default

master
Travis Burtrum 2 years ago
parent
commit
f3a78b2863
10 changed files with 992 additions and 229 deletions
  1. +429
    -8
      Cargo.lock
  2. +9
    -1
      Cargo.toml
  3. +4
    -3
      README.md
  4. +304
    -0
      src/asyncmod.rs
  5. +5
    -3
      src/bin/wireguard-proxy.rs
  6. +2
    -3
      src/error.rs
  7. +25
    -206
      src/lib.rs
  8. +1
    -1
      src/notls.rs
  9. +5
    -4
      src/openssl.rs
  10. +208
    -0
      src/syncmod.rs

+ 429
- 8
Cargo.lock View File

@ -5,14 +5,29 @@ name = "autocfg"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "base64"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bumpalo"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cc"
version = "1.0.48"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -33,6 +48,58 @@ name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-core"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hermit-abi"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "iovec"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "js-sys"
version = "0.3.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -40,7 +107,83 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.66"
version = "0.2.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "log"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mio"
version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio-uds"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "net2"
version = "0.2.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "once_cell"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -52,7 +195,7 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -61,7 +204,7 @@ name = "openssl-src"
version = "111.6.1+1.1.1d"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -70,41 +213,319 @@ version = "0.9.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-src 111.6.1+1.1.1d (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pin-project-lite"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pkg-config"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ring"
version = "0.16.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
"once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"web-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustls"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)",
"sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sct"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio"
version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-macros"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-rustls"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vcpkg"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wasm-bindgen"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro-support 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-backend 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "web-sys"
version = "0.3.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "webpki"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wireguard-proxy"
version = "0.1.0"
dependencies = [
"base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
"checksum base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76"
"checksum bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
"checksum bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
"checksum cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
"checksum hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
"checksum libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)" = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
"checksum mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)" = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
"checksum mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7"
"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
"checksum once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
"checksum openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585"
"checksum openssl-src 111.6.1+1.1.1d (registry+https://github.com/rust-lang/crates.io-index)" = "c91b04cb43c1a8a90e934e0cd612e2a5715d976d2d6cff4490278a0cddf35005"
"checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f"
"checksum pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
"checksum proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
"checksum ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)" = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4"
"checksum rustls 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac94b333ee2aac3284c5b8a1b7fb4dd11cba88c244e3fe33cdbd047af0eb693"
"checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
"checksum syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0"
"checksum tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
"checksum tokio-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "228139ddd4fea3fa345a29233009635235833e52807af7ea6448ead03890d6a9"
"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
"checksum untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
"checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168"
"checksum wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d"
"checksum wasm-bindgen-backend 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d"
"checksum wasm-bindgen-macro 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e"
"checksum wasm-bindgen-macro-support 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6"
"checksum wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87"
"checksum web-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "8be2398f326b7ba09815d0b403095f34dd708579220d099caae89be0b32137b2"
"checksum webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"

+ 9
- 1
Cargo.toml View File

@ -20,10 +20,18 @@ include = [
]
[features]
default = []
default = ["async"]
tls = ["openssl"]
openssl_vendored = ["openssl/vendored"]
verbose = []
async = ["tokio", "tokio-rustls", "ring", "base64"]
[dependencies]
# only for non-async build with TLS support
openssl = { version = "0.10.26", optional = true }
# the rest of these are only required for async build
tokio = { version = "0.2", features = [ "macros", "net", "udp", "io-std", "io-util", "rt-threaded" ], optional = true }
tokio-rustls = { version = "0.14", features = ["dangerous_configuration"], optional = true }
# probably should try to keep ring the exact same version as rustls, same features too
ring = { version = "0.16.11", optional = true }
base64 = { version = "0.12.3", optional = true }

+ 4
- 3
README.md View File

@ -75,9 +75,10 @@ Binaries:
Building:
- `cargo build --release` - minimal build without TLS support, no dependencies
- `cargo build --release --feature tls` - links to system openssl
- `cargo build --release --feature openssl_vendored` - compiles vendored openssl and link to it
- `cargo build --release` - async build with TLS support supplied by rustls
- `cargo build --release --no-default-features ` - minimal build without TLS support, no dependencies
- `cargo build --release --no-default-features --feature tls` - links to system openssl
- `cargo build --release --no-default-features --feature openssl_vendored` - compiles vendored openssl and link to it
Testing:


+ 304
- 0
src/asyncmod.rs View File

@ -0,0 +1,304 @@
use tokio::net::UdpSocket;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::runtime::Runtime;
use tokio_rustls::webpki::DNSNameRef;
use crate::error;
use crate::error::Result;
use crate::*;
pub struct TcpUdpPipe<T: AsyncReadExt + AsyncWriteExt + std::marker::Unpin + std::marker::Send + 'static> {
buf: [u8; 2050], // 2048 + 2 for len
tcp_stream: T,
udp_socket: UdpSocket,
}
impl<T: AsyncReadExt + AsyncWriteExt + std::marker::Unpin + std::marker::Send + 'static> TcpUdpPipe<T> {
pub fn new(tcp_stream: T, udp_socket: UdpSocket) -> TcpUdpPipe<T> {
TcpUdpPipe {
tcp_stream,
udp_socket,
buf: [0u8; 2050],
}
}
pub async fn shuffle_after_first_udp(mut self) -> Result<usize> {
let (len, src_addr) = self.udp_socket.recv_from(&mut self.buf[2..]).await?;
println!("first packet from {}, connecting to that", src_addr);
self.udp_socket.connect(src_addr).await?;
send_udp(&mut self.buf, &mut self.tcp_stream, len).await?;
self.shuffle().await
}
pub async fn shuffle(self) -> Result<usize> {
// todo: investigate https://docs.rs/tokio/0.2.22/tokio/net/struct.TcpStream.html#method.into_split
let (mut tcp_rd, mut tcp_wr) = tokio::io::split(self.tcp_stream);
let (mut udp_rd, mut udp_wr) = self.udp_socket.split();
let mut recv_buf = self.buf.clone(); // or zeroed or?
tokio::spawn(async move {
loop {
let len = udp_rd.recv(&mut recv_buf[2..]).await?;
send_udp(&mut recv_buf, &mut tcp_wr, len).await?;
}
// Sometimes, the rust type inferencer needs
// a little help
#[allow(unreachable_code)]
{
unsafe { std::hint::unreachable_unchecked(); }
Ok::<_, error::Error>(())
}
});
let mut send_buf = self.buf.clone(); // or zeroed or?
loop {
tcp_rd.read_exact(&mut send_buf[..2]).await?;
let len = ((send_buf[0] as usize) << 8) + send_buf[1] as usize;
#[cfg(feature = "verbose")]
println!("tcp expecting len: {}", len);
tcp_rd.read_exact(&mut send_buf[..len]).await?;
#[cfg(feature = "verbose")]
println!("tcp got len: {}", len);
udp_wr.send(&send_buf[..len]).await?;
}
#[allow(unreachable_code)]
{
unsafe { std::hint::unreachable_unchecked(); }
Ok(0)
}
}
}
async fn send_udp<T: AsyncWriteExt + std::marker::Unpin + 'static>(buf: &mut [u8; 2050], tcp_stream: &mut T, len: usize) -> Result<()> {
#[cfg(feature = "verbose")]
println!("udp got len: {}", len);
buf[0] = ((len >> 8) & 0xFF) as u8;
buf[1] = (len & 0xFF) as u8;
// todo: tcp_stream.write_all(&buf[..len + 2]).await
Ok(tcp_stream.write_all(&buf[..len + 2]).await?)
// todo: do this? self.tcp_stream.flush()
}
impl ProxyClient {
pub async fn start_async(&self) -> Result<usize> {
let tcp_stream = self.tcp_connect()?;
let udp_socket = self.udp_connect()?;
TcpUdpPipe::new(tokio::net::TcpStream::from_std(tcp_stream).expect("how could this tokio tcp fail?"), UdpSocket::from_std(udp_socket).expect("how could this tokio udp fail?"))
.shuffle_after_first_udp().await
}
pub fn start(&self) -> Result<usize> {
let mut rt = Runtime::new()?;
rt.block_on(async {
self.start_async().await
})
}
pub async fn start_tls_async(&self, hostname: Option<&str>, pinnedpubkey: Option<&str>) -> Result<usize> {
let tcp_stream = self.tcp_connect()?;
let tcp_stream = tokio::net::TcpStream::from_std(tcp_stream).expect("how could this tokio tcp fail?");
use tokio_rustls::{ TlsConnector, rustls::ClientConfig };
let mut config = ClientConfig::new();
config.dangerous().set_certificate_verifier(match pinnedpubkey {
Some(pinnedpubkey) => Arc::new(PinnedpubkeyCertVerifier { pinnedpubkey: pinnedpubkey.to_owned() }),
None => Arc::new(DummyCertVerifier{}),
});
let hostname = match hostname {
Some(hostname) => match DNSNameRef::try_from_ascii_str(hostname) {
Ok(hostname) => hostname,
Err(_) => {
config.enable_sni = false;
DNSNameRef::try_from_ascii_str(&"dummy.hostname").unwrap() // why does rustls ABSOLUTELY REQUIRE this ????
}
},
None => {
config.enable_sni = false;
DNSNameRef::try_from_ascii_str(&"dummy.hostname").unwrap() // why does rustls ABSOLUTELY REQUIRE this ????
}
};
//println!("hostname: {:?}", hostname);
let connector = TlsConnector::from(Arc::new(config));
let tcp_stream= connector.connect(hostname, tcp_stream).await?;
let udp_socket = self.udp_connect()?;
// we want to wait for first udp packet from client first, to set the target to respond to
TcpUdpPipe::new(tcp_stream, UdpSocket::from_std(udp_socket).expect("how could this tokio udp fail?"))
.shuffle_after_first_udp().await
}
pub fn start_tls(&self, hostname: Option<&str>, pinnedpubkey: Option<&str>) -> Result<usize> {
let mut rt = Runtime::new()?;
rt.block_on(async {
self.start_tls_async(hostname, pinnedpubkey).await
})
}
}
use tokio_rustls::rustls;
use tokio_rustls::webpki;
struct DummyCertVerifier;
impl rustls::ServerCertVerifier for DummyCertVerifier {
fn verify_server_cert(&self,
_roots: &rustls::RootCertStore,
_certs: &[rustls::Certificate],
_hostname: webpki::DNSNameRef<'_>,
_ocsp: &[u8]) -> core::result::Result<rustls::ServerCertVerified, rustls::TLSError> {
// verify nothing, subject to MITM
Ok(rustls::ServerCertVerified::assertion())
}
}
struct PinnedpubkeyCertVerifier {
pinnedpubkey: String,
}
impl rustls::ServerCertVerifier for PinnedpubkeyCertVerifier {
fn verify_server_cert(&self,
_roots: &rustls::RootCertStore,
certs: &[rustls::Certificate],
_hostname: webpki::DNSNameRef<'_>,
_ocsp: &[u8]) -> core::result::Result<rustls::ServerCertVerified, rustls::TLSError> {
if certs.is_empty() {
return Err(rustls::TLSError::NoCertificatesPresented);
}
let cert = webpki::trust_anchor_util::cert_der_as_trust_anchor(&certs[0].0)
.map_err(rustls::TLSError::WebPKIError)?;
//println!("spki.len(): {}", cert.spki.len());
//println!("spki: {:?}", cert.spki);
// todo: what is wrong with webpki? it returns *almost* the right answer but missing these leading bytes:
// guess I'll open an issue... (I assume this is some type of algorithm identifying header or something)
let mut pubkey: Vec<u8> = vec![48, 130, 1, 34];
pubkey.extend(cert.spki);
let pubkey = ring::digest::digest(&ring::digest::SHA256, &pubkey);
let pubkey = base64::encode(pubkey);
let pubkey = ["sha256//", &pubkey].join("");
for key in self.pinnedpubkey.split(";") {
if key == pubkey {
return Ok(rustls::ServerCertVerified::assertion());
}
}
Err(rustls::TLSError::General(format!("pubkey '{}' not found in allowed list '{}'", pubkey, self.pinnedpubkey)))
}
}
impl ProxyServer {
pub async fn start_async(&self) -> Result<()> {
let mut listener = tokio::net::TcpListener::bind(&self.tcp_host).await?;
println!("Listening for connections on {}", &self.tcp_host);
loop {
let (stream, _) = listener.accept().await?;
let client_handler = self.client_handler.clone();
tokio::spawn(async move {
client_handler
.handle_client_async(stream).await
.expect("error handling connection");
});
}
#[allow(unreachable_code)]
{
unsafe { std::hint::unreachable_unchecked(); }
Ok(())
}
}
pub fn start(&self) -> Result<()> {
let mut rt = Runtime::new()?;
rt.block_on(async {
self.start_async().await
})
}
pub async fn start_tls_async(&self, tls_key: &str, tls_cert: &str) -> Result<()> {
use std::fs::File;
use std::io::BufReader;
use std::io;
use tokio_rustls::rustls::internal::pemfile::{ certs, pkcs8_private_keys };
let mut tls_key = pkcs8_private_keys(&mut BufReader::new(File::open(tls_key)?))
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))?;
if tls_key.is_empty() {
return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))?;
}
let tls_key = tls_key.remove(0);
let tls_cert = certs(&mut BufReader::new(File::open(tls_cert)?))
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))?;
let mut config = rustls::ServerConfig::new(rustls::NoClientAuth::new());
config.set_single_cert(tls_cert, tls_key)
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;
let acceptor = tokio_rustls::TlsAcceptor::from(Arc::new(config));
let mut listener = tokio::net::TcpListener::bind(&self.tcp_host).await?;
println!("Listening for TLS connections on {}", &self.tcp_host);
loop {
let (stream, _) = listener.accept().await?;
let client_handler = self.client_handler.clone();
let acceptor = acceptor.clone();
tokio::spawn(async move {
let stream = acceptor.accept(stream).await.expect("failed to wrap with TLS?");
client_handler
.handle_client_async(stream).await
.expect("error handling connection");
});
}
#[allow(unreachable_code)]
{
unsafe { std::hint::unreachable_unchecked(); }
Ok(())
}
}
pub fn start_tls(&self, tls_key: &str, tls_cert: &str) -> Result<()> {
let mut rt = Runtime::new()?;
rt.block_on(async {
self.start_tls_async(tls_key, tls_cert).await
})
}
}
impl ProxyServerClientHandler {
pub async fn handle_client_async<T: AsyncReadExt + AsyncWriteExt + std::marker::Unpin + std::marker::Send + 'static>(&self, tcp_stream: T) -> Result<usize> {
TcpUdpPipe::new(tcp_stream,
UdpSocket::from_std(self.udp_bind()?).expect("how could this tokio udp fail?")
).shuffle().await
}
}

+ 5
- 3
src/bin/wireguard-proxy.rs View File

@ -7,11 +7,13 @@ fn main() {
if args.flag("-V") || args.flag("--version") {
print!("wireguard-proxy {} ", env!("CARGO_PKG_VERSION"));
#[cfg(not(any(feature = "tls", feature = "openssl_vendored")))]
#[cfg(not(any(feature = "tls", feature = "openssl_vendored", feature = "async")))]
println!("TLS support: None");
#[cfg(feature = "openssl_vendored")]
#[cfg(feature = "async")]
println!("TLS support: tokio-rustls");
#[cfg(all(feature = "openssl_vendored", not(feature = "async")))]
println!("TLS support: Static/Vendored OpenSSL");
#[cfg(feature = "tls")]
#[cfg(all(feature = "tls", not(feature = "openssl_vendored"), not(feature = "async")))]
println!("TLS support: System OpenSSL");
return;
}


+ 2
- 3
src/error.rs View File

@ -1,7 +1,6 @@
use core::result;
use std::error::Error as StdError;
#[cfg(not(any(feature = "async")))]
pub type IoResult<T> = result::Result<T, std::io::Error>;
pub type Result<T> = result::Result<T, Error>;
@ -32,7 +31,7 @@ impl std::error::Error for Error {
impl From<std::io::Error> for Error {
fn from(value: std::io::Error) -> Self {
Error::new(value.description())
Error::new(&format!("{}", value))
}
}


+ 25
- 206
src/lib.rs View File

@ -1,29 +1,11 @@
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream, UdpSocket};
use std::net::{TcpStream, UdpSocket};
use std::str::FromStr;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
mod error;
use error::Result;
#[cfg(any(feature = "tls", feature = "openssl_vendored"))]
#[path = ""]
mod tls {
pub mod openssl;
pub use crate::tls::openssl::{TlsStream, TlsListener};
}
#[cfg(not(any(feature = "tls", feature = "openssl_vendored")))]
#[path = ""]
mod tls {
pub mod notls;
pub use crate::tls::notls::{TlsStream, TlsListener};
}
use tls::{TlsStream, TlsListener};
fn arg_to_env(arg: &str) -> Option<String> {
if !arg.starts_with("--") {
return None;
@ -41,7 +23,6 @@ fn env_for_arg(arg: &str) -> Option<String> {
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_arg_to_env() {
assert_eq!(arg_to_env("--tcp-host"), Some("WGP_TCP_HOST".to_owned()));
@ -107,88 +88,40 @@ impl<'a> Args<'a> {
}
}
pub struct TcpUdpPipe<T: Write + Read + TryClone<T> + Send + 'static> {
buf: [u8; 2050], // 2048 + 2 for len
tcp_stream: T,
udp_socket: UdpSocket,
pub struct ProxyClient {
pub udp_host: String,
pub tcp_target: String,
pub socket_timeout: Option<Duration>,
}
impl<T: Write + Read + TryClone<T> + Send + 'static> TcpUdpPipe<T> {
pub fn new(tcp_stream: T, udp_socket: UdpSocket) -> TcpUdpPipe<T> {
TcpUdpPipe {
tcp_stream,
udp_socket,
buf: [0u8; 2050],
}
}
pub fn try_clone(&self) -> Result<TcpUdpPipe<T>> {
Ok(TcpUdpPipe::new(
self.tcp_stream.try_clone()?,
self.udp_socket.try_clone()?,
))
}
pub fn shuffle_after_first_udp(&mut self) -> Result<usize> {
let (len, src_addr) = self.udp_socket.recv_from(&mut self.buf[2..])?;
println!("first packet from {}, connecting to that", src_addr);
self.udp_socket.connect(src_addr)?;
self.send_udp(len)?;
self.shuffle()
}
pub fn udp_to_tcp(&mut self) -> Result<()> {
let len = self.udp_socket.recv(&mut self.buf[2..])?;
self.send_udp(len)
}
fn send_udp(&mut self, len: usize) -> Result<()> {
#[cfg(feature = "verbose")]
println!("udp got len: {}", len);
pub struct ProxyServer {
pub tcp_host: String,
pub client_handler: Arc<ProxyServerClientHandler>,
}
self.buf[0] = ((len >> 8) & 0xFF) as u8;
self.buf[1] = (len & 0xFF) as u8;
pub struct ProxyServerClientHandler {
pub udp_target: String,
pub udp_host: String,
pub udp_low_port: u16,
pub udp_high_port: u16,
pub socket_timeout: Option<Duration>,
}
Ok(self.tcp_stream.write_all(&self.buf[..len + 2])?)
// todo: do this? self.tcp_stream.flush()
}
#[cfg(any(feature = "async"))]
#[path = ""]
mod net {
mod asyncmod;
}
pub fn tcp_to_udp(&mut self) -> Result<usize> {
self.tcp_stream.read_exact(&mut self.buf[..2])?;
let len = ((self.buf[0] as usize) << 8) + self.buf[1] as usize;
#[cfg(feature = "verbose")]
println!("tcp expecting len: {}", len);
self.tcp_stream.read_exact(&mut self.buf[..len])?;
#[cfg(feature = "verbose")]
println!("tcp got len: {}", len);
Ok(self.udp_socket.send(&self.buf[..len])?)
#[cfg(not(any(feature = "async")))]
#[path = ""]
mod net {
//let sent = udp_socket.send_to(&buf[..len], &self.udp_target)?;
//assert_eq!(sent, len);
}
pub fn shuffle(&mut self) -> Result<usize> {
let mut udp_pipe_clone = self.try_clone()?;
thread::spawn(move || loop {
udp_pipe_clone
.udp_to_tcp()
.expect("cannot write to tcp_clone");
});
loop {
self.tcp_to_udp()?;
}
}
mod syncmod;
}
pub struct ProxyClient {
pub udp_host: String,
pub tcp_target: String,
pub socket_timeout: Option<Duration>,
}
impl ProxyClient {
pub fn new(udp_host: String, tcp_target: String, secs: u64) -> ProxyClient {
@ -213,48 +146,6 @@ impl ProxyClient {
udp_socket.set_read_timeout(self.socket_timeout)?;
Ok(udp_socket)
}
pub fn start(&self) -> Result<usize> {
let tcp_stream = self.tcp_connect()?;
let udp_socket = self.udp_connect()?;
// we want to wait for first udp packet from client first, to set the target to respond to
TcpUdpPipe::new(tcp_stream, udp_socket).shuffle_after_first_udp()
}
pub fn start_tls(&self, hostname: Option<&str>, pinnedpubkey: Option<&str>) -> Result<usize> {
let tcp_stream = self.tcp_connect()?;
let tcp_stream = TlsStream::client(hostname, pinnedpubkey, tcp_stream)?;
let udp_socket = self.udp_connect()?;
// we want to wait for first udp packet from client first, to set the target to respond to
TcpUdpPipe::new(tcp_stream, udp_socket).shuffle_after_first_udp()
}
}
pub trait TryClone<T> {
fn try_clone(&self) -> Result<T>;
}
impl TryClone<UdpSocket> for UdpSocket {
fn try_clone(&self) -> Result<UdpSocket> {
Ok(self.try_clone()?)
}
}
impl TryClone<TcpStream> for TcpStream {
fn try_clone(&self) -> Result<TcpStream> {
Ok(self.try_clone()?)
}
}
pub struct ProxyServer {
pub tcp_host: String,
pub client_handler: Arc<ProxyServerClientHandler>,
}
impl ProxyServer {
@ -281,66 +172,6 @@ impl ProxyServer {
client_handler,
}
}
pub fn start(&self) -> Result<()> {
let listener = TcpListener::bind(&self.tcp_host)?;
println!("Listening for connections on {}", &self.tcp_host);
for stream in listener.incoming() {
match stream {
Ok(stream) => {
let client_handler = self.client_handler.clone();
client_handler.set_tcp_options(&stream).expect("cannot set tcp options");
thread::spawn(move || {
client_handler
.handle_client(stream)
.expect("error handling connection")
});
}
Err(e) => {
println!("Unable to connect: {}", e);
}
}
}
Ok(())
}
pub fn start_tls(&self, tls_key: &str, tls_cert: &str) -> Result<()> {
let tls_listener = Arc::new(TlsListener::new(tls_key, tls_cert)?);
let listener = TcpListener::bind(&self.tcp_host)?;
println!("Listening for TLS connections on {}", &self.tcp_host);
for stream in listener.incoming() {
match stream {
Ok(stream) => {
let client_handler = self.client_handler.clone();
client_handler.set_tcp_options(&stream).expect("cannot set tcp options");
let tls_listener = tls_listener.clone();
thread::spawn(move || {
let stream = tls_listener.wrap(stream).expect("cannot wrap with tls");
client_handler
.handle_client_tls(stream)
.expect("error handling connection")
});
}
Err(e) => {
println!("Unable to connect: {}", e);
}
}
}
Ok(())
}
}
pub struct ProxyServerClientHandler {
pub udp_target: String,
pub udp_host: String,
pub udp_low_port: u16,
pub udp_high_port: u16,
pub socket_timeout: Option<Duration>,
}
impl ProxyServerClientHandler {
@ -361,16 +192,4 @@ impl ProxyServerClientHandler {
udp_socket.connect(&self.udp_target)?;
Ok(udp_socket)
}
pub fn set_tcp_options(&self, tcp_stream: &TcpStream) -> Result<()> {
Ok(tcp_stream.set_read_timeout(self.socket_timeout)?)
}
pub fn handle_client(&self, tcp_stream: TcpStream) -> Result<usize> {
TcpUdpPipe::new(tcp_stream, self.udp_bind()?).shuffle()
}
pub fn handle_client_tls(&self, tcp_stream: TlsStream) -> Result<usize> {
TcpUdpPipe::new(tcp_stream, self.udp_bind()?).shuffle()
}
}

+ 1
- 1
src/notls.rs View File

@ -1,5 +1,5 @@
use std::net::TcpStream;
use crate::TryClone;
use super::super::TryClone;
use std::io::{Read, Write};
use crate::error::*;


+ 5
- 4
src/openssl.rs View File

@ -3,11 +3,11 @@ use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode, SslAccepto
use std::sync::Arc;
use std::cell::UnsafeCell;
use std::net::TcpStream;
use crate::TryClone;
use std::io::{Read, Write};
use super::super::TryClone;
use crate::error::*;
use std::error::Error as StdError;
impl TryClone<TlsStream> for TlsStream {
fn try_clone(&self) -> Result<TlsStream> {
@ -37,7 +37,8 @@ impl TlsStream {
let cert = x509_store_ctx.current_cert().expect("could not get TLS cert");
let pubkey = cert.public_key().expect("could not get public key from TLS cert");
let pubkey = pubkey.public_key_to_der().expect("could not get TLS public key bytes");
//println!("pubkey.len(): {}", pubkey.len());
//println!("spki.len(): {}", pubkey.len());
//println!("spki: {:?}", pubkey);
let mut sha256 = openssl::sha::Sha256::new();
sha256.update(&pubkey);
@ -148,6 +149,6 @@ impl From<openssl::error::ErrorStack> for Error {
impl From<HandshakeError<std::net::TcpStream>> for Error {
fn from(value: HandshakeError<std::net::TcpStream>) -> Self {
Error::new(value.description())
Error::new(&format!("{}", value))
}
}

+ 208
- 0
src/syncmod.rs View File

@ -0,0 +1,208 @@
use std::thread;
use crate::error::Result;
use crate::*;
use std::net::TcpListener;
use std::io::{Write, Read};
#[cfg(any(feature = "tls", feature = "openssl_vendored"))]
#[path = ""]
mod tls {
pub mod openssl;
pub use super::tls::openssl::{TlsStream, TlsListener};
}
#[cfg(not(any(feature = "tls", feature = "openssl_vendored")))]
#[path = ""]
mod tls {
pub mod notls;
pub use super::tls::notls::{TlsStream, TlsListener};
}
use tls::{TlsStream, TlsListener};
pub struct TcpUdpPipe<T: Write + Read + TryClone<T> + Send + 'static> {
buf: [u8; 2050], // 2048 + 2 for len
tcp_stream: T,
udp_socket: UdpSocket,
}
impl<T: Write + Read + TryClone<T> + Send + 'static> TcpUdpPipe<T> {
pub fn new(tcp_stream: T, udp_socket: UdpSocket) -> TcpUdpPipe<T> {
TcpUdpPipe {
tcp_stream,
udp_socket,
buf: [0u8; 2050],
}
}
pub fn try_clone(&self) -> Result<TcpUdpPipe<T>> {
Ok(TcpUdpPipe::new(
self.tcp_stream.try_clone()?,
self.udp_socket.try_clone()?,
))
}
pub fn shuffle_after_first_udp(&mut self) -> Result<usize> {
let (len, src_addr) = self.udp_socket.recv_from(&mut self.buf[2..])?;
println!("first packet from {}, connecting to that", src_addr);
self.udp_socket.connect(src_addr)?;
self.send_udp(len)?;
self.shuffle()
}
pub fn udp_to_tcp(&mut self) -> Result<()> {
let len = self.udp_socket.recv(&mut self.buf[2..])?;
self.send_udp(len)
}
fn send_udp(&mut self, len: usize) -> Result<()> {
#[cfg(feature = "verbose")]
println!("udp got len: {}", len);
self.buf[0] = ((len >> 8) & 0xFF) as u8;
self.buf[1] = (len & 0xFF) as u8;
Ok(self.tcp_stream.write_all(&self.buf[..len + 2])?)
// todo: do this? self.tcp_stream.flush()
}
pub fn tcp_to_udp(&mut self) -> Result<usize> {
self.tcp_stream.read_exact(&mut self.buf[..2])?;
let len = ((self.buf[0] as usize) << 8) + self.buf[1] as usize;
#[cfg(feature = "verbose")]
println!("tcp expecting len: {}", len);
self.tcp_stream.read_exact(&mut self.buf[..len])?;
#[cfg(feature = "verbose")]
println!("tcp got len: {}", len);
Ok(self.udp_socket.send(&self.buf[..len])?)
//let sent = udp_socket.send_to(&buf[..len], &self.udp_target)?;
//assert_eq!(sent, len);
}
pub fn shuffle(&mut self) -> Result<usize> {
let mut udp_pipe_clone = self.try_clone()?;
thread::spawn(move || loop {
udp_pipe_clone
.udp_to_tcp()
.expect("cannot write to tcp_clone");
});
loop {
self.tcp_to_udp()?;
}
}
}
pub trait TryClone<T> {
fn try_clone(&self) -> Result<T>;
}
impl TryClone<UdpSocket> for UdpSocket {
fn try_clone(&self) -> Result<UdpSocket> {
Ok(self.try_clone()?)
}
}
impl TryClone<TcpStream> for TcpStream {
fn try_clone(&self) -> Result<TcpStream> {
Ok(self.try_clone()?)
}
}
impl ProxyClient {
pub fn start(&self) -> Result<usize> {
let tcp_stream = self.tcp_connect()?;
let udp_socket = self.udp_connect()?;
// we want to wait for first udp packet from client first, to set the target to respond to
TcpUdpPipe::new(tcp_stream, udp_socket).shuffle_after_first_udp()
}
pub fn start_tls(&self, hostname: Option<&str>, pinnedpubkey: Option<&str>) -> Result<usize> {
let tcp_stream = self.tcp_connect()?;
let tcp_stream = TlsStream::client(hostname, pinnedpubkey, tcp_stream)?;
let udp_socket = self.udp_connect()?;
// we want to wait for first udp packet from client first, to set the target to respond to
TcpUdpPipe::new(tcp_stream, udp_socket).shuffle_after_first_udp()
}
}
impl ProxyServer {
pub fn start(&self) -> Result<()> {
let listener = TcpListener::bind(&self.tcp_host)?;
println!("Listening for connections on {}", &self.tcp_host);
for stream in listener.incoming() {
match stream {
Ok(stream) => {
let client_handler = self.client_handler.clone();
client_handler.set_tcp_options(&stream).expect("cannot set tcp options");
thread::spawn(move || {
client_handler
.handle_client(stream)
.expect("error handling connection")
});
}
Err(e) => {
println!("Unable to connect: {}", e);
}
}
}
Ok(())
}
pub fn start_tls(&self, tls_key: &str, tls_cert: &str) -> Result<()> {
let tls_listener = Arc::new(TlsListener::new(tls_key, tls_cert)?);
let listener = TcpListener::bind(&self.tcp_host)?;
println!("Listening for TLS connections on {}", &self.tcp_host);
for stream in listener.incoming() {
match stream {
Ok(stream) => {
let client_handler = self.client_handler.clone();
client_handler.set_tcp_options(&stream).expect("cannot set tcp options");
let tls_listener = tls_listener.clone();
thread::spawn(move || {
let stream = tls_listener.wrap(stream).expect("cannot wrap with tls");
client_handler
.handle_client_tls(stream)
.expect("error handling connection")
});
}
Err(e) => {
println!("Unable to connect: {}", e);
}
}
}
Ok(())
}
}
impl ProxyServerClientHandler {
pub fn set_tcp_options(&self, tcp_stream: &TcpStream) -> Result<()> {
Ok(tcp_stream.set_read_timeout(self.socket_timeout)?)
}
pub fn handle_client(&self, tcp_stream: TcpStream) -> Result<usize> {
TcpUdpPipe::new(tcp_stream, self.udp_bind()?).shuffle()
}
pub fn handle_client_tls(&self, tcp_stream: TlsStream) -> Result<usize> {
TcpUdpPipe::new(tcp_stream, self.udp_bind()?).shuffle()
}
}

Loading…
Cancel
Save