diff options
| author | David Lönnhager <david.l@mullvad.net> | 2022-03-29 09:32:45 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2022-04-05 10:33:57 +0200 |
| commit | 7c6746e9cb9c24fa04a5d098f110ea24ace1153b (patch) | |
| tree | acb35272268d220a55b7bef41ee42b88f7d242a8 | |
| parent | 85dee12820549c8a8f82c6133c22f275640608bc (diff) | |
| download | mullvadvpn-7c6746e9cb9c24fa04a5d098f110ea24ace1153b.tar.xz mullvadvpn-7c6746e9cb9c24fa04a5d098f110ea24ace1153b.zip | |
Use shadowsocks crate instead of subprocess
| -rw-r--r-- | Cargo.lock | 589 | ||||
| -rw-r--r-- | talpid-core/Cargo.toml | 1 | ||||
| -rw-r--r-- | talpid-core/src/proxy/mod.rs | 8 | ||||
| -rw-r--r-- | talpid-core/src/proxy/noop.rs | 18 | ||||
| -rw-r--r-- | talpid-core/src/proxy/shadowsocks.rs | 347 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/mod.rs | 4 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/openvpn/mod.rs | 83 |
7 files changed, 726 insertions, 324 deletions
diff --git a/Cargo.lock b/Cargo.lock index f03c8d1445..d99fdafe0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ - "generic-array", + "generic-array 0.14.4", ] [[package]] @@ -36,7 +36,7 @@ dependencies = [ "cipher", "cpufeatures", "ctr", - "opaque-debug", + "opaque-debug 0.3.0", ] [[package]] @@ -87,6 +87,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" [[package]] +name = "arc-swap" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dabe5a181f83789739c194cbe5a897dde195078fac08568d09221fd6137a7ba8" + +[[package]] +name = "arc-swap" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d78ce20460b82d3fa150275ed9d55e21064fc7951177baacf86a145c4a4b1f" + +[[package]] name = "ascii" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -176,11 +188,32 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" dependencies = [ - "generic-array", + "generic-array 0.14.4", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", ] [[package]] @@ -190,6 +223,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" [[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] name = "byte_string" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -257,6 +296,12 @@ dependencies = [ ] [[package]] +name = "checked_int_cast" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919" + +[[package]] name = "chrono" version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -276,7 +321,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array", + "generic-array 0.14.4", ] [[package]] @@ -366,12 +411,32 @@ dependencies = [ ] [[package]] +name = "crossbeam-channel" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] name = "crypto-bigint" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" dependencies = [ - "generic-array", + "generic-array 0.14.4", "rand_core 0.6.3", "subtle", "zeroize", @@ -383,7 +448,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" dependencies = [ - "generic-array", + "generic-array 0.14.4", ] [[package]] @@ -480,6 +545,17 @@ dependencies = [ ] [[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "derive-try-from-primitive" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -530,11 +606,20 @@ dependencies = [ [[package]] name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array", + "generic-array 0.14.4", ] [[package]] @@ -543,9 +628,9 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" dependencies = [ - "block-buffer", + "block-buffer 0.10.0", "crypto-common", - "generic-array", + "generic-array 0.14.4", "subtle", ] @@ -617,7 +702,7 @@ dependencies = [ "base16ct", "crypto-bigint", "der", - "generic-array", + "generic-array 0.14.4", "rand_core 0.6.3", "sec1", "subtle", @@ -730,6 +815,12 @@ dependencies = [ ] [[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] name = "fern" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -747,7 +838,7 @@ checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.2.10", "winapi 0.3.9", ] @@ -780,7 +871,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" dependencies = [ "bitflags", - "fsevent-sys", + "fsevent-sys 2.0.1", ] [[package]] @@ -793,6 +884,15 @@ dependencies = [ ] [[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -904,6 +1004,15 @@ dependencies = [ [[package]] name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" @@ -940,7 +1049,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" dependencies = [ - "opaque-debug", + "opaque-debug 0.3.0", "polyval", ] @@ -1095,7 +1204,7 @@ dependencies = [ "httpdate", "itoa 0.4.8", "pin-project-lite", - "socket2", + "socket2 0.4.2", "tokio", "tower-service", "tracing", @@ -1168,6 +1277,17 @@ dependencies = [ ] [[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] name = "inotify-sys" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1211,14 +1331,26 @@ dependencies = [ [[package]] name = "ipconfig" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" +dependencies = [ + "socket2 0.3.19", + "widestring 0.4.3", + "winapi 0.3.9", + "winreg 0.6.2", +] + +[[package]] +name = "ipconfig" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "723519edce41262b05d4143ceb95050e4c614f483e78e9fd9e39a8275a84ad98" dependencies = [ - "socket2", + "socket2 0.4.2", "widestring 0.5.1", "winapi 0.3.9", - "winreg", + "winreg 0.7.0", ] [[package]] @@ -1237,6 +1369,15 @@ dependencies = [ ] [[package]] +name = "iprange" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37209be0ad225457e63814401415e748e2453a5297f9b637338f5fb8afa4ec00" +dependencies = [ + "ipnet", +] + +[[package]] name = "itertools" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1311,6 +1452,17 @@ dependencies = [ ] [[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1321,6 +1473,26 @@ dependencies = [ ] [[package]] +name = "kqueue" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058a107a784f8be94c7d35c1300f4facced2e93d2fbe5b1452b44e905ddca4a9" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587" +dependencies = [ + "bitflags", + "libc", +] + +[[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1369,9 +1541,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ "cfg-if 1.0.0", + "serde", ] [[package]] +name = "log-mdc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" + +[[package]] name = "log-panics" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1381,6 +1560,33 @@ dependencies = [ ] [[package]] +name = "log4rs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1572a880d1115ff867396eee7ae2bc924554225e67a0d3c85c745b3e60ca211" +dependencies = [ + "anyhow", + "arc-swap 0.4.8", + "chrono", + "derivative", + "fnv", + "humantime", + "libc", + "log", + "log-mdc", + "parking_lot 0.11.2", + "regex", + "serde", + "serde-value", + "serde_json", + "serde_yaml", + "thiserror", + "thread-id", + "typemap", + "winapi 0.3.9", +] + +[[package]] name = "lru-cache" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1390,6 +1596,18 @@ dependencies = [ ] [[package]] +name = "lru_time_cache" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9106e1d747ffd48e6be5bb2d97fa706ed25b144fbee4d5c02eae110cd8d6badd" + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] name = "match_cfg" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1478,6 +1696,20 @@ dependencies = [ ] [[package]] +name = "mio" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +dependencies = [ + "libc", + "log", + "miow 0.3.7", + "ntapi", + "wasi 0.11.0+wasi-snapshot-preview1", + "winapi 0.3.9", +] + +[[package]] name = "mio-extras" version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1899,8 +2131,8 @@ dependencies = [ "bitflags", "filetime", "fsevent", - "fsevent-sys", - "inotify", + "fsevent-sys 2.0.1", + "inotify 0.7.1", "libc", "mio 0.6.23", "mio-extras", @@ -1909,6 +2141,24 @@ dependencies = [ ] [[package]] +name = "notify" +version = "5.0.0-pre.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d13c22db70a63592e098fb51735bab36646821e6389a0ba171f3549facdf0b74" +dependencies = [ + "bitflags", + "crossbeam-channel", + "filetime", + "fsevent-sys 4.1.0", + "inotify 0.9.6", + "kqueue", + "libc", + "mio 0.8.2", + "walkdir", + "winapi 0.3.9", +] + +[[package]] name = "ntapi" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1963,6 +2213,12 @@ checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" @@ -1985,6 +2241,15 @@ dependencies = [ ] [[package]] +name = "ordered-float" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" +dependencies = [ + "num-traits", +] + +[[package]] name = "os_pipe" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2069,7 +2334,7 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.10", "smallvec", "winapi 0.3.9", ] @@ -2082,7 +2347,7 @@ checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.2.10", "smallvec", "windows-sys", ] @@ -2109,6 +2374,40 @@ dependencies = [ ] [[package]] +name = "pest_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +dependencies = [ + "maplit", + "pest", + "sha-1", +] + +[[package]] name = "petgraph" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2221,7 +2520,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" dependencies = [ "cpufeatures", - "opaque-debug", + "opaque-debug 0.3.0", "universal-hash", ] @@ -2233,7 +2532,7 @@ checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "opaque-debug", + "opaque-debug 0.3.0", "universal-hash", ] @@ -2340,6 +2639,15 @@ dependencies = [ ] [[package]] +name = "qrcode" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d2f1455f3630c6e5107b4f2b94e74d76dea80736de0981fd27644216cff57f" +dependencies = [ + "checked_int_cast", +] + +[[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2469,6 +2777,12 @@ dependencies = [ [[package]] name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" @@ -2483,7 +2797,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ "getrandom 0.2.3", - "redox_syscall", + "redox_syscall 0.2.10", ] [[package]] @@ -2531,7 +2845,7 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", + "spin 0.5.2", "untrusted", "web-sys", "winapi 0.3.9", @@ -2547,8 +2861,8 @@ dependencies = [ "digest 0.9.0", "ecdsa", "ed25519", - "generic-array", - "opaque-debug", + "generic-array 0.14.4", + "opaque-debug 0.3.0", "p256", "p384", "ring", @@ -2678,7 +2992,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" dependencies = [ "der", - "generic-array", + "generic-array 0.14.4", "subtle", "zeroize", ] @@ -2744,6 +3058,16 @@ dependencies = [ ] [[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + +[[package]] name = "serde-xml-rs" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2790,6 +3114,30 @@ dependencies = [ ] [[package]] +name = "serde_yaml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" +dependencies = [ + "indexmap", + "ryu", + "serde", + "yaml-rust", +] + +[[package]] +name = "sha-1" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] name = "sha1" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2816,6 +3164,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "356770455d9fb911a6b559ceedaa7f2d34e47d2d8ae606041dffba390abb7522" dependencies = [ + "arc-swap 1.5.0", "async-trait", "base64", "byte_string", @@ -2825,6 +3174,7 @@ dependencies = [ "libc", "log", "nix 0.23.1", + "notify 5.0.0-pre.14", "once_cell", "pin-project", "sendfd", @@ -2832,10 +3182,11 @@ dependencies = [ "serde_json", "serde_urlencoded", "shadowsocks-crypto", - "socket2", + "socket2 0.4.2", "thiserror", "tokio", "tokio-tfo", + "trust-dns-resolver 0.20.4", "url", "winapi 0.3.9", ] @@ -2859,6 +3210,41 @@ dependencies = [ ] [[package]] +name = "shadowsocks-service" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c183dded537f8e5949996ca6343bb4a35d64c7f480ab823d8d1e028524f1ec" +dependencies = [ + "arc-swap 1.5.0", + "async-trait", + "byte_string", + "byteorder", + "bytes", + "cfg-if 1.0.0", + "futures", + "idna", + "ipnet", + "iprange", + "json5", + "libc", + "log", + "log4rs", + "lru_time_cache", + "nix 0.23.1", + "once_cell", + "pin-project", + "qrcode", + "regex", + "serde", + "shadowsocks", + "socket2 0.4.2", + "spin 0.9.2", + "thiserror", + "tokio", + "winapi 0.3.9", +] + +[[package]] name = "shared_child" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2922,6 +3308,17 @@ checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "socket2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "socket2" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" @@ -2937,6 +3334,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] +name = "spin" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" +dependencies = [ + "lock_api", +] + +[[package]] name = "strsim" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3036,7 +3442,7 @@ dependencies = [ "netlink-sys", "nftnl", "nix 0.23.1", - "notify", + "notify 4.0.17", "os_pipe", "parity-tokio-ipc", "parking_lot 0.11.2", @@ -3048,8 +3454,9 @@ dependencies = [ "regex", "resolv-conf", "rtnetlink", + "shadowsocks-service", "shell-escape", - "socket2", + "socket2 0.4.2", "subslice", "system-configuration", "talpid-dbus", @@ -3068,7 +3475,7 @@ dependencies = [ "which", "widestring 0.5.1", "winapi 0.3.9", - "winreg", + "winreg 0.7.0", "zeroize", ] @@ -3134,7 +3541,7 @@ dependencies = [ "cfg-if 1.0.0", "libc", "rand 0.8.4", - "redox_syscall", + "redox_syscall 0.2.10", "remove_dir_all", "winapi 0.3.9", ] @@ -3175,6 +3582,17 @@ dependencies = [ ] [[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" +dependencies = [ + "libc", + "redox_syscall 0.1.57", + "winapi 0.3.9", +] + +[[package]] name = "time" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3283,7 +3701,7 @@ dependencies = [ "log", "once_cell", "pin-project", - "socket2", + "socket2 0.4.2", "tokio", "winapi 0.3.9", ] @@ -3430,6 +3848,12 @@ dependencies = [ ] [[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" + +[[package]] name = "translations-converter" version = "0.1.0" dependencies = [ @@ -3464,7 +3888,32 @@ dependencies = [ "thiserror", "time 0.3.5", "tokio", - "trust-dns-proto", + "trust-dns-proto 0.21.0-alpha.5", +] + +[[package]] +name = "trust-dns-proto" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca94d4e9feb6a181c690c4040d7a24ef34018d8313ac5044a61d21222ae24e31" +dependencies = [ + "async-trait", + "cfg-if 1.0.0", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "lazy_static", + "log", + "rand 0.8.4", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "url", ] [[package]] @@ -3495,13 +3944,33 @@ dependencies = [ [[package]] name = "trust-dns-resolver" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecae383baad9995efaa34ce8e57d12c3f305e545887472a492b838f4b5cfb77a" +dependencies = [ + "cfg-if 1.0.0", + "futures-util", + "ipconfig 0.2.2", + "lazy_static", + "log", + "lru-cache", + "parking_lot 0.11.2", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "trust-dns-proto 0.20.4", +] + +[[package]] +name = "trust-dns-resolver" version = "0.21.0-alpha.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f2ce3a81fcddc72de8da5852c4ea0a5507bd129c0aa20a2354a1b1e51d6813a" dependencies = [ "cfg-if 1.0.0", "futures-util", - "ipconfig", + "ipconfig 0.3.0", "lazy_static", "log", "lru-cache", @@ -3511,7 +3980,7 @@ dependencies = [ "smallvec", "thiserror", "tokio", - "trust-dns-proto", + "trust-dns-proto 0.21.0-alpha.5", ] [[package]] @@ -3534,8 +4003,8 @@ dependencies = [ "tokio", "toml", "trust-dns-client", - "trust-dns-proto", - "trust-dns-resolver", + "trust-dns-proto 0.21.0-alpha.5", + "trust-dns-resolver 0.21.0-alpha.5", ] [[package]] @@ -3567,6 +4036,15 @@ dependencies = [ ] [[package]] +name = "typemap" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" +dependencies = [ + "unsafe-any", +] + +[[package]] name = "typenum" version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3624,7 +4102,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" dependencies = [ - "generic-array", + "generic-array 0.14.4", "subtle", ] @@ -3638,6 +4116,15 @@ dependencies = [ ] [[package]] +name = "unsafe-any" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" +dependencies = [ + "traitobject", +] + +[[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3717,6 +4204,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[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.78" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3923,6 +4416,15 @@ checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" [[package]] name = "winreg" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "winreg" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" @@ -3967,6 +4469,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" [[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] name = "zeroize" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml index 7ff3b8721f..80b24e3305 100644 --- a/talpid-core/Cargo.toml +++ b/talpid-core/Cargo.toml @@ -32,6 +32,7 @@ tokio = { version = "1.8", features = ["process", "rt-multi-thread", "fs"] } tokio-stream = { version = "0.1", features = ["io-util"] } rand = "0.7" tunnel-obfuscation = { path = "../tunnel-obfuscation" } +shadowsocks-service = { version = "1.12", default-features = false, features = ["local", "stream-cipher"] } [target.'cfg(not(target_os="android"))'.dependencies] byteorder = "1" diff --git a/talpid-core/src/proxy/mod.rs b/talpid-core/src/proxy/mod.rs index 57065fb99d..c33c09cf05 100644 --- a/talpid-core/src/proxy/mod.rs +++ b/talpid-core/src/proxy/mod.rs @@ -4,6 +4,7 @@ mod shadowsocks; pub use std::io::Result; use self::shadowsocks::ShadowsocksProxyMonitor; +use async_trait::async_trait; use std::{fmt, path::PathBuf}; use talpid_types::net::openvpn; @@ -12,12 +13,13 @@ pub enum WaitResult { ProperShutdown, } +#[async_trait] pub trait ProxyMonitor: Send { /// Create a handle than can be used to ask the proxy service to shut down. fn close_handle(&mut self) -> Box<dyn ProxyMonitorCloseHandle>; /// Consume monitor and wait for proxy service to shut down. - fn wait(self: Box<Self>) -> Result<WaitResult>; + async fn wait(self: Box<Self>) -> Result<WaitResult>; /// The port bound to. fn port(&self) -> u16; @@ -41,7 +43,7 @@ pub struct ProxyResourceData { pub log_dir: Option<PathBuf>, } -pub fn start_proxy( +pub async fn start_proxy( settings: &openvpn::ProxySettings, resource_data: &ProxyResourceData, ) -> Result<Box<dyn ProxyMonitor>> { @@ -59,7 +61,7 @@ pub fn start_proxy( )?)) } openvpn::ProxySettings::Shadowsocks(ss_settings) => Ok(Box::new( - ShadowsocksProxyMonitor::start(ss_settings, resource_data)?, + ShadowsocksProxyMonitor::start(ss_settings, resource_data).await?, )), } } diff --git a/talpid-core/src/proxy/noop.rs b/talpid-core/src/proxy/noop.rs index f6e800a0c4..88ec5b437d 100644 --- a/talpid-core/src/proxy/noop.rs +++ b/talpid-core/src/proxy/noop.rs @@ -1,20 +1,22 @@ -use std::sync::mpsc; +use async_trait::async_trait; +use futures::{channel::mpsc, StreamExt}; use super::{ProxyMonitor, ProxyMonitorCloseHandle, Result, WaitResult}; pub struct NoopProxyMonitor { - tx: mpsc::Sender<()>, - rx: mpsc::Receiver<()>, + tx: mpsc::UnboundedSender<()>, + rx: mpsc::UnboundedReceiver<()>, port: u16, } impl NoopProxyMonitor { pub fn start(port: u16) -> Result<Self> { - let (tx, rx) = mpsc::channel(); + let (tx, rx) = mpsc::unbounded(); Ok(NoopProxyMonitor { tx, rx, port }) } } +#[async_trait] impl ProxyMonitor for NoopProxyMonitor { fn close_handle(&mut self) -> Box<dyn ProxyMonitorCloseHandle> { Box::new(NoopProxyMonitorCloseHandle { @@ -22,8 +24,8 @@ impl ProxyMonitor for NoopProxyMonitor { }) } - fn wait(self: Box<Self>) -> Result<WaitResult> { - let _ = self.rx.recv(); + async fn wait(mut self: Box<Self>) -> Result<WaitResult> { + let _ = self.rx.next().await; Ok(WaitResult::ProperShutdown) } @@ -33,12 +35,12 @@ impl ProxyMonitor for NoopProxyMonitor { } struct NoopProxyMonitorCloseHandle { - tx: mpsc::Sender<()>, + tx: mpsc::UnboundedSender<()>, } impl ProxyMonitorCloseHandle for NoopProxyMonitorCloseHandle { fn close(self: Box<Self>) -> Result<()> { - let _ = self.tx.send(()); + let _ = self.tx.unbounded_send(()); Ok(()) } } diff --git a/talpid-core/src/proxy/shadowsocks.rs b/talpid-core/src/proxy/shadowsocks.rs index 6436e967c5..12f8c1bb69 100644 --- a/talpid-core/src/proxy/shadowsocks.rs +++ b/talpid-core/src/proxy/shadowsocks.rs @@ -1,284 +1,127 @@ -pub use std::io::Result; +pub use std::io; -use crate::logging; -use regex::Regex; +use async_trait::async_trait; +use futures::future::{abortable, AbortHandle, Aborted}; +use socket2::{Domain, SockAddr, Socket}; +use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; +use tokio::task::JoinHandle; -use std::{ - borrow::Cow, - env, - ffi::OsString, - fmt, - fs::File, - io::{BufRead, Error, ErrorKind}, - net::{IpAddr, Ipv4Addr, SocketAddr}, - path::PathBuf, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, +use shadowsocks_service::{ + config::{Config, ConfigType, LocalConfig, ProtocolType}, + local, + shadowsocks::{ + config::{Mode, ServerConfig}, + ServerAddr, }, - thread, - time::Duration, }; use super::{ProxyMonitor, ProxyMonitorCloseHandle, ProxyResourceData, WaitResult}; -use talpid_types::net::openvpn::ShadowsocksProxySettings; -#[cfg(target_os = "linux")] -use talpid_types::ErrorExt; - -struct ShadowsocksCommand { - shadowsocks_bin: OsString, - local: Option<SocketAddr>, - peer: Option<SocketAddr>, - peer_password: Option<String>, - // This should map to the shadowsocks-rust `CipherType` type. - cipher: Option<String>, -} - -impl ShadowsocksCommand { - pub fn new(shadowsocks_bin: OsString) -> Self { - ShadowsocksCommand { - shadowsocks_bin, - local: None, - peer: None, - peer_password: None, - cipher: None, - } - } - - pub fn local(&mut self, local: SocketAddr) -> &mut Self { - self.local = Some(local); - self - } - - pub fn peer(&mut self, peer: SocketAddr) -> &mut Self { - self.peer = Some(peer); - self - } - - pub fn peer_password(&mut self, password: String) -> &mut Self { - self.peer_password = Some(password); - self - } - - pub fn cipher(&mut self, cipher: String) -> &mut Self { - self.cipher = Some(cipher); - self - } - - pub fn build(&self) -> duct::Expression { - log::debug!("Building expression: {}", &self); - duct::cmd(&self.shadowsocks_bin, self.get_arguments()).unchecked() - } - - fn get_arguments(&self) -> Vec<String> { - let mut args: Vec<String> = vec![]; - - // Always activate TCP no-delay. - args.push("--no-delay".to_owned()); - - if let Some(ref local) = self.local { - args.push("--local-addr".to_owned()); - args.push(format!("{}:{}", local.ip(), local.port())); - } - - if let Some(ref peer) = self.peer { - args.push("--server-addr".to_owned()); - args.push(format!("{}:{}", peer.ip(), peer.port())); - } - - if let Some(ref peer_password) = self.peer_password { - args.push("--password".to_owned()); - args.push(peer_password.to_owned()); - } - - if let Some(ref cipher) = self.cipher { - args.push("--encrypt-method".to_owned()); - args.push(cipher.to_string()); - } - - args - } -} - -impl fmt::Display for ShadowsocksCommand { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.write_str(&shell_escape::escape( - self.shadowsocks_bin.to_string_lossy(), - ))?; - for arg in &self.get_arguments() { - fmt.write_str(" ")?; - fmt.write_str(&shell_escape::escape(Cow::from(arg)))?; - } - Ok(()) - } -} +use talpid_types::{net::openvpn::ShadowsocksProxySettings, ErrorExt}; pub struct ShadowsocksProxyMonitor { - subproc: Arc<ProcessHandle>, - closed: Arc<AtomicBool>, port: u16, -} - -const SHADOWSOCKS_LOG_FILENAME: &str = "shadowsocks.log"; -#[cfg(unix)] -const SHADOWSOCKS_BIN_FILENAME: &str = "sslocal"; -#[cfg(windows)] -const SHADOWSOCKS_BIN_FILENAME: &str = "sslocal.exe"; - -struct ProcessHandle { - subproc: duct::Handle, -} - -impl Drop for ProcessHandle { - fn drop(&mut self) { - let _ = self.subproc.kill(); - } -} - -impl std::ops::Deref for ProcessHandle { - type Target = duct::Handle; - - fn deref(&self) -> &Self::Target { - &self.subproc - } + server_join_handle: JoinHandle<Result<io::Result<()>, Aborted>>, + server_abort_handle: AbortHandle, } impl ShadowsocksProxyMonitor { - pub fn start( + pub async fn start( settings: &ShadowsocksProxySettings, - resource_data: &ProxyResourceData, - ) -> Result<Self> { - let binary = resource_data - .resource_dir - .join(SHADOWSOCKS_BIN_FILENAME) - .into_os_string(); + _resource_data: &ProxyResourceData, + ) -> io::Result<Self> { + // TODO: Patch shadowsocks so the bound address can be obtained afterwards. + let addr = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0); + let sock = Socket::new( + Domain::IPV4, + socket2::Type::STREAM, + Some(socket2::Protocol::TCP), + )?; + sock.set_reuse_address(true)?; + sock.bind(&SockAddr::from(addr))?; + + let bound_addr = sock + .local_addr()? + .as_socket_ipv4() + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "missing IPv4 address"))?; - let mut cmd = ShadowsocksCommand::new(binary) - .local(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0)) - .peer(settings.peer) - .peer_password(settings.password.clone()) - .cipher(settings.cipher.clone()) - .build(); + let mut config = Config::new(ConfigType::Local); - let log_dir: PathBuf = if let Some(ref log_dir) = resource_data.log_dir { - log_dir.clone() - } else { - env::temp_dir() - }; + config.fast_open = true; - let logfile = log_dir.join(SHADOWSOCKS_LOG_FILENAME); + let mut local = LocalConfig::new(ProtocolType::Socks); + local.mode = Mode::TcpOnly; + local.addr = Some(ServerAddr::SocketAddr(SocketAddr::from(bound_addr))); - logging::rotate_log(&logfile) - .map_err(|_| Error::new(ErrorKind::Other, "Failed to rotate log file"))?; + config.local.push(local); - cmd = cmd.stdin_null().stderr_to_stdout().stdout_path(&logfile); + let server = ServerConfig::new( + settings.peer, + settings.password.clone(), + settings.cipher.parse().map_err(|_| { + io::Error::new( + io::ErrorKind::Other, + format!("Invalid cipher: {}", settings.cipher), + ) + })?, + ); - let subproc = cmd.start()?; + config.server.push(server); #[cfg(target_os = "linux")] { - // Run this process outside the tunnel - use crate::split_tunnel::PidManager; - - let excluded_pids = PidManager::new().map_err(|error| { - Error::new( - ErrorKind::Other, - error.display_chain_with_msg("Failed to initialize PidManager"), - ) - })?; - for pid in subproc.pids() { - excluded_pids.add(pid as i32).map_err(|error| { - Error::new( - ErrorKind::Other, - error.display_chain_with_msg("Failed to exclude Shadowsocks process"), - ) - })?; - } + config.outbound_fwmark = Some(crate::linux::TUNNEL_FW_MARK); } - match Self::get_bound_port(File::open(&logfile)?, &subproc) { - Ok(port) => Ok(Self { - subproc: Arc::new(ProcessHandle { subproc }), - closed: Arc::new(AtomicBool::new(false)), - port, - }), - Err(err) => { - let _ = subproc.kill(); - Err(err) - } - } - } - - fn get_bound_port(logfile: File, subproc: &duct::Handle) -> Result<u16> { - let mut buffered_reader = std::io::BufReader::new(logfile); + let srv = local::create(config).await?; - for _tries in 0..5 { - loop { - // `read_line` appends to the buffer so keep a small scope for the `line` variable. - let mut line = String::new(); - match buffered_reader.read_line(&mut line) { - Ok(bytes_read) => { - if bytes_read == 0 { - break; - } - // `read_line` includes the line break in the returned line. - if let Ok(port) = Self::parse_port(line.trim_end()) { - return Ok(port); - } - } - Err(_) => { - break; - } - } + let (fut, server_abort_handle) = abortable(async move { + let _ = sock; + let result = srv.run().await; + if let Err(error) = &result { + log::error!( + "{}", + error.display_chain_with_msg("sslocal stopped with an error") + ); } - if subproc.try_wait().unwrap().is_some() { - break; - } - thread::sleep(Duration::from_secs(1)); - } - - Err(Error::new( - ErrorKind::Other, - "Could not determine which port Shadowsocks has bound to", - )) - } - - fn parse_port(logline: &str) -> Result<u16> { - // TODO: Compile once and reuse. - let re = Regex::new(r"(?:TCP listening on \d+\.\d+\.\d+\.\d+:)(\d+$)").unwrap(); - - if let Some(captures) = re.captures(logline) { - return Ok(captures[1].parse().map_err(|_| { - Error::new(ErrorKind::Other, "Failed to parse port number string") - })?); - } + result + }); + let server_join_handle = tokio::spawn(fut); - Err(Error::new(ErrorKind::Other, "No port number present")) + Ok(Self { + port: bound_addr.port(), + server_join_handle, + server_abort_handle, + }) } } +#[async_trait] impl ProxyMonitor for ShadowsocksProxyMonitor { fn close_handle(&mut self) -> Box<dyn ProxyMonitorCloseHandle> { Box::new(ShadowsocksProxyMonitorCloseHandle { - subproc: self.subproc.clone(), - closed: self.closed.clone(), + server_abort_handle: self.server_abort_handle.clone(), }) } - fn wait(self: Box<Self>) -> Result<WaitResult> { - self.subproc.wait().map(|output| { - if self.closed.load(Ordering::SeqCst) { - Ok(WaitResult::ProperShutdown) - } else { - Ok(WaitResult::UnexpectedExit( - if let Some(exit_code) = output.status.code() { - format!("Exit code: {}", exit_code) - } else { - "Exit code is indeterminable".to_string() - }, - )) - } - })? + async fn wait(mut self: Box<Self>) -> io::Result<WaitResult> { + match self.server_join_handle.await { + Ok(Err(Aborted)) => Ok(WaitResult::ProperShutdown), + + Err(join_err) if join_err.is_cancelled() => Ok(WaitResult::ProperShutdown), + Err(_) => Ok(WaitResult::UnexpectedExit( + "Shadowsocks task panicked".to_string(), + )), + + Ok(Ok(result)) => match result { + Ok(()) => Ok(WaitResult::UnexpectedExit( + "Exited without error".to_string(), + )), + Err(error) => Ok(WaitResult::UnexpectedExit(format!( + "Error: {}", + error.display_chain() + ))), + }, + } } fn port(&self) -> u16 { @@ -286,17 +129,13 @@ impl ProxyMonitor for ShadowsocksProxyMonitor { } } -pub struct ShadowsocksProxyMonitorCloseHandle { - subproc: Arc<ProcessHandle>, - closed: Arc<AtomicBool>, +struct ShadowsocksProxyMonitorCloseHandle { + server_abort_handle: AbortHandle, } impl ProxyMonitorCloseHandle for ShadowsocksProxyMonitorCloseHandle { - fn close(self: Box<Self>) -> Result<()> { - if !self.closed.swap(true, Ordering::SeqCst) { - self.subproc.kill() - } else { - Ok(()) - } + fn close(self: Box<Self>) -> io::Result<()> { + self.server_abort_handle.abort(); + Ok(()) } } diff --git a/talpid-core/src/tunnel/mod.rs b/talpid-core/src/tunnel/mod.rs index ca6665114f..5179f408d6 100644 --- a/talpid-core/src/tunnel/mod.rs +++ b/talpid-core/src/tunnel/mod.rs @@ -156,7 +156,9 @@ impl TunnelMonitor { TunnelParameters::OpenVpn(params) => { if let Some(proxy) = ¶ms.proxy { match proxy { - openvpn_types::ProxySettings::Shadowsocks(..) => "sslocal.exe", + openvpn_types::ProxySettings::Shadowsocks(..) => { + return std::env::current_exe().unwrap() + } _ => "openvpn.exe", } } else { diff --git a/talpid-core/src/tunnel/openvpn/mod.rs b/talpid-core/src/tunnel/openvpn/mod.rs index 5517191442..b2341c31e9 100644 --- a/talpid-core/src/tunnel/openvpn/mod.rs +++ b/talpid-core/src/tunnel/openvpn/mod.rs @@ -280,7 +280,13 @@ impl OpenVpnMonitor<OpenVpnCommand> { log_dir, }; - let proxy_monitor = Self::start_proxy(¶ms.proxy, &proxy_resources)?; + let runtime = tokio::runtime::Builder::new_multi_thread() + .worker_threads(1) + .enable_all() + .build() + .map_err(Error::RuntimeError)?; + + let proxy_monitor = runtime.block_on(Self::start_proxy(¶ms.proxy, &proxy_resources))?; #[cfg(windows)] let dll = wintun::WintunDll::instance(resource_dir).map_err(Error::WintunDllError)?; @@ -321,7 +327,8 @@ impl OpenVpnMonitor<OpenVpnCommand> { let (event_server_abort_tx, event_server_abort_rx) = triggered::trigger(); - Self::new_internal( + Self::new_internal_with_runtime( + runtime, cmd, event_server_abort_tx.clone(), event_server_abort_rx, @@ -363,7 +370,8 @@ fn extract_routes(env: &HashMap<String, String>) -> Result<HashSet<RequiredRoute } impl<C: OpenVpnBuilder + Send + 'static> OpenVpnMonitor<C> { - fn new_internal<L>( + fn new_internal_with_runtime<L>( + runtime: tokio::runtime::Runtime, mut cmd: C, event_server_abort_tx: triggered::Trigger, event_server_abort_rx: triggered::Listener, @@ -386,12 +394,6 @@ impl<C: OpenVpnBuilder + Send + 'static> OpenVpnMonitor<C> { format!("/tmp/talpid-openvpn-{}", uuid) }; - let runtime = tokio::runtime::Builder::new_multi_thread() - .worker_threads(1) - .enable_all() - .build() - .map_err(Error::RuntimeError)?; - let server_join_handle = runtime .block_on(event_server::start( ipc_path.clone(), @@ -486,13 +488,17 @@ impl<C: OpenVpnBuilder + Send + 'static> OpenVpnMonitor<C> { Proxy(proxy::Result<proxy::WaitResult>), } + let handle = self.runtime.handle().clone(); + thread::spawn(move || { tx_tunnel.send(Stopped::Tunnel(self.wait_tunnel())).unwrap(); let _ = proxy_close_handle.close(); }); thread::spawn(move || { - tx_proxy.send(Stopped::Proxy(proxy_monitor.wait())).unwrap(); + tx_proxy + .send(Stopped::Proxy(handle.block_on(proxy_monitor.wait()))) + .unwrap(); let _ = tunnel_close_handle.close(); }); @@ -627,13 +633,14 @@ impl<C: OpenVpnBuilder + Send + 'static> OpenVpnMonitor<C> { } /// Starts a proxy service, as applicable. - fn start_proxy( + async fn start_proxy( proxy_settings: &Option<openvpn::ProxySettings>, proxy_resources: &ProxyResourceData, ) -> Result<Option<Box<dyn ProxyMonitor>>> { if let Some(ref settings) = proxy_settings { - let proxy_monitor = - proxy::start_proxy(settings, proxy_resources).map_err(Error::StartProxyError)?; + let proxy_monitor = proxy::start_proxy(settings, proxy_resources) + .await + .map_err(Error::StartProxyError)?; return Ok(Some(proxy_monitor)); } Ok(None) @@ -1215,12 +1222,50 @@ mod tests { } } + fn new_monitor<L>( + cmd: TestOpenVpnBuilder, + event_server_abort_tx: triggered::Trigger, + event_server_abort_rx: triggered::Listener, + on_event: L, + plugin_path: PathBuf, + log_path: Option<PathBuf>, + user_pass_file: mktemp::TempFile, + proxy_auth_file: Option<mktemp::TempFile>, + proxy_monitor: Option<Box<dyn ProxyMonitor>>, + tunnel_close_rx: oneshot::Receiver<()>, + #[cfg(windows)] wintun: Box<dyn WintunContext>, + ) -> Result<OpenVpnMonitor<TestOpenVpnBuilder>> + where + L: event_server::OpenvpnEventProxy + Send + Sync + 'static, + { + let runtime = tokio::runtime::Builder::new_multi_thread() + .worker_threads(1) + .enable_all() + .build() + .map_err(Error::RuntimeError)?; + OpenVpnMonitor::new_internal_with_runtime( + runtime, + cmd, + event_server_abort_tx, + event_server_abort_rx, + on_event, + plugin_path, + log_path, + user_pass_file, + proxy_auth_file, + proxy_monitor, + tunnel_close_rx, + #[cfg(windows)] + wintun, + ) + } + #[test] fn sets_plugin() { let builder = TestOpenVpnBuilder::default(); let (event_server_abort_tx, event_server_abort_rx) = triggered::trigger(); let (_close_tx, close_rx) = oneshot::channel(); - let _ = OpenVpnMonitor::new_internal( + let _ = new_monitor( builder.clone(), event_server_abort_tx, event_server_abort_rx, @@ -1245,7 +1290,7 @@ mod tests { let builder = TestOpenVpnBuilder::default(); let (event_server_abort_tx, event_server_abort_rx) = triggered::trigger(); let (_close_tx, close_rx) = oneshot::channel(); - let _ = OpenVpnMonitor::new_internal( + let _ = new_monitor( builder.clone(), event_server_abort_tx, event_server_abort_rx, @@ -1271,7 +1316,7 @@ mod tests { builder.process_handle = Some(TestProcessHandle(0)); let (event_server_abort_tx, event_server_abort_rx) = triggered::trigger(); let (_close_tx, close_rx) = oneshot::channel(); - let testee = OpenVpnMonitor::new_internal( + let testee = new_monitor( builder, event_server_abort_tx, event_server_abort_rx, @@ -1295,7 +1340,7 @@ mod tests { builder.process_handle = Some(TestProcessHandle(1)); let (event_server_abort_tx, event_server_abort_rx) = triggered::trigger(); let (_close_tx, close_rx) = oneshot::channel(); - let testee = OpenVpnMonitor::new_internal( + let testee = new_monitor( builder, event_server_abort_tx, event_server_abort_rx, @@ -1319,7 +1364,7 @@ mod tests { builder.process_handle = Some(TestProcessHandle(1)); let (event_server_abort_tx, event_server_abort_rx) = triggered::trigger(); let (_close_tx, close_rx) = oneshot::channel(); - let testee = OpenVpnMonitor::new_internal( + let testee = new_monitor( builder, event_server_abort_tx, event_server_abort_rx, @@ -1343,7 +1388,7 @@ mod tests { let builder = TestOpenVpnBuilder::default(); let (event_server_abort_tx, event_server_abort_rx) = triggered::trigger(); let (_close_tx, close_rx) = oneshot::channel(); - let result = OpenVpnMonitor::new_internal( + let result = new_monitor( builder, event_server_abort_tx, event_server_abort_rx, |
