summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2022-03-29 09:32:45 +0200
committerDavid Lönnhager <david.l@mullvad.net>2022-04-05 10:33:57 +0200
commit7c6746e9cb9c24fa04a5d098f110ea24ace1153b (patch)
treeacb35272268d220a55b7bef41ee42b88f7d242a8
parent85dee12820549c8a8f82c6133c22f275640608bc (diff)
downloadmullvadvpn-7c6746e9cb9c24fa04a5d098f110ea24ace1153b.tar.xz
mullvadvpn-7c6746e9cb9c24fa04a5d098f110ea24ace1153b.zip
Use shadowsocks crate instead of subprocess
-rw-r--r--Cargo.lock589
-rw-r--r--talpid-core/Cargo.toml1
-rw-r--r--talpid-core/src/proxy/mod.rs8
-rw-r--r--talpid-core/src/proxy/noop.rs18
-rw-r--r--talpid-core/src/proxy/shadowsocks.rs347
-rw-r--r--talpid-core/src/tunnel/mod.rs4
-rw-r--r--talpid-core/src/tunnel/openvpn/mod.rs83
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) = &params.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(&params.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(&params.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,