diff --git a/Cargo.lock b/Cargo.lock index e6564e99..77c18b89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,33 +3,13 @@ name = "adler32" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "aes" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes-soft 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "aesni 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aes-soft" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "aesni" -version = "0.3.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -128,27 +108,10 @@ dependencies = [ [[package]] name = "block-cipher-trait" -version = "0.5.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-modes" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "block-padding 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-padding" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -161,11 +124,6 @@ name = "byte-tools" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "byte-tools" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "byte_string" version = "1.0.0" @@ -242,14 +200,6 @@ dependencies = [ "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "clear_on_drop" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cloudabi" version = "0.0.3" @@ -260,19 +210,14 @@ dependencies = [ [[package]] name = "cmac" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dbl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dbl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "constant_time_eq" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "crc" version = "1.8.1" @@ -311,11 +256,6 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-utils" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "crossbeam-utils" version = "0.6.3" @@ -326,11 +266,20 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ctr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -340,10 +289,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "dbl" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -487,6 +436,14 @@ dependencies = [ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "generic-array" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "h2" version = "0.1.14" @@ -740,6 +697,17 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio-named-pipes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mio-uds" version = "0.6.7" @@ -762,19 +730,30 @@ dependencies = [ ] [[package]] -name = "miscreant" -version = "0.4.0-beta2" +name = "miow" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "block-modes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miscreant" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cmac 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dbl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pmac 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cmac 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dbl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pmac 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -824,7 +803,7 @@ dependencies = [ [[package]] name = "opaque-debug" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -931,12 +910,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pmac" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dbl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dbl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1225,7 +1204,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "md-5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "miscreant 0.4.0-beta2 (registry+https://github.com/rust-lang/crates.io-index)", + "miscreant 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", "qrcode 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1234,10 +1213,10 @@ dependencies = [ "serde_derive 1.0.83 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-process 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-resolver 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1287,6 +1266,14 @@ name = "stable_deref_trait" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "stream-cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "string" version = "0.1.2" @@ -1298,18 +1285,13 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "subprocess" -version = "0.1.18" +name = "subtle" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "subtle" -version = "0.3.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1457,6 +1439,21 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-process" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-reactor" version = "0.1.7" @@ -1865,6 +1862,11 @@ dependencies = [ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "zeroize" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "zip" version = "0.2.8" @@ -1879,9 +1881,7 @@ dependencies = [ [metadata] "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum aes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0275405eedf13afd19de588add12a3b0d481a50b194eeb826e9dece11e741331" -"checksum aes-soft 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91f401742d8c1b0a3d01f53563f98d8ef0beea460b8d37322faf9fb4c7977cfa" -"checksum aesni 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ca074691b47c3dc585e05e45f6d069c75d0209069ca09b1c49ea37720e7b5f" +"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" "checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" @@ -1894,12 +1894,9 @@ dependencies = [ "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" -"checksum block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "370424437b9459f3dfd68428ed9376ddfe03d8b70ede29cc533b3557df186ab4" -"checksum block-modes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "862511b40f91a3305dc119fdfdc25b561779f78828495e41b71d360b8c9f56df" -"checksum block-padding 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc4358306e344bf9775d0197fd00d2603e5afb0771bb353538630f022068ea3" +"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" -"checksum byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "980479e6fde23246dfb54d47580d66b4e99202e7579c5eaa9fe10ecb5ebd2182" "checksum byte_string 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11aade7a05aa8c3a351cedc44c3fc45806430543382fcc4743a9b757a2a0b4ed" "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" "checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" @@ -1910,19 +1907,17 @@ dependencies = [ "checksum checked_int_cast 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919" "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" -"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cmac 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44f175b5f76aa82ebe4c7e85ef95b23e9293c5618db28461cb10ee929e0f6e2f" -"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +"checksum cmac 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f4a435124bcc292eba031f1f725d7abacdaf13cbf9f935450e8c45aa9e96cad" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192" "checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" "checksum crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f10a4f8f409aaac4b16a5474fb233624238fcdeefb9ba50d5ea059aab63ba31c" -"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" "checksum crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "41ee4864f4797060e52044376f7d107429ce1fb43460021b126424b7180ee21a" -"checksum crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7afa06d05a046c7a47c3a849907ec303504608c927f4e85f7bfff22b7180d971" +"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +"checksum ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "044f882973b245404e90c90e7e42e8ee8d7a64edfd7adf83d684fb97e8e2c1b6" "checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" -"checksum dbl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "920e117b69060a961c4164ccf83af573292cb167ccdd918950bcf0f5afc32c1c" +"checksum dbl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6c40b13b561e11560d7b12785e74113a3163df617e2fbce60ce1764e0b270eaa" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum dns-parser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7020f6760aea312d43d23cb83bf6c0c49f162541db8b02bf95209ac51dc253d" "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" @@ -1940,6 +1935,7 @@ dependencies = [ "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" +"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum h2 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1ac030ae20dee464c5d0f36544d8b914a6bc606da44a57e052d2b0f5dae129e0" "checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e" @@ -1970,16 +1966,18 @@ dependencies = [ "checksum miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c" "checksum miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e" "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" +"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum miscreant 0.4.0-beta2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed87c1c62b5b8fd24c5148aa5ec073467b6eeddc68470675fac711d8156a5b53" +"checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" +"checksum miscreant 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e37d77fff73f19e198036d3ca2bdbf8d4bca650daeda979bae0fdd31fce11d9" "checksum msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238" -"checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7" +"checksum opaque-debug 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "51ecbcb821e1bd256d456fe858aaa7f380b63863eab2eb86eee1bd9f33dd6682" "checksum openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9" "checksum openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)" = "1bb974e77de925ef426b6bc82fce15fd45bdcbeb5728bffcfc7cdeeb7ce1c2d6" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" @@ -1991,7 +1989,7 @@ dependencies = [ "checksum pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63120576c4efd69615b5537d3d052257328a4ca82876771d6944424ccfd9f646" "checksum pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum pmac 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a82cc12454dc99354a9342c237149aec041ef16f618066d0a682df256b97714" +"checksum pmac 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd76d63e86aa67a4bd063079f0d93bb8730b036eea5697345f651e6874ea61e5" "checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" "checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" "checksum qrcode 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5c30325393c280d05db5d2f996ac8f468789b6171de1165fab6de2a05fcb55c" @@ -2030,10 +2028,11 @@ dependencies = [ "checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7" "checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" +"checksum stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8861bc80f649f5b4c9bd38b696ae9af74499d479dbfb327f0607de6b326a36bc" "checksum string 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98998cced76115b1da46f63388b909d118a37ae0be0f82ad35773d4a4bc9d18d" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "28fc0f40f0c0da73339d347aa7d6d2b90341a95683a47722bc4eebed71ff3c00" -"checksum subtle 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7a6bab57c3efd01ebd3d750f4244ae0af4cdd1fc505a7904a41603192b803c5" +"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" +"checksum subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "702662512f3ddeb74a64ce2fbbf3707ee1b6bb663d28bb054e0779bbc720d926" "checksum syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9545a6a093a3f0bd59adb472700acc08cad3776f860f16a897dfce8c88721cbc" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "a303ba60a099fcd2aaa646b14d2724591a96a75283e4b7ed3d1a1658909d9ae2" @@ -2048,6 +2047,7 @@ dependencies = [ "checksum tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c117b6cf86bb730aab4834f10df96e4dd586eff2c3c27d3781348da49e255bde" "checksum tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "60ae25f6b17d25116d2cba342083abe5255d3c2c79cb21ea11aa049c53bf7c75" "checksum tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7392fe0a70d5ce0c882c4778116c519bd5dbaa8a7c3ae3d04578b3afafdcda21" +"checksum tokio-process 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88e1281e412013f1ff5787def044a9577a0bed059f451e835f1643201f8b777d" "checksum tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "502b625acb4ee13cbb3b90b8ca80e0addd263ddacf6931666ef751e610b07fb5" "checksum tokio-rustls 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1c98c5346e4231382951111f42f4651094854462297370a08f0fba57a3b92576" "checksum tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd6dc5276ea05ce379a16de90083ec80836440d5ef8a6a39545a3207373b8296" @@ -2092,4 +2092,5 @@ dependencies = [ "checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +"checksum zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8ddfeb6eee2fb3b262ef6e0898a52b7563bb8e0d5955a313b3cf2f808246ea14" "checksum zip 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "e7341988e4535c60882d5e5f0b7ad0a9a56b080ade8bdb5527cb512f7b2180e0" diff --git a/Cargo.toml b/Cargo.toml index e032eb04..8a1523fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,7 +56,6 @@ md-5 = "0.7" digest = "0.7" typenum = "1.10" qrcode = { version = "0.7", default-features = false } -subprocess = "0.1" serde_urlencoded = "0.5" serde_derive = "1.0" serde = "1.0" @@ -68,6 +67,7 @@ lru-cache = "0.1" dns-parser = "0.7" trust-dns-resolver = { version = "0.10", features = ["dns-over-rustls", "dns-over-https-rustls"] } spin = { version = "0.4", default-features = false } +tokio-process = "0.2.3" [target.'cfg(unix)'.dependencies] tokio-signal = "0.2" diff --git a/src/bin/local.rs b/src/bin/local.rs index 291b59d4..468c2279 100644 --- a/src/bin/local.rs +++ b/src/bin/local.rs @@ -17,16 +17,19 @@ use std::{ env, io::{self, Write}, net::SocketAddr, + process, }; use clap::{App, Arg}; use env_logger::{fmt::Formatter, Builder}; -use futures::Future; +use futures::{future::Either, Future}; use log::{LevelFilter, Record}; use tokio::runtime::Runtime; use shadowsocks::{plugin::PluginConfig, run_local, Config, ConfigType, Mode, ServerAddr, ServerConfig}; +mod monitor; + fn log_time(fmt: &mut Formatter, without_time: bool, record: &Record) -> io::Result<()> { if without_time { writeln!(fmt, "[{}] {}", record.level(), record.args()) @@ -286,11 +289,20 @@ fn main() { let mut runtime = Runtime::new().expect("Creating runtime"); - let result = runtime.block_on(run_local(config)); + let abort_signal = monitor::create_signal_monitor(); + let result = runtime.block_on(run_local(config).select2(abort_signal)); runtime.shutdown_now().wait().unwrap(); - if let Err(err) = result { - panic!("Server exited unexpectly with error: {:?}", err); + match result { + // Server future resolved without an error. This should never happen. + Ok(Either::A(_)) => panic!("Server exited unexpectly"), + // Server future resolved with an error. + Err(Either::A((err, _))) => { + error!("Server exited unexpectly with error: {}", err); + process::exit(1); + } + // The abort signal future resolved. Means we should just exit. + Ok(Either::B(..)) | Err(Either::B(..)) => (), } } diff --git a/src/bin/monitor/mod.rs b/src/bin/monitor/mod.rs new file mode 100644 index 00000000..4337182d --- /dev/null +++ b/src/bin/monitor/mod.rs @@ -0,0 +1,13 @@ +#[cfg(unix)] +#[path = "unix.rs"] +mod imp; + +#[cfg(windows)] +#[path = "windows.rs"] +mod imp; + +#[cfg(not(any(windows, unix)))] +#[path = "other.rs"] +mod imp; + +pub use self::imp::create_signal_monitor; diff --git a/src/bin/monitor/other.rs b/src/bin/monitor/other.rs new file mode 100644 index 00000000..158065df --- /dev/null +++ b/src/bin/monitor/other.rs @@ -0,0 +1,8 @@ +use futures::{self, Future}; +use std::io; + +pub fn create_signal_monitor() -> impl Future + Send { + // FIXME: What can I do ... + // Blocks forever + futures::empty::<(), io::Error>() +} diff --git a/src/bin/monitor/unix.rs b/src/bin/monitor/unix.rs new file mode 100644 index 00000000..c2cf9fb7 --- /dev/null +++ b/src/bin/monitor/unix.rs @@ -0,0 +1,33 @@ +use futures::{Future, Stream}; +use libc; +use std::io; +use tokio_signal::unix::Signal; + +pub fn create_signal_monitor() -> impl Future + Send { + // Future resolving to two signal streams. Can fail if setting up signal monitoring fails + let signals_future = Signal::new(libc::SIGTERM).join(Signal::new(libc::SIGINT)); + + signals_future + // The future resolved into our two streams of signals + .and_then(|(sigterms, sigints)| { + // Stream of all signals we care about + let signals = sigterms.select(sigints); + // Take only the first signal in the stream and log that it was triggered + signals.take(1).for_each(|signal| { + let signal_name = match signal { + libc::SIGTERM => "SIGTERM", + libc::SIGINT => "SIGINT", + _ => unreachable!(), + }; + info!("Received {}, exiting", signal_name); + Ok(()) + }).map_err(|error| { + error!("Error while listening on process signals: {:?}", error); + error + }) + }) + .map_err(|error| { + error!("Failed to set up process signal monitoring: {:?}", error); + error + }) +} diff --git a/src/bin/monitor/windows.rs b/src/bin/monitor/windows.rs new file mode 100644 index 00000000..bfdea37c --- /dev/null +++ b/src/bin/monitor/windows.rs @@ -0,0 +1,34 @@ +use futures::{self, Future, Stream}; +use std::io; +use tokio_signal::windows::Event; + +pub fn create_signal_monitor() -> impl Future + Send { + // Must be wrapped with a future, because when `Event` is being created, it will spawn + // a task into the current executor. So if there is no current running executor, thread + // will panic. + let events = futures::lazy(|| { + Event::ctrl_c() + .join(Event::ctrl_break()) + .and_then(|(c_signals, break_signals)| { + // Stream of all signals we care about + let signals = c_signals.select(break_signals); + // Take only the first signal in the stream and log that it was triggered + signals + .take(1) + .for_each(|()| { + info!("Received shutdown signal, exiting"); + Ok(()) + }) + .map_err(|error| { + error!("Error while listening on process signals: {:?}", error); + error + }) + }) + .map_err(|error| { + error!("Failed to set up process signal monitoring: {:?}", error); + error + }) + }); + + events +} diff --git a/src/bin/server.rs b/src/bin/server.rs index 80193cc3..334af5ee 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -19,16 +19,19 @@ extern crate tokio; use std::{ env, io::{self, Write}, + process, }; use clap::{App, Arg}; use env_logger::{fmt::Formatter, Builder}; -use futures::Future; +use futures::{future::Either, Future}; use log::{LevelFilter, Record}; use tokio::runtime::Runtime; use shadowsocks::{plugin::PluginConfig, run_server, Config, ConfigType, Mode, ServerAddr, ServerConfig}; +mod monitor; + fn log_time(fmt: &mut Formatter, without_time: bool, record: &Record) -> io::Result<()> { if without_time { writeln!(fmt, "[{}] {}", record.level(), record.args()) @@ -269,11 +272,20 @@ fn main() { let mut runtime = Runtime::new().expect("Creating runtime"); - let result = runtime.block_on(run_server(config)); + let abort_signal = monitor::create_signal_monitor(); + let result = runtime.block_on(run_server(config).select2(abort_signal)); runtime.shutdown_now().wait().unwrap(); - if let Err(err) = result { - panic!("Server exited unexpectly with error: {:?}", err); + match result { + // Server future resolved without an error. This should never happen. + Ok(Either::A(_)) => panic!("Server exited unexpectly"), + // Server future resolved with an error. + Err(Either::A((err, _))) => { + error!("Server exited unexpectly with error: {}", err); + process::exit(1); + } + // The abort signal future resolved. Means we should just exit. + Ok(Either::B(..)) | Err(Either::B(..)) => (), } } diff --git a/src/context.rs b/src/context.rs index 75128f35..3e4fdded 100644 --- a/src/context.rs +++ b/src/context.rs @@ -9,7 +9,7 @@ use std::{ use lru_cache::LruCache; use trust_dns_resolver::AsyncResolver; -use crate::{config::Config, plugin::Plugin, relay::dns_resolver::create_resolver}; +use crate::{config::Config, relay::dns_resolver::create_resolver}; type DnsQueryCache = LruCache; @@ -18,7 +18,6 @@ pub struct Context { config: Config, dns_resolver: Arc, dns_query_cache: Option>>, - plugins: Arc>, } pub type SharedContext = Arc; @@ -30,7 +29,6 @@ impl Context { config, dns_resolver: Arc::new(resolver), dns_query_cache: None, - plugins: Arc::new(Vec::new()), } } @@ -40,7 +38,6 @@ impl Context { config, dns_resolver: Arc::new(resolver), dns_query_cache: Some(Arc::new(Mutex::new(LruCache::new(1024)))), - plugins: Arc::new(Vec::new()), } } @@ -59,8 +56,4 @@ impl Context { pub fn dns_query_cache(&self) -> MutexGuard { self.dns_query_cache.as_ref().unwrap().lock().unwrap() } - - pub fn set_plugins(&mut self, plugins: Vec) { - self.plugins = Arc::new(plugins); - } } diff --git a/src/lib.rs b/src/lib.rs index db44409e..aaf15bf1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -93,7 +93,6 @@ extern crate serde_urlencoded; #[macro_use] extern crate serde_derive; extern crate serde; -extern crate subprocess; #[macro_use] extern crate tokio_io; extern crate dns_parser; @@ -111,17 +110,11 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub use self::{ config::{ClientConfig, Config, ConfigType, Mode, ServerAddr, ServerConfig}, - relay::{ - dns::run as run_dns, - local::{run as run_local, run_opt as run_local_opt, Options as LocalOptions}, - server::{run as run_server, run_opt as run_server_opt, Options as ServerOptions}, - tcprelay::client::Socks5Client, - }, + relay::{dns::run as run_dns, local::run as run_local, server::run as run_server, tcprelay::client::Socks5Client}, }; pub mod config; mod context; pub mod crypto; -mod monitor; pub mod plugin; pub mod relay; diff --git a/src/monitor.rs b/src/monitor.rs deleted file mode 100644 index f42e18f1..00000000 --- a/src/monitor.rs +++ /dev/null @@ -1,123 +0,0 @@ -#![allow(unused_imports)] - -use std::{io, process}; - -use libc; -use tokio; -use tokio_io::IoFuture; - -use futures::{self, stream::futures_unordered, Future, Stream}; - -use crate::{plugin::Plugin, relay::boxed_future}; - -#[cfg(unix)] -pub fn monitor_signal() -> impl Future + Send { - use tokio_signal::unix::Signal; - - // Monitor SIGCHLD, triggered if subprocess (plugin) is exited. - let fut1 = Signal::new(libc::SIGCHLD) - .and_then(|signal| { - signal - .take(1) - .for_each(|_| -> Result<(), io::Error> { - error!("Plugin exited unexpectly (SIGCHLD)"); - Ok(()) - }) - .map(|_| libc::SIGCHLD) - }) - .map_err(|err| { - error!("Failed to monitor SIGCHLD, err: {:?}", err); - err - }); - - // Monitor SIGTERM, triggered if shadowsocks is exited gracefully. (Kill by user). - let fut2 = Signal::new(libc::SIGTERM) - .and_then(|sigterm| { - sigterm - .take(1) - .for_each(|_| -> Result<(), io::Error> { - info!("Received SIGTERM, exiting."); - Ok(()) - }) - .map(|_| libc::SIGTERM) - }) - .map_err(|err| { - error!("Failed to monitor SIGTERM, err: {:?}", err); - err - }); - - // Monitor SIGINT, triggered by CTRL-C - let fut3 = Signal::new(libc::SIGINT) - .and_then(|sigint| { - sigint - .take(1) - .for_each(|_| -> Result<(), io::Error> { - info!("Received SIGINT, exiting."); - Ok(()) - }) - .map(|_| libc::SIGINT) - }) - .map_err(|err| { - error!("Failed to monitor SIGINT, err: {:?}", err); - err - }); - - // Join them all, if any of them is triggered, kill all subprocesses and exit. - futures_unordered(vec![boxed_future(fut1), boxed_future(fut2), boxed_future(fut3)]) - .into_future() - .then(move |r| match r { - Ok(..) => Ok(()), - Err((err, ..)) => Err(err), - }) -} - -#[cfg(windows)] -pub fn monitor_signal() -> impl Future + Send { - // FIXME: How to handle SIGTERM equavalent in Windows? - - use tokio_signal::windows::Event; - - // Must be wrapped with a future, because when `Event` is being created, it will spawn - // a task into the current executor. So if there is no current running executor, thread - // will panic. - futures::lazy(|| { - let fut1 = Event::ctrl_c() - .and_then(|ev| { - ev.take(1).for_each(|_| -> Result<(), io::Error> { - error!("Received Ctrl-C event"); - Ok(()) - }) - }) - .map_err(|err| { - error!("Failed to monitor Ctrl-C event: {:?}", err); - err - }); - - let fut2 = Event::ctrl_break() - .and_then(|ev| { - ev.take(1).for_each(|_| -> Result<(), io::Error> { - error!("Received Ctrl-Break event"); - Ok(()) - }) - }) - .map_err(|err| { - error!("Failed to monitor Ctrl-Break event: {:?}", err); - err - }); - - // Join them all, if any of them is triggered, kill all subprocesses and exit. - futures_unordered(vec![boxed_future(fut1), boxed_future(fut2)]) - .into_future() - .then(|r| match r { - Ok(..) => Ok(()), - Err((err, ..)) => Err(err), - }) - }) -} - -#[cfg(not(any(windows, unix)))] -pub fn monitor_signal() -> impl Future + Send { - // FIXME: What can I do ... - // Blocks forever - futures::empty::<(), ()>() -} diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index 7ec26d27..35dcbc1d 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -12,14 +12,13 @@ //! +------------+ +---------------------------+ //! ``` +use crate::config::{Config, ServerAddr}; +use futures::{stream::futures_unordered, Future, Stream}; use std::{ io, net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener}, }; - -use subprocess::{Popen, Result as PopenResult}; - -use crate::config::{Config, ServerAddr}; +use tokio_process::{Child, CommandExt}; mod obfs_proxy; mod ss_plugin; @@ -38,21 +37,13 @@ pub enum PluginMode { Client, } -/// Plugin holder -#[derive(Debug)] -pub struct Plugin { - process: Popen, -} - -impl Drop for Plugin { - fn drop(&mut self) { - debug!("Killing Plugin {:?}", self.process); - let _ = self.process.terminate(); - } -} - -/// Launch plugins in config -pub fn launch_plugin(config: &mut Config, mode: PluginMode) -> io::Result> { +/// Launch plugins in config. Returns a future that completes when any plugin terminates +/// or there were an error in watching the subprocess. Returns `None` if no plugins +/// were launched. +pub fn launch_plugins( + config: &mut Config, + mode: PluginMode, +) -> io::Result>> { let mut plugins = Vec::new(); for svr in &mut config.server { @@ -64,11 +55,12 @@ pub fn launch_plugin(config: &mut Config, mode: PluginMode) -> io::Result { - panic!("Failed to start plugin \"{}\", err: {}", c.plugin, err); + error!("Failed to start plugin \"{}\", err: {}", c.plugin, err); + return Err(err); } Ok(process) => { let svr_addr = ServerAddr::SocketAddr(local_addr); - plugins.push(Plugin { process }); + plugins.push(process); // Replace addr with plugin svr_addr @@ -88,20 +80,38 @@ pub fn launch_plugin(config: &mut Config, mode: PluginMode) -> io::Result { + let msg = format!("Plugin exited unexpectedly with {}", first_plugin_exit_status.unwrap()); + Err(io::Error::new(io::ErrorKind::Other, msg)) + } + Err((first_plugin_error, _)) => { + error!("Error while waiting for plugin subprocess: {}", first_plugin_error); + Err(first_plugin_error) + } + }); + Ok(Some(plugins_future)) + } } -fn start_plugin( - plugin: &PluginConfig, - remote: &ServerAddr, - local: &SocketAddr, - mode: PluginMode, -) -> PopenResult { - if plugin.plugin == "obfsproxy" { - obfs_proxy::start_plugin(plugin, remote, local, mode) +fn start_plugin(plugin: &PluginConfig, remote: &ServerAddr, local: &SocketAddr, mode: PluginMode) -> io::Result { + let mut cmd = if plugin.plugin == "obfsproxy" { + obfs_proxy::plugin_cmd(plugin, remote, local, mode) } else { - ss_plugin::start_plugin(plugin, remote, local, mode) - } + ss_plugin::plugin_cmd(plugin, remote, local, mode) + }; + cmd.spawn_async() } fn get_local_port() -> io::Result { diff --git a/src/plugin/obfs_proxy.rs b/src/plugin/obfs_proxy.rs index 477e0a6c..bf984b80 100644 --- a/src/plugin/obfs_proxy.rs +++ b/src/plugin/obfs_proxy.rs @@ -1,10 +1,9 @@ -use std::net::SocketAddr; - -use subprocess::{Exec, Popen, Result as PopenResult}; - -use crate::config::ServerAddr; - use super::{PluginConfig, PluginMode}; +use crate::config::ServerAddr; +use std::{ + net::SocketAddr, + process::{Command, Stdio}, +}; /// For obfsproxy, we use standalone mode for now. /// Managed mode needs to use SOCKS5 proxy as forwarder, which is not supported @@ -30,23 +29,17 @@ use super::{PluginConfig, PluginMode}; /// And the rest parameters are all assembled here. /// Some old obfsproxy will not be supported as it doesn't even support /// "--data-dir" option -pub fn start_plugin( - plugin: &PluginConfig, - remote: &ServerAddr, - local: &SocketAddr, - mode: PluginMode, -) -> PopenResult { - let mut cmd = Exec::cmd(&plugin.plugin) +pub fn plugin_cmd(plugin: &PluginConfig, remote: &ServerAddr, local: &SocketAddr, mode: PluginMode) -> Command { + let mut cmd = Command::new(&plugin.plugin); + cmd.stdin(Stdio::null()) .arg("--data-dir") .arg(format!("/tmp/{}_{}_{}", plugin.plugin, remote, local)); // FIXME: Not compatible in Windows if let Some(ref opt) = plugin.plugin_opt { - for arg in opt.split(' ') { - cmd = cmd.arg(arg); - } + cmd.args(opt.split(' ')); } - let cmd = match mode { + match mode { PluginMode::Client => cmd .arg("--dest") .arg(remote.to_string()) @@ -59,5 +52,5 @@ pub fn start_plugin( .arg(remote.to_string()), }; - cmd.popen() + cmd } diff --git a/src/plugin/ss_plugin.rs b/src/plugin/ss_plugin.rs index 69244d35..4cc4af52 100644 --- a/src/plugin/ss_plugin.rs +++ b/src/plugin/ss_plugin.rs @@ -1,29 +1,23 @@ -use std::net::SocketAddr; - -use subprocess::{Exec, NullFile, Popen, Result as PopenResult}; - -use crate::config::ServerAddr; - use super::{PluginConfig, PluginMode}; +use crate::config::ServerAddr; +use std::{ + net::SocketAddr, + process::{Command, Stdio}, +}; -pub fn start_plugin( - plugin: &PluginConfig, - remote: &ServerAddr, - local: &SocketAddr, - _mode: PluginMode, -) -> PopenResult { +pub fn plugin_cmd(plugin: &PluginConfig, remote: &ServerAddr, local: &SocketAddr, _mode: PluginMode) -> Command { trace!("Start plugin \"{:?}\" remote: {}, local: {}", plugin, remote, local); - let mut exec = Exec::cmd(&plugin.plugin) - .env("SS_REMOTE_HOST", remote.host()) + let mut cmd = Command::new(&plugin.plugin); + cmd.env("SS_REMOTE_HOST", remote.host()) .env("SS_REMOTE_PORT", remote.port().to_string()) .env("SS_LOCAL_HOST", local.ip().to_string()) .env("SS_LOCAL_PORT", local.port().to_string()) - .stdin(NullFile); + .stdin(Stdio::null()); if let Some(ref opt) = plugin.plugin_opt { - exec = exec.env("SS_PLUGIN_OPTIONS", opt); + cmd.env("SS_PLUGIN_OPTIONS", opt); } - exec.popen() + cmd } diff --git a/src/relay/local.rs b/src/relay/local.rs index 092aa1ca..d3e9def5 100644 --- a/src/relay/local.rs +++ b/src/relay/local.rs @@ -7,56 +7,10 @@ use futures::{stream::futures_unordered, Future, Stream}; use crate::{ config::Config, context::{Context, SharedContext}, - plugin::{launch_plugin, PluginMode}, + plugin::{launch_plugins, PluginMode}, relay::{boxed_future, tcprelay::local::run as run_tcp, udprelay::local::run as run_udp}, }; -/// Options for Local server -#[derive(Clone, Debug, Default)] -pub struct Options { - /// Enable builtin signal monitor - pub enable_signal_monitor: bool, -} - -/// Relay server running under local environment. -pub fn run_opt(config: Config, opt: Options) -> impl Future + Send { - futures::lazy(move || { - let mut vf = Vec::new(); - - let mut context = Context::new(config); - - if opt.enable_signal_monitor { - let mon = crate::monitor::monitor_signal(); - vf.push(boxed_future(mon)); - } - - if context.config().mode.enable_udp() { - // Clone config here, because the config for TCP relay will be modified - // after plugins started - let udp_context = SharedContext::new(context.clone()); - - // Run UDP relay before starting plugins - // Because plugins doesn't support UDP relay - let udp_fut = run_udp(udp_context); - vf.push(boxed_future(udp_fut)); - } - - // Hold it here, kill all plugins when `tokio::run` is finished - let plugins = launch_plugin(context.config_mut(), PluginMode::Client).expect("Failed to launch plugins"); - context.set_plugins(plugins); - - let tcp_fut = run_tcp(SharedContext::new(context)); - - vf.push(boxed_future(tcp_fut)); - futures_unordered(vf).into_future().then(|res| -> io::Result<()> { - match res { - Ok(..) => Ok(()), - Err((err, ..)) => Err(err), - } - }) - }) -} - /// Relay server running under local environment. /// /// ```no_run @@ -82,10 +36,36 @@ pub fn run_opt(config: Config, opt: Options) -> impl Future impl Future + Send { - run_opt( - config, - Options { - enable_signal_monitor: true, - }, - ) + futures::lazy(move || { + let mut context = Context::new(config); + + let mut vf = Vec::new(); + + if context.config().mode.enable_udp() { + // Clone config here, because the config for TCP relay will be modified + // after plugins started + let udp_context = SharedContext::new(context.clone()); + + // Run UDP relay before starting plugins + // Because plugins doesn't support UDP relay + let udp_fut = run_udp(udp_context); + vf.push(boxed_future(udp_fut)); + } + + if let Some(plugins) = + launch_plugins(context.config_mut(), PluginMode::Client).expect("Failed to launch plugins") + { + vf.push(boxed_future(plugins)); + } + + let tcp_fut = run_tcp(SharedContext::new(context)); + + vf.push(boxed_future(tcp_fut)); + futures_unordered(vf).into_future().then(|res| -> io::Result<()> { + match res { + Ok(..) => Ok(()), + Err((err, ..)) => Err(err), + } + }) + }) } diff --git a/src/relay/server.rs b/src/relay/server.rs index ceaee1c3..f0150b18 100644 --- a/src/relay/server.rs +++ b/src/relay/server.rs @@ -7,58 +7,10 @@ use futures::{stream::futures_unordered, Future, Stream}; use crate::{ config::Config, context::{Context, SharedContext}, - plugin::{launch_plugin, PluginMode}, + plugin::{launch_plugins, PluginMode}, relay::{boxed_future, tcprelay::server::run as run_tcp, udprelay::server::run as run_udp}, }; -/// Options for Local server -#[derive(Clone, Debug, Default)] -pub struct Options { - /// Enable builtin signal monitor - pub enable_signal_monitor: bool, -} - -/// Relay server running on server side. -pub fn run_opt(config: Config, opt: Options) -> impl Future + Send { - futures::lazy(move || { - let mut context = Context::new(config); - - let mut vf = Vec::new(); - - if opt.enable_signal_monitor { - let mon = crate::monitor::monitor_signal(); - vf.push(boxed_future(mon)); - } - - if context.config().mode.enable_udp() { - // Clone config here, because the config for TCP relay will be modified - // after plugins started - let udp_context = SharedContext::new(context.clone()); - - // Run UDP relay before starting plugins - // Because plugins doesn't support UDP relay - let udp_fut = run_udp(udp_context); - vf.push(boxed_future(udp_fut)); - } - - if context.config().mode.enable_tcp() { - // Hold it here, kill all plugins when `tokio::run` is finished - let plugins = launch_plugin(context.config_mut(), PluginMode::Server).expect("Failed to launch plugins"); - context.set_plugins(plugins); - - let tcp_fut = run_tcp(SharedContext::new(context)); - vf.push(boxed_future(tcp_fut)); - } - - futures_unordered(vf).into_future().then(|res| -> io::Result<()> { - match res { - Ok(..) => Ok(()), - Err((err, ..)) => Err(err), - } - }) - }) -} - /// Relay server running on server side. /// /// ```no_run @@ -84,10 +36,38 @@ pub fn run_opt(config: Config, opt: Options) -> impl Future impl Future + Send { - run_opt( - config, - Options { - enable_signal_monitor: true, - }, - ) + futures::lazy(move || { + let mut context = Context::new(config); + + let mut vf = Vec::new(); + + if context.config().mode.enable_udp() { + // Clone config here, because the config for TCP relay will be modified + // after plugins started + let udp_context = SharedContext::new(context.clone()); + + // Run UDP relay before starting plugins + // Because plugins doesn't support UDP relay + let udp_fut = run_udp(udp_context); + vf.push(boxed_future(udp_fut)); + } + + if context.config().mode.enable_tcp() { + if let Some(plugins) = + launch_plugins(context.config_mut(), PluginMode::Server).expect("Failed to launch plugins") + { + vf.push(boxed_future(plugins)); + } + + let tcp_fut = run_tcp(SharedContext::new(context)); + vf.push(boxed_future(tcp_fut)); + } + + futures_unordered(vf).into_future().then(|res| -> io::Result<()> { + match res { + Ok(..) => Ok(()), + Err((err, ..)) => Err(err), + } + }) + }) }