diff --git a/Cargo.lock b/Cargo.lock index c06c25ef..7794ddc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,12 +51,56 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "backtrace" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base64" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "base64" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -99,7 +143,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -107,7 +151,7 @@ name = "bytes" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -155,7 +199,7 @@ dependencies = [ "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -264,6 +308,15 @@ dependencies = [ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dbghelp-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dbl" version = "0.1.0" @@ -285,7 +338,7 @@ name = "dns-parser" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -294,11 +347,6 @@ name = "dtoa" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "either" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "env_logger" version = "0.5.10" @@ -311,6 +359,22 @@ dependencies = [ "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "error-chain" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "error-chain" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "filetime" version = "0.2.1" @@ -372,13 +436,9 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "futures-cpupool" -version = "0.1.8" +name = "gcc" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "generic-array" @@ -388,6 +448,15 @@ dependencies = [ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hostname" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "humantime" version = "1.1.1" @@ -415,6 +484,18 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ipconfig" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "widestring 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winreg 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.3.4" @@ -434,6 +515,11 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lazy_static" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazy_static" version = "1.0.0" @@ -468,6 +554,14 @@ name = "linked-hash-map" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "log" version = "0.4.1" @@ -587,7 +681,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aesni 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "block-cipher-trait 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (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.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -602,7 +696,7 @@ name = "msdos_time" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -707,10 +801,9 @@ dependencies = [ [[package]] name = "rayon" -version = "0.9.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -760,15 +853,42 @@ dependencies = [ ] [[package]] -name = "ring" -version = "0.13.0-alpha" +name = "resolv-conf" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hostname 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ring" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustls" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sct 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -781,9 +901,18 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "sct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde" -version = "1.0.52" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -793,7 +922,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -803,7 +932,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -813,14 +942,13 @@ version = "1.7.0-alpha.3" dependencies = [ "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "byte_string 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "dns-parser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "libsodium-ffi 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -831,14 +959,15 @@ dependencies = [ "openssl 0.10.7 (registry+https://github.com/rust-lang/crates.io-index)", "qrcode 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.0-alpha (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "subprocess 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-signal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trust-dns-resolver 0.8.1", "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -848,6 +977,21 @@ name = "slab" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "smallvec" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "socket2" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "strsim" version = "0.7.0" @@ -917,7 +1061,7 @@ dependencies = [ [[package]] name = "time" -version = "0.1.39" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -983,6 +1127,16 @@ dependencies = [ "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-rustls" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-signal" version = "0.2.0" @@ -1046,6 +1200,59 @@ dependencies = [ "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "trust-dns-proto" +version = "0.3.2" +dependencies = [ + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.8.1" +dependencies = [ + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "ipconfig 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "resolv-conf 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "trust-dns-proto 0.3.2", + "trust-dns-rustls 0.2.0", + "webpki-roots 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "trust-dns-rustls" +version = "0.2.0" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trust-dns-proto 0.3.2", +] + [[package]] name = "typenum" version = "1.10.0" @@ -1084,7 +1291,7 @@ dependencies = [ [[package]] name = "untrusted" -version = "0.6.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1114,7 +1321,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "vec_map" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1122,6 +1329,29 @@ name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "webpki" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "webpki-roots" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "widestring" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.2.8" @@ -1159,6 +1389,22 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "winreg" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winutil" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -1185,7 +1431,7 @@ dependencies = [ "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] @@ -1196,6 +1442,10 @@ dependencies = [ "checksum arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd1479b7c29641adbd35ff3b5c293922d696a92f25c8c975da3e0acbc87258f" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" +"checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f" +"checksum backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea58cd16fd6c9d120b5bcb01d63883ae4cc7ba2aed35c1841b862a3c7ef6639" +"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" +"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" "checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" @@ -1203,7 +1453,7 @@ dependencies = [ "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_string 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11aade7a05aa8c3a351cedc44c3fc45806430543382fcc4743a9b757a2a0b4ed" -"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" +"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" "checksum bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1d50c876fb7545f5f289cd8b2aee3f359d073ae819eed5d6373638e2c61e59" "checksum bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" "checksum bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2c5162604199bbb17690ede847eaa6120a3f33d5ab4dcc8e7c25b16d849ae79b" @@ -1223,12 +1473,14 @@ dependencies = [ "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" "checksum crypto-mac 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "99376574a55849855052aa6e3b15f3bdebf8bcdd3b24f3cbc3371469bcd5b480" +"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum dbl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "920e117b69060a961c4164ccf83af573292cb167ccdd918950bcf0f5afc32c1c" "checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603" "checksum dns-parser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7020f6760aea312d43d23cb83bf6c0c49f162541db8b02bf95209ac51dc253d" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" -"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a" +"checksum error-chain 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faa976b4fd2e4c2b2f3f486874b19e61944d3de3de8b61c9fcf835d583871bcc" +"checksum error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6930e04918388a9a2e41d518c25cf679ccafe26733fb4127dbf21993f2575d46" "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" "checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423" "checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909" @@ -1237,19 +1489,23 @@ 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.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" -"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" +"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" +"checksum hostname 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "58fab6e177434b0bb4cd344a4dabaa5bd6d7a8d792b1885aebcae7af1091d1cb" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum ipconfig 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec4e18c0a0d4340870c14284293632d8421f419008371422dd327892b88877c" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" "checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" "checksum libsodium-ffi 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "12aaa02009e30a59f4e1adab39dca446ea668efed9cb28128639fea07823791d" "checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" +"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" "checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" @@ -1277,19 +1533,25 @@ dependencies = [ "checksum qrcode 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5c30325393c280d05db5d2f996ac8f468789b6171de1165fab6de2a05fcb55c" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" -"checksum rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf" +"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3" "checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b" -"checksum ring 0.13.0-alpha (registry+https://github.com/rust-lang/crates.io-index)" = "946e5e2b336032275e23152755ec2a0610ede0302101d3666fdb686795d26535" +"checksum resolv-conf 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e1b086bb6a2659d6ba66e4aa21bde8a53ec03587cd5c80b83bdc3a330f35cab" +"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" +"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649" +"checksum rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc9f2e05fd6a3ce1530cd5dbcc553d2f94d7749fe3e4f5b443668eddd842889e" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "1921d0c6997bf121f5a85e3fed9ffd2cdfa87254f84e92f9b72e4cd84fbcf79f" +"checksum sct 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1137b767bbe1c4d30656993bdd97422ed41255d9400b105d735f8c7d9e800632" +"checksum serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "97f6a6c3caba0cf8f883b53331791036404ce3c1bd895961cf8bb2f8cecfd84b" "checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" +"checksum smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03dab98ab5ded3a8b43b2c80751194608d0b2aa0f1d46cf95d1c35e192844aa7" +"checksum socket2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ff606e0486e88f5fc6cfeb3966e434fb409abbc7a3ab495238f70a1ca97f789d" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum subprocess 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4568d3ac4df6df0cbf2001e1f3f37276b925e9b07f0588cd6ee0b2174dd3cd" "checksum subtle 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7a6bab57c3efd01ebd3d750f4244ae0af4cdd1fc505a7904a41603192b803c5" @@ -1298,12 +1560,13 @@ dependencies = [ "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" +"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" "checksum tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d00555353b013e170ed8bc4e13f648a317d1fd12157dbcae13f7013f6cf29f5" "checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" "checksum tokio-fs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76766830bbf9a2d5bfb50c95350d56a2e79e2c80f675967fff448bc615899708" "checksum tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af9eb326f64b2d6b68438e1953341e00ab3cf54de7e35d92bfc73af8555313a" "checksum tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3cedc8e5af5131dc3423ffa4f877cce78ad25259a9a62de0613735a13ebc64b" +"checksum tokio-rustls 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9263e472d976e4345e50c6cce4cfe6b17c71593ea593cce1df26f1efd36debb" "checksum tokio-signal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6a5bf935a0151cc8899aa806ce6a425bdaec79ed4034de1a1e6bfa247e2def" "checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f" "checksum tokio-threadpool 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5783254b10c7c84a56f62c74766ef7e5b83d1f13053218c7cab8d3f2c826fa0e" @@ -1315,19 +1578,24 @@ dependencies = [ "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum untrusted 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70afa43c8c5d23a53a3c39ec9b56232c5badc19f6bb5ad529c1d6448a7241365" +"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" "checksum unwrap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "999361f54269ac2f0832a39b238ffe077ffa15ff7f6f696968a51164eaffa472" "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380" -"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum webpki 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e1622384bcb5458c6a3e3fa572f53ea8fef1cc85e535a2983dea87e9154fac2" +"checksum webpki-roots 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "155d4060e5befdf3a6076bd28c22513473d9900b763c9e4521acc6f78a75415c" +"checksum widestring 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7157704c2e12e3d2189c507b7482c52820a16dfa4465ba91add92f266667cadb" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767" +"checksum winreg 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9338067aba07889a38beaad4dbb77fa2e62e87c423b770824b3bdf412874bd2c" +"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "abb373b92de38a4301d66bec009929b4fb83120ea1c4a401be89dbe0b9777443" "checksum zip 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "e7341988e4535c60882d5e5f0b7ad0a9a56b080ade8bdb5527cb512f7b2180e0" diff --git a/Cargo.toml b/Cargo.toml index 9f3c0c7e..aa7175d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shadowsocks-rust" -version = "1.7.0-alpha.3" +version = "1.7.0-alpha.4" authors = ["Y. T. CHUNG "] description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls." repository = "https://github.com/zonyitoo/shadowsocks-rust" @@ -50,7 +50,7 @@ lazy_static = "1.0" serde_json = "1.0" base64 = "0.9" bytes = "0.4" -ring = "0.13.0-alpha" +ring = "0.12" md-5 = "0.7" digest = "0.7" typenum = "1.10" @@ -60,10 +60,10 @@ serde_urlencoded = "0.5" url = "1" byte_string = "1.0" libsodium-ffi = { version = "0.1", optional = true } -futures-cpupool = "0.1" miscreant = { version = "0.3", optional = true } lru-cache = "0.1" dns-parser = "0.7" +trust-dns-resolver = { git = "https://github.com/bluejekyll/trust-dns", features = ["dns-over-rustls"] } [target.'cfg(unix)'.dependencies] tokio-signal = "0.2" diff --git a/build/build-release b/build/build-release index be6cc43f..8e4a3624 100755 --- a/build/build-release +++ b/build/build-release @@ -126,6 +126,7 @@ echo "* Packaging XZ in ${PKG_PATH} ..." tar -cJf ${PKG_PATH} \ "sslocal" \ "ssserver" \ - "ssurl" + "ssurl" \ + "ssdns" echo "* Done build package ${PKG_NAME}" diff --git a/src/bin/ssdns.rs b/src/bin/ssdns.rs index 7b43c47f..d6510fd1 100644 --- a/src/bin/ssdns.rs +++ b/src/bin/ssdns.rs @@ -135,18 +135,16 @@ fn main() { let mut has_provided_config = false; let mut config = match matches.value_of("CONFIG") { - Some(cpath) => { - match Config::load_from_file(cpath, ConfigType::Local) { - Ok(cfg) => { - has_provided_config = true; - cfg - } - Err(err) => { - error!("{:?}", err); - return; - } + Some(cpath) => match Config::load_from_file(cpath, ConfigType::Local) { + Ok(cfg) => { + has_provided_config = true; + cfg } - } + Err(err) => { + error!("{:?}", err); + return; + } + }, None => Config::new(), }; @@ -203,7 +201,7 @@ fn main() { } if let Some(dns) = matches.value_of("DNS") { - let dns_addr = dns.parse::().expect("Failed to parse `dns`"); + let dns_addr = dns.parse::().expect("`dns` is not a valid SocketAddr, must be IP:Port"); config.dns = dns_addr; } diff --git a/src/lib.rs b/src/lib.rs index 7cf810b2..e3bdc240 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,7 +77,6 @@ extern crate bytes; extern crate digest; #[macro_use] extern crate futures; -extern crate futures_cpupool; #[macro_use] extern crate lazy_static; extern crate libc; @@ -101,6 +100,7 @@ extern crate lru_cache; extern crate tokio; #[cfg(any(unix, windows))] extern crate tokio_signal; +extern crate trust_dns_resolver; extern crate typenum; extern crate url; diff --git a/src/monitor.rs b/src/monitor.rs index f3365837..8ff3069e 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -14,7 +14,7 @@ use plugin::Plugin; use relay::boxed_future; #[cfg(unix)] -pub fn monitor_signal(plugins: Vec) -> IoFuture<()> { +pub fn monitor_signal(plugins: Vec) -> impl Future + Send { use tokio_signal::unix::Signal; // Monitor SIGCHLD, triggered if subprocess (plugin) is exited. @@ -60,31 +60,31 @@ pub fn monitor_signal(plugins: Vec) -> IoFuture<()> { }); // Join them all, if any of them is triggered, kill all subprocesses and exit. - boxed_future(fut1.select(fut2).then(|r| match r { - Ok((o, _)) => Ok(o), - Err((e, _)) => Err(e), - }) - .select(fut3) - .then(|r| match r { - Ok((o, _)) => Ok(o), - Err((e, _)) => Err(e), - }) - .then(move |r| { - // Something happened ... killing all subprocesses - info!("Killing {} plugin(s) and then ... Bye Bye :)", plugins.len()); - drop(plugins); + fut1.select(fut2).then(|r| match r { + Ok((o, _)) => Ok(o), + Err((e, _)) => Err(e), + }) + .select(fut3) + .then(|r| match r { + Ok((o, _)) => Ok(o), + Err((e, _)) => Err(e), + }) + .then(move |r| { + // Something happened ... killing all subprocesses + info!("Killing {} plugin(s) and then ... Bye Bye :)", plugins.len()); + drop(plugins); - match r { - Ok(..) => { - process::exit(0); - } - Err(err) => Err(err), - } - })) + match r { + Ok(..) => { + process::exit(0); + } + Err(err) => Err(err), + } + }) } #[cfg(windows)] -pub fn monitor_signal(plugins: Vec) -> IoFuture<()> { +pub fn monitor_signal(plugins: Vec) -> impl Future + Send { // FIXME: How to handle SIGTERM equavalent in Windows? use tokio_signal::windows::Event; @@ -111,20 +111,19 @@ pub fn monitor_signal(plugins: Vec) -> IoFuture<()> { err }); - boxed_future(fut1.select(fut2).then(|_| -> Result<(), ()> { - // Something happened ... killing all subprocesses - info!("Killing {} plugin(s) and then ... Bye Bye :)", plugins.len()); - drop(plugins); - process::exit(libc::EXIT_FAILURE); - })) + fut1.select(fut2).then(|_| -> Result<(), ()> { + // Something happened ... killing all subprocesses + info!("Killing {} plugin(s) and then ... Bye Bye :)", plugins.len()); + drop(plugins); + process::exit(libc::EXIT_FAILURE); + }) } #[cfg(not(any(windows, unix)))] -pub fn monitor_signal(plugins: Vec) -> IoFuture<()> { +pub fn monitor_signal(plugins: Vec) -> impl Future + Send { // FIXME: What can I do ... // Blocks forever - let fut = futures::empty::<(), ()>().and_then(|_| { - drop(plugins); - }); - boxed_future(fut) + futures::empty::<(), ()>().and_then(|_| { + drop(plugins); + }) } diff --git a/src/relay/dns_resolver.rs b/src/relay/dns_resolver.rs index e0efe9a5..b817067f 100644 --- a/src/relay/dns_resolver.rs +++ b/src/relay/dns_resolver.rs @@ -1,78 +1,148 @@ //! Asynchronous DNS resolver use std::io::{self, ErrorKind}; -use std::net::{IpAddr, SocketAddr, ToSocketAddrs}; +use std::mem; +use std::net::SocketAddr; use std::sync::Arc; -use futures::{future, Future}; - -use futures_cpupool::CpuPool; - -use tokio_io::IoFuture; +use futures::Future; +use tokio::runtime::current_thread::Runtime; +use trust_dns_resolver::config::{ResolverConfig, ResolverOpts}; +use trust_dns_resolver::ResolverFuture; use config::Config; -use relay::boxed_future; +// Taken from +// bluejekyll/trust-dns/resolver/examples/global_resolver.rs lazy_static! { - static ref GLOBAL_DNS_CPU_POOL: CpuPool = CpuPool::new_num_cpus(); + // First we need to setup the global Resolver + static ref GLOBAL_DNS_RESOLVER: ResolverFuture = init_resolver(false); + static ref GLOBAL_GOOGLE_DNS_RESOLVER: ResolverFuture = init_resolver(true); } -pub fn resolve(config: Arc, addr: &str, port: u16, check_forbidden: bool) -> IoFuture> { - // FIXME: Sometimes addr is actually an IpAddr! - if let Ok(addr) = addr.parse::() { - if !check_forbidden { - return boxed_future(future::finished(vec![SocketAddr::new(addr, port)])); - } +fn init_resolver(force_google: bool) -> ResolverFuture { + use std::sync::{Arc, Condvar, Mutex}; + use std::thread; - let result = { - let forbidden_ip = &config.forbidden_ip; + // We'll be using this condvar to get the Resolver from the thread... + let pair = Arc::new((Mutex::new(None::), Condvar::new())); + let pair2 = pair.clone(); - if forbidden_ip.contains(&addr) { - let err = io::Error::new(ErrorKind::Other, format!("{} is forbidden, all IPs are filtered", addr)); - Err(err) - } else { - Ok(vec![SocketAddr::new(addr, port)]) - } - }; + // Spawn the runtime to a new thread... + // + // This thread will manage the actual resolution runtime + thread::spawn(move || { + // A runtime for this new thread + let mut runtime = Runtime::new().expect("failed to launch Runtime"); - return boxed_future(future::done(result)); + // our platform independent future, result, see next blocks + let future; + + // To make this independent, if targeting macOS, BSD, Linux, or Windows, we can use the system's configuration: + #[cfg(any(unix, windows))] + { + if force_google { + future = ResolverFuture::new(ResolverConfig::google(), ResolverOpts::default()); + } else { + // use the system resolver configuration + future = ResolverFuture::from_system_conf().expect("Failed to create ResolverFuture"); + } + } + + // For other operating systems, we can use one of the preconfigured definitions + #[cfg(not(any(unix, windows)))] + { + // Directly reference the config types + use trust_dns_resolver::config::{ResolverConfig, ResolverOpts}; + + // Get a new resolver with the google nameservers as the upstream recursive resolvers + future = ResolverFuture::new(ResolverConfig::google(), ResolverOpts::default()); + } + + // this will block the thread until the Resolver is constructed with the above configuration + let resolver = runtime.block_on(future).expect("Failed to create DNS resolver"); + + let &(ref lock, ref cvar) = &*pair2; + let mut started = lock.lock().unwrap(); + *started = Some(resolver); + cvar.notify_one(); + drop(started); + + runtime.run().expect("Resolver Thread shutdown!"); + }); + + // Wait for the thread to start up. + let &(ref lock, ref cvar) = &*pair; + let mut resolver = lock.lock().unwrap(); + while resolver.is_none() { + resolver = cvar.wait(resolver).unwrap(); } - trace!("Going to resolve \"{}:{}\"", addr, port); - let owned_addr = addr.to_owned(); - let fut = - GLOBAL_DNS_CPU_POOL.spawn_fn(move || match (owned_addr.as_str(), port).to_socket_addrs() { - Ok(a) => Ok((owned_addr, a)), - Err(err) => { - error!("Failed to resolve {}, {}", owned_addr, err); - Err(err) - } - }) - .and_then(move |(owned_addr, addr_iter)| { - let v = if !check_forbidden { - addr_iter.collect::>() - } else { - let forbidden_ip = &config.forbidden_ip; - addr_iter.filter(|addr| { - let filtered = forbidden_ip.contains(&addr.ip()); - if filtered { - error!("{} is forbidden and ignored", addr.ip()); - } - !filtered - }) - .collect::>() - }; + // take the started resolver + let resolver = mem::replace(&mut *resolver, None); - if v.is_empty() { - let err = io::Error::new(io::ErrorKind::Other, - format!("resolved \"{}:{}\" to empty address", - owned_addr, port)); - Err(err) - } else { - debug!("Resolved \"{}\" => {:?}", owned_addr, v); - Ok(v) - } - }); - - boxed_future(fut) + // set the global resolver + resolver.expect("resolver should not be none") +} + +fn inner_resolve(config: Arc, + addr: &str, + port: u16, + check_forbidden: bool, + force_google: bool) + -> impl Future, Error = io::Error> + Send { + let owned_addr = addr.to_owned(); + let owned_addr2 = owned_addr.clone(); + + let resolver = if force_google { + &*GLOBAL_GOOGLE_DNS_RESOLVER + } else { + &*GLOBAL_DNS_RESOLVER + }; + + resolver.lookup_ip(addr) + .map_err(move |err| { + error!("Failed to resolve {}, err: {}", owned_addr2, err); + io::Error::new(io::ErrorKind::Other, "dns resolve error") + }) + .and_then(move |lookup_result| { + let mut vaddr = Vec::new(); + for ip in lookup_result.iter() { + if check_forbidden { + let forbidden_ip = &config.forbidden_ip; + if forbidden_ip.contains(&ip) { + debug!("Resolved {} => {}, which is skipped by forbidden_ip", owned_addr, ip); + continue; + } + + vaddr.push(SocketAddr::new(ip, port)); + } + } + + if vaddr.is_empty() { + let err = io::Error::new(ErrorKind::Other, + format!("resolved {} to empty address, all IPs are filtered", + owned_addr)); + Err(err) + } else { + debug!("Resolved {} => {:?}", owned_addr, vaddr); + Ok(vaddr) + } + }) +} + +pub fn resolve(config: Arc, + addr: &str, + port: u16, + check_forbidden: bool) + -> impl Future, Error = io::Error> + Send { + inner_resolve(config, addr, port, check_forbidden, false) +} + +pub fn resolve_by_google(config: Arc, + addr: &str, + port: u16, + check_forbidden: bool) + -> impl Future, Error = io::Error> + Send { + inner_resolve(config, addr, port, check_forbidden, true) } diff --git a/src/relay/local.rs b/src/relay/local.rs index b39a13b1..38f7d132 100644 --- a/src/relay/local.rs +++ b/src/relay/local.rs @@ -9,6 +9,7 @@ use futures::Future; use config::Config; use plugin::{launch_plugin, PluginMode}; +use relay::boxed_future; use relay::tcprelay::local::run as run_tcp; use relay::udprelay::local::run as run_udp; @@ -35,20 +36,15 @@ pub fn run(mut config: Config) { let enable_udp = config.enable_udp; + let tcp_fut = run_tcp(config.clone()); + let mut vf = vec![boxed_future(mon), boxed_future(tcp_fut)]; if enable_udp { - let tcp_fut = run_tcp(config.clone()); let udp_fut = run_udp(config); - tokio::run(join_all(vec![mon, tcp_fut, udp_fut]).then(|res| match res { - Ok(..) => Ok(()), - Err(err) => { - panic!("Failed to run server, err: {}", err) - } - })); - } else { - let tcp_fut = run_tcp(config); - tokio::run(join_all(vec![mon, tcp_fut]).then(|res| match res { - Ok(..) => Ok(()), - Err(err) => panic!("Failed to run server, err: {}", err), - })) + vf.push(boxed_future(udp_fut)); } + + tokio::run(join_all(vf).then(|res| match res { + Ok(..) => Ok(()), + Err(err) => panic!("Failed to run server, err: {}", err), + })); } diff --git a/src/relay/server.rs b/src/relay/server.rs index 227ac18a..b55a819f 100644 --- a/src/relay/server.rs +++ b/src/relay/server.rs @@ -9,6 +9,7 @@ use futures::Future; use config::Config; use plugin::{launch_plugin, PluginMode}; +use relay::boxed_future; use relay::tcprelay::server::run as run_tcp; use relay::udprelay::server::run as run_udp; @@ -34,20 +35,15 @@ pub fn run(mut config: Config) { let config = Arc::new(config); let enable_udp = config.enable_udp; + let tcp_fut = run_tcp(config.clone()); + let mut vf = vec![boxed_future(mon), boxed_future(tcp_fut)]; if enable_udp { - let tcp_fut = run_tcp(config.clone()); let udp_fut = run_udp(config); - tokio::run(join_all(vec![mon, tcp_fut, udp_fut]).then(|res| match res { - Ok(..) => Ok(()), - Err(err) => { - panic!("Failed to run server, err: {}", err) - } - })); - } else { - let tcp_fut = run_tcp(config); - tokio::run(join_all(vec![mon, tcp_fut]).then(|res| match res { - Ok(..) => Ok(()), - Err(err) => panic!("Failed to run server, err: {}", err), - })) + vf.push(boxed_future(udp_fut)); } + + tokio::run(join_all(vf).then(|res| match res { + Ok(..) => Ok(()), + Err(err) => panic!("Failed to run server, err: {}", err), + })); } diff --git a/src/relay/socks5.rs b/src/relay/socks5.rs index 7a960eb1..e6f26f4a 100644 --- a/src/relay/socks5.rs +++ b/src/relay/socks5.rs @@ -16,7 +16,7 @@ use bytes::{BufMut, Bytes, BytesMut, IntoBuf}; use futures::{Async, Future, Poll}; use tokio_io::io::read_exact; -use tokio_io::{AsyncRead, AsyncWrite, IoFuture}; +use tokio_io::{AsyncRead, AsyncWrite}; pub use self::consts::{ SOCKS5_AUTH_METHOD_GSSAPI, SOCKS5_AUTH_METHOD_NONE, SOCKS5_AUTH_METHOD_NOT_ACCEPTABLE, SOCKS5_AUTH_METHOD_PASSWORD, @@ -544,38 +544,37 @@ impl TcpRequestHeader { } /// Read from a reader - pub fn read_from( - r: R) - -> Box + Send + 'static> { - let fut = read_exact(r, [0u8; 3]).map_err(From::from) - .and_then(|(r, buf)| { - let ver = buf[0]; - if ver != consts::SOCKS5_VERSION { - return Err(Error::new(Reply::ConnectionRefused, - "Unsupported Socks version")); - } + pub fn read_from(r: R) -> impl Future + Send + where R: AsyncRead + Send + 'static + { + read_exact(r, [0u8; 3]).map_err(From::from) + .and_then(|(r, buf)| { + let ver = buf[0]; + if ver != consts::SOCKS5_VERSION { + return Err(Error::new(Reply::ConnectionRefused, + "Unsupported Socks version")); + } - let cmd = buf[1]; - let command = match Command::from_u8(cmd) { - Some(c) => c, - None => { - return Err(Error::new(Reply::CommandNotSupported, - "Unsupported command")) - } - }; + let cmd = buf[1]; + let command = match Command::from_u8(cmd) { + Some(c) => c, + None => { + return Err(Error::new(Reply::CommandNotSupported, + "Unsupported command")) + } + }; - Ok((r, command)) - }) - .and_then(|(r, command)| { - Address::read_from(r).map(move |(conn, address)| { - let header = TcpRequestHeader { command: command, - address: address, }; + Ok((r, command)) + }) + .and_then(|(r, command)| { + Address::read_from(r).map(move |(conn, address)| { + let header = + TcpRequestHeader { command: command, + address: address, }; - (conn, header) - }) - }); - - Box::new(fut) + (conn, header) + }) + }) } /// Write data into a writer @@ -626,32 +625,30 @@ impl TcpResponseHeader { } /// Read from a reader - pub fn read_from( - r: R) - -> Box + Send + 'static> { - let fut = read_exact(r, [0u8; 3]).map_err(From::from) - .and_then(|(r, buf)| { - let ver = buf[0]; - let reply_code = buf[1]; + pub fn read_from(r: R) -> impl Future + Send + where R: AsyncRead + Send + 'static + { + read_exact(r, [0u8; 3]).map_err(From::from) + .and_then(|(r, buf)| { + let ver = buf[0]; + let reply_code = buf[1]; - if ver != consts::SOCKS5_VERSION { - return Err(Error::new(Reply::ConnectionRefused, - "Unsupported Socks version")); - } + if ver != consts::SOCKS5_VERSION { + return Err(Error::new(Reply::ConnectionRefused, + "Unsupported Socks version")); + } - Ok((r, reply_code)) - }) - .and_then(|(r, reply_code)| { - Address::read_from(r).map(move |(r, address)| { - let rep = TcpResponseHeader { reply: + Ok((r, reply_code)) + }) + .and_then(|(r, reply_code)| { + Address::read_from(r).map(move |(r, address)| { + let rep = TcpResponseHeader { reply: Reply::from_u8(reply_code), address: address, }; - (r, rep) - }) - }); - - Box::new(fut) + (r, rep) + }) + }) } /// Write to a writer @@ -696,23 +693,22 @@ impl HandshakeRequest { } /// Read from a reader - pub fn read_from(r: R) -> IoFuture<(R, HandshakeRequest)> { - let fut = read_exact(r, [0u8, 0u8]).and_then(|(r, buf)| { - let ver = buf[0]; - let nmet = buf[1]; + pub fn read_from(r: R) -> impl Future + where R: AsyncRead + Send + 'static + { + read_exact(r, [0u8, 0u8]).and_then(|(r, buf)| { + let ver = buf[0]; + let nmet = buf[1]; - if ver != consts::SOCKS5_VERSION { - return Err(io::Error::new(io::ErrorKind::Other, - "Invalid Socks5 version")); - } + if ver != consts::SOCKS5_VERSION { + return Err(io::Error::new(io::ErrorKind::Other, + "Invalid Socks5 version")); + } - Ok((r, nmet)) - }) - .and_then(|(r, nmet)| { - read_exact(r, vec![0u8; nmet as usize]) - .and_then(|(r, methods)| Ok((r, HandshakeRequest { methods: methods }))) - }); - Box::new(fut) + Ok((r, nmet)) + }) + .and_then(|(r, nmet)| read_exact(r, vec![0u8; nmet as usize])) + .and_then(|(r, methods)| Ok((r, HandshakeRequest { methods: methods }))) } /// Write to a writer @@ -756,19 +752,19 @@ impl HandshakeResponse { } /// Read from a reader - pub fn read_from(r: R) -> IoFuture<(R, HandshakeResponse)> { - let fut = read_exact(r, [0u8, 0u8]).and_then(|(r, buf)| { - let ver = buf[0]; - let met = buf[1]; + pub fn read_from(r: R) -> impl Future + where R: AsyncRead + Send + 'static + { + read_exact(r, [0u8, 0u8]).and_then(|(r, buf)| { + let ver = buf[0]; + let met = buf[1]; - if ver != consts::SOCKS5_VERSION { - Err(io::Error::new(io::ErrorKind::Other, - "Invalid Socks5 version")) - } else { - Ok((r, HandshakeResponse { chosen_method: met })) - } - }); - Box::new(fut) + if ver != consts::SOCKS5_VERSION { + Err(io::Error::new(io::ErrorKind::Other, "Invalid Socks5 version")) + } else { + Ok((r, HandshakeResponse { chosen_method: met })) + } + }) } /// Write to a writer @@ -816,17 +812,16 @@ impl UdpAssociateHeader { } /// Read from a reader - pub fn read_from( - r: R) - -> Box + Send + 'static> { - let fut = read_exact(r, [0u8; 3]).map_err(From::from).and_then(|(r, buf)| { + pub fn read_from(r: R) -> impl Future + Send + where R: AsyncRead + Send + 'static + { + read_exact(r, [0u8; 3]).map_err(From::from).and_then(|(r, buf)| { let frag = buf[2]; Address::read_from(r).map(move |(r, address)| { let h = UdpAssociateHeader::new(frag, address); (r, h) }) - }); - Box::new(fut) + }) } /// Write to a writer diff --git a/src/relay/tcprelay/client.rs b/src/relay/tcprelay/client.rs index 226084e5..dffbb8fc 100644 --- a/src/relay/tcprelay/client.rs +++ b/src/relay/tcprelay/client.rs @@ -5,11 +5,10 @@ use std::net::SocketAddr; use tokio::net::TcpStream; use tokio_io::io::flush; -use tokio_io::{AsyncRead, AsyncWrite, IoFuture}; +use tokio_io::{AsyncRead, AsyncWrite}; use futures::{self, Async, Future, Poll}; -use relay::boxed_future; use relay::socks5::{ self, Address, Command, HandshakeRequest, HandshakeResponse, Reply, TcpRequestHeader, TcpResponseHeader, }; @@ -21,11 +20,11 @@ pub struct Socks5Client { impl Socks5Client { /// Connects to `addr` via `proxy` - pub fn connect(addr: A, proxy: SocketAddr) -> IoFuture + pub fn connect(addr: A, proxy: SocketAddr) -> impl Future + Send where Address: From, A: Send + 'static { - let fut = futures::lazy(move || TcpStream::connect(&proxy)) + futures::lazy(move || TcpStream::connect(&proxy)) .and_then(move |s| { // 1. Handshake let hs = HandshakeRequest::new(vec![socks5::SOCKS5_AUTH_METHOD_NONE]); @@ -58,17 +57,17 @@ impl Socks5Client { } }) }) - .map(|s| Socks5Client { stream: s }); - - boxed_future(fut) + .map(|s| Socks5Client { stream: s }) } /// UDP Associate `addr` via `proxy` - pub fn udp_associate(addr: A, proxy: SocketAddr) -> IoFuture<(Socks5Client, Address)> + pub fn udp_associate(addr: A, + proxy: SocketAddr) + -> impl Future + Send where Address: From, A: Send + 'static { - let fut = futures::lazy(move || TcpStream::connect(&proxy)) + futures::lazy(move || TcpStream::connect(&proxy)) .and_then(move |s| { // 1. Handshake let hs = HandshakeRequest::new(vec![socks5::SOCKS5_AUTH_METHOD_NONE]); @@ -101,9 +100,7 @@ impl Socks5Client { } }) }) - .map(|(s, a)| (Socks5Client { stream: s }, a)); - - boxed_future(fut) + .map(|(s, a)| (Socks5Client { stream: s }, a)) } } diff --git a/src/relay/tcprelay/local.rs b/src/relay/tcprelay/local.rs index 6dbae4e8..3413aacf 100644 --- a/src/relay/tcprelay/local.rs +++ b/src/relay/tcprelay/local.rs @@ -1,13 +1,14 @@ //! Relay for TCP server that running on local environment +use std::io; use std::sync::Arc; -use tokio_io::IoFuture; +use futures::Future; use super::socks5_local; use config::Config; /// Starts a TCP local server -pub fn run(config: Arc) -> IoFuture<()> { +pub fn run(config: Arc) -> impl Future + Send { socks5_local::run(config) } diff --git a/src/relay/tcprelay/mod.rs b/src/relay/tcprelay/mod.rs index 8ec2e070..5d4f1ca8 100644 --- a/src/relay/tcprelay/mod.rs +++ b/src/relay/tcprelay/mod.rs @@ -209,22 +209,29 @@ impl> Future for TcpStreamConnect { match mem::replace(self, TcpStreamConnect::Empty) { TcpStreamConnect::Empty => unreachable!(), - TcpStreamConnect::Connect { last_err, .. } => match last_err { - None => { - let err = io::Error::new(ErrorKind::Other, "connect TCP without any addresses"); - Err(err) + TcpStreamConnect::Connect { last_err, .. } => { + match last_err { + None => { + let err = io::Error::new(ErrorKind::Other, "connect TCP without any addresses"); + Err(err) + } + Some(err) => Err(err), } - Some(err) => Err(err), - }, + } } } } -fn connect_proxy_server(config: Arc, svr_cfg: Arc) -> IoFuture { +fn connect_proxy_server(config: Arc, + svr_cfg: Arc) + -> impl Future + Send { let timeout = *svr_cfg.timeout(); trace!("Connecting to proxy {:?}, timeout: {:?}", svr_cfg.addr(), timeout); match *svr_cfg.addr() { - ServerAddr::SocketAddr(ref addr) => try_timeout(TcpStream::connect(addr), timeout), + ServerAddr::SocketAddr(ref addr) => { + let fut = try_timeout(TcpStream::connect(addr), timeout); + boxed_future(fut) + } ServerAddr::DomainName(ref domain, port) => { let fut = { try_timeout(resolve(config.clone(), &domain[..], port, false), timeout).and_then(move |vec_ipaddr| { @@ -241,9 +248,9 @@ fn connect_proxy_server(config: Arc, svr_cfg: Arc) -> IoFu pub fn proxy_server_handshake(remote_stream: TcpStream, svr_cfg: Arc, relay_addr: Address) - -> IoFuture<(DecryptedHalfFut, EncryptedHalfFut)> { + -> impl Future + Send { let timeout = *svr_cfg.timeout(); - let fut = proxy_handshake(remote_stream, svr_cfg).and_then(move |(r_fut, w_fut)| { + proxy_handshake(remote_stream, svr_cfg).and_then(move |(r_fut, w_fut)| { let w_fut = w_fut.and_then(move |enc_w| { // Send relay address to remote let mut buf = BytesMut::with_capacity(relay_addr.len()); @@ -257,16 +264,15 @@ pub fn proxy_server_handshake(remote_stream: TcpStream, }); Ok((r_fut, boxed_future(w_fut))) - }); - boxed_future(fut) + }) } /// ShadowSocks Client-Server handshake protocol /// Exchange cipher IV and creates stream wrapper pub fn proxy_handshake(remote_stream: TcpStream, svr_cfg: Arc) - -> IoFuture<(DecryptedHalfFut, EncryptedHalfFut)> { - let fut = futures::lazy(|| Ok(remote_stream.split())).and_then(move |(r, w)| { + -> impl Future + Send { + futures::lazy(|| Ok(remote_stream.split())).and_then(move |(r, w)| { let timeout = svr_cfg.timeout().clone(); let svr_cfg_cloned = svr_cfg.clone(); @@ -333,13 +339,11 @@ pub fn proxy_handshake(remote_stream: TcpStream, }; Ok((boxed_future(dec), boxed_future(enc))) - }); - - boxed_future(fut) + }) } /// Establish tunnel between server and client -pub fn tunnel(addr: Address, c2s: CF, s2c: SF) -> IoFuture<()> +pub fn tunnel(addr: Address, c2s: CF, s2c: SF) -> impl Future + Send where CF: Future + Send + 'static, SF: Future + Send + 'static { @@ -374,21 +378,19 @@ pub fn tunnel(addr: Address, c2s: CF, s2c: SF) -> IoFuture<()> } }); - let fut = c2s.select(s2c).and_then(move |(dir, _)| { - match dir { - TunnelDirection::Server2Client => { - trace!("Relay {} client <- server is closed, abort connection", addr) - } - TunnelDirection::Client2Server => { - trace!("Relay {} server -> client is closed, abort connection", addr) - } - } + c2s.select(s2c).and_then(move |(dir, _)| { + match dir { + TunnelDirection::Server2Client => { + trace!("Relay {} client <- server is closed, abort connection", addr) + } + TunnelDirection::Client2Server => { + trace!("Relay {} server -> client is closed, abort connection", addr) + } + } - Ok(()) - }) - .map_err(|(err, _)| err); - - boxed_future(fut) + Ok(()) + }) + .map_err(|(err, _)| err) } /// Read until EOF, and ignore @@ -429,26 +431,24 @@ pub fn ignore_until_end(r: R) -> IgnoreUntilEnd { IgnoreUntilEnd::Pending { r: r, amt: 0 } } -fn try_timeout(fut: F, dur: Option) -> IoFuture +fn try_timeout(fut: F, dur: Option) -> impl Future + Send where F: Future + Send + 'static, T: 'static { match dur { - Some(dur) => io_timeout(fut, dur), + Some(dur) => boxed_future(io_timeout(fut, dur)), None => boxed_future(fut), } } -fn io_timeout(fut: F, dur: Duration) -> IoFuture +fn io_timeout(fut: F, dur: Duration) -> impl Future + Send where F: Future + Send + 'static, T: 'static { use tokio::prelude::*; - let fut = fut.deadline(Instant::now() + dur).map_err(|err| match err.into_inner() { - Some(e) => e, - None => io::Error::new(io::ErrorKind::TimedOut, "connection timed out"), - }); - - boxed_future(fut) + fut.deadline(Instant::now() + dur).map_err(|err| match err.into_inner() { + Some(e) => e, + None => io::Error::new(io::ErrorKind::TimedOut, "connection timed out"), + }) } diff --git a/src/relay/tcprelay/server.rs b/src/relay/tcprelay/server.rs index 4de01d81..6b6049b2 100644 --- a/src/relay/tcprelay/server.rs +++ b/src/relay/tcprelay/server.rs @@ -30,10 +30,10 @@ pub struct TcpRelayClientHandshake { impl TcpRelayClientHandshake { /// Doing handshake with client - pub fn handshake(self) -> IoFuture { + pub fn handshake(self) -> impl Future { let TcpRelayClientHandshake { s, svr_cfg, config } = self; - let fut = futures::lazy(move || s.peer_addr().map(|p| (s, p))).and_then(|(s, peer_addr)| { + futures::lazy(move || s.peer_addr().map(|p| (s, p))).and_then(|(s, peer_addr)| { debug!("Handshaking with peer {}", peer_addr); let timeout = *svr_cfg.timeout(); @@ -52,8 +52,7 @@ impl TcpRelayClientHandshake { timeout: timeout, config: config, }) }) - }); - boxed_future(fut) + }) } } @@ -69,7 +68,10 @@ pub struct TcpRelayClientPending { impl TcpRelayClientPending { /// Connect to the remote server #[inline] - fn connect_remote(config: Arc, addr: Address, timeout: Option) -> IoFuture { + fn connect_remote(config: Arc, + addr: Address, + timeout: Option) + -> impl Future { debug!("Connecting to remote {}", addr); match addr { @@ -81,7 +83,8 @@ impl TcpRelayClientPending { } let conn = TcpStream::connect(&saddr); - try_timeout(conn, timeout) + let fut = try_timeout(conn, timeout); + boxed_future(fut) } Address::DomainNameAddress(dname, port) => { let fut = { @@ -96,16 +99,16 @@ impl TcpRelayClientPending { } /// Connect to the remote server - pub fn connect(self) -> IoFuture { + pub fn connect(self) -> impl Future + Send { let addr = self.addr.clone(); let client_pair = (self.r, self.w); let timeout = self.timeout; - let fut = TcpRelayClientPending::connect_remote(self.config, self.addr, self.timeout); - let fut = fut.map(move |stream| TcpRelayClientConnected { server: stream.split(), - client: client_pair, - addr: addr, - timeout: timeout, }); - Box::new(fut) + TcpRelayClientPending::connect_remote(self.config, self.addr, self.timeout).map(move |stream| { + TcpRelayClientConnected { server: stream.split(), + client: client_pair, + addr: addr, + timeout: timeout, } + }) } } @@ -120,7 +123,7 @@ pub struct TcpRelayClientConnected { impl TcpRelayClientConnected { /// Establish tunnel #[inline] - pub fn tunnel(self) -> IoFuture<()> { + pub fn tunnel(self) -> impl Future + Send { let (svr_r, svr_w) = self.server; let (r, w_fut) = self.client; let timeout = self.timeout; @@ -132,7 +135,7 @@ impl TcpRelayClientConnected { } /// Runs the server -pub fn run(config: Arc) -> IoFuture<()> { +pub fn run(config: Arc) -> impl Future + Send { let mut fut: Option> = None; for svr_cfg in &config.server { diff --git a/src/relay/tcprelay/socks5_local.rs b/src/relay/tcprelay/socks5_local.rs index 94309297..cf863ea4 100644 --- a/src/relay/tcprelay/socks5_local.rs +++ b/src/relay/tcprelay/socks5_local.rs @@ -11,7 +11,6 @@ use futures::{self, Future}; use tokio_io::io::flush; use tokio_io::io::{ReadHalf, WriteHalf}; use tokio_io::AsyncRead; -use tokio_io::IoFuture; use tokio; use tokio::net::{TcpListener, TcpStream}; @@ -38,11 +37,11 @@ fn handle_socks5_connect(config: Arc, client_addr: SocketAddr, addr: Address, svr_cfg: Arc) - -> IoFuture<()> { + -> impl Future + Send { let cloned_addr = addr.clone(); let cloned_svr_cfg = svr_cfg.clone(); let timeout = *svr_cfg.timeout(); - let fut = super::connect_proxy_server(config.clone(), svr_cfg) + super::connect_proxy_server(config.clone(), svr_cfg) .then(move |res| { match res { Ok(svr_s) => { @@ -85,9 +84,7 @@ fn handle_socks5_connect(config: Arc, tunnel(cloned_addr, whalf, rhalf) }) - }); - - Box::new(fut) + }) } fn handle_socks5_client(config: Arc, @@ -142,7 +139,8 @@ fn handle_socks5_client(config: Arc, match header.command { socks5::Command::TcpConnect => { debug!("CONNECT {}", addr); - handle_socks5_connect(config, (r, w), cloned_client_addr, addr, conf) + let fut = handle_socks5_connect(config, (r, w), cloned_client_addr, addr, conf); + boxed_future(fut) } socks5::Command::TcpBind => { warn!("BIND is not supported"); @@ -188,7 +186,7 @@ fn handle_socks5_client(config: Arc, } /// Starts a TCP local server with Socks5 proxy protocol -pub fn run(config: Arc) -> IoFuture<()> { +pub fn run(config: Arc) -> impl Future + Send { let local_addr = *config.local.as_ref().expect("Missing local config"); let listener = TcpListener::bind(&local_addr).unwrap_or_else(|err| panic!("Failed to listen, {}", err)); @@ -199,15 +197,12 @@ pub fn run(config: Arc) -> IoFuture<()> { client_addr: local_addr, }; let mut servers = RoundRobin::new(&*config); - let listening = - listener.incoming().for_each(move |socket| { - let server_cfg = servers.pick_server(); + listener.incoming().for_each(move |socket| { + let server_cfg = servers.pick_server(); - trace!("Got connection, addr: {}", socket.peer_addr()?); - trace!("Picked proxy server: {:?}", server_cfg); + trace!("Got connection, addr: {}", socket.peer_addr()?); + trace!("Picked proxy server: {:?}", server_cfg); - handle_socks5_client(config.clone(), socket, server_cfg, udp_conf.clone()) - }); - - Box::new(listening) + handle_socks5_client(config.clone(), socket, server_cfg, udp_conf.clone()) + }) } diff --git a/src/relay/udprelay/dns.rs b/src/relay/udprelay/dns.rs index ac7e741e..80442866 100644 --- a/src/relay/udprelay/dns.rs +++ b/src/relay/udprelay/dns.rs @@ -18,7 +18,7 @@ use super::crypto_io::{decrypt_payload, encrypt_payload}; use super::{PacketStream, SendDgramRc, SharedUdpSocket}; use config::{Config, ServerAddr, ServerConfig}; use relay::boxed_future; -use relay::dns_resolver::resolve; +use relay::dns_resolver::resolve_by_google; use relay::socks5::Address; struct PrettyRRData<'a> { @@ -133,7 +133,7 @@ pub fn run(config: Arc) -> IoFuture<()> { boxed_future(fut) } -fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { +fn listen(config: Arc, l: UdpSocket) -> impl Future + Send { assert!(!config.server.is_empty()); let mut svr_fut = Vec::with_capacity(config.server.len()); @@ -143,35 +143,32 @@ fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { svr_fut.push(boxed_future(futures::finished::<_, io::Error>(vec![*addr]))); } ServerAddr::DomainName(ref dom, ref port) => { - svr_fut.push(resolve(config.clone(), &*dom, *port, false)); + svr_fut.push(boxed_future(resolve_by_google(config.clone(), &*dom, *port, false))); } } } let cloned_config = config.clone(); - let fut = join_all(svr_fut).and_then(move |svr_addrs| { - let mut u = Vec::with_capacity(svr_addrs.len()); - for (idx, svr_addr) in svr_addrs.into_iter().enumerate() { - let local_addr = - SocketAddr::new(IpAddr::from(Ipv4Addr::new(0, 0, 0, 0)), 0); - let s = UdpSocket::bind(&local_addr)?; - let svr_cfg = Arc::new(cloned_config.server[idx].clone()); - u.push((Arc::new(Mutex::new(s)), svr_cfg, svr_addr[0])); - } - Ok(u) - }) - .and_then(move |vec_servers| { - let mut f = Vec::with_capacity(1 + vec_servers.len()); - let l = Arc::new(Mutex::new(l)); - f.push(handle_l2r(config, l.clone(), vec_servers.clone())); - for (svr, cfg, _) in vec_servers { - f.push(handle_r2l(l.clone(), svr, cfg)) - } - join_all(f) - }) - .map(|_| ()); - - boxed_future(fut) + join_all(svr_fut).and_then(move |svr_addrs| { + let mut u = Vec::with_capacity(svr_addrs.len()); + for (idx, svr_addr) in svr_addrs.into_iter().enumerate() { + let local_addr = SocketAddr::new(IpAddr::from(Ipv4Addr::new(0, 0, 0, 0)), 0); + let s = UdpSocket::bind(&local_addr)?; + let svr_cfg = Arc::new(cloned_config.server[idx].clone()); + u.push((Arc::new(Mutex::new(s)), svr_cfg, svr_addr[0])); + } + Ok(u) + }) + .and_then(move |vec_servers| { + let mut f = Vec::with_capacity(1 + vec_servers.len()); + let l = Arc::new(Mutex::new(l)); + f.push(boxed_future(handle_l2r(config, l.clone(), vec_servers.clone()))); + for (svr, cfg, _) in vec_servers { + f.push(boxed_future(handle_r2l(l.clone(), svr, cfg))) + } + join_all(f) + }) + .map(|_| ()) } lazy_static! { @@ -181,14 +178,13 @@ lazy_static! { fn handle_l2r(config: Arc, l: SharedUdpSocket, server: Vec<(SharedUdpSocket, Arc, SocketAddr)>) - -> IoFuture<()> { + -> impl Future + Send { assert!(!server.is_empty()); let mut server_idx: usize = 0; let server = Arc::new(server); - let fut = - PacketStream::new(l).for_each(move |(payload, src)| { + PacketStream::new(l).for_each(move |(payload, src)| { let server = server.clone(); let config = config.clone(); let pkt_fut = futures::lazy(move || { @@ -234,12 +230,14 @@ fn handle_l2r(config: Arc, })); Ok(()) - }); - boxed_future(fut) + }) } -fn handle_r2l(l: SharedUdpSocket, r: SharedUdpSocket, svr_cfg: Arc) -> IoFuture<()> { - let fut = PacketStream::new(r).for_each(move |(payload, src)| { +fn handle_r2l(l: SharedUdpSocket, + r: SharedUdpSocket, + svr_cfg: Arc) + -> impl Future + Send { + PacketStream::new(r).for_each(move |(payload, src)| { let l = l.clone(); let svr_cfg = svr_cfg.clone(); let pkt_fut = futures::lazy(move || { @@ -293,7 +291,5 @@ fn handle_r2l(l: SharedUdpSocket, r: SharedUdpSocket, svr_cfg: Arc })); Ok(()) - }); - - boxed_future(fut) + }) } diff --git a/src/relay/udprelay/local.rs b/src/relay/udprelay/local.rs index f843c665..d8172c09 100644 --- a/src/relay/udprelay/local.rs +++ b/src/relay/udprelay/local.rs @@ -11,7 +11,6 @@ use futures::{self, Future, Stream}; use tokio; use tokio::net::UdpSocket; use tokio::util::FutureExt; -use tokio_io::IoFuture; use config::{Config, ServerAddr, ServerConfig}; use relay::boxed_future; @@ -24,7 +23,9 @@ use super::MAXIMUM_UDP_PAYLOAD_SIZE; use super::{PacketStream, SendDgramRc}; /// Resolves server address to SocketAddr -fn resolve_server_addr(config: Arc, svr_cfg: Arc) -> IoFuture { +fn resolve_server_addr(config: Arc, + svr_cfg: Arc) + -> impl Future + Send { match *svr_cfg.addr() { // Return directly if it is a SocketAddr ServerAddr::SocketAddr(ref addr) => boxed_future(futures::finished(*addr)), @@ -39,11 +40,11 @@ fn resolve_server_addr(config: Arc, svr_cfg: Arc) -> IoFut } } -fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { +fn listen(config: Arc, l: UdpSocket) -> impl Future + Send { let socket = Arc::new(Mutex::new(l)); let mut balancer = RoundRobin::new(&*config); - let fut = PacketStream::new(socket.clone()).for_each(move |(pkt, src)| { + PacketStream::new(socket.clone()).for_each(move |(pkt, src)| { let svr_cfg = balancer.pick_server(); let svr_cfg_cloned = svr_cfg.clone(); let svr_cfg_cloned_cloned = svr_cfg.clone(); @@ -144,19 +145,16 @@ fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { })); Ok(()) - }); - boxed_future(fut) + }) } /// Starts a UDP local server -pub fn run(config: Arc) -> IoFuture<()> { +pub fn run(config: Arc) -> impl Future + Send { let local_addr = *config.local.as_ref().unwrap(); - let fut = futures::lazy(move || { - info!("ShadowSocks UDP Listening on {}", local_addr); + futures::lazy(move || { + info!("ShadowSocks UDP Listening on {}", local_addr); - UdpSocket::bind(&local_addr) - }).and_then(move |l| listen(config, l)); - - boxed_future(fut) + UdpSocket::bind(&local_addr) + }).and_then(move |l| listen(config, l)) } diff --git a/src/relay/udprelay/server.rs b/src/relay/udprelay/server.rs index 7d0a6508..16b12446 100644 --- a/src/relay/udprelay/server.rs +++ b/src/relay/udprelay/server.rs @@ -21,7 +21,7 @@ use super::crypto_io::{decrypt_payload, encrypt_payload}; use super::MAXIMUM_UDP_PAYLOAD_SIZE; use super::{PacketStream, SendDgramRc}; -fn resolve_remote_addr(config: Arc, addr: Address) -> IoFuture { +fn resolve_remote_addr(config: Arc, addr: Address) -> impl Future + Send { match addr { Address::SocketAddress(s) => { if config.forbidden_ip.contains(&s.ip()) { @@ -42,10 +42,10 @@ fn resolve_remote_addr(config: Arc, addr: Address) -> IoFuture, svr_cfg: Arc) -> IoFuture<()> { +fn listen(config: Arc, svr_cfg: Arc) -> impl Future + Send { let listen_addr = *svr_cfg.addr().listen_addr(); info!("ShadowSocks UDP listening on {}", listen_addr); - let fut = futures::lazy(move || UdpSocket::bind(&listen_addr)).and_then(move |socket| { + futures::lazy(move || UdpSocket::bind(&listen_addr)).and_then(move |socket| { let socket = Arc::new(Mutex::new(socket)); PacketStream::new(socket.clone()).for_each(move |(pkt, src)| { let svr_cfg = svr_cfg.clone(); @@ -127,20 +127,19 @@ fn listen(config: Arc, svr_cfg: Arc) -> IoFuture<()> { Ok(()) }) - }); - boxed_future(fut) + }) } /// Starts a UDP relay server -pub fn run(config: Arc) -> IoFuture<()> { - let mut fut = None; +pub fn run(config: Arc) -> impl Future + Send { + let mut fut: Option> = None; for svr in &config.server { let svr_cfg = Arc::new(svr.clone()); let svr_fut = listen(config.clone(), svr_cfg); fut = match fut { - None => Some(svr_fut), + None => Some(boxed_future(svr_fut)), Some(fut) => Some(boxed_future(fut.join(svr_fut).map(|_| ()))), }; }