From dc72c938137051f0b15246d41b79aef44abc660f Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Fri, 27 Apr 2018 22:16:40 +0800 Subject: [PATCH 01/22] Add #102 link in README --- Cargo.lock | 302 +++++++++++++++++++++++++++++++++++------------------ Cargo.toml | 1 + README.md | 2 + src/lib.rs | 1 + 4 files changed, 205 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2bed72b30a43..c187740b2b6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "aesni" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-cipher-trait 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -22,8 +22,11 @@ dependencies = [ [[package]] name = "ansi_term" -version = "0.10.2" +version = "0.11.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 = "arrayref" @@ -40,10 +43,10 @@ dependencies = [ [[package]] name = "atty" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -119,7 +122,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -127,13 +130,13 @@ name = "bzip2-sys" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -148,11 +151,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "clap" -version = "2.30.0" +version = "2.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "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)", @@ -165,7 +168,7 @@ name = "clear_on_drop" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -205,6 +208,15 @@ dependencies = [ "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-deque" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-epoch" version = "0.3.0" @@ -219,6 +231,19 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-epoch" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-utils" version = "0.2.2" @@ -264,13 +289,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "env_logger" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -280,7 +305,7 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -289,7 +314,7 @@ name = "flate2" version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -298,7 +323,7 @@ name = "flate2" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide_c_api 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -348,7 +373,7 @@ name = "generic-array" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -374,7 +399,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -409,7 +434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.37" +version = "0.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -417,9 +442,9 @@ name = "libsodium-ffi" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "unwrap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -462,7 +487,7 @@ name = "memchr" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -475,8 +500,8 @@ name = "miniz-sys" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -485,7 +510,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -493,15 +518,15 @@ name = "miniz_oxide_c_api" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "mio" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -509,11 +534,11 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -522,8 +547,8 @@ name = "mio-uds" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -542,7 +567,7 @@ name = "miscreant" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aesni 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "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.1 (registry+https://github.com/rust-lang/crates.io-index)", "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -570,7 +595,7 @@ version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -589,7 +614,7 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -605,7 +630,7 @@ dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -614,8 +639,8 @@ name = "openssl-sys" version = "0.9.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -658,13 +683,23 @@ name = "quick-error" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rand" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -684,7 +719,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (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.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -704,29 +739,32 @@ dependencies = [ [[package]] name = "regex" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.4.2" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "ring" version = "0.13.0-alpha" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (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.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (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)", ] @@ -738,7 +776,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "scoped-tls" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -748,18 +786,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.27" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_json" -version = "1.0.10" +version = "1.0.11" 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)", "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -769,7 +807,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.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -781,13 +819,13 @@ dependencies = [ "byte_string 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.30.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.18 (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.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "libsodium-ffi 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "md-5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -796,23 +834,19 @@ dependencies = [ "qrcode 0.5.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)", - "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.11 (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)", - "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-signal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.15 (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.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", ] -[[package]] -name = "slab" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "slab" version = "0.4.0" @@ -830,7 +864,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam 0.2.12 (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.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -845,7 +879,7 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -863,7 +897,7 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -890,29 +924,57 @@ name = "time" version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.0 (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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-core" -version = "0.1.12" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.0 (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.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-executor" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-io" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -920,23 +982,54 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-reactor" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.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.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-threadpool" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "typenum" -version = "1.9.0" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ucd-util" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1056,7 +1149,7 @@ name = "xattr" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1073,12 +1166,12 @@ dependencies = [ [metadata] "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" -"checksum aesni 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7ba47de7c13f758a674d0685118346945e8bb0e2e906da6e36e403788a73662" +"checksum aesni 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e88c3698cd61460af7bdbcc747d0e37b61255492fcfc81845dd4666f3bf6714" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" -"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "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.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859" +"checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4" "checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" @@ -1091,24 +1184,26 @@ dependencies = [ "checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" "checksum bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3eafc42c44e0d827de6b1c131175098fe7fb53b8ce8a47e65cb3ea94688be24" "checksum bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2c5162604199bbb17690ede847eaa6120a3f33d5ab4dcc8e7c25b16d849ae79b" -"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" +"checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum checked_int_cast 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919" -"checksum clap 2.30.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1c07b9257a00f3fc93b7f3c417fc15607ec7a56823bc2c37ec744e266387de5b" +"checksum clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc18f6f4005132120d9711636b32c46a233fad94df6217fa1d81c5e97a9f200" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "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 crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7" "checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" +"checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2" "checksum crossbeam-epoch 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59796cc6cbbdc6bb319161349db0c3250ec73ec7fcb763a51065ec4e2e158552" +"checksum crossbeam-epoch 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2066d2bac93369853e53064ae60d7eab9e8edba77be4ad81bc7628be30aa7960" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crypto-mac 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "99376574a55849855052aa6e3b15f3bdebf8bcdd3b24f3cbc3371469bcd5b480" "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 dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" -"checksum env_logger 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f3cc21490995c841d68e00276eba02071ebb269ec24011d5728bd00eabd39e31" +"checksum env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0628f04f7c26ebccf40d7fc2c1cf92236c05ec88cf2132641cc956812312f0f" "checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f" "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" @@ -1127,7 +1222,7 @@ dependencies = [ "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.37 (registry+https://github.com/rust-lang/crates.io-index)" = "56aebce561378d99a0bb578f8cb15b6114d2a1814a6c7949bbe646d968bb4fa9" +"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff" "checksum libsodium-ffi 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "12aaa02009e30a59f4e1adab39dca446ea668efed9cb28128639fea07823791d" "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" @@ -1138,7 +1233,7 @@ dependencies = [ "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" "checksum miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aaa2d3ad070f428fffbd7d3ca2ea20bb0d8cffe9024405c44e1840bc1418b398" "checksum miniz_oxide_c_api 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "92d98fdbd6145645828069b37ea92ca3de225e000d80702da25c20d3584b38a5" -"checksum mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7da01a5e23070d92d99b1ecd1cd0af36447c6fd44b0fe283c2db199fa136724f" +"checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe" "checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miscreant 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "345b52b06ce7a0e2fab0a0ea99ef52e81d63102ba0425b2914f1867b9d820628" @@ -1156,21 +1251,21 @@ dependencies = [ "checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" "checksum qrcode 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2859df7fe4bc44b30accf2b6e44e5083a2e9874bbb346df3eb3662b00d457dd3" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" +"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "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-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 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "5be5347bde0c48cfd8c3fdc0766cdfe9d8a755ef84d620d6794c778c91de8b2b" -"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" +"checksum regex 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0a33e44e4f5dbeb5619910f68b874d85b01e15f86fa7bb0fbc41bbd148883a48" +"checksum regex-syntax 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d8337992c33b62cf49462a1ce4d0eedbb021f48de017e40ec307cca445df0ca9" "checksum ring 0.13.0-alpha (registry+https://github.com/rust-lang/crates.io-index)" = "946e5e2b336032275e23152755ec2a0610ede0302101d3666fdb686795d26535" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" +"checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" -"checksum serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57781ed845b8e742fc2bf306aba8e3b408fe8c366b900e3769fbc39f49eb8b39" +"checksum serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4763b773978e495252615e814d2ad04773b2c1f85421c7913869a537f35cb406" +"checksum serde_json 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fab6c4d75bedcf880711c85e39ebf8ccc70d0eba259899047ec5d7436643ee17" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" -"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" "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" @@ -1181,10 +1276,15 @@ dependencies = [ "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 tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "52b4e32d8edbf29501aabb3570f027c6ceb00ccef6538f4bddba0200503e74e8" -"checksum tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9532748772222bf70297ec0e2ad0f17213b4a7dd0e6afb68e0a0768f69f4e4f" -"checksum tokio-signal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4ef9836ecceb2583e0ddf25b7ca448fac74c1115461436f85e088a8e39e7904" -"checksum typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a99dc6780ef33c78780b826cf9d2a78840b72cae9474de4bcaf9051e60ebbd" +"checksum tokio 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "490c5ff233997a62649c0a7b523b25a1cc6fab1389b3faed0d72e8bdcef7b0ad" +"checksum tokio-core 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "b630092b9a89f5c4eedfe9d022a0c16fb111ed2403a38f985bd1ca68b6b762d3" +"checksum tokio-executor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46108c2aca0eb4b9a883bf37a28d122ca70f5318446f59f729cd1ff78a0bb5fb" +"checksum tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af9eb326f64b2d6b68438e1953341e00ab3cf54de7e35d92bfc73af8555313a" +"checksum tokio-reactor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f21d00eb356854d502b81776cec931d12771e4ed6d198478d23ffd38c19279af" +"checksum tokio-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f46863230f9a05cf52d173721ec391b9c5782a2465f593029922b8782b9ffe" +"checksum tokio-threadpool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "19a8656c45ae7893c9090ac5c98749e7ff904932973fabd541463f82628efacb" +"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" +"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" diff --git a/Cargo.toml b/Cargo.toml index 2f8971a408b2..8ce4b535f2b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ libc = "0.2" futures = "0.1" tokio-core = "0.1" tokio-io = "0.1" +tokio = "0.1" lazy_static = "1.0" serde_json = "1.0" base64 = "0.9" diff --git a/README.md b/README.md index 2ec5c83b7511..85cd7983e113 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ make install TARGET=release Then `sslocal`, `ssserver` and `ssurl` will be installed in `/usr/local/bin` (variable PREFIX). +For Windows users, if you have encountered any problem in building, check and discuss in [#102](https://github.com/shadowsocks/shadowsocks-rust/issues/102). + ### **Build standalone binaries** Requirements: diff --git a/src/lib.rs b/src/lib.rs index 7d290cec4280..619807d6ae91 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -99,6 +99,7 @@ extern crate subprocess; extern crate tokio_core; #[macro_use] extern crate tokio_io; +extern crate tokio; #[cfg(any(unix, windows))] extern crate tokio_signal; extern crate typenum; From fabcb057834bfa0d19869d901dc21caf79e59efe Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Tue, 1 May 2018 05:14:25 +0800 Subject: [PATCH 02/22] Migrating to tokio, #100 --- Cargo.lock | 404 ++++++++++--------- Cargo.toml | 2 - src/bin/local.rs | 2 +- src/bin/server.rs | 2 +- src/lib.rs | 9 +- src/monitor.rs | 1 + src/relay/dns_resolver.rs | 35 +- src/relay/loadbalancing/server/mod.rs | 4 +- src/relay/loadbalancing/server/roundrobin.rs | 8 +- src/relay/local.rs | 50 ++- src/relay/mod.rs | 59 +-- src/relay/server.rs | 61 ++- src/relay/socks5.rs | 14 +- src/relay/tcprelay/client.rs | 19 +- src/relay/tcprelay/crypto_io.rs | 14 +- src/relay/tcprelay/local.rs | 10 +- src/relay/tcprelay/mod.rs | 159 ++++---- src/relay/tcprelay/server.rs | 160 ++++---- src/relay/tcprelay/socks5_local.rs | 164 ++++---- src/relay/tcprelay/utils.rs | 14 +- src/relay/udprelay/local.rs | 161 ++++---- src/relay/udprelay/mod.rs | 20 +- src/relay/udprelay/server.rs | 83 ++-- tests/socks5.rs | 24 +- tests/udp.rs | 14 +- 25 files changed, 728 insertions(+), 765 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c187740b2b6c..5d80f10cdc21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,20 +43,20 @@ dependencies = [ [[package]] name = "atty" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "base64" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -67,7 +67,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -89,7 +89,7 @@ dependencies = [ [[package]] name = "build_const" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -104,7 +104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -112,7 +112,7 @@ name = "bytes" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -122,7 +122,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -130,13 +130,13 @@ name = "bzip2-sys" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" -version = "1.0.6" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -151,12 +151,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "clap" -version = "2.31.1" +version = "2.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "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)", @@ -168,7 +168,7 @@ name = "clear_on_drop" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -188,10 +188,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crc" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -204,7 +204,7 @@ name = "crossbeam-deque" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -213,19 +213,19 @@ name = "crossbeam-deque" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -233,13 +233,13 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -252,6 +252,14 @@ dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-utils" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crypto-mac" version = "0.6.0" @@ -284,28 +292,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "either" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "env_logger" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "filetime" -version = "0.1.15" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -314,7 +322,7 @@ name = "flate2" version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -323,7 +331,7 @@ name = "flate2" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide_c_api 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -345,7 +353,7 @@ name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -356,7 +364,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures" -version = "0.1.18" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -364,7 +372,7 @@ name = "futures-cpupool" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", ] @@ -399,7 +407,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -408,6 +416,11 @@ name = "itoa" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "itoa" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -417,11 +430,6 @@ 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" @@ -434,7 +442,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.39" +version = "0.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -442,23 +450,15 @@ name = "libsodium-ffi" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tar 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", "unwrap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "zip 0.2.8 (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" @@ -487,7 +487,7 @@ name = "memchr" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -500,8 +500,8 @@ name = "miniz-sys" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -510,7 +510,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -518,9 +518,9 @@ name = "miniz_oxide_c_api" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -534,7 +534,7 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", @@ -547,7 +547,7 @@ name = "mio-uds" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -569,7 +569,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.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.2 (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)", @@ -581,12 +581,11 @@ dependencies = [ [[package]] name = "msdos_time" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -595,7 +594,7 @@ version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (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)", ] @@ -604,17 +603,12 @@ name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "num-traits" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -630,19 +624,19 @@ dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.27" +version = "0.9.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -652,7 +646,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pkg-config" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -683,23 +677,13 @@ name = "quick-error" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "rand" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (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)", ] @@ -708,7 +692,7 @@ name = "rayon" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", ] @@ -719,7 +703,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (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.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -739,19 +723,19 @@ dependencies = [ [[package]] name = "regex" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.5.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -762,9 +746,9 @@ name = "ring" version = "0.13.0-alpha" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.12 (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.39 (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)", ] @@ -786,18 +770,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.29" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_json" -version = "1.0.11" +version = "1.0.16" 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)", - "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (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.43 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -807,7 +790,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.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -815,17 +798,17 @@ dependencies = [ name = "shadowsocks-rust" version = "1.6.12" dependencies = [ - "base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.31.1 (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)", - "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.9 (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.39 (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)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "md-5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -834,13 +817,11 @@ dependencies = [ "qrcode 0.5.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)", - "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.16 (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)", - "tokio 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.5 (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.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -864,7 +845,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam 0.2.12 (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.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -875,18 +856,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "tar" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "xattr 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "termcolor" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -897,7 +878,7 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -924,52 +905,51 @@ name = "time" version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.0 (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.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.0 (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-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-core" -version = "0.1.15" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-executor" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -978,20 +958,20 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-reactor" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.0 (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)", ] @@ -1000,26 +980,61 @@ name = "tokio-signal" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "tokio-threadpool" +name = "tokio-tcp" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (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)", +] + +[[package]] +name = "tokio-threadpool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-timer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-udp" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (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)", ] [[package]] @@ -1085,7 +1100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "vcpkg" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1146,10 +1161,10 @@ dependencies = [ [[package]] name = "xattr" -version = "0.1.11" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1159,7 +1174,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "msdos_time 0.1.5 (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)", ] @@ -1171,60 +1186,60 @@ dependencies = [ "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "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.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4" -"checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" +"checksum atty 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6609a866dd1a1b2d0ee1362195bf3e4f6438abb2d80120b83b1e1f4fb6476dd0" +"checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" +"checksum bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1b2bf7093258c32e0825b635948de528a5949799dcd61bef39534c8aab95870c" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" "checksum block-cipher-trait 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6136d803280ae3532efa36114335255ea94f3d75d735ddedd66b0d7cd30bad3" -"checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9" +"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" +"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" "checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" "checksum bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3eafc42c44e0d827de6b1c131175098fe7fb53b8ce8a47e65cb3ea94688be24" "checksum bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2c5162604199bbb17690ede847eaa6120a3f33d5ab4dcc8e7c25b16d849ae79b" -"checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" +"checksum cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b90658a0d04c19acb58f07c9076948d3a716db1039674430c94e4aec88de20" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum checked_int_cast 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919" -"checksum clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc18f6f4005132120d9711636b32c46a233fad94df6217fa1d81c5e97a9f200" +"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "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 crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7" +"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2" -"checksum crossbeam-epoch 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59796cc6cbbdc6bb319161349db0c3250ec73ec7fcb763a51065ec4e2e158552" -"checksum crossbeam-epoch 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2066d2bac93369853e53064ae60d7eab9e8edba77be4ad81bc7628be30aa7960" +"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" +"checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81" "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 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 dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" -"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" -"checksum env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0628f04f7c26ebccf40d7fc2c1cf92236c05ec88cf2132641cc956812312f0f" -"checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f" +"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" +"checksum env_logger 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "00c45cec4cde3daac5f036c74098b4956151525cdf360cff5ee0092c98823e54" +"checksum filetime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08530a39af0bd442c40aabb9e854f442a83bd2403feb1ed58fbe982dec2385f3" "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" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0bab5b5e94f5c31fc764ba5dd9ad16568aae5d4825538c01d6bca680c9bf94a7" +"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 generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "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 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.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff" +"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 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 matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum md-5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9402eaae33a9e144ce18ef488a0e4ca19869673c7bcdbbfe2030fdc3f84211cd" @@ -1237,52 +1252,53 @@ dependencies = [ "checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miscreant 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "345b52b06ce7a0e2fab0a0ea99ef52e81d63102ba0425b2914f1867b9d820628" -"checksum msdos_time 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65ba9d75bcea84e07812618fedf284a64776c2f2ea0cad6bca7f69739695a958" +"checksum msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729" "checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3c2bd9b9d21e48e956b763c9f37134dc62d9e95da6edb3f672cacb6caf3cd3" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7" "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" -"checksum openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdc5c4a02e69ce65046f1763a0181107038e02176233acb0b3351d7cc588f9" +"checksum openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)" = "0bbd90640b148b46305c1691eed6039b5c8509bed16991e3562a01eeb76902a3" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" +"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" "checksum pmac 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a82cc12454dc99354a9342c237149aec041ef16f618066d0a682df256b97714" "checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" "checksum qrcode 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2859df7fe4bc44b30accf2b6e44e5083a2e9874bbb346df3eb3662b00d457dd3" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" -"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "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-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 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0a33e44e4f5dbeb5619910f68b874d85b01e15f86fa7bb0fbc41bbd148883a48" -"checksum regex-syntax 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d8337992c33b62cf49462a1ce4d0eedbb021f48de017e40ec307cca445df0ca9" +"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb" +"checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb" "checksum ring 0.13.0-alpha (registry+https://github.com/rust-lang/crates.io-index)" = "946e5e2b336032275e23152755ec2a0610ede0302101d3666fdb686795d26535" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4763b773978e495252615e814d2ad04773b2c1f85421c7913869a537f35cb406" -"checksum serde_json 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fab6c4d75bedcf880711c85e39ebf8ccc70d0eba259899047ec5d7436643ee17" +"checksum serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)" = "0c855d888276f20d140223bd06515e5bf1647fd6d02593cb5792466d9a8ec2d0" +"checksum serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6c4e049dc657a99e394bd85c22acbf97356feeec6dbf44150f2dcf79fb3118" "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 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" -"checksum tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1605d3388ceb50252952ffebab4b5dc43017ead7e4481b175961c283bb951195" -"checksum termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "56c456352e44f9f91f774ddeeed27c1ec60a2455ed66d692059acfb1d731bda1" +"checksum tar 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "6af6b94659f9a571bf769a5b71f54079393585ee0bfdd71b691be22d7d6b1d18" +"checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" "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 tokio 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "490c5ff233997a62649c0a7b523b25a1cc6fab1389b3faed0d72e8bdcef7b0ad" -"checksum tokio-core 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "b630092b9a89f5c4eedfe9d022a0c16fb111ed2403a38f985bd1ca68b6b762d3" -"checksum tokio-executor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46108c2aca0eb4b9a883bf37a28d122ca70f5318446f59f729cd1ff78a0bb5fb" +"checksum tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be15ef40f675c9fe66e354d74c73f3ed012ca1aa14d65846a33ee48f1ae8d922" +"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" +"checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" "checksum tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af9eb326f64b2d6b68438e1953341e00ab3cf54de7e35d92bfc73af8555313a" -"checksum tokio-reactor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f21d00eb356854d502b81776cec931d12771e4ed6d198478d23ffd38c19279af" +"checksum tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3cedc8e5af5131dc3423ffa4f877cce78ad25259a9a62de0613735a13ebc64b" "checksum tokio-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f46863230f9a05cf52d173721ec391b9c5782a2465f593029922b8782b9ffe" -"checksum tokio-threadpool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "19a8656c45ae7893c9090ac5c98749e7ff904932973fabd541463f82628efacb" +"checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f" +"checksum tokio-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3d05cdd6a78005e535d2b27c21521bdf91fbb321027a62d8e178929d18966d" +"checksum tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "29a89e4ad0c8f1e4c9860e605c38c69bfdad3cccd4ea446e58ff588c1c07a397" +"checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" @@ -1293,7 +1309,7 @@ dependencies = [ "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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" +"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 void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" @@ -1303,5 +1319,5 @@ dependencies = [ "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 ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5f04de8a1346489a2f9e9bd8526b73d135ec554227b17568456e86aa35b6f3fc" +"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 8ce4b535f2b1..10ff8963e649 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,14 +40,12 @@ env_logger = "0.5.0-rc.1" openssl = "0.9" libc = "0.2" futures = "0.1" -tokio-core = "0.1" tokio-io = "0.1" tokio = "0.1" lazy_static = "1.0" serde_json = "1.0" base64 = "0.9" bytes = "0.4" -scoped-tls = "0.1" ring = "0.13.0-alpha" md-5 = "0.7" digest = "0.7" diff --git a/src/bin/local.rs b/src/bin/local.rs index f7802cba40f5..1b8dc2bff26c 100644 --- a/src/bin/local.rs +++ b/src/bin/local.rs @@ -232,5 +232,5 @@ fn main() { debug!("Config: {:?}", config); - run_local(config).unwrap(); + run_local(config); } diff --git a/src/bin/server.rs b/src/bin/server.rs index dbf7054c4731..ba20463475cd 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -194,5 +194,5 @@ fn main() { debug!("Config: {:?}", config); - run_server(config).unwrap(); + run_server(config); } diff --git a/src/lib.rs b/src/lib.rs index 619807d6ae91..2ea64dc6005b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,7 +54,7 @@ //! use shadowsocks::{run_local, Config, ConfigType}; //! //! let config = Config::load_from_file("shadowsocks.json", ConfigType::Local).unwrap(); -//! run_local(config).unwrap(); +//! run_local(config); //! ``` //! //! That's all! And let me show you how to run a proxy server @@ -63,7 +63,7 @@ //! use shadowsocks::{run_server, Config, ConfigType}; //! //! let config = Config::load_from_file("shadowsocks.json", ConfigType::Server).unwrap(); -//! run_server(config).unwrap(); +//! run_server(config); //! ``` //! @@ -91,12 +91,9 @@ extern crate miscreant; extern crate openssl; extern crate rand; extern crate ring; -#[macro_use] -extern crate scoped_tls; extern crate serde_json; extern crate serde_urlencoded; extern crate subprocess; -extern crate tokio_core; #[macro_use] extern crate tokio_io; extern crate tokio; @@ -117,4 +114,4 @@ pub mod config; pub mod relay; pub mod crypto; pub mod plugin; -mod monitor; +// mod monitor; diff --git a/src/monitor.rs b/src/monitor.rs index dfb0b816baf5..2b59ac2be680 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -5,6 +5,7 @@ use std::process; use libc; use tokio_core::reactor::Handle; +use tokio; use futures::{self, Future, Stream}; diff --git a/src/relay/dns_resolver.rs b/src/relay/dns_resolver.rs index d294492cd5c8..4e4b571f5763 100644 --- a/src/relay/dns_resolver.rs +++ b/src/relay/dns_resolver.rs @@ -2,37 +2,40 @@ use std::io::{self, ErrorKind}; use std::net::{IpAddr, SocketAddr, ToSocketAddrs}; +use std::sync::Arc; use futures::{future, Future}; use futures_cpupool::CpuPool; -use relay::{boxed_future, BoxIoFuture}; -use relay::Context; +use tokio_io::IoFuture; + +use relay::boxed_future; +use config::Config; lazy_static! { static ref GLOBAL_DNS_CPU_POOL: CpuPool = CpuPool::new_num_cpus(); } -pub fn resolve(addr: &str, port: u16, check_forbidden: bool) -> BoxIoFuture> { +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)])); } - let result = Context::with(move |ctx| { - let forbidden_ip = &ctx.forbidden_ip(); + let result = { + let forbidden_ip = &config.forbidden_ip; - 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)]) - } - }); + 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)]) + } + }; return boxed_future(future::done(result)); } @@ -51,8 +54,7 @@ pub fn resolve(addr: &str, port: u16, check_forbidden: bool) -> BoxIoFuture>() } else { - Context::with(move |ctx| { - let forbidden_ip = ctx.forbidden_ip(); + let forbidden_ip = &config.forbidden_ip; addr_iter.filter(|addr| { let filtered = forbidden_ip.contains(&addr.ip()); if filtered { @@ -61,7 +63,6 @@ pub fn resolve(addr: &str, port: u16, check_forbidden: bool) -> BoxIoFuture>() - }) }; if v.is_empty() { diff --git a/src/relay/loadbalancing/server/mod.rs b/src/relay/loadbalancing/server/mod.rs index 3c925615aa81..872dde4d219f 100644 --- a/src/relay/loadbalancing/server/mod.rs +++ b/src/relay/loadbalancing/server/mod.rs @@ -1,6 +1,6 @@ //! Load balancer for picking servers -use std::rc::Rc; +use std::sync::Arc; pub use self::roundrobin::RoundRobin; @@ -9,6 +9,6 @@ use config::ServerConfig; pub mod roundrobin; pub trait LoadBalancer { - fn pick_server(&mut self) -> Rc; + fn pick_server(&mut self) -> Arc; fn total(&self) -> usize; } diff --git a/src/relay/loadbalancing/server/roundrobin.rs b/src/relay/loadbalancing/server/roundrobin.rs index 9a79b680e476..e55c3fc2b744 100644 --- a/src/relay/loadbalancing/server/roundrobin.rs +++ b/src/relay/loadbalancing/server/roundrobin.rs @@ -1,25 +1,25 @@ //! Load balancer using round robin strategy -use std::rc::Rc; +use std::sync::Arc; use config::{Config, ServerConfig}; use relay::loadbalancing::server::LoadBalancer; #[derive(Clone)] pub struct RoundRobin { - servers: Vec>, + servers: Vec>, index: usize, } impl RoundRobin { pub fn new(config: &Config) -> RoundRobin { - RoundRobin { servers: config.server.iter().map(|s| Rc::new(s.clone())).collect(), + RoundRobin { servers: config.server.iter().map(|s| Arc::new(s.clone())).collect(), index: 0usize, } } } impl LoadBalancer for RoundRobin { - fn pick_server(&mut self) -> Rc { + fn pick_server(&mut self) -> Arc { let server = &self.servers; if server.is_empty() { diff --git a/src/relay/local.rs b/src/relay/local.rs index 98a5f18b8874..fe484bc18157 100644 --- a/src/relay/local.rs +++ b/src/relay/local.rs @@ -1,14 +1,13 @@ //! Local side -use std::io; +use std::sync::Arc; -use tokio_core::reactor::Core; +use tokio; use futures::Future; use config::Config; use plugin::{launch_plugin, PluginMode}; -use relay::Context; use relay::tcprelay::local::run as run_tcp; use relay::udprelay::local::run as run_udp; @@ -24,27 +23,34 @@ use relay::udprelay::local::run as run_udp; /// config.server = vec![ServerConfig::basic("127.0.0.1:8388".parse().unwrap(), /// "server-password".to_string(), /// CipherType::Aes256Cfb)]; -/// run(config).unwrap(); +/// run(config); /// ``` -pub fn run(mut config: Config) -> io::Result<()> { - let mut lp = Core::new()?; - let handle = lp.handle(); +pub fn run(mut config: Config) { + // Hold it here, kill all plugins when Core is finished + let plugins = launch_plugin(&mut config, PluginMode::Client) + .expect("Failed to launch plugins"); + // ::monitor::monitor_signal(&handle, plugins); + + let config = Arc::new(config); let enable_udp = config.enable_udp; - // Hold it here, kill all plugins when Core is finished - let plugins = launch_plugin(&mut config, PluginMode::Client)?; - ::monitor::monitor_signal(&handle, plugins); - - let context = Context::new(handle, config); - Context::set(&context, move || { - if enable_udp { - let tcp_fut = run_tcp(); - let udp_fut = run_udp(); - lp.run(tcp_fut.join(udp_fut).map(|_| ())) - } else { - let tcp_fut = run_tcp(); - lp.run(tcp_fut) - } - }) + if enable_udp { + let tcp_fut = run_tcp(config.clone()); + let udp_fut = run_udp(config); + tokio::run(tcp_fut.join(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(tcp_fut.then(|res| { + match res { + Ok(..) => Ok(()), + Err(err) => panic!("Failed to run server, err: {}", err), + } + })) + } } diff --git a/src/relay/mod.rs b/src/relay/mod.rs index 8fd5c69de9a1..3fa6d835a4b1 100644 --- a/src/relay/mod.rs +++ b/src/relay/mod.rs @@ -1,12 +1,6 @@ //! Relay server in local and server side implementations. -use std::collections::HashSet; -use std::io; -use std::net::IpAddr; - -use config::Config; use futures::Future; -use tokio_core::reactor::Handle; pub mod tcprelay; pub mod udprelay; @@ -17,57 +11,8 @@ mod dns_resolver; pub mod socks5; mod utils; -/// Alias for Boxed Future without Send -pub type BoxIoFuture = Box>; - -fn boxed_future(f: F) -> Box> - where F: Future + 'static +fn boxed_future(f: F) -> Box + Send + 'static> + where F: Future + Send + 'static { Box::new(f) } - -scoped_thread_local!(static CONTEXT: Context); - -/// Local server running context -pub struct Context { - handle: Handle, - config: Config, -} - -impl Context { - #[doc(hidden)] - /// Creates a new Context - pub fn new(handle: Handle, config: Config) -> Context { - Context { handle: handle, - config: config, } - } - - /// Get the value in this context - pub fn with(f: F) -> R - where F: FnOnce(&Context) -> R - { - CONTEXT.with(f) - } - - #[doc(hidden)] - pub fn set(ctx: &Context, f: F) -> R - where F: FnOnce() -> R - { - CONTEXT.set(ctx, f) - } - - /// Get Core handle - pub fn handle(&self) -> &Handle { - &self.handle - } - - /// Get config - pub fn config(&self) -> &Config { - &self.config - } - - /// Get forbidden IPs - pub fn forbidden_ip(&self) -> &HashSet { - &self.config.forbidden_ip - } -} diff --git a/src/relay/server.rs b/src/relay/server.rs index ad62fded975a..18c15494e89a 100644 --- a/src/relay/server.rs +++ b/src/relay/server.rs @@ -1,14 +1,13 @@ //! Server side -use std::io; +use std::sync::Arc; -use tokio_core::reactor::Core; +use tokio; use futures::Future; use config::Config; use plugin::{launch_plugin, PluginMode}; -use relay::Context; use relay::tcprelay::server::run as run_tcp; use relay::udprelay::server::run as run_udp; @@ -23,38 +22,34 @@ use relay::udprelay::server::run as run_udp; /// config.server = vec![ServerConfig::basic("127.0.0.1:8388".parse().unwrap(), /// "server-password".to_string(), /// CipherType::Aes256Cfb)]; -/// run(config).unwrap(); +/// run(config); /// ``` /// -pub fn run(mut config: Config) -> io::Result<()> { - let mut lp = Core::new()?; - let handle = lp.handle(); - - // let config = Rc::new(config); - - // let tcp_fut = run_tcp(config.clone(), handle.clone()); - - // if config.enable_udp { - // lp.run(tcp_fut.join(run_udp(config, handle)).map(|_| ())) - // } else { - // lp.run(tcp_fut) - // } - - let enable_udp = config.enable_udp; - +pub fn run(mut config: Config) { // Hold it here, kill all plugins when Core is finished - let plugins = launch_plugin(&mut config, PluginMode::Server)?; - ::monitor::monitor_signal(&handle, plugins); + let plugins = launch_plugin(&mut config, PluginMode::Server) + .expect("Failed to launch plugins"); + // ::monitor::monitor_signal(&handle, plugins); - let context = Context::new(handle, config); - Context::set(&context, move || { - if enable_udp { - let tcp_fut = run_tcp(); - let udp_fut = run_udp(); - lp.run(tcp_fut.join(udp_fut).map(|_| ())) - } else { - let tcp_fut = run_tcp(); - lp.run(tcp_fut) - } - }) + let config = Arc::new(config); + let enable_udp = config.enable_udp; + + if enable_udp { + let tcp_fut = run_tcp(config.clone()); + let udp_fut = run_udp(config); + tokio::run(tcp_fut.join(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(tcp_fut.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 c603c93c4e39..cb7b9ca355d2 100644 --- a/src/relay/socks5.rs +++ b/src/relay/socks5.rs @@ -15,11 +15,9 @@ use bytes::{BufMut, Bytes, BytesMut, IntoBuf}; use futures::{Async, Future, Poll}; -use tokio_io::{AsyncRead, AsyncWrite}; +use tokio_io::{IoFuture, AsyncRead, AsyncWrite}; use tokio_io::io::read_exact; -use relay::BoxIoFuture; - pub use self::consts::{SOCKS5_AUTH_METHOD_GSSAPI, SOCKS5_AUTH_METHOD_NONE, SOCKS5_AUTH_METHOD_NOT_ACCEPTABLE, SOCKS5_AUTH_METHOD_PASSWORD}; @@ -551,7 +549,7 @@ impl TcpRequestHeader { } /// Read from a reader - pub fn read_from(r: R) -> Box> { + 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]; @@ -631,7 +629,7 @@ impl TcpResponseHeader { } /// Read from a reader - pub fn read_from(r: R) -> Box> { + 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]; @@ -700,7 +698,7 @@ impl HandshakeRequest { } /// Read from a reader - pub fn read_from(r: R) -> BoxIoFuture<(R, HandshakeRequest)> { + 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]; @@ -760,7 +758,7 @@ impl HandshakeResponse { } /// Read from a reader - pub fn read_from(r: R) -> BoxIoFuture<(R, HandshakeResponse)> { + 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]; @@ -820,7 +818,7 @@ impl UdpAssociateHeader { } /// Read from a reader - pub fn read_from(r: R) -> Box> { + 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 frag = buf[2]; diff --git a/src/relay/tcprelay/client.rs b/src/relay/tcprelay/client.rs index a71f1623d326..ef6802408733 100644 --- a/src/relay/tcprelay/client.rs +++ b/src/relay/tcprelay/client.rs @@ -3,14 +3,13 @@ use std::io::{self, Read, Write}; use std::net::SocketAddr; -use tokio_core::net::TcpStream; -use tokio_core::reactor::Handle; -use tokio_io::{AsyncRead, AsyncWrite}; +use tokio::net::TcpStream; +use tokio_io::{IoFuture, AsyncRead, AsyncWrite}; use tokio_io::io::flush; use futures::{self, Async, Future, Poll}; -use relay::{boxed_future, BoxIoFuture}; +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, handle: Handle) -> BoxIoFuture + pub fn connect(addr: A, proxy: SocketAddr) -> IoFuture where Address: From, - A: 'static + A: Send + 'static { - let fut = futures::lazy(move || TcpStream::connect(&proxy, &handle)) + let fut = futures::lazy(move || TcpStream::connect(&proxy)) .and_then(move |s| { // 1. Handshake let hs = HandshakeRequest::new(vec![socks5::SOCKS5_AUTH_METHOD_NONE]); @@ -64,11 +63,11 @@ impl Socks5Client { } /// UDP Associate `addr` via `proxy` - pub fn udp_associate(addr: A, proxy: SocketAddr, handle: Handle) -> BoxIoFuture<(Socks5Client, Address)> + pub fn udp_associate(addr: A, proxy: SocketAddr) -> IoFuture<(Socks5Client, Address)> where Address: From, - A: 'static + A: Send + 'static { - let fut = futures::lazy(move || TcpStream::connect(&proxy, &handle)) + let fut = futures::lazy(move || TcpStream::connect(&proxy)) .and_then(move |s| { // 1. Handshake let hs = HandshakeRequest::new(vec![socks5::SOCKS5_AUTH_METHOD_NONE]); diff --git a/src/relay/tcprelay/crypto_io.rs b/src/relay/tcprelay/crypto_io.rs index 2e2123e62237..6393541770d3 100644 --- a/src/relay/tcprelay/crypto_io.rs +++ b/src/relay/tcprelay/crypto_io.rs @@ -2,21 +2,19 @@ use std::io::{self, BufRead, Read}; use std::mem; -use std::time::Duration; +use std::time::{Instant, Duration}; use futures::{Async, Future, Poll}; -use tokio_core::reactor::Timeout; use tokio_io::{AsyncRead, AsyncWrite}; use tokio_io::io::{copy, Copy}; +use tokio::timer::Delay; use bytes::{BufMut, BytesMut}; use super::BUFFER_SIZE; use super::utils::{copy_timeout, copy_timeout_opt, CopyTimeout, CopyTimeoutOpt}; -use relay::Context; - static DUMMY_BUFFER: [u8; BUFFER_SIZE] = [0u8; BUFFER_SIZE]; /// Reader to read data from ShadowSocks protocol @@ -261,7 +259,7 @@ pub struct EncryptedCopyTimeout pos: usize, cap: usize, timeout: Duration, - timer: Option, + timer: Option, read_buf: [u8; BUFFER_SIZE], write_buf: BytesMut, } @@ -288,7 +286,7 @@ impl EncryptedCopyTimeout match self.timer.as_mut() { None => Ok(()), Some(t) => match t.poll() { - Err(err) => Err(err), + Err(err) => panic!("Failed to poll on timer, err: {}", err), Ok(Async::Ready(..)) => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")), Ok(Async::NotReady) => Ok(()), }, @@ -328,7 +326,7 @@ impl EncryptedCopyTimeout } Err(e) => { if e.kind() == io::ErrorKind::WouldBlock { - Context::with(|ctx| self.timer = Some(Timeout::new(self.timeout, ctx.handle()).unwrap())); + self.timer = Some(Delay::new(Instant::now() + self.timeout)); } Err(e) } @@ -352,7 +350,7 @@ impl EncryptedCopyTimeout } Err(e) => { if e.kind() == io::ErrorKind::WouldBlock { - self.timer = Context::with(|ctx| Some(Timeout::new(self.timeout, ctx.handle()).unwrap())); + self.timer = Some(Delay::new(Instant::now() + self.timeout)); } Err(e) } diff --git a/src/relay/tcprelay/local.rs b/src/relay/tcprelay/local.rs index fc559aadfa31..6dbae4e80385 100644 --- a/src/relay/tcprelay/local.rs +++ b/src/relay/tcprelay/local.rs @@ -1,9 +1,13 @@ //! Relay for TCP server that running on local environment +use std::sync::Arc; + +use tokio_io::IoFuture; + use super::socks5_local; -use relay::BoxIoFuture; +use config::Config; /// Starts a TCP local server -pub fn run() -> BoxIoFuture<()> { - socks5_local::run() +pub fn run(config: Arc) -> IoFuture<()> { + socks5_local::run(config) } diff --git a/src/relay/tcprelay/mod.rs b/src/relay/tcprelay/mod.rs index 04a896eb1c90..35cb2d06c65f 100644 --- a/src/relay/tcprelay/mod.rs +++ b/src/relay/tcprelay/mod.rs @@ -4,19 +4,17 @@ use std::io::{self, BufRead, Read}; use std::iter::{IntoIterator, Iterator}; use std::mem; use std::net::SocketAddr; -use std::rc::Rc; -use std::time::Duration; +use std::sync::Arc; +use std::time::{Instant, Duration}; -use config::{ServerAddr, ServerConfig}; +use config::{ServerAddr, Config, ServerConfig}; use crypto::CipherCategory; -use relay::{boxed_future, BoxIoFuture}; -use relay::Context; +use relay::{boxed_future}; use relay::dns_resolver::resolve; use relay::socks5::Address; -use tokio_core::net::{TcpStream, TcpStreamNew}; -use tokio_core::reactor::{Handle, Timeout}; -use tokio_io::AsyncRead; +use tokio::net::{TcpStream, ConnectFuture}; +use tokio_io::{IoFuture, AsyncRead}; use tokio_io::io::{ReadHalf, WriteHalf}; use tokio_io::io::{read_exact, write_all}; @@ -151,9 +149,9 @@ impl From> for EncryptedHalf { } /// Boxed future of `DecryptedHalf` -pub type DecryptedHalfFut = BoxIoFuture; +pub type DecryptedHalfFut = IoFuture; /// Boxed future of `EncryptedHalf` -pub type EncryptedHalfFut = BoxIoFuture; +pub type EncryptedHalfFut = IoFuture; /// Try to connect every IPs one by one enum TcpStreamConnect> { @@ -161,17 +159,15 @@ enum TcpStreamConnect> { Connect { last_err: Option, addr_iter: I, - opt_stream_new: Option<(TcpStreamNew, SocketAddr)>, - handle: Handle, + opt_stream_new: Option<(ConnectFuture, SocketAddr)>, }, } impl> TcpStreamConnect { - fn new(iter: I, handle: &Handle) -> TcpStreamConnect { + fn new(iter: I) -> TcpStreamConnect { TcpStreamConnect::Connect { last_err: None, addr_iter: iter, - opt_stream_new: None, - handle: handle.clone(), } + opt_stream_new: None, } } } @@ -185,8 +181,8 @@ impl> Future for TcpStreamConnect { TcpStreamConnect::Empty => unreachable!(), TcpStreamConnect::Connect { ref mut last_err, ref mut addr_iter, - ref mut opt_stream_new, - ref handle, } => { + ref mut opt_stream_new + } => { loop { // 1. Poll before doing anything else if let Some((ref mut stream_new, ref addr)) = *opt_stream_new { @@ -205,7 +201,7 @@ impl> Future for TcpStreamConnect { match addr_iter.next() { None => break, Some(addr) => { - *opt_stream_new = Some((TcpStream::connect(&addr, &handle), addr)); + *opt_stream_new = Some((TcpStream::connect(&addr), addr)); } } } @@ -225,26 +221,22 @@ impl> Future for TcpStreamConnect { } } -fn connect_proxy_server(svr_cfg: Rc) -> BoxIoFuture { +fn connect_proxy_server(config: Arc, svr_cfg: Arc) -> IoFuture { let timeout = *svr_cfg.timeout(); trace!("Connecting to proxy {:?}, timeout: {:?}", svr_cfg.addr(), timeout); match *svr_cfg.addr() { ServerAddr::SocketAddr(ref addr) => { - Context::with(|ctx| { - let handle = ctx.handle(); - try_timeout(TcpStream::connect(addr, handle), timeout, handle) - }) + try_timeout(TcpStream::connect(addr), timeout) } ServerAddr::DomainName(ref domain, port) => { - let fut = Context::with(|ctx| { - let handle = ctx.handle().clone(); - try_timeout(resolve(&domain[..], port, false), timeout, &handle).and_then(move |vec_ipaddr| { - let fut = TcpStreamConnect::new(vec_ipaddr.into_iter(), &handle); - try_timeout(fut, timeout, &handle) + let fut = { + try_timeout(resolve(config.clone(), &domain[..], port, false), timeout).and_then(move |vec_ipaddr| { + let fut = TcpStreamConnect::new(vec_ipaddr.into_iter()); + try_timeout(fut, timeout) }) - }); + }; boxed_future(fut) } } @@ -252,9 +244,9 @@ fn connect_proxy_server(svr_cfg: Rc) -> BoxIoFuture { /// Handshake logic for ShadowSocks Client pub fn proxy_server_handshake(remote_stream: TcpStream, - svr_cfg: Rc, + svr_cfg: Arc, relay_addr: Address) - -> BoxIoFuture<(DecryptedHalfFut, EncryptedHalfFut)> { + -> IoFuture<(DecryptedHalfFut, EncryptedHalfFut)> { let timeout = *svr_cfg.timeout(); let fut = proxy_handshake(remote_stream, svr_cfg).and_then(move |(r_fut, w_fut)| { let w_fut = w_fut.and_then(move |enc_w| { @@ -264,7 +256,7 @@ pub fn proxy_server_handshake(remote_stream: TcpStream, trace!("Got encrypt stream and going to send addr: {:?}, buf: {:?}", relay_addr, buf); - Context::with(|ctx| try_timeout(enc_w.write_all(buf), timeout, ctx.handle()).map(|(w, _)| w)) + try_timeout(enc_w.write_all(buf), timeout).map(|(w, _)| w) }); Ok((r_fut, boxed_future(w_fut))) @@ -275,8 +267,8 @@ pub fn proxy_server_handshake(remote_stream: TcpStream, /// ShadowSocks Client-Server handshake protocol /// Exchange cipher IV and creates stream wrapper pub fn proxy_handshake(remote_stream: TcpStream, - svr_cfg: Rc) - -> BoxIoFuture<(DecryptedHalfFut, EncryptedHalfFut)> { + svr_cfg: Arc) + -> IoFuture<(DecryptedHalfFut, EncryptedHalfFut)> { let fut = futures::lazy(|| Ok(remote_stream.split())).and_then(move |(r, w)| { let timeout = svr_cfg.timeout().clone(); @@ -301,21 +293,19 @@ pub fn proxy_handshake(remote_stream: TcpStream, } }; - Context::with(|ctx| { - try_timeout(write_all(w, prev_buf), timeout, ctx.handle()).and_then( - move |(w, prev_buf)| match svr_cfg.method().category() { - CipherCategory::Stream => { - let local_iv = prev_buf; - Ok(From::from(StreamEncryptedWriter::new(w, svr_cfg.method(), svr_cfg.key(), &local_iv))) - } - CipherCategory::Aead => { - let local_salt = prev_buf; - let wtr = AeadEncryptedWriter::new(w, svr_cfg.method(), svr_cfg.key(), &local_salt[..]); - Ok(From::from(wtr)) - } - }, - ) - }) + try_timeout(write_all(w, prev_buf), timeout).and_then( + move |(w, prev_buf)| match svr_cfg.method().category() { + CipherCategory::Stream => { + let local_iv = prev_buf; + Ok(From::from(StreamEncryptedWriter::new(w, svr_cfg.method(), svr_cfg.key(), &local_iv))) + } + CipherCategory::Aead => { + let local_salt = prev_buf; + let wtr = AeadEncryptedWriter::new(w, svr_cfg.method(), svr_cfg.key(), &local_salt[..]); + Ok(From::from(wtr)) + } + }, + ) }; let dec = { @@ -329,23 +319,21 @@ pub fn proxy_handshake(remote_stream: TcpStream, CipherCategory::Aead => method.salt_size(), }; - Context::with(|ctx| { - try_timeout(read_exact(r, vec![0u8; prev_len]), timeout, ctx.handle()).and_then( - move |(r, remote_iv)| match svr_cfg.method().category() { - CipherCategory::Stream => { - trace!("Got initialize vector {:?}", ByteStr::new(&remote_iv)); - let decrypt_stream = - StreamDecryptedReader::new(r, svr_cfg.method(), svr_cfg.key(), &remote_iv); - Ok(From::from(decrypt_stream)) - } - CipherCategory::Aead => { - trace!("Got salt {:?}", ByteStr::new(&remote_iv)); - let dr = AeadDecryptedReader::new(r, svr_cfg.method(), svr_cfg.key(), &remote_iv); - Ok(From::from(dr)) - } - }, - ) - }) + try_timeout(read_exact(r, vec![0u8; prev_len]), timeout).and_then( + move |(r, remote_iv)| match svr_cfg.method().category() { + CipherCategory::Stream => { + trace!("Got initialize vector {:?}", ByteStr::new(&remote_iv)); + let decrypt_stream = + StreamDecryptedReader::new(r, svr_cfg.method(), svr_cfg.key(), &remote_iv); + Ok(From::from(decrypt_stream)) + } + CipherCategory::Aead => { + trace!("Got salt {:?}", ByteStr::new(&remote_iv)); + let dr = AeadDecryptedReader::new(r, svr_cfg.method(), svr_cfg.key(), &remote_iv); + Ok(From::from(dr)) + } + }, + ) }; Ok((boxed_future(dec), boxed_future(enc))) @@ -355,11 +343,11 @@ pub fn proxy_handshake(remote_stream: TcpStream, } /// Establish tunnel between server and client -pub fn tunnel(addr: Address, c2s: CF, s2c: SF) -> BoxIoFuture<()> - where CF: Future + 'static, - SF: Future + 'static +pub fn tunnel(addr: Address, c2s: CF, s2c: SF) -> IoFuture<()> + where CF: Future + Send + 'static, + SF: Future + Send + 'static { - let addr = Rc::new(addr); + let addr = Arc::new(addr); let cloned_addr = addr.clone(); let c2s = c2s.then(move |res| { @@ -448,26 +436,33 @@ pub fn ignore_until_end(r: R) -> IgnoreUntilEnd { IgnoreUntilEnd::Pending { r: r, amt: 0 } } -fn try_timeout(fut: F, dur: Option, handle: &Handle) -> BoxIoFuture - where F: Future + 'static, +fn try_timeout(fut: F, dur: Option) -> IoFuture + where F: Future + Send + 'static, T: 'static { match dur { - Some(dur) => io_timeout(fut, dur, handle), + Some(dur) => io_timeout(fut, dur), None => boxed_future(fut), } } -fn io_timeout(fut: F, dur: Duration, handle: &Handle) -> BoxIoFuture - where F: Future + 'static, +fn io_timeout(fut: F, dur: Duration) -> IoFuture + where F: Future + Send + 'static, T: 'static { - let fut = fut.select(Timeout::new(dur, handle) - .unwrap() // It must be succeeded! - .and_then(|_| Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")))) - .then(|res| match res { - Ok((t, _)) => Ok(t), - Err((err, _)) => Err(err), - }); + 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) } diff --git a/src/relay/tcprelay/server.rs b/src/relay/tcprelay/server.rs index f96959cdbba8..674ad2d0a467 100644 --- a/src/relay/tcprelay/server.rs +++ b/src/relay/tcprelay/server.rs @@ -1,13 +1,12 @@ //! Relay for TCP server that running on the server side use std::io::{self, ErrorKind}; -use std::rc::Rc; use std::time::Duration; +use std::sync::Arc; -use config::ServerConfig; +use config::{Config, ServerConfig}; -use relay::{boxed_future, BoxIoFuture}; -use relay::Context; +use relay::boxed_future; use relay::dns_resolver::resolve; use relay::socks5::Address; use relay::tcprelay::crypto_io::{DecryptedRead, EncryptedWrite}; @@ -15,22 +14,24 @@ use relay::tcprelay::crypto_io::{DecryptedRead, EncryptedWrite}; use futures::{self, Future}; use futures::stream::Stream; -use tokio_core::net::{TcpListener, TcpStream}; -use tokio_io::AsyncRead; +use tokio::net::{TcpListener, TcpStream}; +use tokio_io::{IoFuture, AsyncRead}; use tokio_io::io::{ReadHalf, WriteHalf}; +use tokio; use super::{proxy_handshake, try_timeout, tunnel, DecryptedHalf, EncryptedHalfFut, TcpStreamConnect}; /// Context for doing handshake with client pub struct TcpRelayClientHandshake { s: TcpStream, - svr_cfg: Rc, + svr_cfg: Arc, + config: Arc, } impl TcpRelayClientHandshake { /// Doing handshake with client - pub fn handshake(self) -> BoxIoFuture { - let TcpRelayClientHandshake { s, svr_cfg } = self; + pub fn handshake(self) -> IoFuture { + let TcpRelayClientHandshake { s, svr_cfg, config } = self; let fut = futures::lazy(move || s.peer_addr().map(|p| (s, p))).and_then(|(s, peer_addr)| { debug!("Handshaking with peer {}", peer_addr); @@ -48,13 +49,14 @@ impl TcpRelayClientHandshake { ), ) }); - Context::with(|ctx| try_timeout(fut, timeout, ctx.handle())) + try_timeout(fut, timeout) }) .map(move |(r, addr)| TcpRelayClientPending { r: r, addr: addr, w: w_fut, timeout: timeout, + config: config, }) }) }); @@ -68,17 +70,18 @@ pub struct TcpRelayClientPending { addr: Address, w: EncryptedHalfFut, timeout: Option, + config: Arc, } impl TcpRelayClientPending { /// Connect to the remote server #[inline] - fn connect_remote(addr: Address, timeout: Option) -> BoxIoFuture { + fn connect_remote(config: Arc, addr: Address, timeout: Option) -> IoFuture { debug!("Connecting to remote {}", addr); match addr { - Address::SocketAddress(saddr) => Context::with(move |ctx| { - if ctx.forbidden_ip().contains(&saddr.ip()) { + Address::SocketAddress(saddr) => { + if config.forbidden_ip.contains(&saddr.ip()) { let err = io::Error::new( ErrorKind::Other, format!("{} is forbidden, failed to connect {}", saddr.ip(), saddr), @@ -86,28 +89,27 @@ impl TcpRelayClientPending { return boxed_future(futures::done(Err(err))); } - let conn = TcpStream::connect(&saddr, ctx.handle()); - try_timeout(conn, timeout, ctx.handle()) - }), + let conn = TcpStream::connect(&saddr); + try_timeout(conn, timeout) + }, Address::DomainNameAddress(dname, port) => { - let fut = Context::with(move |ctx| { - let handle = ctx.handle().clone(); - try_timeout(resolve(dname.as_str(), port, true), timeout, &handle).and_then(move |addrs| { - let conn = TcpStreamConnect::new(addrs.into_iter(), &handle); - try_timeout(conn, timeout, &handle) + let fut = { + try_timeout(resolve(config, dname.as_str(), port, true), timeout).and_then(move |addrs| { + let conn = TcpStreamConnect::new(addrs.into_iter()); + try_timeout(conn, timeout) }) - }); + }; boxed_future(fut) } } } /// Connect to the remote server - pub fn connect(self) -> BoxIoFuture { + pub fn connect(self) -> IoFuture { let addr = self.addr.clone(); let client_pair = (self.r, self.w); let timeout = self.timeout; - let fut = TcpRelayClientPending::connect_remote(self.addr, 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, @@ -129,7 +131,7 @@ pub struct TcpRelayClientConnected { impl TcpRelayClientConnected { /// Establish tunnel #[inline] - pub fn tunnel(self) -> BoxIoFuture<()> { + pub fn tunnel(self) -> IoFuture<()> { let (svr_r, svr_w) = self.server; let (r, w_fut) = self.client; let timeout = self.timeout; @@ -143,60 +145,60 @@ impl TcpRelayClientConnected { } /// Runs the server -pub fn run() -> Box> { - let mut fut: Option>> = None; - - Context::with(|ctx| { - let config = ctx.config(); - - for svr_cfg in &config.server { - let listener = { - let addr = svr_cfg.addr(); - let addr = addr.listen_addr(); - - let listener = - TcpListener::bind(&addr, ctx.handle()).unwrap_or_else(|err| panic!("Failed to listen, {}", err)); - - info!("ShadowSocks TCP Listening on {}", addr); - listener - }; - - let svr_cfg = Rc::new(svr_cfg.clone()); - let listening = listener - .incoming() - .for_each(move |(socket, addr)| { - let server_cfg = svr_cfg.clone(); - - trace!("Got connection, addr: {}", addr); - trace!("Picked proxy server: {:?}", server_cfg); - - let client = TcpRelayClientHandshake { - s: socket, - svr_cfg: server_cfg, - }; - - let fut = client - .handshake() - .and_then(|c| c.connect()) - .and_then(|c| c.tunnel()) - .map_err(move |err| { - error!("Failed to handle client ({}): {}", addr, err); - }); - - Context::with(|ctx| ctx.handle().spawn(fut)); - Ok(()) - }) - .map_err(|err| { - error!("Server run failed: {}", err); - err - }); - - fut = Some(match fut.take() { - Some(fut) => Box::new(fut.join(listening).map(|_| ())) as Box>, - None => Box::new(listening) as Box>, +pub fn run(config: Arc) -> IoFuture<()> { + let mut fut: Option> = None; + + for svr_cfg in &config.server { + let listener = { + let addr = svr_cfg.addr(); + let addr = addr.listen_addr(); + + let listener = + TcpListener::bind(&addr).unwrap_or_else(|err| panic!("Failed to listen, {}", err)); + + info!("ShadowSocks TCP Listening on {}", addr); + listener + }; + + let svr_cfg = Arc::new(svr_cfg.clone()); + let config = config.clone(); + let listening = listener + .incoming() + .for_each(move |socket| { + let server_cfg = svr_cfg.clone(); + + let addr = socket.peer_addr()?; + + trace!("Got connection, addr: {}", addr); + trace!("Picked proxy server: {:?}", server_cfg); + + let client = TcpRelayClientHandshake { + s: socket, + svr_cfg: server_cfg, + config: config.clone(), + }; + + let fut = client + .handshake() + .and_then(|c| c.connect()) + .and_then(|c| c.tunnel()) + .map_err(move |err| { + error!("Failed to handle client ({}): {}", addr, err); + }); + + tokio::spawn(fut); + Ok(()) }) - } + .map_err(|err| { + error!("Server run failed: {}", err); + err + }); + + fut = Some(match fut.take() { + Some(fut) => Box::new(fut.join(listening).map(|_| ())) as IoFuture<()>, + None => Box::new(listening) as IoFuture<()>, + }) + } - fut.expect("Must have at least one server") - }) + fut.expect("Must have at least one server") } diff --git a/src/relay/tcprelay/socks5_local.rs b/src/relay/tcprelay/socks5_local.rs index 01c91e352ce5..c18628df3a3b 100644 --- a/src/relay/tcprelay/socks5_local.rs +++ b/src/relay/tcprelay/socks5_local.rs @@ -2,20 +2,23 @@ use std::io; use std::net::SocketAddr; -use std::rc::Rc; +use std::sync::Arc; use futures::{self, Future}; use futures::stream::Stream; -use tokio_core::net::{TcpListener, TcpStream}; +// use tokio_core::net::{TcpListener, TcpStream}; use tokio_io::AsyncRead; use tokio_io::io::{ReadHalf, WriteHalf}; use tokio_io::io::flush; +use tokio_io::IoFuture; -use config::ServerConfig; +use tokio::net::{TcpListener, TcpStream}; +use tokio; -use relay::{boxed_future, BoxIoFuture}; -use relay::Context; +use config::{Config, ServerConfig}; + +use relay::boxed_future; use relay::loadbalancing::server::LoadBalancer; use relay::loadbalancing::server::RoundRobin; use relay::socks5::{self, Address, HandshakeRequest, HandshakeResponse}; @@ -27,18 +30,19 @@ use super::{ignore_until_end, try_timeout, tunnel}; #[derive(Debug, Clone)] struct UdpConfig { enable_udp: bool, - client_addr: Rc, + client_addr: SocketAddr, } -fn handle_socks5_connect((r, w): (ReadHalf, WriteHalf), +fn handle_socks5_connect(config: Arc, + (r, w): (ReadHalf, WriteHalf), client_addr: SocketAddr, addr: Address, - svr_cfg: Rc) - -> BoxIoFuture<()> { + svr_cfg: Arc) + -> IoFuture<()> { let cloned_addr = addr.clone(); let cloned_svr_cfg = svr_cfg.clone(); let timeout = *svr_cfg.timeout(); - let fut = super::connect_proxy_server(svr_cfg) + let fut = super::connect_proxy_server(config.clone(), svr_cfg) .then(move |res| { match res { Ok(svr_s) => { @@ -48,13 +52,9 @@ fn handle_socks5_connect((r, w): (ReadHalf, WriteHalf), let header = TcpResponseHeader::new(socks5::Reply::Succeeded, Address::SocketAddress(client_addr)); trace!("Send header: {:?}", header); - let fut = Context::with(|ctx| { - let handle = ctx.handle(); - let fut = try_timeout(header.write_to(w), timeout, &handle); - try_timeout(fut.and_then(flush), timeout, &handle) - }); - - boxed_future(fut.map(move |w| (svr_s, w))) + boxed_future( + try_timeout(try_timeout(header.write_to(w), timeout).and_then(flush), timeout) + .map(move |w| (svr_s, w))) } Err(err) => { use std::io::ErrorKind; @@ -71,13 +71,7 @@ fn handle_socks5_connect((r, w): (ReadHalf, WriteHalf), let header = TcpResponseHeader::new(reply, Address::SocketAddress(client_addr)); trace!("Send header: {:?}", header); - let fut = Context::with(|ctx| { - let handle = ctx.handle(); - let fut = try_timeout(header.write_to(w), timeout, &handle); - try_timeout(fut.and_then(flush), timeout, &handle) - }); - - boxed_future(fut.and_then(|_| Err(err))) + boxed_future(try_timeout(try_timeout(header.write_to(w), timeout).and_then(flush), timeout).and_then(|_| Err(err))) } } }) @@ -96,7 +90,7 @@ fn handle_socks5_connect((r, w): (ReadHalf, WriteHalf), Box::new(fut) } -fn handle_socks5_client(s: TcpStream, conf: Rc, udp_conf: UdpConfig) -> io::Result<()> { +fn handle_socks5_client(config: Arc, s: TcpStream, conf: Arc, udp_conf: UdpConfig) -> io::Result<()> { let client_addr = s.peer_addr()?; let cloned_client_addr = client_addr; let fut = futures::lazy(|| Ok(s.split())) @@ -144,7 +138,7 @@ fn handle_socks5_client(s: TcpStream, conf: Rc, udp_conf: UdpConfi match header.command { socks5::Command::TcpConnect => { debug!("CONNECT {}", addr); - handle_socks5_connect((r, w), cloned_client_addr, addr, conf) + handle_socks5_connect(config, (r, w), cloned_client_addr, addr, conf) } socks5::Command::TcpBind => { warn!("BIND is not supported"); @@ -156,7 +150,7 @@ fn handle_socks5_client(s: TcpStream, conf: Rc, udp_conf: UdpConfi socks5::Command::UdpAssociate => { if udp_conf.enable_udp { debug!("UDP ASSOCIATE {}", addr); - let fut = TcpResponseHeader::new(socks5::Reply::Succeeded, From::from(*udp_conf.client_addr)) + let fut = TcpResponseHeader::new(socks5::Reply::Succeeded, From::from(udp_conf.client_addr)) .write_to(w) .and_then(flush) .and_then(|_| { @@ -177,50 +171,84 @@ fn handle_socks5_client(s: TcpStream, conf: Rc, udp_conf: UdpConfi }); // Runs in Tokio - Context::with(|ctx| { - let handle = &ctx.handle; - handle.spawn(fut.then(|res| match res { - Ok(..) => Ok(()), - Err(err) => { - if err.kind() != io::ErrorKind::BrokenPipe { - error!("Failed to handle client: {}", err); - } - Err(()) - } - })); - }); + // Context::with(|ctx| { + // let handle = &ctx.handle; + // handle.spawn(fut.then(|res| match res { + // Ok(..) => Ok(()), + // Err(err) => { + // if err.kind() != io::ErrorKind::BrokenPipe { + // error!("Failed to handle client: {}", err); + // } + // Err(()) + // } + // })); + // }); + + tokio::spawn(fut.then(|res| match res { + Ok(..) => Ok(()), + Err(err) => { + if err.kind() != io::ErrorKind::BrokenPipe { + error!("Failed to handle client: {}", err); + } + Err(()) + } + })); Ok(()) } /// Starts a TCP local server with Socks5 proxy protocol -pub fn run() -> Box> { - let (listener, local_addr) = Context::with(|ctx| { - let config = &ctx.config; - let handle = &ctx.handle; - - let local_addr = config.local.as_ref().unwrap(); - - let l = TcpListener::bind(&local_addr, &handle) - .unwrap_or_else(|err| panic!("Failed to listen, {}", err)); - - info!("ShadowSocks TCP Listening on {}", local_addr); - (l, *local_addr) - }); - - let udp_conf = UdpConfig { enable_udp: Context::with(|ctx| ctx.config.enable_udp), - client_addr: Rc::new(local_addr), }; - - let mut servers = Context::with(|ctx| RoundRobin::new(ctx.config())); - let listening = listener.incoming().for_each(move |(socket, addr)| { - let server_cfg = servers.pick_server(); - trace!("Got connection, addr: {}", addr); - trace!("Picked proxy server: {:?}", server_cfg); - handle_socks5_client(socket, server_cfg, udp_conf.clone()) - }); - - Box::new(listening.map_err(|err| { - error!("Socks5 server run failed: {}", err); - err - })) +pub fn run(config: Arc) -> IoFuture<()> { + 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)); + + info!("ShadowSocks TCP Listening on {}", local_addr); + + let udp_conf = UdpConfig { + enable_udp: config.enable_udp, + client_addr: local_addr, + }; + + let mut servers = RoundRobin::new(&*config); + let listening = 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); + + handle_socks5_client(config.clone(), socket, server_cfg, udp_conf.clone()) + }); + + Box::new(listening) + + // let (listener, local_addr) = Context::with(|ctx| { + // let config = &ctx.config; + // let handle = &ctx.handle; + + // let local_addr = config.local.as_ref().unwrap(); + + // let l = TcpListener::bind(&local_addr, &handle) + // .unwrap_or_else(|err| panic!("Failed to listen, {}", err)); + + // info!("ShadowSocks TCP Listening on {}", local_addr); + // (l, *local_addr) + // }); + + // let udp_conf = UdpConfig { enable_udp: Context::with(|ctx| ctx.config.enable_udp), + // client_addr: Rc::new(local_addr), }; + + // let mut servers = Context::with(|ctx| RoundRobin::new(ctx.config())); + // let listening = listener.incoming().for_each(move |(socket, addr)| { + // let server_cfg = servers.pick_server(); + // trace!("Got connection, addr: {}", addr); + // trace!("Picked proxy server: {:?}", server_cfg); + // handle_socks5_client(socket, server_cfg, udp_conf.clone()) + // }); + + // Box::new(listening.map_err(|err| { + // error!("Socks5 server run failed: {}", err); + // err + // })) } diff --git a/src/relay/tcprelay/utils.rs b/src/relay/tcprelay/utils.rs index e7bb4de6a800..efac500969cf 100644 --- a/src/relay/tcprelay/utils.rs +++ b/src/relay/tcprelay/utils.rs @@ -1,16 +1,14 @@ //! Utility functions use std::io; -use std::time::Duration; +use std::time::{Instant, Duration}; -use tokio_core::reactor::Timeout; use tokio_io::{AsyncRead, AsyncWrite}; use tokio_io::io::{copy, Copy}; +use tokio::timer::Delay; use futures::{Async, Future, Poll}; -use relay::Context; - use super::BUFFER_SIZE; /// Copies all data from `r` to `w`, abort if timeout reaches @@ -30,7 +28,7 @@ pub struct CopyTimeout w: Option, timeout: Duration, amt: u64, - timer: Option, + timer: Option, buf: [u8; BUFFER_SIZE], pos: usize, cap: usize, @@ -56,7 +54,7 @@ impl CopyTimeout None => Ok(()), Some(t) => { match t.poll() { - Err(err) => Err(err), + Err(err) => panic!("Failed to poll on timer, err: {}", err), Ok(Async::Ready(..)) => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")), Ok(Async::NotReady) => Ok(()), } @@ -79,7 +77,7 @@ impl CopyTimeout Ok(n) => Ok(n), Err(e) => { if e.kind() == io::ErrorKind::WouldBlock { - self.timer = Context::with(|ctx| Some(Timeout::new(self.timeout, ctx.handle()).unwrap())); + self.timer = Some(Delay::new(Instant::now() + self.timeout)); } Err(e) } @@ -97,7 +95,7 @@ impl CopyTimeout Ok(n) => Ok(n), Err(e) => { if e.kind() == io::ErrorKind::WouldBlock { - self.timer = Context::with(|ctx| Some(Timeout::new(self.timeout, ctx.handle()).unwrap())); + self.timer = Some(Delay::new(Instant::now() + self.timeout)); } Err(e) } diff --git a/src/relay/udprelay/local.rs b/src/relay/udprelay/local.rs index 3158d26bd9d2..49a4be90b88d 100644 --- a/src/relay/udprelay/local.rs +++ b/src/relay/udprelay/local.rs @@ -3,15 +3,16 @@ use std::io::{self, Cursor, ErrorKind, Read}; use std::net::{IpAddr, Ipv4Addr}; use std::net::SocketAddr; -use std::rc::Rc; +use std::sync::{Arc, Mutex}; use futures::{self, Future, Stream}; -use tokio_core::net::UdpSocket; +use tokio::net::UdpSocket; +use tokio; +use tokio_io::IoFuture; -use config::{ServerAddr, ServerConfig}; -use relay::{boxed_future, BoxIoFuture}; -use relay::Context; +use config::{Config, ServerAddr, ServerConfig}; +use relay::boxed_future; use relay::dns_resolver::resolve; use relay::loadbalancing::server::{LoadBalancer, RoundRobin}; use relay::socks5::{Address, UdpAssociateHeader}; @@ -21,72 +22,72 @@ use super::MAXIMUM_UDP_PAYLOAD_SIZE; use super::crypto_io::{decrypt_payload, encrypt_payload}; /// Resolves server address to SocketAddr -fn resolve_server_addr(svr_cfg: Rc) -> BoxIoFuture { +fn resolve_server_addr(config: Arc, svr_cfg: Arc) -> IoFuture { match *svr_cfg.addr() { // Return directly if it is a SocketAddr ServerAddr::SocketAddr(ref addr) => boxed_future(futures::finished(*addr)), // Resolve domain name to SocketAddr ServerAddr::DomainName(ref dname, port) => { - let fut = resolve(dname, port, false).map(move |vec_ipaddr| { - assert!(!vec_ipaddr.is_empty()); - vec_ipaddr[0] - }); + let fut = resolve(config, dname, port, false) + .map(move |vec_ipaddr| { + assert!(!vec_ipaddr.is_empty()); + vec_ipaddr[0] + }); boxed_future(fut) } } } -fn listen(l: UdpSocket) -> BoxIoFuture<()> { - let socket = Rc::new(l); - let mut balancer = Context::with(|ctx| RoundRobin::new(ctx.config())); +fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { + let socket = Arc::new(Mutex::new(l)); + let mut balancer = RoundRobin::new(&*config); - let fut = PacketStream::new(socket.clone()).for_each(move |(pkt, src)| { + let fut = 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(); let socket = socket.clone(); - - let rel = futures::lazy(|| UdpAssociateHeader::read_from(Cursor::new(pkt))).map_err(From::from) - .and_then( - |(cur, header)| if header.frag != 0 { - error!("Received UDP associate with frag != 0, which is not supported by ShadowSocks"); - let err = io::Error::new(ErrorKind::Other, "unsupported UDP fragmentation"); - Err(err) - } else { - Ok((cur, header.address)) - }, - ) - .and_then(|(mut cur, addr)| { - let svr_cfg = svr_cfg_cloned_cloned; - - let mut payload = Vec::new(); - cur.read_to_end(&mut payload).unwrap(); - - resolve_server_addr(svr_cfg).and_then(|remote_addr| { - let local_addr = SocketAddr::new(IpAddr::from(Ipv4Addr::new(0, 0, 0, 0)), 0); - Context::with(|ctx| UdpSocket::bind(&local_addr, ctx.handle())) - .map(|remote_udp| (remote_udp, remote_addr)) + let config = config.clone(); + + let rel = futures::lazy(|| UdpAssociateHeader::read_from(Cursor::new(pkt))) + .map_err(From::from) + .and_then(|(cur, header)| { + if header.frag != 0 { + error!("Received UDP associate with frag != 0, which is not supported by ShadowSocks"); + let err = io::Error::new(ErrorKind::Other, "unsupported UDP fragmentation"); + Err(err) + } else { + Ok((cur, header.address)) + } + }) + .and_then(|(mut cur, addr)| { + let svr_cfg = svr_cfg_cloned_cloned; + + let mut payload = Vec::new(); + cur.read_to_end(&mut payload).unwrap(); + + resolve_server_addr(config, svr_cfg) + .and_then(|remote_addr| { + let local_addr = SocketAddr::new(IpAddr::from(Ipv4Addr::new(0, 0, 0, 0)), 0); + UdpSocket::bind(&local_addr) + .map(|remote_udp| (remote_udp, remote_addr)) + }) + .map(|(remote_udp, remote_addr)| (remote_udp, remote_addr, payload, addr)) }) - .map(|(remote_udp, remote_addr)| (remote_udp, remote_addr, payload, addr)) - }) - .and_then( - move |(remote_udp, remote_addr, payload, addr)| { + .and_then(move |(remote_udp, remote_addr, payload, addr)| { let mut buf = Vec::new(); addr.write_to_buf(&mut buf); buf.extend_from_slice(&payload); encrypt_payload(svr_cfg.method(), svr_cfg.key(), &buf) .map(|payload| (remote_udp, remote_addr, payload, addr)) - }, - ) - .and_then( - move |(remote_udp, remote_addr, payload, addr)| { + }) + .and_then(move |(remote_udp, remote_addr, payload, addr)| { info!("UDP ASSOCIATE {} -> {}, payload length {} bytes", src, addr, payload.len()); - remote_udp.send_dgram(payload, remote_addr) + remote_udp.send_dgram(payload, &remote_addr) .map(|(remote_udp, _)| (remote_udp, addr)) - }, - ) - .and_then( - move |(remote_udp, addr)| { + }) + .and_then(move |(remote_udp, addr)| { let buf = vec![0u8; MAXIMUM_UDP_PAYLOAD_SIZE]; remote_udp.recv_dgram(buf) .and_then(move |(_remote_udp, buf, n, _from)| { @@ -94,31 +95,28 @@ fn listen(l: UdpSocket) -> BoxIoFuture<()> { decrypt_payload(svr_cfg.method(), svr_cfg.key(), &buf[..n]) }) .map(|payload| (payload, addr)) - }, - ) - .and_then(move |(payload, addr)| { - Address::read_from(Cursor::new(payload)).map_err(From::from) - .map(|(cur, ..)| (cur, addr)) - }) - .and_then(move |(mut cur, addr)| { - let payload_len = cur.get_ref().len() - cur.position() as usize; - info!("UDP ASSOCIATE {} <- {}, payload length {} bytes", src, addr, payload_len); - - let mut data = Vec::new(); - UdpAssociateHeader::new(0, Address::SocketAddress(src)).write_to_buf(&mut data); - - cur.read_to_end(&mut data).unwrap(); - - SendDgramRc::new(socket, data, src) - }) - .map(|_| ()); - - Context::with(|ctx| { - let handle = ctx.handle(); - handle.spawn(rel.map_err(|err| { - error!("Error occurs in UDP relay: {}", err); - })); - }); + }) + .and_then(move |(payload, addr)| { + Address::read_from(Cursor::new(payload)) + .map_err(From::from) + .map(|(cur, ..)| (cur, addr)) + }) + .and_then(move |(mut cur, addr)| { + let payload_len = cur.get_ref().len() - cur.position() as usize; + info!("UDP ASSOCIATE {} <- {}, payload length {} bytes", src, addr, payload_len); + + let mut data = Vec::new(); + UdpAssociateHeader::new(0, Address::SocketAddress(src)).write_to_buf(&mut data); + + cur.read_to_end(&mut data).unwrap(); + + SendDgramRc::new(socket, data, src) + }) + .map(|_| ()); + + tokio::spawn(rel.map_err(|err| { + error!("Error occurs in UDP relay: {}", err); + })); Ok(()) }); @@ -126,15 +124,14 @@ fn listen(l: UdpSocket) -> BoxIoFuture<()> { } /// Starts a UDP local server -pub fn run() -> BoxIoFuture<()> { - let fut = futures::lazy(|| { - Context::with(|ctx| { - let local_addr = ctx.config().local.as_ref().unwrap(); - info!("ShadowSocks UDP Listening on {}", local_addr); - - UdpSocket::bind(local_addr, ctx.handle()) - }) - }).and_then(|l| listen(l)); +pub fn run(config: Arc) -> IoFuture<()> { + let local_addr = *config.local.as_ref().unwrap(); + + let fut = futures::lazy(move || { + info!("ShadowSocks UDP Listening on {}", local_addr); + + UdpSocket::bind(&local_addr) + }).and_then(move |l| listen(config, l)); boxed_future(fut) } diff --git a/src/relay/udprelay/mod.rs b/src/relay/udprelay/mod.rs index 54633af80ab0..7620a2db51c4 100644 --- a/src/relay/udprelay/mod.rs +++ b/src/relay/udprelay/mod.rs @@ -40,9 +40,9 @@ use std::io; use std::mem; use std::net::SocketAddr; -use std::rc::Rc; +use std::sync::{Arc, Mutex}; -use tokio_core::net::UdpSocket; +use tokio::net::UdpSocket; use futures::{Async, Future, Poll, Stream}; @@ -58,15 +58,17 @@ mod crypto_io; /// [here](http://support.microsoft.com/kb/822061/)* pub const MAXIMUM_UDP_PAYLOAD_SIZE: usize = 65536; +type SharedUdpSocket = Arc>; + /// UDP `recv_from` stream pub struct PacketStream { - udp: Rc, + udp: SharedUdpSocket, buf: [u8; MAXIMUM_UDP_PAYLOAD_SIZE], } impl PacketStream { /// Creates a new `PacketStream` - pub fn new(udp: Rc) -> PacketStream { + pub fn new(udp: SharedUdpSocket) -> PacketStream { PacketStream { udp: udp, buf: [0u8; MAXIMUM_UDP_PAYLOAD_SIZE], } } @@ -76,14 +78,14 @@ impl Stream for PacketStream { type Item = (Vec, SocketAddr); type Error = io::Error; fn poll(&mut self) -> Poll, Self::Error> { - let (n, addr) = try_nb!(self.udp.recv_from(&mut self.buf)); + let (n, addr) = try_ready!(self.udp.lock().unwrap().poll_recv_from(&mut self.buf)); Ok(Async::Ready(Some((self.buf[..n].to_vec(), addr)))) } } enum SendDgramStat> { Pending { - udp: Rc, + udp: SharedUdpSocket, buf: B, addr: SocketAddr, }, @@ -96,7 +98,7 @@ pub struct SendDgramRc> { } impl> SendDgramRc { - pub fn new(udp: Rc, buf: B, addr: SocketAddr) -> SendDgramRc { + pub fn new(udp: SharedUdpSocket, buf: B, addr: SocketAddr) -> SendDgramRc { SendDgramRc { stat: SendDgramStat::Pending { udp: udp, buf: buf, addr: addr, }, } @@ -104,13 +106,13 @@ impl> SendDgramRc { } impl> Future for SendDgramRc { - type Item = (Rc, usize, B); + type Item = (SharedUdpSocket, usize, B); type Error = io::Error; fn poll(&mut self) -> Poll { let n = match self.stat { SendDgramStat::Pending { ref udp, ref buf, - ref addr, } => try_nb!(udp.send_to(buf.as_ref(), addr)), + ref addr, } => try_ready!(udp.lock().unwrap().poll_send_to(buf.as_ref(), addr)), SendDgramStat::Empty => unreachable!(), }; diff --git a/src/relay/udprelay/server.rs b/src/relay/udprelay/server.rs index a82847d65c80..5a76b6c39da1 100644 --- a/src/relay/udprelay/server.rs +++ b/src/relay/udprelay/server.rs @@ -2,15 +2,16 @@ use std::io::{self, Cursor, ErrorKind}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; -use std::rc::Rc; +use std::sync::{Mutex, Arc}; use futures::{self, Future, Stream}; -use tokio_core::net::UdpSocket; +use tokio::net::UdpSocket; +use tokio_io::IoFuture; +use tokio; -use config::ServerConfig; -use relay::{boxed_future, BoxIoFuture}; -use relay::Context; +use config::{Config, ServerConfig}; +use relay::boxed_future; use relay::dns_resolver::resolve; use relay::socks5::Address; @@ -18,39 +19,39 @@ use super::{PacketStream, SendDgramRc}; use super::MAXIMUM_UDP_PAYLOAD_SIZE; use super::crypto_io::{decrypt_payload, encrypt_payload}; -fn resolve_remote_addr(addr: Address) -> BoxIoFuture { +fn resolve_remote_addr(config: Arc, addr: Address) -> IoFuture { match addr { Address::SocketAddress(s) => { - Context::with(|ctx| { - if ctx.forbidden_ip().contains(&s.ip()) { - let err = io::Error::new(ErrorKind::Other, - format!("{} is forbidden, failed to connect {}", s.ip(), s)); - return boxed_future(futures::done(Err(err))); - } - - boxed_future(futures::finished(s)) - }) + if config.forbidden_ip.contains(&s.ip()) { + let err = io::Error::new(ErrorKind::Other, + format!("{} is forbidden, failed to connect {}", s.ip(), s)); + return boxed_future(futures::done(Err(err))); + } + + boxed_future(futures::finished(s)) } Address::DomainNameAddress(dname, port) => { - let fut = resolve(&dname, port, true).map(move |vec_ipaddr| { - assert!(!vec_ipaddr.is_empty()); - vec_ipaddr[0] - }); + let fut = resolve(config, &dname, port, true) + .map(move |vec_ipaddr| { + assert!(!vec_ipaddr.is_empty()); + vec_ipaddr[0] + }); boxed_future(fut) } } } -fn listen(svr_cfg: Rc) -> BoxIoFuture<()> { +fn listen(config: Arc, svr_cfg: Arc) -> IoFuture<()> { let listen_addr = *svr_cfg.addr().listen_addr(); info!("ShadowSocks UDP listening on {}", listen_addr); - let fut = futures::lazy(move || Context::with(|ctx| UdpSocket::bind(&listen_addr, ctx.handle()))) + let fut = futures::lazy(move || UdpSocket::bind(&listen_addr)) .and_then(move |socket| { - let socket = Rc::new(socket); + let socket = Arc::new(Mutex::new(socket)); PacketStream::new(socket.clone()).for_each(move |(pkt, src)| { let svr_cfg = svr_cfg.clone(); let svr_cfg_cloned = svr_cfg.clone(); let socket = socket.clone(); + let config = config.clone(); let rel = futures::lazy(move || decrypt_payload(svr_cfg.method(), svr_cfg.key(), &pkt)) .and_then(move |payload| { // Read Address in the front (ShadowSocks protocol) @@ -67,12 +68,12 @@ fn listen(svr_cfg: Rc) -> BoxIoFuture<()> { }) .and_then(|(addr, body)| { let local_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0); - Context::with(|ctx| UdpSocket::bind(&local_addr, ctx.handle())) + UdpSocket::bind(&local_addr) .map(|remote_udp| (remote_udp, addr, body)) }) .and_then(|(remote_udp, addr, body)| { - resolve_remote_addr(addr.clone()) - .and_then(|addr| remote_udp.send_dgram(body, addr)) + resolve_remote_addr(config, addr.clone()) + .and_then(|addr| remote_udp.send_dgram(body, &addr)) .map(|(remote_udp, _)| (remote_udp, addr)) }) }) @@ -94,12 +95,9 @@ fn listen(svr_cfg: Rc) -> BoxIoFuture<()> { }) .map(|_| ()); - Context::with(|ctx| { - let handle = ctx.handle(); - handle.spawn(rel.map_err(|err| { - error!("Udp relay error: {}", err); - })); - }); + tokio::spawn(rel.map_err(|err| { + error!("Udp relay error: {}", err); + })); Ok(()) }) @@ -108,21 +106,18 @@ fn listen(svr_cfg: Rc) -> BoxIoFuture<()> { } /// Starts a UDP relay server -pub fn run() -> BoxIoFuture<()> { +pub fn run(config: Arc) -> IoFuture<()> { let mut fut = None; - Context::with(|ctx| { - let config = ctx.config(); - for svr in &config.server { - let svr_cfg = Rc::new(svr.clone()); + for svr in &config.server { + let svr_cfg = Arc::new(svr.clone()); - let svr_fut = listen(svr_cfg); - fut = match fut { - None => Some(svr_fut), - Some(fut) => Some(boxed_future(fut.join(svr_fut).map(|_| ()))), - }; - } + let svr_fut = listen(config.clone(), svr_cfg); + fut = match fut { + None => Some(svr_fut), + Some(fut) => Some(boxed_future(fut.join(svr_fut).map(|_| ()))), + }; + } - fut.expect("Should have at least one server") - }) + fut.expect("Should have at least one server") } diff --git a/tests/socks5.rs b/tests/socks5.rs index 80a88a137fc2..c50a224c3a22 100644 --- a/tests/socks5.rs +++ b/tests/socks5.rs @@ -2,15 +2,14 @@ extern crate env_logger; extern crate futures; extern crate log; extern crate shadowsocks; -extern crate tokio_core; extern crate tokio_io; +extern crate tokio; use std::net::{SocketAddr, ToSocketAddrs}; use std::thread; use std::time::Duration; use futures::Future; -use tokio_core::reactor::Core; use tokio_io::io::{flush, read_to_end, write_all}; use shadowsocks::{run_local, run_server}; @@ -54,12 +53,12 @@ impl Socks5TestServer { pub fn run(&self) { let svr_cfg = self.config.clone(); thread::spawn(move || { - run_server(svr_cfg).unwrap(); + run_server(svr_cfg); }); let client_cfg = self.config.clone(); thread::spawn(move || { - run_local(client_cfg).unwrap(); + run_local(client_cfg); }); thread::sleep(Duration::from_secs(1)); @@ -77,12 +76,9 @@ fn socks5_relay_stream() { let svr = Socks5TestServer::new(SERVER_ADDR, LOCAL_ADDR, PASSWORD, METHOD, false); svr.run(); - let mut lp = Core::new().unwrap(); - let handle = lp.handle(); - let c = Socks5Client::connect(Address::DomainNameAddress("www.example.com".to_owned(), 80), - *svr.client_addr(), - handle); + *svr.client_addr()); + let fut = c.and_then(|c| { let req = b"GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n"; write_all(c, req.to_vec()).and_then(|(c, _)| flush(c)) @@ -93,7 +89,7 @@ fn socks5_relay_stream() { }) }); - lp.run(fut).unwrap(); + tokio::run(fut.map_err(|_| ())); } #[test] @@ -107,12 +103,8 @@ fn socks5_relay_aead() { let svr = Socks5TestServer::new(SERVER_ADDR, LOCAL_ADDR, PASSWORD, METHOD, false); svr.run(); - let mut lp = Core::new().unwrap(); - let handle = lp.handle(); - let c = Socks5Client::connect(Address::DomainNameAddress("www.example.com".to_owned(), 80), - *svr.client_addr(), - handle); + *svr.client_addr()); let fut = c.and_then(|c| { let req = b"GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n"; write_all(c, req.to_vec()).and_then(|(c, _)| flush(c)) @@ -123,5 +115,5 @@ fn socks5_relay_aead() { }) }); - lp.run(fut).unwrap(); + tokio::run(fut.map_err(|_| ())); } diff --git a/tests/udp.rs b/tests/udp.rs index 35898aed81d6..219ca0b28de3 100644 --- a/tests/udp.rs +++ b/tests/udp.rs @@ -4,8 +4,8 @@ extern crate bytes; extern crate env_logger; extern crate futures; extern crate shadowsocks; -extern crate tokio_core; extern crate tokio_io; +extern crate tokio; use std::io::Cursor; use std::net::SocketAddr; @@ -15,7 +15,6 @@ use std::time::Duration; use bytes::{BufMut, BytesMut}; use futures::Future; -use tokio_core::reactor::Core; use tokio_io::io::read_to_end; use shadowsocks::{run_local, run_server}; @@ -48,14 +47,14 @@ fn get_client_addr() -> SocketAddr { fn start_server(bar: Arc) { thread::spawn(move || { bar.wait(); - run_server(get_config()).unwrap(); + run_server(get_config()); }); } fn start_local(bar: Arc) { thread::spawn(move || { bar.wait(); - run_local(get_config()).unwrap(); + run_local(get_config()); }); } @@ -76,10 +75,7 @@ fn start_udp_echo_server(bar: Arc) { fn start_udp_request_holder(bar: Arc, addr: Address) { thread::spawn(move || { - let mut lp = Core::new().unwrap(); - let handle = lp.handle(); - - let c = Socks5Client::udp_associate(addr, get_client_addr(), handle); + let c = Socks5Client::udp_associate(addr, get_client_addr()); let fut = c.and_then(|(c, addr)| { assert_eq!(addr, Address::SocketAddress(LOCAL_ADDR.parse().unwrap())); @@ -89,7 +85,7 @@ fn start_udp_request_holder(bar: Arc, addr: Address) { bar.wait(); - lp.run(fut).unwrap(); + tokio::run(fut.map_err(|_| ())); }); } From 4cd03a431734aa4763eb85010ff166a5c5419fb5 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Tue, 8 May 2018 21:12:56 +0800 Subject: [PATCH 03/22] Migrated to tokio-signal v0.2, reformatted --- Cargo.lock | 19 ++++- Cargo.toml | 4 +- src/lib.rs | 4 +- src/monitor.rs | 123 ++++++++++++++--------------- src/relay/dns_resolver.rs | 53 ++++++------- src/relay/local.rs | 25 +++--- src/relay/mod.rs | 8 +- src/relay/server.rs | 29 +++---- src/relay/tcprelay/client.rs | 2 +- src/relay/tcprelay/crypto_io.rs | 28 +++---- src/relay/tcprelay/mod.rs | 94 ++++++++++------------ src/relay/tcprelay/socks5_local.rs | 95 +++++++--------------- src/relay/tcprelay/stream.rs | 2 +- src/relay/tcprelay/utils.rs | 18 ++--- src/relay/udprelay/crypto_io.rs | 2 +- src/relay/udprelay/local.rs | 24 +++--- src/relay/udprelay/server.rs | 48 ++++++----- 17 files changed, 259 insertions(+), 319 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d80f10cdc21..9b00744255d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -796,7 +796,7 @@ dependencies = [ [[package]] name = "shadowsocks-rust" -version = "1.6.12" +version = "1.7.0" 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)", @@ -824,6 +824,7 @@ dependencies = [ "tokio 0.1.5 (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.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-signal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", ] @@ -989,6 +990,21 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-signal" +version = "0.2.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)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.4 (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)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-tcp" version = "0.1.0" @@ -1295,6 +1311,7 @@ dependencies = [ "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-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f46863230f9a05cf52d173721ec391b9c5782a2465f593029922b8782b9ffe" +"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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3d05cdd6a78005e535d2b27c21521bdf91fbb321027a62d8e178929d18966d" "checksum tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "29a89e4ad0c8f1e4c9860e605c38c69bfdad3cccd4ea446e58ff588c1c07a397" diff --git a/Cargo.toml b/Cargo.toml index 10ff8963e649..7f9f9b838b84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shadowsocks-rust" -version = "1.6.12" +version = "1.7.0" authors = ["Y. T. CHUNG "] description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls." repository = "https://github.com/zonyitoo/shadowsocks-rust" @@ -60,7 +60,7 @@ futures-cpupool = "0.1" miscreant = { version = "0.3", optional = true } [target.'cfg(unix)'.dependencies] -tokio-signal = "0.1" +tokio-signal = "0.2" [target.'cfg(windows)'.dependencies] tokio-signal = "0.1" diff --git a/src/lib.rs b/src/lib.rs index 2ea64dc6005b..3a3d028d5b76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -111,7 +111,7 @@ pub use self::relay::server::run as run_server; pub use self::relay::tcprelay::client::Socks5Client; pub mod config; -pub mod relay; pub mod crypto; +mod monitor; pub mod plugin; -// mod monitor; +pub mod relay; diff --git a/src/monitor.rs b/src/monitor.rs index 2b59ac2be680..9154286f995b 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -4,7 +4,6 @@ use std::io; use std::process; use libc; -use tokio_core::reactor::Handle; use tokio; use futures::{self, Future, Stream}; @@ -12,47 +11,47 @@ use futures::{self, Future, Stream}; use plugin::Plugin; #[cfg(unix)] -pub fn monitor_signal(handle: &Handle, plugins: Vec) { +pub fn monitor_signal(plugins: Vec) { use tokio_signal::unix::Signal; // Monitor SIGCHLD, triggered if subprocess (plugin) is exited. - let fut1 = Signal::new(libc::SIGCHLD, handle).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); - }); + 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); + }); // Monitor SIGTERM, triggered if shadowsocks is exited gracefully. (Kill by user). - let fut2 = Signal::new(libc::SIGTERM, handle).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); - }); + 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); + }); // Monitor SIGINT, triggered by CTRL-C - let fut3 = Signal::new(libc::SIGINT, handle).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); - }); + 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); + }); // Join them all, if any of them is triggered, kill all subprocesses and exit. let fut = fut1.select(fut2).map(|(sig, _)| sig) @@ -62,8 +61,7 @@ pub fn monitor_signal(handle: &Handle, plugins: Vec) { .map_err(|(e, _)| e) .then(|r| { // Something happened ... killing all subprocesses - info!("Killing {} plugin(s) and then ... Bye Bye :)", - plugins.len()); + info!("Killing {} plugin(s) and then ... Bye Bye :)", plugins.len()); drop(plugins); match r { @@ -74,51 +72,50 @@ pub fn monitor_signal(handle: &Handle, plugins: Vec) { } }); - handle.spawn(fut); + tokio::spawn(fut); } #[cfg(windows)] -pub fn monitor_signal(handle: &Handle, plugins: Vec) { +pub fn monitor_signal(plugins: Vec) { // FIXME: How to handle SIGTERM equavalent in Windows? use tokio_signal::windows::Event; - let fut1 = Event::ctrl_c(handle).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); - }); - - let fut2 = Event::ctrl_break(handle).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); - }); + 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); + }); + + 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); + }); let fut = fut1.select(fut2).then(|_| -> Result<(), ()> { // Something happened ... killing all subprocesses - info!("Killing {} plugin(s) and then ... Bye Bye :)", - plugins.len()); + info!("Killing {} plugin(s) and then ... Bye Bye :)", plugins.len()); drop(plugins); process::exit(libc::EXIT_FAILURE); }); - handle.spawn(fut); + tokio::spawn(fut); } #[cfg(not(any(windows, unix)))] -pub fn monitor_signal(handle: &Handle, plugins: Vec) { +pub fn monitor_signal(plugins: Vec) { // FIXME: What can I do ... // Blocks forever let fut = futures::empty::<(), ()>().and_then(|_| { drop(plugins); }); - handle.spawn(fut); + tokio::spawn(fut); } diff --git a/src/relay/dns_resolver.rs b/src/relay/dns_resolver.rs index 4e4b571f5763..e0efe9a574cf 100644 --- a/src/relay/dns_resolver.rs +++ b/src/relay/dns_resolver.rs @@ -10,8 +10,8 @@ use futures_cpupool::CpuPool; use tokio_io::IoFuture; -use relay::boxed_future; use config::Config; +use relay::boxed_future; lazy_static! { static ref GLOBAL_DNS_CPU_POOL: CpuPool = CpuPool::new_num_cpus(); @@ -28,9 +28,7 @@ pub fn resolve(config: Arc, addr: &str, port: u16, check_forbidden: bool let forbidden_ip = &config.forbidden_ip; if forbidden_ip.contains(&addr) { - let err = io::Error::new(ErrorKind::Other, - format!("{} is forbidden, all IPs are filtered", - 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)]) @@ -42,20 +40,20 @@ pub fn resolve(config: Arc, addr: &str, port: u16, check_forbidden: bool 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 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()); @@ -63,19 +61,18 @@ pub fn resolve(config: Arc, addr: &str, port: u16, check_forbidden: bool !filtered }) .collect::>() - }; + }; - if v.is_empty() { - let err = - io::Error::new(io::ErrorKind::Other, + 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) - } - }); + Err(err) + } else { + debug!("Resolved \"{}\" => {:?}", owned_addr, v); + Ok(v) + } + }); boxed_future(fut) } diff --git a/src/relay/local.rs b/src/relay/local.rs index fe484bc18157..78e19b520b5f 100644 --- a/src/relay/local.rs +++ b/src/relay/local.rs @@ -27,9 +27,8 @@ use relay::udprelay::local::run as run_udp; /// ``` pub fn run(mut config: Config) { // Hold it here, kill all plugins when Core is finished - let plugins = launch_plugin(&mut config, PluginMode::Client) - .expect("Failed to launch plugins"); - // ::monitor::monitor_signal(&handle, plugins); + let plugins = launch_plugin(&mut config, PluginMode::Client).expect("Failed to launch plugins"); + ::monitor::monitor_signal(plugins); let config = Arc::new(config); @@ -38,19 +37,15 @@ pub fn run(mut config: Config) { if enable_udp { let tcp_fut = run_tcp(config.clone()); let udp_fut = run_udp(config); - tokio::run(tcp_fut.join(udp_fut).then(|res| { - match res { - Ok(..) => Ok(()), - Err(err) => panic!("Failed to run server, err: {}", err), - } - })); + tokio::run(tcp_fut.join(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(tcp_fut.then(|res| { - match res { - Ok(..) => Ok(()), - Err(err) => panic!("Failed to run server, err: {}", err), - } - })) + tokio::run(tcp_fut.then(|res| match res { + Ok(..) => Ok(()), + Err(err) => panic!("Failed to run server, err: {}", err), + })) } } diff --git a/src/relay/mod.rs b/src/relay/mod.rs index 3fa6d835a4b1..8e971c9ec53a 100644 --- a/src/relay/mod.rs +++ b/src/relay/mod.rs @@ -2,13 +2,13 @@ use futures::Future; -pub mod tcprelay; -pub mod udprelay; +mod dns_resolver; +mod loadbalancing; pub mod local; pub mod server; -mod loadbalancing; -mod dns_resolver; pub mod socks5; +pub mod tcprelay; +pub mod udprelay; mod utils; fn boxed_future(f: F) -> Box + Send + 'static> diff --git a/src/relay/server.rs b/src/relay/server.rs index 18c15494e89a..dceed8434be2 100644 --- a/src/relay/server.rs +++ b/src/relay/server.rs @@ -24,32 +24,27 @@ use relay::udprelay::server::run as run_udp; /// CipherType::Aes256Cfb)]; /// run(config); /// ``` -/// +/// pub fn run(mut config: Config) { // Hold it here, kill all plugins when Core is finished - let plugins = launch_plugin(&mut config, PluginMode::Server) - .expect("Failed to launch plugins"); - // ::monitor::monitor_signal(&handle, plugins); + let plugins = launch_plugin(&mut config, PluginMode::Server).expect("Failed to launch plugins"); + ::monitor::monitor_signal(plugins); let config = Arc::new(config); let enable_udp = config.enable_udp; - + if enable_udp { let tcp_fut = run_tcp(config.clone()); let udp_fut = run_udp(config); - tokio::run(tcp_fut.join(udp_fut).then(|res| { - match res { - Ok(..) => Ok(()), - Err(err) => panic!("Failed to run server, err: {}", err), - } - })); + tokio::run(tcp_fut.join(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(tcp_fut.then(|res| { - match res { - Ok(..) => Ok(()), - Err(err) => panic!("Failed to run server, err: {}", err), - } - })) + tokio::run(tcp_fut.then(|res| match res { + Ok(..) => Ok(()), + Err(err) => panic!("Failed to run server, err: {}", err), + })) } } diff --git a/src/relay/tcprelay/client.rs b/src/relay/tcprelay/client.rs index ef6802408733..ed4bf3dba32a 100644 --- a/src/relay/tcprelay/client.rs +++ b/src/relay/tcprelay/client.rs @@ -4,8 +4,8 @@ use std::io::{self, Read, Write}; use std::net::SocketAddr; use tokio::net::TcpStream; -use tokio_io::{IoFuture, AsyncRead, AsyncWrite}; use tokio_io::io::flush; +use tokio_io::{AsyncRead, AsyncWrite, IoFuture}; use futures::{self, Async, Future, Poll}; diff --git a/src/relay/tcprelay/crypto_io.rs b/src/relay/tcprelay/crypto_io.rs index 6393541770d3..4faa8c3366ee 100644 --- a/src/relay/tcprelay/crypto_io.rs +++ b/src/relay/tcprelay/crypto_io.rs @@ -2,18 +2,18 @@ use std::io::{self, BufRead, Read}; use std::mem; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; use futures::{Async, Future, Poll}; -use tokio_io::{AsyncRead, AsyncWrite}; -use tokio_io::io::{copy, Copy}; use tokio::timer::Delay; +use tokio_io::io::{copy, Copy}; +use tokio_io::{AsyncRead, AsyncWrite}; use bytes::{BufMut, BytesMut}; -use super::BUFFER_SIZE; use super::utils::{copy_timeout, copy_timeout_opt, CopyTimeout, CopyTimeoutOpt}; +use super::BUFFER_SIZE; static DUMMY_BUFFER: [u8; BUFFER_SIZE] = [0u8; BUFFER_SIZE]; @@ -229,9 +229,7 @@ impl Future for EncryptedCopy // If our buffer has some data, let's write it out! while self.pos < self.cap { - let i = try_nb!(self.writer.as_mut() - .unwrap() - .write_raw(&self.buf[self.pos..self.cap])); + let i = try_nb!(self.writer.as_mut().unwrap().write_raw(&self.buf[self.pos..self.cap])); self.pos += i; self.amt += i as u64; } @@ -285,11 +283,13 @@ impl EncryptedCopyTimeout fn try_poll_timeout(&mut self) -> io::Result<()> { match self.timer.as_mut() { None => Ok(()), - Some(t) => match t.poll() { - Err(err) => panic!("Failed to poll on timer, err: {}", err), - Ok(Async::Ready(..)) => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")), - Ok(Async::NotReady) => Ok(()), - }, + Some(t) => { + match t.poll() { + Err(err) => panic!("Failed to poll on timer, err: {}", err), + Ok(Async::Ready(..)) => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")), + Ok(Async::NotReady) => Ok(()), + } + } } } @@ -317,9 +317,7 @@ impl EncryptedCopyTimeout let buffer_len = self.writer.as_mut().unwrap().buffer_size(data); self.write_buf.reserve(buffer_len); - self.writer.as_mut() - .unwrap() - .encrypt(data, &mut self.write_buf)?; + self.writer.as_mut().unwrap().encrypt(data, &mut self.write_buf)?; self.cap = self.write_buf.len(); self.pos = 0; Ok(n) diff --git a/src/relay/tcprelay/mod.rs b/src/relay/tcprelay/mod.rs index 35cb2d06c65f..12c7db6318bf 100644 --- a/src/relay/tcprelay/mod.rs +++ b/src/relay/tcprelay/mod.rs @@ -5,18 +5,18 @@ use std::iter::{IntoIterator, Iterator}; use std::mem; use std::net::SocketAddr; use std::sync::Arc; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; -use config::{ServerAddr, Config, ServerConfig}; +use config::{Config, ServerAddr, ServerConfig}; use crypto::CipherCategory; -use relay::{boxed_future}; +use relay::boxed_future; use relay::dns_resolver::resolve; use relay::socks5::Address; -use tokio::net::{TcpStream, ConnectFuture}; -use tokio_io::{IoFuture, AsyncRead}; -use tokio_io::io::{ReadHalf, WriteHalf}; +use tokio::net::{ConnectFuture, TcpStream}; use tokio_io::io::{read_exact, write_all}; +use tokio_io::io::{ReadHalf, WriteHalf}; +use tokio_io::{AsyncRead, IoFuture}; use futures::{self, Async, Future, Poll}; @@ -29,13 +29,13 @@ pub use self::crypto_io::{DecryptedRead, EncryptedWrite}; use self::aead::{DecryptedReader as AeadDecryptedReader, EncryptedWriter as AeadEncryptedWriter}; use self::stream::{DecryptedReader as StreamDecryptedReader, EncryptedWriter as StreamEncryptedWriter}; +mod aead; +pub mod client; +mod crypto_io; pub mod local; -mod socks5_local; pub mod server; +mod socks5_local; mod stream; -pub mod client; -mod crypto_io; -mod aead; mod utils; const BUFFER_SIZE: usize = 8 * 1024; // 8K buffer @@ -181,8 +181,7 @@ impl> Future for TcpStreamConnect { TcpStreamConnect::Empty => unreachable!(), TcpStreamConnect::Connect { ref mut last_err, ref mut addr_iter, - ref mut opt_stream_new - } => { + ref mut opt_stream_new, } => { loop { // 1. Poll before doing anything else if let Some((ref mut stream_new, ref addr)) = *opt_stream_new { @@ -210,26 +209,24 @@ 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 { let timeout = *svr_cfg.timeout(); - trace!("Connecting to proxy {:?}, timeout: {:?}", - svr_cfg.addr(), - 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) => try_timeout(TcpStream::connect(addr), timeout), ServerAddr::DomainName(ref domain, port) => { let fut = { try_timeout(resolve(config.clone(), &domain[..], port, false), timeout).and_then(move |vec_ipaddr| { @@ -250,14 +247,16 @@ pub fn proxy_server_handshake(remote_stream: TcpStream, let timeout = *svr_cfg.timeout(); let 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()); - relay_addr.write_to_buf(&mut buf); + // Send relay address to remote + let mut buf = BytesMut::with_capacity(relay_addr.len()); + relay_addr.write_to_buf(&mut buf); - trace!("Got encrypt stream and going to send addr: {:?}, buf: {:?}", relay_addr, buf); + trace!("Got encrypt stream and going to send addr: {:?}, buf: {:?}", + relay_addr, + buf); - try_timeout(enc_w.write_all(buf), timeout).map(|(w, _)| w) - }); + try_timeout(enc_w.write_all(buf), timeout).map(|(w, _)| w) + }); Ok((r_fut, boxed_future(w_fut))) }); @@ -319,12 +318,11 @@ pub fn proxy_handshake(remote_stream: TcpStream, CipherCategory::Aead => method.salt_size(), }; - try_timeout(read_exact(r, vec![0u8; prev_len]), timeout).and_then( - move |(r, remote_iv)| match svr_cfg.method().category() { + try_timeout(read_exact(r, vec![0u8; prev_len]), timeout).and_then(move |(r, remote_iv)| { + match svr_cfg.method().category() { CipherCategory::Stream => { trace!("Got initialize vector {:?}", ByteStr::new(&remote_iv)); - let decrypt_stream = - StreamDecryptedReader::new(r, svr_cfg.method(), svr_cfg.key(), &remote_iv); + let decrypt_stream = StreamDecryptedReader::new(r, svr_cfg.method(), svr_cfg.key(), &remote_iv); Ok(From::from(decrypt_stream)) } CipherCategory::Aead => { @@ -332,8 +330,8 @@ pub fn proxy_handshake(remote_stream: TcpStream, let dr = AeadDecryptedReader::new(r, svr_cfg.method(), svr_cfg.key(), &remote_iv); Ok(From::from(dr)) } - }, - ) + } + }) }; Ok((boxed_future(dec), boxed_future(enc))) @@ -381,12 +379,10 @@ 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) + trace!("Relay {} client <- server is closed, abort connection", addr) } TunnelDirection::Client2Server => { - trace!("Relay {} server -> client is closed, abort connection", - addr) + trace!("Relay {} server -> client is closed, abort connection", addr) } } @@ -410,8 +406,7 @@ impl Future for IgnoreUntilEnd { fn poll(&mut self) -> Poll { match *self { IgnoreUntilEnd::Empty => panic!("poll IgnoreUntilEnd after it is finished"), - IgnoreUntilEnd::Pending { ref mut r, - ref mut amt, } => { + IgnoreUntilEnd::Pending { ref mut r, ref mut amt } => { let mut buf = [0u8; 4096]; loop { let n = try_nb!(r.read(&mut buf)); @@ -452,17 +447,10 @@ fn io_timeout(fut: F, dur: Duration) -> IoFuture { 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") - } - } - }); + 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) } diff --git a/src/relay/tcprelay/socks5_local.rs b/src/relay/tcprelay/socks5_local.rs index c18628df3a3b..943092973e8e 100644 --- a/src/relay/tcprelay/socks5_local.rs +++ b/src/relay/tcprelay/socks5_local.rs @@ -4,17 +4,17 @@ use std::io; use std::net::SocketAddr; use std::sync::Arc; -use futures::{self, Future}; use futures::stream::Stream; +use futures::{self, Future}; // use tokio_core::net::{TcpListener, TcpStream}; -use tokio_io::AsyncRead; -use tokio_io::io::{ReadHalf, WriteHalf}; use tokio_io::io::flush; +use tokio_io::io::{ReadHalf, WriteHalf}; +use tokio_io::AsyncRead; use tokio_io::IoFuture; -use tokio::net::{TcpListener, TcpStream}; use tokio; +use tokio::net::{TcpListener, TcpStream}; use config::{Config, ServerConfig}; @@ -90,7 +90,11 @@ fn handle_socks5_connect(config: Arc, Box::new(fut) } -fn handle_socks5_client(config: Arc, s: TcpStream, conf: Arc, udp_conf: UdpConfig) -> io::Result<()> { +fn handle_socks5_client(config: Arc, + s: TcpStream, + conf: Arc, + udp_conf: UdpConfig) + -> io::Result<()> { let client_addr = s.peer_addr()?; let cloned_client_addr = client_addr; let fut = futures::lazy(|| Ok(s.split())) @@ -170,29 +174,15 @@ fn handle_socks5_client(config: Arc, s: TcpStream, conf: Arc Ok(()), - // Err(err) => { - // if err.kind() != io::ErrorKind::BrokenPipe { - // error!("Failed to handle client: {}", err); - // } - // Err(()) - // } - // })); - // }); - tokio::spawn(fut.then(|res| match res { - Ok(..) => Ok(()), - Err(err) => { - if err.kind() != io::ErrorKind::BrokenPipe { - error!("Failed to handle client: {}", err); - } - Err(()) - } - })); + Ok(..) => Ok(()), + Err(err) => { + if err.kind() != io::ErrorKind::BrokenPipe { + error!("Failed to handle client: {}", err); + } + Err(()) + } + })); Ok(()) } @@ -201,54 +191,23 @@ fn handle_socks5_client(config: Arc, s: TcpStream, conf: Arc) -> IoFuture<()> { 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)); + let listener = TcpListener::bind(&local_addr).unwrap_or_else(|err| panic!("Failed to listen, {}", err)); info!("ShadowSocks TCP Listening on {}", local_addr); - let udp_conf = UdpConfig { - enable_udp: config.enable_udp, - client_addr: local_addr, - }; + let udp_conf = UdpConfig { enable_udp: config.enable_udp, + client_addr: local_addr, }; let mut servers = RoundRobin::new(&*config); - let listening = listener.incoming().for_each(move |socket| { - let server_cfg = servers.pick_server(); + let listening = + 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()) - }); + handle_socks5_client(config.clone(), socket, server_cfg, udp_conf.clone()) + }); Box::new(listening) - - // let (listener, local_addr) = Context::with(|ctx| { - // let config = &ctx.config; - // let handle = &ctx.handle; - - // let local_addr = config.local.as_ref().unwrap(); - - // let l = TcpListener::bind(&local_addr, &handle) - // .unwrap_or_else(|err| panic!("Failed to listen, {}", err)); - - // info!("ShadowSocks TCP Listening on {}", local_addr); - // (l, *local_addr) - // }); - - // let udp_conf = UdpConfig { enable_udp: Context::with(|ctx| ctx.config.enable_udp), - // client_addr: Rc::new(local_addr), }; - - // let mut servers = Context::with(|ctx| RoundRobin::new(ctx.config())); - // let listening = listener.incoming().for_each(move |(socket, addr)| { - // let server_cfg = servers.pick_server(); - // trace!("Got connection, addr: {}", addr); - // trace!("Picked proxy server: {:?}", server_cfg); - // handle_socks5_client(socket, server_cfg, udp_conf.clone()) - // }); - - // Box::new(listening.map_err(|err| { - // error!("Socks5 server run failed: {}", err); - // err - // })) } diff --git a/src/relay/tcprelay/stream.rs b/src/relay/tcprelay/stream.rs index f60233fa857f..9d20a802782c 100644 --- a/src/relay/tcprelay/stream.rs +++ b/src/relay/tcprelay/stream.rs @@ -7,8 +7,8 @@ use bytes::{BufMut, BytesMut}; use crypto::{new_stream, CipherType, CryptoMode, StreamCipher, StreamCipherVariant}; use tokio_io::{AsyncRead, AsyncWrite}; -use super::{DecryptedRead, EncryptedWrite}; use super::BUFFER_SIZE; +use super::{DecryptedRead, EncryptedWrite}; const DUMMY_BUFFER: [u8; BUFFER_SIZE] = [0u8; BUFFER_SIZE]; diff --git a/src/relay/tcprelay/utils.rs b/src/relay/tcprelay/utils.rs index efac500969cf..49252b108f67 100644 --- a/src/relay/tcprelay/utils.rs +++ b/src/relay/tcprelay/utils.rs @@ -1,11 +1,11 @@ //! Utility functions use std::io; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; -use tokio_io::{AsyncRead, AsyncWrite}; -use tokio_io::io::{copy, Copy}; use tokio::timer::Delay; +use tokio_io::io::{copy, Copy}; +use tokio_io::{AsyncRead, AsyncWrite}; use futures::{Async, Future, Poll}; @@ -52,13 +52,11 @@ impl CopyTimeout fn try_poll_timeout(&mut self) -> io::Result<()> { match self.timer.as_mut() { None => Ok(()), - Some(t) => { - match t.poll() { - Err(err) => panic!("Failed to poll on timer, err: {}", err), - Ok(Async::Ready(..)) => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")), - Ok(Async::NotReady) => Ok(()), - } - } + Some(t) => match t.poll() { + Err(err) => panic!("Failed to poll on timer, err: {}", err), + Ok(Async::Ready(..)) => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")), + Ok(Async::NotReady) => Ok(()), + }, } } diff --git a/src/relay/udprelay/crypto_io.rs b/src/relay/udprelay/crypto_io.rs index 101f7817e88e..69815ca33f76 100644 --- a/src/relay/udprelay/crypto_io.rs +++ b/src/relay/udprelay/crypto_io.rs @@ -22,8 +22,8 @@ use std::io; -use crypto::{self, CipherCategory, CipherType, CryptoMode}; use crypto::StreamCipher; +use crypto::{self, CipherCategory, CipherType, CryptoMode}; /// Encrypt payload into ShadowSocks UDP encrypted packet pub fn encrypt_payload(t: CipherType, key: &[u8], payload: &[u8]) -> io::Result> { diff --git a/src/relay/udprelay/local.rs b/src/relay/udprelay/local.rs index 49a4be90b88d..c84fa33d41a7 100644 --- a/src/relay/udprelay/local.rs +++ b/src/relay/udprelay/local.rs @@ -1,14 +1,14 @@ //! UDP relay local server use std::io::{self, Cursor, ErrorKind, Read}; -use std::net::{IpAddr, Ipv4Addr}; use std::net::SocketAddr; +use std::net::{IpAddr, Ipv4Addr}; use std::sync::{Arc, Mutex}; use futures::{self, Future, Stream}; -use tokio::net::UdpSocket; use tokio; +use tokio::net::UdpSocket; use tokio_io::IoFuture; use config::{Config, ServerAddr, ServerConfig}; @@ -17,9 +17,9 @@ use relay::dns_resolver::resolve; use relay::loadbalancing::server::{LoadBalancer, RoundRobin}; use relay::socks5::{Address, UdpAssociateHeader}; -use super::{PacketStream, SendDgramRc}; -use super::MAXIMUM_UDP_PAYLOAD_SIZE; use super::crypto_io::{decrypt_payload, encrypt_payload}; +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 { @@ -28,11 +28,10 @@ fn resolve_server_addr(config: Arc, svr_cfg: Arc) -> IoFut ServerAddr::SocketAddr(ref addr) => boxed_future(futures::finished(*addr)), // Resolve domain name to SocketAddr ServerAddr::DomainName(ref dname, port) => { - let fut = resolve(config, dname, port, false) - .map(move |vec_ipaddr| { - assert!(!vec_ipaddr.is_empty()); - vec_ipaddr[0] - }); + let fut = resolve(config, dname, port, false).map(move |vec_ipaddr| { + assert!(!vec_ipaddr.is_empty()); + vec_ipaddr[0] + }); boxed_future(fut) } } @@ -42,8 +41,7 @@ fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { let socket = Arc::new(Mutex::new(l)); let mut balancer = RoundRobin::new(&*config); - let fut = PacketStream::new(socket.clone()) - .for_each(move |(pkt, src)| { + let fut = 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(); @@ -115,8 +113,8 @@ fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { .map(|_| ()); tokio::spawn(rel.map_err(|err| { - error!("Error occurs in UDP relay: {}", err); - })); + error!("Error occurs in UDP relay: {}", err); + })); Ok(()) }); diff --git a/src/relay/udprelay/server.rs b/src/relay/udprelay/server.rs index 5a76b6c39da1..8fb0639dda64 100644 --- a/src/relay/udprelay/server.rs +++ b/src/relay/udprelay/server.rs @@ -2,40 +2,39 @@ use std::io::{self, Cursor, ErrorKind}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; -use std::sync::{Mutex, Arc}; +use std::sync::{Arc, Mutex}; use futures::{self, Future, Stream}; +use tokio; use tokio::net::UdpSocket; use tokio_io::IoFuture; -use tokio; use config::{Config, ServerConfig}; use relay::boxed_future; use relay::dns_resolver::resolve; use relay::socks5::Address; -use super::{PacketStream, SendDgramRc}; -use super::MAXIMUM_UDP_PAYLOAD_SIZE; 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 { match addr { Address::SocketAddress(s) => { if config.forbidden_ip.contains(&s.ip()) { let err = io::Error::new(ErrorKind::Other, - format!("{} is forbidden, failed to connect {}", s.ip(), s)); + format!("{} is forbidden, failed to connect {}", s.ip(), s)); return boxed_future(futures::done(Err(err))); } boxed_future(futures::finished(s)) } Address::DomainNameAddress(dname, port) => { - let fut = resolve(config, &dname, port, true) - .map(move |vec_ipaddr| { - assert!(!vec_ipaddr.is_empty()); - vec_ipaddr[0] - }); + let fut = resolve(config, &dname, port, true).map(move |vec_ipaddr| { + assert!(!vec_ipaddr.is_empty()); + vec_ipaddr[0] + }); boxed_future(fut) } } @@ -44,15 +43,14 @@ fn resolve_remote_addr(config: Arc, addr: Address) -> IoFuture, svr_cfg: Arc) -> IoFuture<()> { 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| { - let socket = Arc::new(Mutex::new(socket)); - PacketStream::new(socket.clone()).for_each(move |(pkt, src)| { - let svr_cfg = svr_cfg.clone(); - let svr_cfg_cloned = svr_cfg.clone(); - let socket = socket.clone(); - let config = config.clone(); - let rel = futures::lazy(move || decrypt_payload(svr_cfg.method(), svr_cfg.key(), &pkt)) + let fut = 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(); + let svr_cfg_cloned = svr_cfg.clone(); + let socket = socket.clone(); + let config = config.clone(); + let rel = futures::lazy(move || decrypt_payload(svr_cfg.method(), svr_cfg.key(), &pkt)) .and_then(move |payload| { // Read Address in the front (ShadowSocks protocol) Address::read_from(Cursor::new(payload)) @@ -95,13 +93,13 @@ fn listen(config: Arc, svr_cfg: Arc) -> IoFuture<()> { }) .map(|_| ()); - tokio::spawn(rel.map_err(|err| { - error!("Udp relay error: {}", err); - })); + tokio::spawn(rel.map_err(|err| { + error!("Udp relay error: {}", err); + })); - Ok(()) - }) - }); + Ok(()) + }) + }); boxed_future(fut) } From b95e17203b141554d052de21638239150c42e8ec Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Tue, 8 May 2018 22:05:31 +0800 Subject: [PATCH 04/22] Should not call tokio::spawn before tokio::run --- src/monitor.rs | 69 +++++++++++++++++++++++++-------------------- src/relay/local.rs | 21 ++++++++------ src/relay/mod.rs | 2 +- src/relay/server.rs | 21 ++++++++------ 4 files changed, 64 insertions(+), 49 deletions(-) diff --git a/src/monitor.rs b/src/monitor.rs index 9154286f995b..f3365837b3a9 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -5,13 +5,16 @@ use std::process; use libc; use tokio; +use tokio_io::IoFuture; +use futures::future::select_all; use futures::{self, Future, Stream}; use plugin::Plugin; +use relay::boxed_future; #[cfg(unix)] -pub fn monitor_signal(plugins: Vec) { +pub fn monitor_signal(plugins: Vec) -> IoFuture<()> { use tokio_signal::unix::Signal; // Monitor SIGCHLD, triggered if subprocess (plugin) is exited. @@ -25,6 +28,7 @@ pub fn monitor_signal(plugins: Vec) { }) .map_err(|err| { error!("Failed to monitor SIGCHLD, err: {:?}", err); + err }); // Monitor SIGTERM, triggered if shadowsocks is exited gracefully. (Kill by user). @@ -38,6 +42,7 @@ pub fn monitor_signal(plugins: Vec) { }) .map_err(|err| { error!("Failed to monitor SIGTERM, err: {:?}", err); + err }); // Monitor SIGINT, triggered by CTRL-C @@ -51,32 +56,35 @@ pub fn monitor_signal(plugins: Vec) { }) .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. - let fut = fut1.select(fut2).map(|(sig, _)| sig) - .map_err(|(e, _)| e) - .select(fut3) - .map(|(sig, _)| sig) - .map_err(|(e, _)| e) - .then(|r| { - // Something happened ... killing all subprocesses - info!("Killing {} plugin(s) and then ... Bye Bye :)", plugins.len()); - drop(plugins); - - match r { - Ok(_signo) => { - process::exit(0); - } - Err(..) => Err(()), - } - }); - - tokio::spawn(fut); + 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); + + match r { + Ok(..) => { + process::exit(0); + } + Err(err) => Err(err), + } + })) } #[cfg(windows)] -pub fn monitor_signal(plugins: Vec) { +pub fn monitor_signal(plugins: Vec) -> IoFuture<()> { // FIXME: How to handle SIGTERM equavalent in Windows? use tokio_signal::windows::Event; @@ -89,6 +97,7 @@ pub fn monitor_signal(plugins: Vec) { }) .map_err(|err| { error!("Failed to monitor Ctrl-C event: {:?}", err); + err }); let fut2 = Event::ctrl_break().and_then(|ev| { @@ -99,23 +108,23 @@ pub fn monitor_signal(plugins: Vec) { }) .map_err(|err| { error!("Failed to monitor Ctrl-Break event: {:?}", err); + err }); - let fut = 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); - }); - tokio::spawn(fut); + 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); + })) } #[cfg(not(any(windows, unix)))] -pub fn monitor_signal(plugins: Vec) { +pub fn monitor_signal(plugins: Vec) -> IoFuture<()> { // FIXME: What can I do ... // Blocks forever let fut = futures::empty::<(), ()>().and_then(|_| { drop(plugins); }); - tokio::spawn(fut); + boxed_future(fut) } diff --git a/src/relay/local.rs b/src/relay/local.rs index 78e19b520b5f..b39a13b1912a 100644 --- a/src/relay/local.rs +++ b/src/relay/local.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use tokio; +use futures::future::join_all; use futures::Future; use config::Config; @@ -28,7 +29,7 @@ use relay::udprelay::local::run as run_udp; pub fn run(mut config: Config) { // Hold it here, kill all plugins when Core is finished let plugins = launch_plugin(&mut config, PluginMode::Client).expect("Failed to launch plugins"); - ::monitor::monitor_signal(plugins); + let mon = ::monitor::monitor_signal(plugins); let config = Arc::new(config); @@ -37,15 +38,17 @@ pub fn run(mut config: Config) { if enable_udp { let tcp_fut = run_tcp(config.clone()); let udp_fut = run_udp(config); - tokio::run(tcp_fut.join(udp_fut).then(|res| match res { - Ok(..) => Ok(()), - Err(err) => panic!("Failed to run server, err: {}", err), - })); + 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(tcp_fut.then(|res| match res { - Ok(..) => Ok(()), - Err(err) => panic!("Failed to run server, err: {}", err), - })) + tokio::run(join_all(vec![mon, tcp_fut]).then(|res| match res { + Ok(..) => Ok(()), + Err(err) => panic!("Failed to run server, err: {}", err), + })) } } diff --git a/src/relay/mod.rs b/src/relay/mod.rs index 8e971c9ec53a..2a4241fbd6df 100644 --- a/src/relay/mod.rs +++ b/src/relay/mod.rs @@ -11,7 +11,7 @@ pub mod tcprelay; pub mod udprelay; mod utils; -fn boxed_future(f: F) -> Box + Send + 'static> +pub fn boxed_future(f: F) -> Box + Send + 'static> where F: Future + Send + 'static { Box::new(f) diff --git a/src/relay/server.rs b/src/relay/server.rs index dceed8434be2..227ac18abee1 100644 --- a/src/relay/server.rs +++ b/src/relay/server.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use tokio; +use futures::future::join_all; use futures::Future; use config::Config; @@ -28,7 +29,7 @@ use relay::udprelay::server::run as run_udp; pub fn run(mut config: Config) { // Hold it here, kill all plugins when Core is finished let plugins = launch_plugin(&mut config, PluginMode::Server).expect("Failed to launch plugins"); - ::monitor::monitor_signal(plugins); + let mon = ::monitor::monitor_signal(plugins); let config = Arc::new(config); let enable_udp = config.enable_udp; @@ -36,15 +37,17 @@ pub fn run(mut config: Config) { if enable_udp { let tcp_fut = run_tcp(config.clone()); let udp_fut = run_udp(config); - tokio::run(tcp_fut.join(udp_fut).then(|res| match res { - Ok(..) => Ok(()), - Err(err) => panic!("Failed to run server, err: {}", err), - })); + 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(tcp_fut.then(|res| match res { - Ok(..) => Ok(()), - Err(err) => panic!("Failed to run server, err: {}", err), - })) + tokio::run(join_all(vec![mon, tcp_fut]).then(|res| match res { + Ok(..) => Ok(()), + Err(err) => panic!("Failed to run server, err: {}", err), + })) } } From 00724f383be4a3accf59af74ca4964423e5681ba Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Tue, 8 May 2018 23:26:23 +0800 Subject: [PATCH 05/22] Build nightly and stable with different image tag --- build/Dockerfile | 3 ++- build/build-release | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/build/Dockerfile b/build/Dockerfile index f8150c8a8b3a..03f9812c3288 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -1,4 +1,5 @@ -FROM ekidd/rust-musl-builder +ARG TOOLCHAIN=stable +FROM ekidd/rust-musl-builder:$TOOLCHAIN #ENV HTTP_PROXY="http://192.168.0.106:8118" #ENV HTTPS_PROXY="http://192.168.0.106:8118" diff --git a/build/build-release b/build/build-release index 9b0656a80905..be6cc43feec1 100755 --- a/build/build-release +++ b/build/build-release @@ -40,11 +40,19 @@ fi echo "* Building ${RELEASE_NAME} package ${VERSION} ..." -IMAGE='shadowsocks-rust:latest' +if $BUILD_NIGHTLY; then + IMAGE='shadowsocks-rust:nightly' +else + IMAGE='shadowsocks-rust:stable' +fi if $BUILD_DOCKER_IMG; then echo "* Rebuild docker image ${IMAGE} ..."; - docker build -t "${IMAGE}" "$CUR_DIR"; + if $BUILD_NIGHTLY; then + docker build -t "${IMAGE}" "$CUR_DIR" --build-arg TOOLCHAIN=nightly; + else + docker build -t "${IMAGE}" "$CUR_DIR" --build-arg TOOLCHAIN=stable; + fi fi SRC_PATH="/home/rust/src" @@ -59,6 +67,7 @@ if $BUILD_NIGHTLY; then docker run \ -e CARGO_TARGET_DIR="${CARGO_TARGET_DIR}" \ -e CARGO_INSTALL_ROOT="${CARGO_INSTALL_ROOT}" \ + -e RUSTFLAGS="-Ctarget-feature=+aes" \ -e HTTP_PROXY="$HTTP_PROXY" \ -e HTTPS_PROXY="$HTTPS_PROXY" \ -v "${CUR_DIR}"/..:"$SRC_PATH" \ @@ -67,7 +76,7 @@ if $BUILD_NIGHTLY; then /bin/bash -c \ "sudo mkdir -p $CARGO_TARGET_DIR \ && sudo rm -rf $CARGO_INSTALL_ROOT \ - && rustup run nightly cargo install -f --features miscreant \ + && cargo install -f --features miscreant \ && sudo chown -R $LOCAL_USER $CARGO_INSTALL_ROOT"; else docker run \ From 4376528f68bd400e9e9e0abd0f3f3045dce204fb Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Tue, 8 May 2018 23:47:57 +0800 Subject: [PATCH 06/22] Removed unnecessary rustup install --- build/Dockerfile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/build/Dockerfile b/build/Dockerfile index 03f9812c3288..7071522da26d 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -1,9 +1,6 @@ ARG TOOLCHAIN=stable FROM ekidd/rust-musl-builder:$TOOLCHAIN -#ENV HTTP_PROXY="http://192.168.0.106:8118" -#ENV HTTPS_PROXY="http://192.168.0.106:8118" - ENV SODIUM_VERS="1.0.16" # Build a static copy of libsodium. @@ -14,9 +11,5 @@ RUN cd /home/rust/libs && \ make && sudo make install && \ cd .. && rm -rf libsodium-$SODIUM_VERS.tar.gz libsodium-$SODIUM_VERS -RUN rustup install nightly -RUN rustup default nightly -RUN rustup target add x86_64-unknown-linux-musl - ENV SODIUM_STATIC=yes ENV SODIUM_LIB_DIR=/usr/local/musl/lib From c9ff14fd5c6b2de0c94229bafee7bf616ebe866b Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Wed, 9 May 2018 00:44:25 +0800 Subject: [PATCH 07/22] Renamed version to v1.7.0-alpha --- Cargo.lock | 181 ++++++++++++++++++++++++++++------------------------- Cargo.toml | 2 +- 2 files changed, 98 insertions(+), 85 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b00744255d9..c5fd831646b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,7 +43,7 @@ dependencies = [ [[package]] name = "atty" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -67,7 +67,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -109,7 +109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bytes" -version = "0.4.6" +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)", @@ -118,7 +118,7 @@ dependencies = [ [[package]] name = "bzip2" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -130,18 +130,18 @@ name = "bzip2-sys" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "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 = "cc" -version = "1.0.12" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -155,8 +155,8 @@ version = "2.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "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)", @@ -168,7 +168,7 @@ name = "clear_on_drop" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -210,11 +210,11 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -223,7 +223,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -237,7 +237,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -249,7 +249,7 @@ name = "crossbeam-utils" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -257,7 +257,7 @@ name = "crossbeam-utils" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -297,22 +297,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "env_logger" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "filetime" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.2 (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)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -353,7 +353,7 @@ name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -399,7 +399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -450,7 +450,7 @@ name = "libsodium-ffi" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -464,7 +464,7 @@ name = "log" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -500,7 +500,7 @@ name = "miniz-sys" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", ] @@ -518,7 +518,7 @@ name = "miniz_oxide_c_api" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -544,9 +544,10 @@ dependencies = [ [[package]] name = "mio-uds" -version = "0.6.4" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -593,7 +594,7 @@ name = "net2" version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.2 (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)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -625,15 +626,15 @@ dependencies = [ "foreign-types 0.3.2 (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)", - "openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.30 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.28" +version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -723,19 +724,19 @@ dependencies = [ [[package]] name = "regex" -version = "0.2.10" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.5.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -746,7 +747,7 @@ name = "ring" version = "0.13.0-alpha" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", "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)", @@ -760,7 +761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "scoped-tls" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -770,17 +771,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.43" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_json" -version = "1.0.16" +version = "1.0.17" 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.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -790,21 +791,21 @@ 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.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "shadowsocks-rust" -version = "1.7.0" +version = "1.7.0-alpha" 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)", - "bytes 0.4.6 (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)", - "env_logger 0.5.9 (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)", @@ -817,11 +818,11 @@ dependencies = [ "qrcode 0.5.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)", - "serde_json 1.0.16 (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)", - "tokio 0.1.5 (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.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-signal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -860,7 +861,7 @@ name = "tar" version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "filetime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "xattr 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -913,17 +914,18 @@ dependencies = [ [[package]] name = "tokio" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-fs 0.1.0 (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-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.3 (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)", ] @@ -932,17 +934,17 @@ name = "tokio-core" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.6 (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-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -953,12 +955,22 @@ dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-fs" +version = "0.1.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)", + "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-io" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -984,7 +996,7 @@ dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -998,7 +1010,7 @@ dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.6 (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)", @@ -1010,7 +1022,7 @@ name = "tokio-tcp" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1020,10 +1032,10 @@ dependencies = [ [[package]] name = "tokio-threadpool" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1033,7 +1045,7 @@ dependencies = [ [[package]] name = "tokio-timer" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1045,7 +1057,7 @@ name = "tokio-udp" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1073,7 +1085,7 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1188,7 +1200,7 @@ name = "zip" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "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)", @@ -1202,21 +1214,21 @@ dependencies = [ "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "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.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6609a866dd1a1b2d0ee1362195bf3e4f6438abb2d80120b83b1e1f4fb6476dd0" +"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" "checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1b2bf7093258c32e0825b635948de528a5949799dcd61bef39534c8aab95870c" +"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" "checksum block-cipher-trait 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6136d803280ae3532efa36114335255ea94f3d75d735ddedd66b0d7cd30bad3" "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 bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" -"checksum bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3eafc42c44e0d827de6b1c131175098fe7fb53b8ce8a47e65cb3ea94688be24" +"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" -"checksum cc 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b90658a0d04c19acb58f07c9076948d3a716db1039674430c94e4aec88de20" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" +"checksum cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebb87d1116151416c0cf66a0e3fb6430cccd120fd6300794b4dfaa050ac40ba" +"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18" "checksum checked_int_cast 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919" "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" @@ -1225,7 +1237,7 @@ dependencies = [ "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2" +"checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" @@ -1235,8 +1247,8 @@ dependencies = [ "checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603" "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.9 (registry+https://github.com/rust-lang/crates.io-index)" = "00c45cec4cde3daac5f036c74098b4956151525cdf360cff5ee0092c98823e54" -"checksum filetime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08530a39af0bd442c40aabb9e854f442a83bd2403feb1ed58fbe982dec2385f3" +"checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a" +"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" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" @@ -1265,7 +1277,7 @@ dependencies = [ "checksum miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aaa2d3ad070f428fffbd7d3ca2ea20bb0d8cffe9024405c44e1840bc1418b398" "checksum miniz_oxide_c_api 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "92d98fdbd6145645828069b37ea92ca3de225e000d80702da25c20d3584b38a5" "checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe" -"checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673" +"checksum mio-uds 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "84c7b5caa3a118a6e34dbac36504503b1e8dc5835e833306b9d6af0e05929f79" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miscreant 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "345b52b06ce7a0e2fab0a0ea99ef52e81d63102ba0425b2914f1867b9d820628" "checksum msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729" @@ -1274,7 +1286,7 @@ dependencies = [ "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7" "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" -"checksum openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)" = "0bbd90640b148b46305c1691eed6039b5c8509bed16991e3562a01eeb76902a3" +"checksum openssl-sys 0.9.30 (registry+https://github.com/rust-lang/crates.io-index)" = "73ae718c3562989cd3a0a5c26610feca02f8116822f6f195e6cf4887481e57f5" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" "checksum pmac 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a82cc12454dc99354a9342c237149aec041ef16f618066d0a682df256b97714" @@ -1286,14 +1298,14 @@ dependencies = [ "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 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb" -"checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb" +"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 safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" +"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)" = "0c855d888276f20d140223bd06515e5bf1647fd6d02593cb5792466d9a8ec2d0" -"checksum serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6c4e049dc657a99e394bd85c22acbf97356feeec6dbf44150f2dcf79fb3118" +"checksum serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "428d3d818cb94ee037a17bf4f2200db2552e19b1825d33df2196624290716f92" +"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 strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" @@ -1305,21 +1317,22 @@ dependencies = [ "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 tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be15ef40f675c9fe66e354d74c73f3ed012ca1aa14d65846a33ee48f1ae8d922" +"checksum tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d00555353b013e170ed8bc4e13f648a317d1fd12157dbcae13f7013f6cf29f5" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" "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-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f46863230f9a05cf52d173721ec391b9c5782a2465f593029922b8782b9ffe" "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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3d05cdd6a78005e535d2b27c21521bdf91fbb321027a62d8e178929d18966d" -"checksum tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "29a89e4ad0c8f1e4c9860e605c38c69bfdad3cccd4ea446e58ff588c1c07a397" +"checksum tokio-threadpool 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5783254b10c7c84a56f62c74766ef7e5b83d1f13053218c7cab8d3f2c826fa0e" +"checksum tokio-timer 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535fed0ccee189f3d48447587697ba3fd234b3dbbb091f0ec4613ddfec0a7c4c" "checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" +"checksum unicode-normalization 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90d662d111b0dbb08a180f2761026cba648c258023c355954a7c00e00e354636" "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" diff --git a/Cargo.toml b/Cargo.toml index 7f9f9b838b84..949066a24739 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shadowsocks-rust" -version = "1.7.0" +version = "1.7.0-alpha" authors = ["Y. T. CHUNG "] description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls." repository = "https://github.com/zonyitoo/shadowsocks-rust" From dfa1345ac2b46a0bfa94d54add259cf973c02146 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Wed, 9 May 2018 00:59:26 +0800 Subject: [PATCH 08/22] Removed deprecated calls of Buf --- src/relay/socks5.rs | 52 ++++++++++++++++++-------------------- src/relay/tcprelay/aead.rs | 6 ++--- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/relay/socks5.rs b/src/relay/socks5.rs index cb7b9ca355d2..7a960eb128c8 100644 --- a/src/relay/socks5.rs +++ b/src/relay/socks5.rs @@ -15,11 +15,12 @@ use bytes::{BufMut, Bytes, BytesMut, IntoBuf}; use futures::{Async, Future, Poll}; -use tokio_io::{IoFuture, AsyncRead, AsyncWrite}; use tokio_io::io::read_exact; +use tokio_io::{AsyncRead, AsyncWrite, IoFuture}; -pub use self::consts::{SOCKS5_AUTH_METHOD_GSSAPI, SOCKS5_AUTH_METHOD_NONE, SOCKS5_AUTH_METHOD_NOT_ACCEPTABLE, - SOCKS5_AUTH_METHOD_PASSWORD}; +pub use self::consts::{ + SOCKS5_AUTH_METHOD_GSSAPI, SOCKS5_AUTH_METHOD_NONE, SOCKS5_AUTH_METHOD_NOT_ACCEPTABLE, SOCKS5_AUTH_METHOD_PASSWORD, +}; use super::utils::{write_bytes, WriteBytes}; @@ -197,8 +198,7 @@ impl error::Error for Error { impl From for Error { fn from(err: io::Error) -> Error { - Error::new(Reply::GeneralFailure, - ::description(&err)) + Error::new(Reply::GeneralFailure, ::description(&err)) } } @@ -442,10 +442,7 @@ impl ReadAddress let buf = self.buf.as_mut().unwrap(); while self.already_read < buf.len() { - match self.reader.as_mut() - .unwrap() - .read(&mut buf[self.already_read..]) - { + match self.reader.as_mut().unwrap().read(&mut buf[self.already_read..]) { Ok(0) => { let err = io::Error::new(io::ErrorKind::Other, "Unexpected EOF"); return Err(err); @@ -491,14 +488,12 @@ fn write_ipv6_address(addr: &SocketAddrV6, buf: &mut B) { } fn write_domain_name_address(dnaddr: &str, port: u16, buf: &mut B) { - use bytes::BigEndian; - assert!(dnaddr.len() <= u8::max_value() as usize); buf.put_u8(consts::SOCKS5_ADDR_TYPE_DOMAIN_NAME); buf.put_u8(dnaddr.len() as u8); buf.put_slice(dnaddr[..].as_bytes()); - buf.put_u16::(port); + buf.put_u16_be(port); } fn write_socket_address(addr: &SocketAddr, buf: &mut B) { @@ -549,7 +544,9 @@ impl TcpRequestHeader { } /// Read from a reader - pub fn read_from(r: R) -> Box + Send + 'static> { + 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]; @@ -629,7 +626,9 @@ impl TcpResponseHeader { } /// Read from a reader - pub fn read_from(r: R) -> Box + Send + 'static> { + 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]; @@ -664,8 +663,7 @@ impl TcpResponseHeader { /// Writes to buffer pub fn write_to_buf(&self, buf: &mut B) { - let TcpResponseHeader { ref reply, - ref address, } = *self; + let TcpResponseHeader { ref reply, ref address } = *self; buf.put_slice(&[consts::SOCKS5_VERSION, reply.as_u8(), 0x00]); address.write_to_buf(buf); } @@ -818,15 +816,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)| { - let frag = buf[2]; - Address::read_from(r).map(move |(r, address)| { - let h = UdpAssociateHeader::new(frag, address); - (r, h) - }) - }); + 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 frag = buf[2]; + Address::read_from(r).map(move |(r, address)| { + let h = UdpAssociateHeader::new(frag, address); + (r, h) + }) + }); Box::new(fut) } @@ -839,8 +838,7 @@ impl UdpAssociateHeader { /// Write to buffer pub fn write_to_buf(&self, buf: &mut B) { - let UdpAssociateHeader { ref frag, - ref address, } = *self; + let UdpAssociateHeader { ref frag, ref address } = *self; buf.put_slice(&[0x00, 0x00, *frag]); address.write_to_buf(buf); } diff --git a/src/relay/tcprelay/aead.rs b/src/relay/tcprelay/aead.rs index 31578fb93e1f..d5e21a088de8 100644 --- a/src/relay/tcprelay/aead.rs +++ b/src/relay/tcprelay/aead.rs @@ -36,7 +36,7 @@ use std::cmp; use std::io::{self, BufRead, Cursor, Read}; use std::u16; -use bytes::{BigEndian, Buf, BufMut, BytesMut}; +use bytes::{Buf, BufMut, BytesMut}; use tokio_io::{AsyncRead, AsyncWrite}; use crypto::{self, BoxAeadDecryptor, BoxAeadEncryptor, CipherType}; @@ -138,7 +138,7 @@ impl DecryptedReader let len = { let mut len_buf = [0u8; 2]; self.cipher.decrypt(data, &mut len_buf, tag)?; - Cursor::new(len_buf).get_u16::() as usize + Cursor::new(len_buf).get_u16_be() as usize }; if len > MAX_PACKET_SIZE { @@ -288,7 +288,7 @@ impl EncryptedWrite for EncryptedWriter let data_length = data.len() as u16; let mut data_len_buf = BytesMut::with_capacity(2); - data_len_buf.put_u16::(data_length); + data_len_buf.put_u16_be(data_length); let mut tag_buf = BytesMut::with_capacity(self.tag_size); unsafe { From 42d51baaf0e89c7143418de794d0bf7ef4e2066b Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Wed, 9 May 2018 09:26:46 +0800 Subject: [PATCH 09/22] Updated dependencies --- Cargo.lock | 69 ++++++------------------------------ Cargo.toml | 14 ++++---- src/relay/tcprelay/client.rs | 5 +-- 3 files changed, 21 insertions(+), 67 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5fd831646b5..0ef5dd9255b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,11 +60,6 @@ dependencies = [ "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "bitflags" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bitflags" version = "1.0.3" @@ -619,10 +614,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl" -version = "0.9.24" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -667,7 +662,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "qrcode" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "checked_int_cast 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -759,11 +754,6 @@ name = "safemem" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "scoped-tls" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "scopeguard" version = "0.3.3" @@ -771,7 +761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -781,7 +771,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.50 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -791,7 +781,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.50 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -814,8 +804,8 @@ dependencies = [ "log 0.4.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.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", - "qrcode 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -824,7 +814,6 @@ dependencies = [ "time 0.1.39 (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.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-signal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", @@ -929,24 +918,6 @@ dependencies = [ "tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio-core" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.6 (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-timer 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio-executor" version = "0.1.2" @@ -988,20 +959,6 @@ dependencies = [ "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio-signal" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio-signal" version = "0.2.0" @@ -1216,7 +1173,6 @@ dependencies = [ "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 base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" -"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "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" "checksum block-cipher-trait 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6136d803280ae3532efa36114335255ea94f3d75d735ddedd66b0d7cd30bad3" @@ -1285,13 +1241,13 @@ dependencies = [ "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7" -"checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" +"checksum openssl 0.10.7 (registry+https://github.com/rust-lang/crates.io-index)" = "63c6ff2c7d9903daf9f3429eb2f6beedb15b1f7362e3529e5bf00b6caf182400" "checksum openssl-sys 0.9.30 (registry+https://github.com/rust-lang/crates.io-index)" = "73ae718c3562989cd3a0a5c26610feca02f8116822f6f195e6cf4887481e57f5" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" "checksum pmac 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a82cc12454dc99354a9342c237149aec041ef16f618066d0a682df256b97714" "checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" -"checksum qrcode 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2859df7fe4bc44b30accf2b6e44e5083a2e9874bbb346df3eb3662b00d457dd3" +"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" @@ -1302,9 +1258,8 @@ dependencies = [ "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 safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "428d3d818cb94ee037a17bf4f2200db2552e19b1825d33df2196624290716f92" +"checksum serde 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)" = "21924cc18e5281f232a17c040355fac97732b42cf019c24996a1642bcb169cdb" "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" @@ -1318,12 +1273,10 @@ dependencies = [ "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 tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d00555353b013e170ed8bc4e13f648a317d1fd12157dbcae13f7013f6cf29f5" -"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" "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-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f46863230f9a05cf52d173721ec391b9c5782a2465f593029922b8782b9ffe" "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" diff --git a/Cargo.toml b/Cargo.toml index 949066a24739..bd48fac0972b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,12 +32,12 @@ sodium = ["libsodium-ffi"] [dependencies] log = "0.4" -byteorder = "1.1" +byteorder = "1.2" rand = "0.4" time = "0.1" clap = "2" -env_logger = "0.5.0-rc.1" -openssl = "0.9" +env_logger = "0.5" +openssl = "0.10" libc = "0.2" futures = "0.1" tokio-io = "0.1" @@ -49,11 +49,11 @@ bytes = "0.4" ring = "0.13.0-alpha" md-5 = "0.7" digest = "0.7" -typenum = "1.9" -qrcode = { version = "0.5", default-features = false } +typenum = "1.10" +qrcode = { version = "0.7", default-features = false } subprocess = "0.1" serde_urlencoded = "0.5" -url = "1.5" +url = "1" byte_string = "1.0" libsodium-ffi = { version = "0.1", optional = true } futures-cpupool = "0.1" @@ -63,4 +63,4 @@ miscreant = { version = "0.3", optional = true } tokio-signal = "0.2" [target.'cfg(windows)'.dependencies] -tokio-signal = "0.1" +tokio-signal = "0.2" diff --git a/src/relay/tcprelay/client.rs b/src/relay/tcprelay/client.rs index ed4bf3dba32a..226084e5d5bf 100644 --- a/src/relay/tcprelay/client.rs +++ b/src/relay/tcprelay/client.rs @@ -10,8 +10,9 @@ use tokio_io::{AsyncRead, AsyncWrite, IoFuture}; use futures::{self, Async, Future, Poll}; use relay::boxed_future; -use relay::socks5::{self, Address, Command, HandshakeRequest, HandshakeResponse, Reply, TcpRequestHeader, - TcpResponseHeader}; +use relay::socks5::{ + self, Address, Command, HandshakeRequest, HandshakeResponse, Reply, TcpRequestHeader, TcpResponseHeader, +}; /// Socks5 proxy client pub struct Socks5Client { From ca85f75c72d7b360bd71e60cd466de1e84e600f7 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Thu, 10 May 2018 01:26:55 +0800 Subject: [PATCH 10/22] [#106] Fixed bug, should not hold UDP connections forever --- src/relay/udprelay/local.rs | 27 +++++++++++++++++++++++++++ src/relay/udprelay/server.rs | 30 +++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/relay/udprelay/local.rs b/src/relay/udprelay/local.rs index c84fa33d41a7..baaa6b009f4b 100644 --- a/src/relay/udprelay/local.rs +++ b/src/relay/udprelay/local.rs @@ -4,11 +4,13 @@ use std::io::{self, Cursor, ErrorKind, Read}; use std::net::SocketAddr; use std::net::{IpAddr, Ipv4Addr}; use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; use futures::{self, Future, Stream}; use tokio; use tokio::net::UdpSocket; +use tokio::util::FutureExt; use tokio_io::IoFuture; use config::{Config, ServerAddr, ServerConfig}; @@ -47,6 +49,7 @@ fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { let svr_cfg_cloned_cloned = svr_cfg.clone(); let socket = socket.clone(); let config = config.clone(); + let timeout = *svr_cfg.timeout(); let rel = futures::lazy(|| UdpAssociateHeader::read_from(Cursor::new(pkt))) .map_err(From::from) @@ -82,12 +85,36 @@ fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { }) .and_then(move |(remote_udp, remote_addr, payload, addr)| { info!("UDP ASSOCIATE {} -> {}, payload length {} bytes", src, addr, payload.len()); + let to = timeout.unwrap_or(Duration::from_secs(5)); + let caddr = addr.clone(); remote_udp.send_dgram(payload, &remote_addr) + .deadline(Instant::now() + to) + .map_err(move |err| { + match err.into_inner() { + Some(e) => e, + None => { + error!("Udp associate sending datagram {} -> {} timed out in {:?}", src, caddr, to); + io::Error::new(io::ErrorKind::TimedOut, "udp send timed out") + } + } + }) .map(|(remote_udp, _)| (remote_udp, addr)) }) .and_then(move |(remote_udp, addr)| { let buf = vec![0u8; MAXIMUM_UDP_PAYLOAD_SIZE]; + let to = timeout.unwrap_or(Duration::from_secs(5)); + let caddr = addr.clone(); remote_udp.recv_dgram(buf) + .deadline(Instant::now() + to) + .map_err(move |err| { + match err.into_inner() { + Some(e) => e, + None => { + error!("Udp associate waiting datagram {} <- {} timed out in {:?}", src, caddr, to); + io::Error::new(io::ErrorKind::TimedOut, "udp recv timed out") + } + } + }) .and_then(move |(_remote_udp, buf, n, _from)| { let svr_cfg = svr_cfg_cloned; decrypt_payload(svr_cfg.method(), svr_cfg.key(), &buf[..n]) diff --git a/src/relay/udprelay/server.rs b/src/relay/udprelay/server.rs index 8fb0639dda64..fb92a99bce04 100644 --- a/src/relay/udprelay/server.rs +++ b/src/relay/udprelay/server.rs @@ -3,11 +3,13 @@ use std::io::{self, Cursor, ErrorKind}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; use futures::{self, Future, Stream}; use tokio; use tokio::net::UdpSocket; +use tokio::util::FutureExt; use tokio_io::IoFuture; use config::{Config, ServerConfig}; @@ -50,6 +52,7 @@ fn listen(config: Arc, svr_cfg: Arc) -> IoFuture<()> { let svr_cfg_cloned = svr_cfg.clone(); let socket = socket.clone(); let config = config.clone(); + let timeout = *svr_cfg.timeout(); let rel = futures::lazy(move || decrypt_payload(svr_cfg.method(), svr_cfg.key(), &pkt)) .and_then(move |payload| { // Read Address in the front (ShadowSocks protocol) @@ -75,9 +78,21 @@ fn listen(config: Arc, svr_cfg: Arc) -> IoFuture<()> { .map(|(remote_udp, _)| (remote_udp, addr)) }) }) - .and_then(|(remote_udp, addr)| { + .and_then(move |(remote_udp, addr)| { let buf = vec![0u8; MAXIMUM_UDP_PAYLOAD_SIZE]; + let to = timeout.unwrap_or(Duration::from_secs(5)); + let caddr = addr.clone(); remote_udp.recv_dgram(buf) + .deadline(Instant::now() + to) + .map_err(move |err| { + match err.into_inner() { + Some(e) => e, + None => { + error!("Udp associate waiting datagram {} -> {} timed out in {:?}", src, caddr, to); + io::Error::new(io::ErrorKind::TimedOut, "udp recv timed out") + } + } + }) .and_then(|(_remote_udp, buf, n, _from)| { let svr_cfg = svr_cfg_cloned; @@ -89,7 +104,20 @@ fn listen(config: Arc, svr_cfg: Arc) -> IoFuture<()> { }) .and_then(move |(buf, addr)| { info!("UDP ASSOCIATE {} <- {}, payload length {} bytes", src, addr, buf.len()); + + let to = timeout.unwrap_or(Duration::from_secs(5)); + let caddr = addr.clone(); SendDgramRc::new(socket, buf, src) + .deadline(Instant::now() + to) + .map_err(move |err| { + match err.into_inner() { + Some(e) => e, + None => { + error!("Udp associate sending datagram {} <- {} timed out in {:?}", src, caddr, to); + io::Error::new(io::ErrorKind::TimedOut, "udp recv timed out") + } + } + }) }) .map(|_| ()); From c53ed633625fa485fc47a925d6ac0133525a5db0 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Thu, 10 May 2018 01:58:17 +0800 Subject: [PATCH 11/22] Lower info log to debug --- src/relay/udprelay/local.rs | 4 ++-- src/relay/udprelay/server.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/relay/udprelay/local.rs b/src/relay/udprelay/local.rs index baaa6b009f4b..f843c665da75 100644 --- a/src/relay/udprelay/local.rs +++ b/src/relay/udprelay/local.rs @@ -84,7 +84,7 @@ fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { .map(|payload| (remote_udp, remote_addr, payload, addr)) }) .and_then(move |(remote_udp, remote_addr, payload, addr)| { - info!("UDP ASSOCIATE {} -> {}, payload length {} bytes", src, addr, payload.len()); + debug!("UDP ASSOCIATE {} -> {}, payload length {} bytes", src, addr, payload.len()); let to = timeout.unwrap_or(Duration::from_secs(5)); let caddr = addr.clone(); remote_udp.send_dgram(payload, &remote_addr) @@ -128,7 +128,7 @@ fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { }) .and_then(move |(mut cur, addr)| { let payload_len = cur.get_ref().len() - cur.position() as usize; - info!("UDP ASSOCIATE {} <- {}, payload length {} bytes", src, addr, payload_len); + debug!("UDP ASSOCIATE {} <- {}, payload length {} bytes", src, addr, payload_len); let mut data = Vec::new(); UdpAssociateHeader::new(0, Address::SocketAddress(src)).write_to_buf(&mut data); diff --git a/src/relay/udprelay/server.rs b/src/relay/udprelay/server.rs index fb92a99bce04..7d0a65080371 100644 --- a/src/relay/udprelay/server.rs +++ b/src/relay/udprelay/server.rs @@ -64,7 +64,7 @@ fn listen(config: Arc, svr_cfg: Arc) -> IoFuture<()> { payload.drain(..header_len); let body = payload; - info!("UDP ASSOCIATE {} -> {}, payload length {} bytes", src, addr, body.len()); + debug!("UDP ASSOCIATE {} -> {}, payload length {} bytes", src, addr, body.len()); Ok((addr, body)) }) .and_then(|(addr, body)| { @@ -103,7 +103,7 @@ fn listen(config: Arc, svr_cfg: Arc) -> IoFuture<()> { }) }) .and_then(move |(buf, addr)| { - info!("UDP ASSOCIATE {} <- {}, payload length {} bytes", src, addr, buf.len()); + debug!("UDP ASSOCIATE {} <- {}, payload length {} bytes", src, addr, buf.len()); let to = timeout.unwrap_or(Duration::from_secs(5)); let caddr = addr.clone(); @@ -114,7 +114,7 @@ fn listen(config: Arc, svr_cfg: Arc) -> IoFuture<()> { Some(e) => e, None => { error!("Udp associate sending datagram {} <- {} timed out in {:?}", src, caddr, to); - io::Error::new(io::ErrorKind::TimedOut, "udp recv timed out") + io::Error::new(io::ErrorKind::TimedOut, "udp send timed out") } } }) From df133764389c98efe8fb20b348b840e92308c2bb Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Thu, 10 May 2018 09:17:03 +0800 Subject: [PATCH 12/22] Bump version to v1.7.0-alpha.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ef5dd9255b7..8027fd7ee213 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -787,7 +787,7 @@ dependencies = [ [[package]] name = "shadowsocks-rust" -version = "1.7.0-alpha" +version = "1.7.0-alpha.2" 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)", diff --git a/Cargo.toml b/Cargo.toml index bd48fac0972b..23cf72071f18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shadowsocks-rust" -version = "1.7.0-alpha" +version = "1.7.0-alpha.2" authors = ["Y. T. CHUNG "] description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls." repository = "https://github.com/zonyitoo/shadowsocks-rust" From 2c916eb4ca0da405d4135efd134bd1d7dc400310 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Fri, 11 May 2018 00:36:50 +0800 Subject: [PATCH 13/22] Implement a simple DNS relay server, bump version to v1.7.0-alpha.3 --- Cargo.lock | 43 +++- Cargo.toml | 8 +- README.md | 8 +- src/bin/ssdns.rs | 206 ++++++++++++++++++ src/config.rs | 432 +++++++++++++++++--------------------- src/lib.rs | 3 + src/relay/dns.rs | 18 ++ src/relay/mod.rs | 1 + src/relay/udprelay/dns.rs | 165 +++++++++++++++ src/relay/udprelay/mod.rs | 1 + 10 files changed, 636 insertions(+), 249 deletions(-) create mode 100644 src/bin/ssdns.rs create mode 100644 src/relay/dns.rs create mode 100644 src/relay/udprelay/dns.rs diff --git a/Cargo.lock b/Cargo.lock index 8027fd7ee213..c06c25ef3103 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -280,6 +280,15 @@ dependencies = [ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +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)", + "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dtoa" version = "0.4.2" @@ -394,7 +403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -454,6 +463,11 @@ dependencies = [ "zip 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "linked-hash-map" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "log" version = "0.4.1" @@ -462,6 +476,14 @@ dependencies = [ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lru-cache" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "matches" version = "0.1.6" @@ -761,7 +783,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.51" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -771,7 +793,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.51 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -781,13 +803,13 @@ 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.51 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "shadowsocks-rust" -version = "1.7.0-alpha.2" +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)", @@ -795,6 +817,7 @@ dependencies = [ "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)", @@ -802,6 +825,7 @@ dependencies = [ "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)", "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)", "md-5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "miscreant 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1042,7 +1066,7 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1201,6 +1225,7 @@ dependencies = [ "checksum crypto-mac 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "99376574a55849855052aa6e3b15f3bdebf8bcdd3b24f3cbc3371469bcd5b480" "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" @@ -1224,7 +1249,9 @@ dependencies = [ "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.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" "checksum md-5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9402eaae33a9e144ce18ef488a0e4ca19869673c7bcdbbfe2030fdc3f84211cd" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" @@ -1259,7 +1286,7 @@ dependencies = [ "checksum ring 0.13.0-alpha (registry+https://github.com/rust-lang/crates.io-index)" = "946e5e2b336032275e23152755ec2a0610ede0302101d3666fdb686795d26535" "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.51 (registry+https://github.com/rust-lang/crates.io-index)" = "21924cc18e5281f232a17c040355fac97732b42cf019c24996a1642bcb169cdb" +"checksum serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "1921d0c6997bf121f5a85e3fed9ffd2cdfa87254f84e92f9b72e4cd84fbcf79f" "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" @@ -1285,7 +1312,7 @@ dependencies = [ "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90d662d111b0dbb08a180f2761026cba648c258023c355954a7c00e00e354636" +"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" diff --git a/Cargo.toml b/Cargo.toml index 23cf72071f18..9f3c0c7e9c71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shadowsocks-rust" -version = "1.7.0-alpha.2" +version = "1.7.0-alpha.3" authors = ["Y. T. CHUNG "] description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls." repository = "https://github.com/zonyitoo/shadowsocks-rust" @@ -23,6 +23,10 @@ path = "src/bin/server.rs" name = "ssurl" path = "src/bin/ssurl.rs" +[[bin]] +name = "ssdns" +path = "src/bin/ssdns.rs" + [profile.release] lto = true @@ -58,6 +62,8 @@ 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" [target.'cfg(unix)'.dependencies] tokio-signal = "0.2" diff --git a/README.md b/README.md index 85cd7983e113..5edb6b7b114f 100644 --- a/README.md +++ b/README.md @@ -182,9 +182,11 @@ $ ssserver -s "[::]:8388" -m "aes-256-gcm" -k "hello-kitty" --plugin "obfs-serve 1. `ssurl` is for encoding and decoding ShadowSocks URLs (SIP002). Example: -```plain -ss://YWVzLTI1Ni1jZmI6cGFzc3dvcmQ@127.0.0.1:8388/?plugin=obfs-local%3Bobfs%3Dhttp%3Bobfs-host%3Dwww.baidu.com -``` + ```plain + ss://YWVzLTI1Ni1jZmI6cGFzc3dvcmQ@127.0.0.1:8388/?plugin=obfs-local%3Bobfs%3Dhttp%3Bobfs-host%3Dwww.baidu.com + ``` + +2. `ssdns` is a DNS server which will do DNS queries via ShadowSocks' servers. Currently it only supports UDP DNS. ## Notes diff --git a/src/bin/ssdns.rs b/src/bin/ssdns.rs new file mode 100644 index 000000000000..b67a928135b7 --- /dev/null +++ b/src/bin/ssdns.rs @@ -0,0 +1,206 @@ +//! DNS over shadowsocks + +extern crate clap; +extern crate shadowsocks; +extern crate tokio; +#[macro_use] +extern crate log; +extern crate env_logger; +extern crate time; + +use clap::{App, Arg}; + +use std::env; +use std::io::{self, Write}; +use std::net::SocketAddr; + +use env_logger::fmt::Formatter; +use env_logger::Builder; +use log::{LevelFilter, Record}; + +use shadowsocks::{run_dns, Config, ConfigType, ServerAddr, ServerConfig}; + +fn log_time(fmt: &mut Formatter, without_time: bool, record: &Record) -> io::Result<()> { + if without_time { + writeln!(fmt, "[{}] {}", record.level(), record.args()) + } else { + writeln!(fmt, + "[{}][{}] {}", + time::now().strftime("%Y-%m-%d][%H:%M:%S.%f").unwrap(), + record.level(), + record.args()) + } +} + +fn log_time_module(fmt: &mut Formatter, without_time: bool, record: &Record) -> io::Result<()> { + if without_time { + writeln!(fmt, + "[{}] [{}] {}", + record.level(), + record.module_path().unwrap_or("*"), + record.args()) + } else { + writeln!(fmt, + "[{}][{}] [{}] {}", + time::now().strftime("%Y-%m-%d][%H:%M:%S.%f").unwrap(), + record.level(), + record.module_path().unwrap_or("*"), + record.args()) + } +} + +fn main() { + let matches = App::new("ssdns") + .version(shadowsocks::VERSION) + .about("A DNS proxy that helps you bypass firewalls.") + .arg(Arg::with_name("VERBOSE") + .short("v") + .multiple(true) + .help("Set the level of debug")) + .arg(Arg::with_name("CONFIG") + .short("c") + .long("config") + .takes_value(true) + .help("Specify config file")) + .arg(Arg::with_name("SERVER_ADDR") + .short("s") + .long("server-addr") + .takes_value(true) + .help("Server address")) + .arg(Arg::with_name("LOCAL_ADDR") + .short("b") + .long("local-addr") + .takes_value(true) + .help("Local address, listen only to this address if specified")) + .arg(Arg::with_name("PASSWORD") + .short("k") + .long("password") + .takes_value(true) + .help("Password")) + .arg(Arg::with_name("ENCRYPT_METHOD") + .short("m") + .long("encrypt-method") + .takes_value(true) + .help("Encryption method")) + .arg(Arg::with_name("LOG_WITHOUT_TIME") + .long("log-without-time") + .help("Disable time in log")) + .arg(Arg::with_name("URL") + .long("server-url") + .takes_value(true) + .help("Server address in SIP002 URL")) + .get_matches(); + + let mut log_builder = Builder::new(); + log_builder.filter(None, LevelFilter::Info); + + let without_time = matches.is_present("LOG_WITHOUT_TIME"); + + let debug_level = matches.occurrences_of("VERBOSE"); + match debug_level { + 0 => { + // Default filter + log_builder.format(move |fmt, r| log_time(fmt, without_time, r)); + } + 1 => { + let log_builder = log_builder.format(move |fmt, r| log_time_module(fmt, without_time, r)); + log_builder.filter(Some("sslocal"), LevelFilter::Debug); + } + 2 => { + let log_builder = log_builder.format(move |fmt, r| log_time_module(fmt, without_time, r)); + log_builder.filter(Some("sslocal"), LevelFilter::Debug) + .filter(Some("shadowsocks"), LevelFilter::Debug); + } + 3 => { + let log_builder = log_builder.format(move |fmt, r| log_time_module(fmt, without_time, r)); + log_builder.filter(Some("sslocal"), LevelFilter::Trace) + .filter(Some("shadowsocks"), LevelFilter::Trace); + } + _ => { + let log_builder = log_builder.format(move |fmt, r| log_time_module(fmt, without_time, r)); + log_builder.filter(None, LevelFilter::Trace); + } + } + + if let Ok(env_conf) = env::var("RUST_LOG") { + log_builder.parse(&env_conf); + } + + log_builder.init(); + + 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; + } + } + } + None => Config::new(), + }; + + let mut has_provided_server_config = + match (matches.value_of("SERVER_ADDR"), matches.value_of("PASSWORD"), matches.value_of("ENCRYPT_METHOD")) { + (Some(svr_addr), Some(password), Some(method)) => { + let method = match method.parse() { + Ok(m) => m, + Err(err) => { + panic!("Does not support {:?} method: {:?}", method, err); + } + }; + + let sc = ServerConfig::new(svr_addr.parse::().expect("Invalid server addr"), + password.to_owned(), + method, + None, + None); + + config.server.push(sc); + true + } + (None, None, None) => { + // Does not provide server config + false + } + _ => { + panic!("`server-addr`, `method` and `password` should be provided together"); + } + }; + + if let Some(url) = matches.value_of("URL") { + let svr_addr = url.parse::().expect("Failed to parse `url`"); + + has_provided_server_config = true; + + config.server.push(svr_addr); + } + + let has_provided_local_config = match matches.value_of("LOCAL_ADDR") { + Some(local_addr) => { + let local_addr: SocketAddr = local_addr.parse().expect("`local-addr` is not a valid IP address"); + + config.local = Some(local_addr); + true + } + None => false, + }; + + if !has_provided_config && !(has_provided_server_config && has_provided_local_config) { + println!("You have to specify a configuration file or pass arguments by argument list"); + println!("{}", matches.usage()); + return; + } + + info!("ShadowSocks DNS {}", shadowsocks::VERSION); + + debug!("Config: {:?}", config); + + run_dns(config); +} diff --git a/src/config.rs b/src/config.rs index 08ddd991c09e..121cbc9b8776 100644 --- a/src/config.rs +++ b/src/config.rs @@ -40,7 +40,7 @@ //! ``` //! //! These defined server will be used with a load balancing algorithm. -//! +//! use std::collections::HashSet; use std::convert::From; @@ -48,8 +48,8 @@ use std::default::Default; use std::error; use std::fmt::{self, Debug, Display, Formatter}; use std::fs::OpenOptions; -use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use std::net::IpAddr; +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use std::option::Option; use std::path::Path; use std::str::FromStr; @@ -138,10 +138,12 @@ impl FromStr for ServerAddr { Err(..) => { let mut sp = s.split(':'); match (sp.next(), sp.next()) { - (Some(dn), Some(port)) => match port.parse::() { - Ok(port) => Ok(ServerAddr::DomainName(dn.to_owned(), port)), - Err(..) => Err(ServerAddrError), - }, + (Some(dn), Some(port)) => { + match port.parse::() { + Ok(port) => Ok(ServerAddr::DomainName(dn.to_owned(), port)), + Err(..) => Err(ServerAddrError), + } + } _ => Err(ServerAddrError), } } @@ -177,23 +179,20 @@ pub struct ServerConfig { impl ServerConfig { /// Creates a new ServerConfig - pub fn new( - addr: ServerAddr, - pwd: String, - method: CipherType, - timeout: Option, - plugin: Option, - ) -> ServerConfig { + pub fn new(addr: ServerAddr, + pwd: String, + method: CipherType, + timeout: Option, + plugin: Option) + -> ServerConfig { let enc_key = method.bytes_to_key(pwd.as_bytes()); trace!("Initialize config with pwd: {:?}, key: {:?}", pwd, enc_key); - ServerConfig { - addr: addr, - password: pwd, - method: method, - timeout: timeout, - enc_key: enc_key, - plugin: plugin, - } + ServerConfig { addr: addr, + password: pwd, + method: method, + timeout: timeout, + enc_key: enc_key, + plugin: plugin, } } /// Create a basic config @@ -288,12 +287,14 @@ impl ServerConfig { let user_info = parsed.username(); let account = match decode_config(user_info, URL_SAFE_NO_PAD) { - Ok(account) => match String::from_utf8(account) { - Ok(ac) => ac, - Err(..) => { - return Err(UrlParseError::InvalidAuthInfo); + Ok(account) => { + match String::from_utf8(account) { + Ok(ac) => ac, + Err(..) => { + return Err(UrlParseError::InvalidAuthInfo); + } } - }, + } Err(err) => { error!("Failed to parse UserInfo with Base64, err: {}", err); return Err(UrlParseError::InvalidUserInfo); @@ -341,10 +342,8 @@ impl ServerConfig { match vsp.next() { None => {} Some(p) => { - plugin = Some(PluginConfig { - plugin: p.to_owned(), - plugin_opt: vsp.next().map(ToOwned::to_owned), - }) + plugin = Some(PluginConfig { plugin: p.to_owned(), + plugin_opt: vsp.next().map(ToOwned::to_owned), }) } } } @@ -465,6 +464,7 @@ pub struct Config { pub local: Option, pub enable_udp: bool, pub forbidden_ip: HashSet, + pub dns: SocketAddr, } impl Default for Config { @@ -492,47 +492,37 @@ pub struct Error { impl Error { pub fn new(kind: ErrorKind, desc: &'static str, detail: Option) -> Error { - Error { - kind: kind, - desc: desc, - detail: detail, - } + Error { kind: kind, + desc: desc, + detail: detail, } } } macro_rules! impl_from { - ($error:ty,$kind:expr,$desc:expr) => ( + ($error:ty, $kind:expr, $desc:expr) => { impl From<$error> for Error { - fn from(err:$error) -> Self { - Error::new($kind,$desc,Some(format!("{:?}",err))) + fn from(err: $error) -> Self { + Error::new($kind, $desc, Some(format!("{:?}", err))) } } - ) + }; } -impl_from!( - ::std::io::Error, - ErrorKind::IoError, - "error while reading file" -); -impl_from!( - serde_json::Error, - ErrorKind::JsonParsingError, - "Json parse error" -); +impl_from!(::std::io::Error, ErrorKind::IoError, "error while reading file"); +impl_from!(serde_json::Error, ErrorKind::JsonParsingError, "Json parse error"); macro_rules! except { - ($expr:expr,$kind:expr,$desc:expr) => (except!($expr,$kind,$desc,None)); - ($expr:expr,$kind:expr,$desc:expr,$detail:expr) => ( + ($expr:expr, $kind:expr, $desc:expr) => { + except!($expr, $kind, $desc, None) + }; + ($expr:expr, $kind:expr, $desc:expr, $detail:expr) => { match $expr { ::std::option::Option::Some(val) => val, ::std::option::Option::None => { - return ::std::result::Result::Err( - $crate::config::Error::new($kind,$desc,$detail) - ) + return ::std::result::Result::Err($crate::config::Error::new($kind, $desc, $detail)) } } - ) + }; } impl Debug for Error { fn fmt(&self, f: &mut Formatter) -> fmt::Result { @@ -546,94 +536,78 @@ impl Debug for Error { impl Config { /// Creates an empty configuration pub fn new() -> Config { - Config { - server: Vec::new(), - local: None, - enable_udp: false, - forbidden_ip: HashSet::new(), - } + Config { server: Vec::new(), + local: None, + enable_udp: false, + forbidden_ip: HashSet::new(), + dns: "8.8.8.8:53".parse::().unwrap(), } } fn parse_server(server: &Map) -> Result { - let method = server - .get("method") - .ok_or_else(|| Error::new(ErrorKind::MissingField, "need to specify a method", None)) - .and_then(|method_o| { - method_o - .as_str() - .ok_or_else(|| Error::new(ErrorKind::Malformed, "`method` should be a string", None)) - }) - .and_then(|method_str| { - method_str.parse::().map_err(|_| { - Error::new( - ErrorKind::Invalid, - "not supported method", - Some(format!("`{}` is not a supported method", method_str)), - ) - }) - })?; - - let port = server - .get("port") - .or_else(|| server.get("server_port")) - .ok_or_else(|| { - Error::new( - ErrorKind::MissingField, - "need to specify a server port", - None, - ) - }) - .and_then(|port_o| { - port_o - .as_u64() - .map(|u| u as u16) - .ok_or_else(|| Error::new(ErrorKind::Malformed, "`port` should be an integer", None)) - })?; - - let addr = server - .get("address") - .or_else(|| server.get("server")) - .ok_or_else(|| { - Error::new( - ErrorKind::MissingField, - "need to specify a server address", - None, - ) - }) - .and_then(|addr_o| { - addr_o - .as_str() - .ok_or_else(|| Error::new(ErrorKind::Malformed, "`address` should be a string", None)) - }) - .and_then(|addr_str| { - addr_str - .parse::() - .map(|v4| ServerAddr::SocketAddr(SocketAddr::V4(SocketAddrV4::new(v4, port)))) - .or_else(|_| { - addr_str + let method = server.get("method") + .ok_or_else(|| Error::new(ErrorKind::MissingField, "need to specify a method", None)) + .and_then(|method_o| { + method_o.as_str().ok_or_else(|| { + Error::new(ErrorKind::Malformed, + "`method` should be a string", + None) + }) + }) + .and_then(|method_str| { + method_str.parse::().map_err(|_| { + Error::new(ErrorKind::Invalid, + "not supported method", + Some(format!("`{}` is not a supported method", method_str))) + }) + })?; + + let port = server.get("port") + .or_else(|| server.get("server_port")) + .ok_or_else(|| Error::new(ErrorKind::MissingField, "need to specify a server port", None)) + .and_then(|port_o| { + port_o.as_u64().map(|u| u as u16).ok_or_else(|| { + Error::new(ErrorKind::Malformed, + "`port` should be an integer", + None) + }) + })?; + + let addr = server.get("address") + .or_else(|| server.get("server")) + .ok_or_else(|| Error::new(ErrorKind::MissingField, "need to specify a server address", None)) + .and_then(|addr_o| { + addr_o.as_str().ok_or_else(|| { + Error::new(ErrorKind::Malformed, + "`address` should be a string", + None) + }) + }) + .and_then(|addr_str| { + addr_str.parse::() + .map(|v4| ServerAddr::SocketAddr(SocketAddr::V4(SocketAddrV4::new(v4, port)))) + .or_else(|_| { + addr_str .parse::() .map(|v6| ServerAddr::SocketAddr(SocketAddr::V6(SocketAddrV6::new(v6, port, 0, 0)))) - }) - .or_else(|_| Ok(ServerAddr::DomainName(addr_str.to_string(), port))) - })?; - - let password = server - .get("password") - .ok_or_else(|| Error::new(ErrorKind::MissingField, "need to specify a password", None)) - .and_then(|pwd_o| { - pwd_o - .as_str() - .ok_or_else(|| Error::new(ErrorKind::Malformed, "`password` should be a string", None)) - .map(|s| s.to_string()) - })?; + }) + .or_else(|_| Ok(ServerAddr::DomainName(addr_str.to_string(), port))) + })?; + + let password = server.get("password") + .ok_or_else(|| Error::new(ErrorKind::MissingField, "need to specify a password", None)) + .and_then(|pwd_o| { + pwd_o.as_str() + .ok_or_else(|| { + Error::new(ErrorKind::Malformed, + "`password` should be a string", + None) + }) + .map(|s| s.to_string()) + })?; let timeout = match server.get("timeout") { Some(t) => { - let val = t.as_u64().ok_or(Error::new( - ErrorKind::Malformed, - "`timeout` should be an integer", - None, - ))?; + let val = t.as_u64().ok_or(Error::new(ErrorKind::Malformed, "`timeout` should be an integer", None))?; Some(Duration::from_secs(val)) } None => None, @@ -641,27 +615,23 @@ impl Config { let plugin = match server.get("plugin") { Some(p) => { - let plugin = p.as_str() - .ok_or_else(|| Error::new(ErrorKind::Malformed, "`plugin` should be a string", None))?; + let plugin = + p.as_str().ok_or_else(|| Error::new(ErrorKind::Malformed, "`plugin` should be a string", None))?; let opt = match server.get("plugin_opts") { None => None, Some(o) => { let o = o.as_str().ok_or_else(|| { - Error::new( - ErrorKind::Malformed, - "`plugin_opts` should be a string", - None, - ) - })?; + Error::new(ErrorKind::Malformed, + "`plugin_opts` should be a string", + None) + })?; Some(o.to_owned()) } }; - Some(PluginConfig { - plugin: plugin.to_owned(), - plugin_opt: opt, - }) + Some(PluginConfig { plugin: plugin.to_owned(), + plugin_opt: opt, }) } None => None, }; @@ -673,11 +643,9 @@ impl Config { let mut config = Config::new(); if o.contains_key("servers") { - let server_list = o.get("servers").unwrap().as_array().ok_or(Error::new( - ErrorKind::Malformed, - "`servers` should be a list", - None, - ))?; + let server_list = o.get("servers").unwrap() + .as_array() + .ok_or(Error::new(ErrorKind::Malformed, "`servers` should be a list", None))?; for server in server_list.iter() { if let Some(server) = server.as_object() { @@ -686,7 +654,7 @@ impl Config { } } } else if o.contains_key("server") && o.contains_key("server_port") && o.contains_key("password") - && o.contains_key("method") + && o.contains_key("method") { // Traditional configuration file let single_server = Config::parse_server(o)?; @@ -700,31 +668,28 @@ impl Config { if has_local_address && has_local_port { config.local = match o.get("local_address") { Some(local_addr) => { - let addr_str = local_addr.as_str().ok_or(Error::new( - ErrorKind::Malformed, - "`local_address` should be a string", - None, - ))?; - - let port = o.get("local_port").unwrap().as_u64().ok_or(Error::new( - ErrorKind::Malformed, - "`local_port` should be an integer", - None, - ))? as u16; + let addr_str = local_addr.as_str().ok_or(Error::new(ErrorKind::Malformed, + "`local_address` should be a string", + None))?; + + let port = o.get("local_port").unwrap() + .as_u64() + .ok_or(Error::new(ErrorKind::Malformed, "`local_port` should be an integer", None))? + as u16; match addr_str.parse::() { Ok(ip) => Some(SocketAddr::V4(SocketAddrV4::new(ip, port))), - Err(..) => match addr_str.parse::() { - Ok(ip) => Some(SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0))), - Err(..) => { - return Err(Error::new( - ErrorKind::Malformed, - "`local_address` is not a valid IP \ - address", - None, - )) + Err(..) => { + match addr_str.parse::() { + Ok(ip) => Some(SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0))), + Err(..) => { + return Err(Error::new(ErrorKind::Malformed, + "`local_address` is not a valid IP \ + address", + None)) + } } - }, + } } } None => None, @@ -735,33 +700,27 @@ impl Config { } if let Some(forbidden_ip_conf) = o.get("forbidden_ip") { - let forbidden_ip_arr = forbidden_ip_conf.as_array().ok_or(Error::new( - ErrorKind::Malformed, - "`forbidden_ip` should be a list", - None, - ))?; - config - .forbidden_ip - .extend(forbidden_ip_arr.into_iter().filter_map(|x| { - let x = match x.as_str() { - Some(x) => x, - None => { - error!( - "Forbidden IP should be a string, but found {:?}, skipping", - x - ); - return None; - } - }; - - match x.parse::() { - Ok(sock) => Some(sock), - Err(err) => { - error!("Invalid forbidden IP {}, {:?}, skipping", x, err); - None - } - } - })); + let forbidden_ip_arr = forbidden_ip_conf.as_array().ok_or(Error::new(ErrorKind::Malformed, + "`forbidden_ip` should be a list", + None))?; + config.forbidden_ip.extend(forbidden_ip_arr.into_iter().filter_map(|x| { + let x = match x.as_str() { + Some(x) => x, + None => { + error!("Forbidden IP should be a string, but found {:?}, skipping", + x); + return None; + } + }; + + match x.parse::() { + Ok(sock) => Some(sock), + Err(err) => { + error!("Invalid forbidden IP {}, {:?}, skipping", x, err); + None + } + } + })); } if let Some(udp_enable) = o.get("enable_udp") { @@ -774,40 +733,48 @@ impl Config { } } + if let Some(dns) = o.get("dns") { + match dns.as_str() { + None => { + let err = Error::new(ErrorKind::Malformed, "`dns` should be string", None); + return Err(err); + } + Some(dns) => match dns.parse::() { + Err(..) => { + let err = Error::new(ErrorKind::Malformed, "`dns` should be IpAddr", None); + return Err(err); + } + Ok(addr) => { + config.dns = SocketAddr::new(addr, 53); + } + }, + } + } + Ok(config) } pub fn load_from_str(s: &str, config_type: ConfigType) -> Result { let object = serde_json::from_str::(s)?; - let json_object = except!( - object.as_object(), - ErrorKind::JsonParsingError, - "root is not a JsonObject" - ); - Config::parse_json_object( - json_object, - match config_type { - ConfigType::Local => true, - ConfigType::Server => false, - }, - ) + let json_object = except!(object.as_object(), + ErrorKind::JsonParsingError, + "root is not a JsonObject"); + Config::parse_json_object(json_object, match config_type { + ConfigType::Local => true, + ConfigType::Server => false, + }) } pub fn load_from_file(filename: &str, config_type: ConfigType) -> Result { let reader = &mut OpenOptions::new().read(true).open(&Path::new(filename))?; let object = serde_json::from_reader::<_, Value>(reader)?; - let json_object = except!( - object.as_object(), - ErrorKind::JsonParsingError, - "root is not a JsonObject" - ); - Config::parse_json_object( - json_object, - match config_type { - ConfigType::Local => true, - ConfigType::Server => false, - }, - ) + let json_object = except!(object.as_object(), + ErrorKind::JsonParsingError, + "root is not a JsonObject"); + Config::parse_json_object(json_object, match config_type { + ConfigType::Local => true, + ConfigType::Server => false, + }) } } @@ -820,14 +787,8 @@ impl Config { let server = &self.server[0]; server.addr.to_json_object_old(&mut obj); - obj.insert( - "password".to_owned(), - Value::String(server.password.clone()), - ); - obj.insert( - "method".to_owned(), - Value::String(server.method.to_string()), - ); + obj.insert("password".to_owned(), Value::String(server.password.clone())); + obj.insert("method".to_owned(), Value::String(server.method.to_string())); if let Some(t) = server.timeout { obj.insert("timeout".to_owned(), Value::Number(From::from(t.as_secs()))); } @@ -850,10 +811,7 @@ impl Config { }; obj.insert("local_address".to_owned(), Value::String(ip_str)); - obj.insert( - "local_port".to_owned(), - Value::Number(From::from(l.port() as u64)), - ); + obj.insert("local_port".to_owned(), Value::Number(From::from(l.port() as u64))); } obj.insert("enable_udp".to_owned(), Value::Bool(self.enable_udp)); diff --git a/src/lib.rs b/src/lib.rs index 3a3d028d5b76..7cf810b28084 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -96,6 +96,8 @@ extern crate serde_urlencoded; extern crate subprocess; #[macro_use] extern crate tokio_io; +extern crate dns_parser; +extern crate lru_cache; extern crate tokio; #[cfg(any(unix, windows))] extern crate tokio_signal; @@ -106,6 +108,7 @@ extern crate url; pub const VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub use self::config::{ClientConfig, Config, ConfigType, ServerAddr, ServerConfig}; +pub use self::relay::dns::run as run_dns; pub use self::relay::local::run as run_local; pub use self::relay::server::run as run_server; pub use self::relay::tcprelay::client::Socks5Client; diff --git a/src/relay/dns.rs b/src/relay/dns.rs new file mode 100644 index 000000000000..b176e990cd4d --- /dev/null +++ b/src/relay/dns.rs @@ -0,0 +1,18 @@ +//! DNS relay + +use std::sync::Arc; + +use futures::Future; +use tokio; + +use config::Config; +use relay::udprelay::dns::run as run_udp; + +/// DNS Relay server running under local environment. +pub fn run(config: Config) { + let config = Arc::new(config); + tokio::run(run_udp(config).then(|res| match res { + Ok(..) => Ok(()), + Err(err) => panic!("Failed to run server, err: {}", err), + })); +} diff --git a/src/relay/mod.rs b/src/relay/mod.rs index 2a4241fbd6df..1d8b20a4ae45 100644 --- a/src/relay/mod.rs +++ b/src/relay/mod.rs @@ -2,6 +2,7 @@ use futures::Future; +pub mod dns; mod dns_resolver; mod loadbalancing; pub mod local; diff --git a/src/relay/udprelay/dns.rs b/src/relay/udprelay/dns.rs new file mode 100644 index 000000000000..d3140474088f --- /dev/null +++ b/src/relay/udprelay/dns.rs @@ -0,0 +1,165 @@ +//! UDP DNS relay + +use std::io::{self, Cursor}; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::sync::{Arc, Mutex}; + +use dns_parser::Packet; +use futures::future::join_all; +use futures::{self, Future, Stream}; +use lru_cache::LruCache; +use tokio::net::UdpSocket; +use tokio_io::IoFuture; + +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::socks5::Address; + +/// Starts a UDP DNS server +pub fn run(config: Arc) -> IoFuture<()> { + let local_addr = *config.local.as_ref().unwrap(); + + let fut = futures::lazy(move || { + info!("ShadowSocks UDP DNS Listening on {}", local_addr); + + UdpSocket::bind(&local_addr) + }).and_then(move |l| listen(config, l)); + + boxed_future(fut) +} + +fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { + assert!(!config.server.is_empty()); + + let mut svr_fut = Vec::with_capacity(config.server.len()); + for svr in &config.server { + match *svr.addr() { + ServerAddr::SocketAddr(ref addr) => { + 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)); + } + } + } + + 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) +} + +lazy_static! { + static ref GLOBAL_QUERY_ADDR: Mutex> = Mutex::new(LruCache::new(1024)); +} + +fn handle_l2r(config: Arc, + l: SharedUdpSocket, + server: Vec<(SharedUdpSocket, Arc, SocketAddr)>) + -> IoFuture<()> { + 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)| { + let server = server.clone(); + let config = config.clone(); + futures::lazy(move || { + let pkt = Packet::parse(&payload[..]).map_err(|err| { + error!("Failed to parse DNS payload, err: {}", err); + io::Error::new(io::ErrorKind::Other, + "parse DNS packet failed") + })?; + + debug!("DNS QUERY id={} src={} {:?}", pkt.header.id, src, pkt); + + let (ref socket, ref svr_cfg, svr_addr) = &server[server_idx % server.len()]; + let (ni, _) = server_idx.overflowing_add(1); + server_idx = ni; + + let mut buf = Vec::new(); + Address::SocketAddress(config.dns).write_to_buf(&mut buf); + + buf.extend_from_slice(&payload); + + let socket = socket.clone(); + let id = pkt.header.id; + encrypt_payload(svr_cfg.method(), svr_cfg.key(), &buf).map(move |send_payload| { + (socket, + *svr_addr, + send_payload, + id) + }) + }).and_then(move |(socket, svr_addr, send_payload, id)| { + SendDgramRc::new(socket, send_payload, svr_addr).map(move |_| { + GLOBAL_QUERY_ADDR.lock().unwrap().insert(id, src); + }) + }) + }); + boxed_future(fut) +} + +fn handle_r2l(l: SharedUdpSocket, r: SharedUdpSocket, svr_cfg: Arc) -> IoFuture<()> { + let fut = PacketStream::new(r).for_each(move |(payload, src)| { + let l = l.clone(); + let svr_cfg = svr_cfg.clone(); + futures::lazy(move || { + decrypt_payload(svr_cfg.method(), svr_cfg.key(), &payload) + }).and_then(move |payload| { + Address::read_from(Cursor::new(payload)) + .map_err(From::from) + }).and_then(move |(cur, ..)| { + let pos = cur.position() as usize; + let payload = cur.into_inner(); + + let pkt = Packet::parse(&payload[pos..]).map_err(|err| { + error!("Failed to parse DNS payload, err: {}", err); + io::Error::new(io::ErrorKind::Other, "parse DNS packet failed") + })?; + + let payload = payload[pos..].to_vec(); + + debug!("DNS RESPONSE id={} server={} {:?}", pkt.header.id, src, pkt); + + Ok((pkt.header.id, payload)) + }).and_then(move |(id, payload)| { + match GLOBAL_QUERY_ADDR.lock().unwrap().remove(&id) { + Some(cli_addr) => { + let f = SendDgramRc::new(l, payload, cli_addr) + .map(|_| ()); + boxed_future(f) + } + None => { + boxed_future(futures::finished(())) + } + } + }) + }); + + boxed_future(fut) +} diff --git a/src/relay/udprelay/mod.rs b/src/relay/udprelay/mod.rs index 7620a2db51c4..8c67bfe366e3 100644 --- a/src/relay/udprelay/mod.rs +++ b/src/relay/udprelay/mod.rs @@ -46,6 +46,7 @@ use tokio::net::UdpSocket; use futures::{Async, Future, Poll, Stream}; +pub mod dns; pub mod local; pub mod server; From ddc2680c4cb701a9e2f5042589abf6186b4ee23f Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Fri, 11 May 2018 01:21:05 +0800 Subject: [PATCH 14/22] Better logging --- src/relay/udprelay/dns.rs | 122 ++++++++++++++++++++++++++++++++++---- 1 file changed, 111 insertions(+), 11 deletions(-) diff --git a/src/relay/udprelay/dns.rs b/src/relay/udprelay/dns.rs index d3140474088f..fe1728e4b60d 100644 --- a/src/relay/udprelay/dns.rs +++ b/src/relay/udprelay/dns.rs @@ -1,10 +1,11 @@ //! UDP DNS relay +use std::fmt; use std::io::{self, Cursor}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::{Arc, Mutex}; -use dns_parser::Packet; +use dns_parser::{Packet, RRData}; use futures::future::join_all; use futures::{self, Future, Stream}; use lru_cache::LruCache; @@ -18,6 +19,95 @@ use relay::boxed_future; use relay::dns_resolver::resolve; use relay::socks5::Address; +struct PrettyRRData<'a> { + data: &'a RRData<'a>, +} + +impl<'a> PrettyRRData<'a> { + pub fn new(d: &'a RRData<'a>) -> PrettyRRData<'a> { + PrettyRRData { data: d } + } +} + +impl<'a> fmt::Display for PrettyRRData<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.data { + RRData::CNAME(ref c) => write!(f, "CNAME({})", c.to_string()), + RRData::NS(ref c) => write!(f, "NS({})", c.to_string()), + RRData::A(ref i) => write!(f, "A({})", i), + RRData::AAAA(ref i) => write!(f, "AAAA({})", i), + RRData::SRV{ + priority, weight, port, target + } => write!(f, "SRV({{priority: {}, weight: {}, port: {}, target: {}}})", + priority, weight, port, target.to_string()), + RRData::SOA(ref s) => write!(f, "SOA({{primary_ns: {}, mailbox: {}, serial: {}, refresh: {}, retry: {}, expire: {}, minimum_ttl: {}}})", + s.primary_ns.to_string(), s.mailbox.to_string(), s.serial, s.refresh, s.retry, s.expire, s.minimum_ttl), + RRData::PTR(ref p) => write!(f, "PTR({})", p.to_string()), + RRData::MX{ + preference, exchange + } => write!(f, "MX({{preference: {}, exchange: {}}})", preference, exchange.to_string()), + RRData::TXT(t) => write!(f, "TXT({})", t), + RRData::Unknown(u) => write!(f, "Unknown({:?})", u), + } + } +} + +struct PrettyPacket<'a> { + pkt: &'a Packet<'a>, +} + +impl<'a> PrettyPacket<'a> { + pub fn new(pkt: &'a Packet<'a>) -> PrettyPacket<'a> { + PrettyPacket { pkt: pkt } + } +} + +impl<'a> fmt::Display for PrettyPacket<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, + "Packet (id={} opcode={:?})", + self.pkt.header.id, self.pkt.header.opcode)?; + + if !self.pkt.questions.is_empty() { + write!(f, " QUESTION[")?; + for q in &self.pkt.questions { + write!(f, "{}, ", q.qname.to_string())?; + } + write!(f, "]")?; + } + + if !self.pkt.answers.is_empty() { + write!(f, " ANSWER[")?; + for a in &self.pkt.answers { + write!(f, "{}:{}, ", a.name.to_string(), PrettyRRData::new(&a.data))?; + } + write!(f, "]")?; + } + + if !self.pkt.nameservers.is_empty() { + write!(f, " NAMESERVERS[")?; + for n in &self.pkt.nameservers { + write!(f, "{}:{}, ", n.name.to_string(), PrettyRRData::new(&n.data))?; + } + write!(f, "]")?; + } + + if !self.pkt.additional.is_empty() { + write!(f, " ADDITIONAL[")?; + for n in &self.pkt.additional { + write!(f, "{}:{}, ", n.name.to_string(), PrettyRRData::new(&n.data))?; + } + write!(f, "]")?; + } + + if let Some(ref opt) = self.pkt.opt { + write!(f, " OPT[{:?}]", opt)?; + } + + Ok(()) + } +} + /// Starts a UDP DNS server pub fn run(config: Arc) -> IoFuture<()> { let local_addr = *config.local.as_ref().unwrap(); @@ -96,12 +186,13 @@ fn handle_l2r(config: Arc, "parse DNS packet failed") })?; - debug!("DNS QUERY id={} src={} {:?}", pkt.header.id, src, pkt); - let (ref socket, ref svr_cfg, svr_addr) = &server[server_idx % server.len()]; let (ni, _) = server_idx.overflowing_add(1); server_idx = ni; + debug!("DNS {} -> {} {}", src, svr_cfg.addr(), PrettyPacket::new(&pkt)); + trace!("DETAIL {} -> {} {:?}", src, svr_cfg.addr(), pkt); + let mut buf = Vec::new(); Address::SocketAddress(config.dns).write_to_buf(&mut buf); @@ -144,20 +235,29 @@ fn handle_r2l(l: SharedUdpSocket, r: SharedUdpSocket, svr_cfg: Arc let payload = payload[pos..].to_vec(); - debug!("DNS RESPONSE id={} server={} {:?}", pkt.header.id, src, pkt); - - Ok((pkt.header.id, payload)) - }).and_then(move |(id, payload)| { - match GLOBAL_QUERY_ADDR.lock().unwrap().remove(&id) { + match GLOBAL_QUERY_ADDR.lock().unwrap().remove(&pkt.header.id) { Some(cli_addr) => { + debug!("DNS {} <- {} {}", cli_addr, src, PrettyPacket::new(&pkt)); + trace!("DETAIL {} <- {} {:?}", cli_addr, src, pkt); + + Ok(Some((cli_addr, payload))) + } + None => { + error!("DNS received packet id={} opcode={:?} but found no local endpoint", + pkt.header.id, pkt.header.opcode); + Ok(None) + } + } + }).and_then(move |opt| { + match opt { + Some((cli_addr, payload)) => { let f = SendDgramRc::new(l, payload, cli_addr) .map(|_| ()); boxed_future(f) } - None => { - boxed_future(futures::finished(())) - } + None => boxed_future(futures::finished(())) } + }) }); From 8ffa68c749c25586873fdf5e0a1bcc151c588126 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Fri, 11 May 2018 01:23:22 +0800 Subject: [PATCH 15/22] Fixed build on travis --- src/relay/udprelay/dns.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/relay/udprelay/dns.rs b/src/relay/udprelay/dns.rs index fe1728e4b60d..1e3013df24d8 100644 --- a/src/relay/udprelay/dns.rs +++ b/src/relay/udprelay/dns.rs @@ -186,7 +186,7 @@ fn handle_l2r(config: Arc, "parse DNS packet failed") })?; - let (ref socket, ref svr_cfg, svr_addr) = &server[server_idx % server.len()]; + let (ref socket, ref svr_cfg, svr_addr) = server[server_idx % server.len()]; let (ni, _) = server_idx.overflowing_add(1); server_idx = ni; From d3857ac3b502fb210f1a0540a555980050d03e13 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Fri, 11 May 2018 01:37:32 +0800 Subject: [PATCH 16/22] Add elapsed time in log --- src/relay/udprelay/dns.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/relay/udprelay/dns.rs b/src/relay/udprelay/dns.rs index 1e3013df24d8..d545f1c7e256 100644 --- a/src/relay/udprelay/dns.rs +++ b/src/relay/udprelay/dns.rs @@ -4,6 +4,7 @@ use std::fmt; use std::io::{self, Cursor}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::{Arc, Mutex}; +use std::time::Instant; use dns_parser::{Packet, RRData}; use futures::future::join_all; @@ -163,7 +164,7 @@ fn listen(config: Arc, l: UdpSocket) -> IoFuture<()> { } lazy_static! { - static ref GLOBAL_QUERY_ADDR: Mutex> = Mutex::new(LruCache::new(1024)); + static ref GLOBAL_QUERY_ADDR: Mutex> = Mutex::new(LruCache::new(1024)); } fn handle_l2r(config: Arc, @@ -202,13 +203,13 @@ fn handle_l2r(config: Arc, let id = pkt.header.id; encrypt_payload(svr_cfg.method(), svr_cfg.key(), &buf).map(move |send_payload| { (socket, - *svr_addr, + svr_addr, send_payload, id) }) }).and_then(move |(socket, svr_addr, send_payload, id)| { SendDgramRc::new(socket, send_payload, svr_addr).map(move |_| { - GLOBAL_QUERY_ADDR.lock().unwrap().insert(id, src); + GLOBAL_QUERY_ADDR.lock().unwrap().insert(id, (src, Instant::now())); }) }) }); @@ -236,8 +237,8 @@ fn handle_r2l(l: SharedUdpSocket, r: SharedUdpSocket, svr_cfg: Arc let payload = payload[pos..].to_vec(); match GLOBAL_QUERY_ADDR.lock().unwrap().remove(&pkt.header.id) { - Some(cli_addr) => { - debug!("DNS {} <- {} {}", cli_addr, src, PrettyPacket::new(&pkt)); + Some((cli_addr, start_time)) => { + debug!("DNS {} <- {} {} elapsed: {:?}", cli_addr, src, PrettyPacket::new(&pkt), Instant::now() - start_time); trace!("DETAIL {} <- {} {:?}", cli_addr, src, pkt); Ok(Some((cli_addr, payload))) From 8e4a6d5d5de39afdc98ac9a8d4f289ca4ec384d1 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Fri, 11 May 2018 01:43:17 +0800 Subject: [PATCH 17/22] Should not exit if handler return error --- src/relay/udprelay/dns.rs | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/relay/udprelay/dns.rs b/src/relay/udprelay/dns.rs index d545f1c7e256..ee3d356984f0 100644 --- a/src/relay/udprelay/dns.rs +++ b/src/relay/udprelay/dns.rs @@ -10,6 +10,7 @@ use dns_parser::{Packet, RRData}; use futures::future::join_all; use futures::{self, Future, Stream}; use lru_cache::LruCache; +use tokio; use tokio::net::UdpSocket; use tokio_io::IoFuture; @@ -180,7 +181,7 @@ fn handle_l2r(config: Arc, PacketStream::new(l).for_each(move |(payload, src)| { let server = server.clone(); let config = config.clone(); - futures::lazy(move || { + let pkt_fut = futures::lazy(move || { let pkt = Packet::parse(&payload[..]).map_err(|err| { error!("Failed to parse DNS payload, err: {}", err); io::Error::new(io::ErrorKind::Other, @@ -211,7 +212,18 @@ fn handle_l2r(config: Arc, SendDgramRc::new(socket, send_payload, svr_addr).map(move |_| { GLOBAL_QUERY_ADDR.lock().unwrap().insert(id, (src, Instant::now())); }) - }) + }); + tokio::spawn(pkt_fut.then(|res| { + match res { + Ok(..) => Ok(()), + Err(err) => { + error!("Failed to handle local -> remote packet, err: {}", err); + Err(()) + } + } + })); + + Ok(()) }); boxed_future(fut) } @@ -220,7 +232,7 @@ fn handle_r2l(l: SharedUdpSocket, r: SharedUdpSocket, svr_cfg: Arc let fut = PacketStream::new(r).for_each(move |(payload, src)| { let l = l.clone(); let svr_cfg = svr_cfg.clone(); - futures::lazy(move || { + let pkt_fut = futures::lazy(move || { decrypt_payload(svr_cfg.method(), svr_cfg.key(), &payload) }).and_then(move |payload| { Address::read_from(Cursor::new(payload)) @@ -258,8 +270,19 @@ fn handle_r2l(l: SharedUdpSocket, r: SharedUdpSocket, svr_cfg: Arc } None => boxed_future(futures::finished(())) } - - }) + }); + + tokio::spawn(pkt_fut.then(|res| { + match res { + Ok(..) => Ok(()), + Err(err) => { + error!("Failed to handle local <- remote packet, err: {}", err); + Err(()) + } + } + })); + + Ok(()) }); boxed_future(fut) From e095db30f0d50324d63611a3e1f6940ea20ebfa3 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Fri, 11 May 2018 01:54:24 +0800 Subject: [PATCH 18/22] reformatted --- rustfmt.toml | 2 +- src/bin/local.rs | 29 +++---- src/bin/server.rs | 24 +++--- src/bin/ssdns.rs | 20 +++-- src/bin/ssurl.rs | 4 +- src/config.rs | 58 +++++++------- src/crypto/cipher.rs | 65 ++++++--------- src/crypto/mod.rs | 15 ++-- src/crypto/openssl.rs | 7 +- src/crypto/rc4_md5.rs | 6 +- src/crypto/ring.rs | 17 ++-- src/crypto/siv.rs | 4 +- src/crypto/sodium.rs | 62 +++++++++------ src/crypto/stream.rs | 2 +- src/crypto/table.rs | 4 +- src/plugin/mod.rs | 12 +-- src/plugin/obfs_proxy.rs | 18 ++--- src/plugin/ss_plugin.rs | 7 +- src/relay/tcprelay/crypto_io.rs | 12 ++- src/relay/tcprelay/mod.rs | 14 ++-- src/relay/tcprelay/server.rs | 135 ++++++++++++++------------------ src/relay/tcprelay/utils.rs | 12 +-- src/relay/udprelay/dns.rs | 28 ++++--- src/relay/utils.rs | 2 +- tests/socks5.rs | 4 +- tests/udp.rs | 7 +- 26 files changed, 268 insertions(+), 302 deletions(-) diff --git a/rustfmt.toml b/rustfmt.toml index cf0cb09608d2..762f11c0cd67 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -9,4 +9,4 @@ condense_wildcard_suffixes = true #fn_call_style = "Visual" #chain_indent = "Visual" normalize_comments = true -use_try_shorthand = true \ No newline at end of file +use_try_shorthand = true diff --git a/src/bin/local.rs b/src/bin/local.rs index 1b8dc2bff26c..5e89d9aff576 100644 --- a/src/bin/local.rs +++ b/src/bin/local.rs @@ -3,7 +3,7 @@ //! You have to provide all needed configuration attributes via command line parameters, //! or you could specify a configuration file. The format of configuration file is defined //! in mod `config`. -//! +//! extern crate clap; extern crate env_logger; @@ -18,12 +18,12 @@ use std::env; use std::io::{self, Write}; use std::net::SocketAddr; -use env_logger::Builder; use env_logger::fmt::Formatter; +use env_logger::Builder; use log::{LevelFilter, Record}; -use shadowsocks::{run_local, Config, ConfigType, ServerAddr, ServerConfig}; use shadowsocks::plugin::PluginConfig; +use shadowsocks::{run_local, Config, ConfigType, ServerAddr, ServerConfig}; fn log_time(fmt: &mut Formatter, without_time: bool, record: &Record) -> io::Result<()> { if without_time { @@ -148,18 +148,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(), }; @@ -201,8 +199,7 @@ fn main() { let has_provided_local_config = match matches.value_of("LOCAL_ADDR") { Some(local_addr) => { - let local_addr: SocketAddr = local_addr.parse() - .expect("`local-addr` is not a valid IP address"); + let local_addr: SocketAddr = local_addr.parse().expect("`local-addr` is not a valid IP address"); config.local = Some(local_addr); true diff --git a/src/bin/server.rs b/src/bin/server.rs index ba20463475cd..5aeaaf211d18 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -19,12 +19,12 @@ use std::io::{self, Write}; use clap::{App, Arg}; -use env_logger::Builder; use env_logger::fmt::Formatter; +use env_logger::Builder; use log::{LevelFilter, Record}; -use shadowsocks::{run_server, Config, ConfigType, ServerAddr, ServerConfig}; use shadowsocks::plugin::PluginConfig; +use shadowsocks::{run_server, Config, ConfigType, ServerAddr, ServerConfig}; fn log_time(fmt: &mut Formatter, without_time: bool, record: &Record) -> io::Result<()> { if without_time { @@ -129,18 +129,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::Server) { - Ok(cfg) => { - has_provided_config = true; - cfg - } - Err(err) => { - error!("{:?}", err); - return; - } + Some(cpath) => match Config::load_from_file(cpath, ConfigType::Server) { + Ok(cfg) => { + has_provided_config = true; + cfg } - } + Err(err) => { + error!("{:?}", err); + return; + } + }, None => Config::new(), }; diff --git a/src/bin/ssdns.rs b/src/bin/ssdns.rs index b67a928135b7..5ca0b6901181 100644 --- a/src/bin/ssdns.rs +++ b/src/bin/ssdns.rs @@ -131,18 +131,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(), }; diff --git a/src/bin/ssurl.rs b/src/bin/ssurl.rs index 849849b3ec22..4b3b1f0eca3b 100644 --- a/src/bin/ssurl.rs +++ b/src/bin/ssurl.rs @@ -10,11 +10,11 @@ extern crate shadowsocks; use clap::{App, Arg}; -use qrcode::QrCode; use qrcode::types::Color; +use qrcode::QrCode; -use shadowsocks::VERSION; use shadowsocks::config::{Config, ConfigType, ServerConfig}; +use shadowsocks::VERSION; const BLACK: &'static str = "\x1b[40m \x1b[0m"; const WHITE: &'static str = "\x1b[47m \x1b[0m"; diff --git a/src/config.rs b/src/config.rs index 121cbc9b8776..5610ab8bd1a4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -138,12 +138,10 @@ impl FromStr for ServerAddr { Err(..) => { let mut sp = s.split(':'); match (sp.next(), sp.next()) { - (Some(dn), Some(port)) => { - match port.parse::() { - Ok(port) => Ok(ServerAddr::DomainName(dn.to_owned(), port)), - Err(..) => Err(ServerAddrError), - } - } + (Some(dn), Some(port)) => match port.parse::() { + Ok(port) => Ok(ServerAddr::DomainName(dn.to_owned(), port)), + Err(..) => Err(ServerAddrError), + }, _ => Err(ServerAddrError), } } @@ -287,14 +285,12 @@ impl ServerConfig { let user_info = parsed.username(); let account = match decode_config(user_info, URL_SAFE_NO_PAD) { - Ok(account) => { - match String::from_utf8(account) { - Ok(ac) => ac, - Err(..) => { - return Err(UrlParseError::InvalidAuthInfo); - } + Ok(account) => match String::from_utf8(account) { + Ok(ac) => ac, + Err(..) => { + return Err(UrlParseError::InvalidAuthInfo); } - } + }, Err(err) => { error!("Failed to parse UserInfo with Base64, err: {}", err); return Err(UrlParseError::InvalidUserInfo); @@ -679,17 +675,15 @@ impl Config { match addr_str.parse::() { Ok(ip) => Some(SocketAddr::V4(SocketAddrV4::new(ip, port))), - Err(..) => { - match addr_str.parse::() { - Ok(ip) => Some(SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0))), - Err(..) => { - return Err(Error::new(ErrorKind::Malformed, - "`local_address` is not a valid IP \ - address", - None)) - } + Err(..) => match addr_str.parse::() { + Ok(ip) => Some(SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0))), + Err(..) => { + return Err(Error::new(ErrorKind::Malformed, + "`local_address` is not a valid IP \ + address", + None)) } - } + }, } } None => None, @@ -739,15 +733,17 @@ impl Config { let err = Error::new(ErrorKind::Malformed, "`dns` should be string", None); return Err(err); } - Some(dns) => match dns.parse::() { - Err(..) => { - let err = Error::new(ErrorKind::Malformed, "`dns` should be IpAddr", None); - return Err(err); - } - Ok(addr) => { - config.dns = SocketAddr::new(addr, 53); + Some(dns) => { + match dns.parse::() { + Err(..) => { + let err = Error::new(ErrorKind::Malformed, "`dns` should be IpAddr", None); + return Err(err); + } + Ok(addr) => { + config.dns = SocketAddr::new(addr, 53); + } } - }, + } } } diff --git a/src/crypto/cipher.rs b/src/crypto/cipher.rs index 3ed775df3af8..5cb2b5dfed1c 100644 --- a/src/crypto/cipher.rs +++ b/src/crypto/cipher.rs @@ -121,18 +121,24 @@ pub enum CipherType { Rc4, Rc4Md5, - #[cfg(feature = "sodium")] ChaCha20, - #[cfg(feature = "sodium")] Salsa20, - #[cfg(feature = "sodium")] XSalsa20, - #[cfg(feature = "sodium")] ChaCha20Ietf, + #[cfg(feature = "sodium")] + ChaCha20, + #[cfg(feature = "sodium")] + Salsa20, + #[cfg(feature = "sodium")] + XSalsa20, + #[cfg(feature = "sodium")] + ChaCha20Ietf, Aes128Gcm, Aes256Gcm, ChaCha20Poly1305, - #[cfg(feature = "miscreant")] Aes128PmacSiv, - #[cfg(feature = "miscreant")] Aes256PmacSiv, + #[cfg(feature = "miscreant")] + Aes128PmacSiv, + #[cfg(feature = "miscreant")] + Aes256PmacSiv, } /// Category of ciphers @@ -215,35 +221,24 @@ impl CipherType { match *self { CipherType::Table | CipherType::Plain => 0, - CipherType::Aes128Cfb1 => { - symm::Cipher::aes_128_cfb1().iv_len() - .expect("iv_len should not be None") - } - CipherType::Aes128Cfb8 => { - symm::Cipher::aes_128_cfb8().iv_len() - .expect("iv_len should not be None") - } + CipherType::Aes128Cfb1 => symm::Cipher::aes_128_cfb1().iv_len() + .expect("iv_len should not be None"), + CipherType::Aes128Cfb8 => symm::Cipher::aes_128_cfb8().iv_len() + .expect("iv_len should not be None"), CipherType::Aes128Cfb | CipherType::Aes128Cfb128 => { symm::Cipher::aes_128_cfb128().iv_len() .expect("iv_len should not be None") } - CipherType::Aes256Cfb1 => { - symm::Cipher::aes_256_cfb1().iv_len() - .expect("iv_len should not be None") - } - CipherType::Aes256Cfb8 => { - symm::Cipher::aes_256_cfb8().iv_len() - .expect("iv_len should not be None") - } + CipherType::Aes256Cfb1 => symm::Cipher::aes_256_cfb1().iv_len() + .expect("iv_len should not be None"), + CipherType::Aes256Cfb8 => symm::Cipher::aes_256_cfb8().iv_len() + .expect("iv_len should not be None"), CipherType::Aes256Cfb | CipherType::Aes256Cfb128 => { symm::Cipher::aes_256_cfb128().iv_len() .expect("iv_len should not be None") } - CipherType::Rc4 => { - symm::Cipher::rc4().iv_len() - .expect("iv_len should not be None") - } + CipherType::Rc4 => symm::Cipher::rc4().iv_len().expect("iv_len should not be None"), CipherType::Rc4Md5 => 16, #[cfg(feature = "sodium")] @@ -410,29 +405,21 @@ impl Display for CipherType { #[cfg(test)] mod test_cipher { - use crypto::{new_stream, CipherType, StreamCipher}; use crypto::CryptoMode; + use crypto::{new_stream, CipherType, StreamCipher}; #[test] fn test_get_cipher() { let key = CipherType::Aes128Cfb.bytes_to_key(b"PassWORD"); let iv = CipherType::Aes128Cfb.gen_init_vec(); - let mut encryptor = new_stream(CipherType::Aes128Cfb, - &key[0..], - &iv[0..], - CryptoMode::Encrypt); - let mut decryptor = new_stream(CipherType::Aes128Cfb, - &key[0..], - &iv[0..], - CryptoMode::Decrypt); + let mut encryptor = new_stream(CipherType::Aes128Cfb, &key[0..], &iv[0..], CryptoMode::Encrypt); + let mut decryptor = new_stream(CipherType::Aes128Cfb, &key[0..], &iv[0..], CryptoMode::Decrypt); let message = "HELLO WORLD"; let mut encrypted_msg = Vec::new(); - encryptor.update(message.as_bytes(), &mut encrypted_msg) - .unwrap(); + encryptor.update(message.as_bytes(), &mut encrypted_msg).unwrap(); let mut decrypted_msg = Vec::new(); - decryptor.update(&encrypted_msg[..], &mut decrypted_msg) - .unwrap(); + decryptor.update(&encrypted_msg[..], &mut decrypted_msg).unwrap(); assert!(message.as_bytes() == &decrypted_msg[..]); } diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs index 5343c320f8ef..6035ff5d6683 100644 --- a/src/crypto/mod.rs +++ b/src/crypto/mod.rs @@ -4,24 +4,25 @@ use std::convert::From; use openssl::symm; -pub use self::aead::{new_aead_decryptor, new_aead_encryptor, AeadDecryptor, AeadEncryptor, BoxAeadDecryptor, - BoxAeadEncryptor}; +pub use self::aead::{ + new_aead_decryptor, new_aead_encryptor, AeadDecryptor, AeadEncryptor, BoxAeadDecryptor, BoxAeadEncryptor, +}; pub use self::cipher::{CipherCategory, CipherResult, CipherType}; pub use self::stream::{new_stream, StreamCipher, StreamCipherVariant}; +pub mod aead; pub mod cipher; -pub mod openssl; pub mod digest; -pub mod table; +pub mod dummy; +pub mod openssl; pub mod rc4_md5; pub mod ring; -pub mod dummy; -pub mod aead; -pub mod stream; #[cfg(feature = "miscreant")] pub mod siv; #[cfg(feature = "sodium")] pub mod sodium; +pub mod stream; +pub mod table; /// Crypto mode, encrypt or decrypt #[derive(Clone, Copy, Eq, PartialEq, Debug)] diff --git a/src/crypto/openssl.rs b/src/crypto/openssl.rs index 340b70fe3da6..49096c53a06e 100644 --- a/src/crypto/openssl.rs +++ b/src/crypto/openssl.rs @@ -2,8 +2,8 @@ use std::convert::From; -use crypto::{CipherResult, CipherType, StreamCipher}; use crypto::cipher; +use crypto::{CipherResult, CipherType, StreamCipher}; use crypto::CryptoMode; @@ -28,8 +28,7 @@ impl OpenSSLCrypto { CipherType::Aes256Cfb128 => symm::Cipher::aes_256_cfb128(), CipherType::Rc4 => symm::Cipher::rc4(), - _ => panic!("Cipher type {:?} does not supported by OpenSSLCrypt yet", - cipher_type), + _ => panic!("Cipher type {:?} does not supported by OpenSSLCrypt yet", cipher_type), }; // Panic if error occurs @@ -81,8 +80,8 @@ impl OpenSSLCrypto { /// *Note: This behavior works just the same as the official version of shadowsocks.* /// /// ```rust -/// use shadowsocks::crypto::{CipherType, CryptoMode, StreamCipher}; /// use shadowsocks::crypto::openssl::OpenSSLCipher; +/// use shadowsocks::crypto::{CipherType, CryptoMode, StreamCipher}; /// /// let method = CipherType::Aes128Cfb; /// diff --git a/src/crypto/rc4_md5.rs b/src/crypto/rc4_md5.rs index 7b59a4c4ce7c..090e0a964b32 100644 --- a/src/crypto/rc4_md5.rs +++ b/src/crypto/rc4_md5.rs @@ -1,9 +1,9 @@ //! Rc4Md5 cipher definition -use crypto::{CipherResult, CipherType, StreamCipher}; -use crypto::CryptoMode; use crypto::digest::{self, Digest, DigestType}; use crypto::openssl::OpenSSLCrypto; +use crypto::CryptoMode; +use crypto::{CipherResult, CipherType, StreamCipher}; use bytes::{BufMut, BytesMut}; @@ -43,8 +43,8 @@ unsafe impl Send for Rc4Md5Cipher {} #[cfg(test)] mod test { use super::*; - use crypto::{CipherType, StreamCipher}; use crypto::CryptoMode; + use crypto::{CipherType, StreamCipher}; #[test] fn test_rc4_md5_cipher() { diff --git a/src/crypto/ring.rs b/src/crypto/ring.rs index e7f1ee86588a..196dfd09cc94 100644 --- a/src/crypto/ring.rs +++ b/src/crypto/ring.rs @@ -5,10 +5,10 @@ use std::ptr; use ring::aead::{open_in_place, seal_in_place, AES_128_GCM, AES_256_GCM, CHACHA20_POLY1305, OpeningKey, SealingKey}; -use crypto::{AeadDecryptor, AeadEncryptor}; -use crypto::{CipherResult, CipherType}; use crypto::aead::{increase_nonce, make_skey}; use crypto::cipher::Error; +use crypto::{AeadDecryptor, AeadEncryptor}; +use crypto::{CipherResult, CipherType}; use bytes::{BufMut, Bytes, BytesMut}; @@ -52,13 +52,16 @@ impl RingAeadCipher { fn new_variant(t: CipherType, key: &[u8], nonce: &[u8], is_seal: bool) -> RingAeadCryptoVariant { macro_rules! seal_or_open { - ( $item:ident, $key:ident, $crypt:ident ) => { + ($item:ident, $key:ident, $crypt:ident) => { RingAeadCryptoVariant::$item($key::new(&$crypt, key).unwrap(), Bytes::from(nonce)) }; - ( $crypt:ident ) => { - if is_seal { seal_or_open!(Seal, SealingKey, $crypt) } - else { seal_or_open!(Open, OpeningKey, $crypt) } - } + ($crypt:ident) => { + if is_seal { + seal_or_open!(Seal, SealingKey, $crypt) + } else { + seal_or_open!(Open, OpeningKey, $crypt) + } + }; } match t { diff --git a/src/crypto/siv.rs b/src/crypto/siv.rs index 4bbdb2ca8372..f28a7ef5c049 100644 --- a/src/crypto/siv.rs +++ b/src/crypto/siv.rs @@ -4,10 +4,10 @@ use std::ptr; use miscreant::aead::{Aes128PmacSiv, Aes256PmacSiv, Algorithm}; -use crypto::{AeadDecryptor, AeadEncryptor}; -use crypto::{CipherResult, CipherType}; use crypto::aead::{increase_nonce, make_skey}; use crypto::cipher::Error; +use crypto::{AeadDecryptor, AeadEncryptor}; +use crypto::{CipherResult, CipherType}; use bytes::{BufMut, BytesMut}; diff --git a/src/crypto/sodium.rs b/src/crypto/sodium.rs index 61b30f14415a..4a1f9e8fe075 100644 --- a/src/crypto/sodium.rs +++ b/src/crypto/sodium.rs @@ -7,8 +7,10 @@ use bytes::{BufMut, BytesMut}; use crypto::{CipherResult, CipherType, StreamCipher}; use libc::{c_ulonglong, uint32_t}; -use libsodium_ffi::{sodium_init, crypto_stream_chacha20_ietf_xor_ic, crypto_stream_chacha20_xor_ic, - crypto_stream_salsa20_xor_ic, crypto_stream_xsalsa20_xor_ic}; +use libsodium_ffi::{ + crypto_stream_chacha20_ietf_xor_ic, crypto_stream_chacha20_xor_ic, crypto_stream_salsa20_xor_ic, + crypto_stream_xsalsa20_xor_ic, sodium_init, +}; use crypto::cipher::Error; @@ -79,30 +81,38 @@ fn crypto_stream_xor_ic(t: CipherType, let ret = unsafe { match t { - CipherType::ChaCha20 => crypto_stream_chacha20_xor_ic(out.bytes_mut().as_mut_ptr(), - data.as_ptr(), - data.len() as c_ulonglong, - iv.as_ptr(), - ic as c_ulonglong, - key.as_ptr()), - CipherType::ChaCha20Ietf => crypto_stream_chacha20_ietf_xor_ic(out.bytes_mut().as_mut_ptr(), - data.as_ptr(), - data.len() as c_ulonglong, - iv.as_ptr(), - ic as uint32_t, - key.as_ptr()), - CipherType::Salsa20 => crypto_stream_salsa20_xor_ic(out.bytes_mut().as_mut_ptr(), - data.as_ptr(), - data.len() as c_ulonglong, - iv.as_ptr(), - ic as c_ulonglong, - key.as_ptr()), - CipherType::XSalsa20 => crypto_stream_xsalsa20_xor_ic(out.bytes_mut().as_mut_ptr(), - data.as_ptr(), - data.len() as c_ulonglong, - iv.as_ptr(), - ic as c_ulonglong, - key.as_ptr()), + CipherType::ChaCha20 => { + crypto_stream_chacha20_xor_ic(out.bytes_mut().as_mut_ptr(), + data.as_ptr(), + data.len() as c_ulonglong, + iv.as_ptr(), + ic as c_ulonglong, + key.as_ptr()) + } + CipherType::ChaCha20Ietf => { + crypto_stream_chacha20_ietf_xor_ic(out.bytes_mut().as_mut_ptr(), + data.as_ptr(), + data.len() as c_ulonglong, + iv.as_ptr(), + ic as uint32_t, + key.as_ptr()) + } + CipherType::Salsa20 => { + crypto_stream_salsa20_xor_ic(out.bytes_mut().as_mut_ptr(), + data.as_ptr(), + data.len() as c_ulonglong, + iv.as_ptr(), + ic as c_ulonglong, + key.as_ptr()) + } + CipherType::XSalsa20 => { + crypto_stream_xsalsa20_xor_ic(out.bytes_mut().as_mut_ptr(), + data.as_ptr(), + data.len() as c_ulonglong, + iv.as_ptr(), + ic as c_ulonglong, + key.as_ptr()) + } _ => unreachable!(), } }; diff --git a/src/crypto/stream.rs b/src/crypto/stream.rs index 60a15a99da19..dfa848f636e8 100644 --- a/src/crypto/stream.rs +++ b/src/crypto/stream.rs @@ -1,6 +1,5 @@ //! Stream ciphers -use crypto::CryptoMode; use crypto::cipher::{CipherCategory, CipherResult, CipherType}; use crypto::dummy; use crypto::openssl; @@ -8,6 +7,7 @@ use crypto::rc4_md5; #[cfg(feature = "sodium")] use crypto::sodium; use crypto::table; +use crypto::CryptoMode; use bytes::BufMut; diff --git a/src/crypto/table.rs b/src/crypto/table.rs index ceaa8eb6095b..6939f341e222 100644 --- a/src/crypto/table.rs +++ b/src/crypto/table.rs @@ -2,9 +2,9 @@ use std::io::Cursor; -use crypto::{CipherResult, StreamCipher}; -use crypto::CryptoMode; use crypto::digest::{self, Digest, DigestType}; +use crypto::CryptoMode; +use crypto::{CipherResult, StreamCipher}; use byteorder::{LittleEndian, ReadBytesExt}; use bytes::{BufMut, BytesMut}; diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index 926192c31813..05d52973eb6e 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -20,8 +20,8 @@ use subprocess::Result as PopenResult; use config::{Config, ServerAddr}; -mod ss_plugin; mod obfs_proxy; +mod ss_plugin; /// Config for plugin #[derive(Debug, Clone)] @@ -84,14 +84,8 @@ pub fn launch_plugin(config: &mut Config, mode: PluginMode) -> io::Result info!("Started plugin \"{}\" on {} <-> {}", - c.plugin, - local_addr, - svr.addr()), - PluginMode::Server => info!("Started plugin \"{}\" on {} <-> {}", - c.plugin, - svr.addr(), - local_addr), + PluginMode::Client => info!("Started plugin \"{}\" on {} <-> {}", c.plugin, local_addr, svr.addr()), + PluginMode::Server => info!("Started plugin \"{}\" on {} <-> {}", c.plugin, svr.addr(), local_addr), } svr_addr_opt = Some(svr_addr); // Fuck borrow checker diff --git a/src/plugin/obfs_proxy.rs b/src/plugin/obfs_proxy.rs index cdb4e5d2212c..0b39d00e623f 100644 --- a/src/plugin/obfs_proxy.rs +++ b/src/plugin/obfs_proxy.rs @@ -1,7 +1,7 @@ use std::net::SocketAddr; -use subprocess::{Exec, Popen}; use subprocess::Result as PopenResult; +use subprocess::{Exec, Popen}; use config::ServerAddr; @@ -46,16 +46,12 @@ pub fn start_plugin(plugin: &PluginConfig, } let cmd = match mode { - PluginMode::Client => { - cmd.arg("--dest").arg(remote.to_string()) - .arg("client") - .arg(local.to_string()) - } - PluginMode::Server => { - cmd.arg("--dest").arg(local.to_string()) - .arg("server") - .arg(remote.to_string()) - } + PluginMode::Client => cmd.arg("--dest").arg(remote.to_string()) + .arg("client") + .arg(local.to_string()), + PluginMode::Server => cmd.arg("--dest").arg(local.to_string()) + .arg("server") + .arg(remote.to_string()), }; cmd.popen() diff --git a/src/plugin/ss_plugin.rs b/src/plugin/ss_plugin.rs index 205b7bf28b47..a18488aee112 100644 --- a/src/plugin/ss_plugin.rs +++ b/src/plugin/ss_plugin.rs @@ -1,7 +1,7 @@ use std::net::SocketAddr; -use subprocess::{Exec, NullFile, Popen}; use subprocess::Result as PopenResult; +use subprocess::{Exec, NullFile, Popen}; use config::ServerAddr; @@ -12,10 +12,7 @@ pub fn start_plugin(plugin: &PluginConfig, local: &SocketAddr, _mode: PluginMode) -> PopenResult { - trace!("Start plugin \"{:?}\" remote: {}, local: {}", - plugin, - remote, - local); + trace!("Start plugin \"{:?}\" remote: {}, local: {}", plugin, remote, local); let mut exec = Exec::cmd(&plugin.plugin).env("SS_REMOTE_HOST", remote.host()) .env("SS_REMOTE_PORT", remote.port().to_string()) diff --git a/src/relay/tcprelay/crypto_io.rs b/src/relay/tcprelay/crypto_io.rs index 4faa8c3366ee..0d73ba56ed3c 100644 --- a/src/relay/tcprelay/crypto_io.rs +++ b/src/relay/tcprelay/crypto_io.rs @@ -283,13 +283,11 @@ impl EncryptedCopyTimeout fn try_poll_timeout(&mut self) -> io::Result<()> { match self.timer.as_mut() { None => Ok(()), - Some(t) => { - match t.poll() { - Err(err) => panic!("Failed to poll on timer, err: {}", err), - Ok(Async::Ready(..)) => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")), - Ok(Async::NotReady) => Ok(()), - } - } + Some(t) => match t.poll() { + Err(err) => panic!("Failed to poll on timer, err: {}", err), + Ok(Async::Ready(..)) => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")), + Ok(Async::NotReady) => Ok(()), + }, } } diff --git a/src/relay/tcprelay/mod.rs b/src/relay/tcprelay/mod.rs index 12c7db6318bf..8ec2e0706e4f 100644 --- a/src/relay/tcprelay/mod.rs +++ b/src/relay/tcprelay/mod.rs @@ -209,15 +209,13 @@ 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) - } - Some(err) => 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), + }, } } } diff --git a/src/relay/tcprelay/server.rs b/src/relay/tcprelay/server.rs index 674ad2d0a467..4de01d81dce7 100644 --- a/src/relay/tcprelay/server.rs +++ b/src/relay/tcprelay/server.rs @@ -1,8 +1,8 @@ //! Relay for TCP server that running on the server side use std::io::{self, ErrorKind}; -use std::time::Duration; use std::sync::Arc; +use std::time::Duration; use config::{Config, ServerConfig}; @@ -11,13 +11,13 @@ use relay::dns_resolver::resolve; use relay::socks5::Address; use relay::tcprelay::crypto_io::{DecryptedRead, EncryptedWrite}; -use futures::{self, Future}; use futures::stream::Stream; +use futures::{self, Future}; +use tokio; use tokio::net::{TcpListener, TcpStream}; -use tokio_io::{IoFuture, AsyncRead}; use tokio_io::io::{ReadHalf, WriteHalf}; -use tokio; +use tokio_io::{AsyncRead, IoFuture}; use super::{proxy_handshake, try_timeout, tunnel, DecryptedHalf, EncryptedHalfFut, TcpStreamConnect}; @@ -38,26 +38,19 @@ impl TcpRelayClientHandshake { let timeout = *svr_cfg.timeout(); proxy_handshake(s, svr_cfg).and_then(move |(r_fut, w_fut)| { - r_fut - .and_then(move |r| { - let fut = Address::read_from(r).map_err(move |_| { - io::Error::new( - ErrorKind::Other, - format!( - "failed to decode Address, may be wrong method or key, peer: {}", - peer_addr - ), - ) - }); - try_timeout(fut, timeout) - }) - .map(move |(r, addr)| TcpRelayClientPending { - r: r, - addr: addr, - w: w_fut, - timeout: timeout, - config: config, - }) + r_fut.and_then(move |r| { + let fut = Address::read_from(r).map_err(move |_| { + io::Error::new(ErrorKind::Other, + format!("failed to decode Address, may be wrong method or key, peer: {}", + peer_addr)) + }); + try_timeout(fut, timeout) + }) + .map(move |(r, addr)| TcpRelayClientPending { r: r, + addr: addr, + w: w_fut, + timeout: timeout, + config: config, }) }) }); boxed_future(fut) @@ -82,16 +75,14 @@ impl TcpRelayClientPending { match addr { Address::SocketAddress(saddr) => { if config.forbidden_ip.contains(&saddr.ip()) { - let err = io::Error::new( - ErrorKind::Other, - format!("{} is forbidden, failed to connect {}", saddr.ip(), saddr), - ); + let err = io::Error::new(ErrorKind::Other, + format!("{} is forbidden, failed to connect {}", saddr.ip(), saddr)); return boxed_future(futures::done(Err(err))); } let conn = TcpStream::connect(&saddr); try_timeout(conn, timeout) - }, + } Address::DomainNameAddress(dname, port) => { let fut = { try_timeout(resolve(config, dname.as_str(), port, true), timeout).and_then(move |addrs| { @@ -110,12 +101,10 @@ impl TcpRelayClientPending { 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, - }); + let fut = fut.map(move |stream| TcpRelayClientConnected { server: stream.split(), + client: client_pair, + addr: addr, + timeout: timeout, }); Box::new(fut) } } @@ -136,11 +125,9 @@ impl TcpRelayClientConnected { let (r, w_fut) = self.client; let timeout = self.timeout; - tunnel( - self.addr, - r.copy_timeout_opt(svr_w, self.timeout), - w_fut.and_then(move |w| w.copy_timeout_opt(svr_r, timeout)), - ) + tunnel(self.addr, + r.copy_timeout_opt(svr_w, self.timeout), + w_fut.and_then(move |w| w.copy_timeout_opt(svr_r, timeout))) } } @@ -153,8 +140,7 @@ pub fn run(config: Arc) -> IoFuture<()> { let addr = svr_cfg.addr(); let addr = addr.listen_addr(); - let listener = - TcpListener::bind(&addr).unwrap_or_else(|err| panic!("Failed to listen, {}", err)); + let listener = TcpListener::bind(&addr).unwrap_or_else(|err| panic!("Failed to listen, {}", err)); info!("ShadowSocks TCP Listening on {}", addr); listener @@ -162,42 +148,39 @@ pub fn run(config: Arc) -> IoFuture<()> { let svr_cfg = Arc::new(svr_cfg.clone()); let config = config.clone(); - let listening = listener - .incoming() - .for_each(move |socket| { - let server_cfg = svr_cfg.clone(); - - let addr = socket.peer_addr()?; - - trace!("Got connection, addr: {}", addr); - trace!("Picked proxy server: {:?}", server_cfg); - - let client = TcpRelayClientHandshake { - s: socket, - svr_cfg: server_cfg, - config: config.clone(), - }; - - let fut = client - .handshake() - .and_then(|c| c.connect()) - .and_then(|c| c.tunnel()) - .map_err(move |err| { - error!("Failed to handle client ({}): {}", addr, err); - }); - - tokio::spawn(fut); - Ok(()) - }) - .map_err(|err| { - error!("Server run failed: {}", err); - err - }); + let listening = listener.incoming() + .for_each(move |socket| { + let server_cfg = svr_cfg.clone(); + + let addr = socket.peer_addr()?; + + trace!("Got connection, addr: {}", addr); + trace!("Picked proxy server: {:?}", server_cfg); + + let client = TcpRelayClientHandshake { s: socket, + svr_cfg: server_cfg, + config: config.clone(), }; + + let fut = client.handshake() + .and_then(|c| c.connect()) + .and_then(|c| c.tunnel()) + .map_err(move |err| { + error!("Failed to handle client ({}): {}", + addr, err); + }); + + tokio::spawn(fut); + Ok(()) + }) + .map_err(|err| { + error!("Server run failed: {}", err); + err + }); fut = Some(match fut.take() { - Some(fut) => Box::new(fut.join(listening).map(|_| ())) as IoFuture<()>, - None => Box::new(listening) as IoFuture<()>, - }) + Some(fut) => Box::new(fut.join(listening).map(|_| ())) as IoFuture<()>, + None => Box::new(listening) as IoFuture<()>, + }) } fut.expect("Must have at least one server") diff --git a/src/relay/tcprelay/utils.rs b/src/relay/tcprelay/utils.rs index 49252b108f67..5aa6624d819f 100644 --- a/src/relay/tcprelay/utils.rs +++ b/src/relay/tcprelay/utils.rs @@ -52,11 +52,13 @@ impl CopyTimeout fn try_poll_timeout(&mut self) -> io::Result<()> { match self.timer.as_mut() { None => Ok(()), - Some(t) => match t.poll() { - Err(err) => panic!("Failed to poll on timer, err: {}", err), - Ok(Async::Ready(..)) => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")), - Ok(Async::NotReady) => Ok(()), - }, + Some(t) => { + match t.poll() { + Err(err) => panic!("Failed to poll on timer, err: {}", err), + Ok(Async::Ready(..)) => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")), + Ok(Async::NotReady) => Ok(()), + } + } } } diff --git a/src/relay/udprelay/dns.rs b/src/relay/udprelay/dns.rs index ee3d356984f0..ac7e741e1d56 100644 --- a/src/relay/udprelay/dns.rs +++ b/src/relay/udprelay/dns.rs @@ -38,16 +38,26 @@ impl<'a> fmt::Display for PrettyRRData<'a> { RRData::NS(ref c) => write!(f, "NS({})", c.to_string()), RRData::A(ref i) => write!(f, "A({})", i), RRData::AAAA(ref i) => write!(f, "AAAA({})", i), - RRData::SRV{ - priority, weight, port, target - } => write!(f, "SRV({{priority: {}, weight: {}, port: {}, target: {}}})", - priority, weight, port, target.to_string()), - RRData::SOA(ref s) => write!(f, "SOA({{primary_ns: {}, mailbox: {}, serial: {}, refresh: {}, retry: {}, expire: {}, minimum_ttl: {}}})", - s.primary_ns.to_string(), s.mailbox.to_string(), s.serial, s.refresh, s.retry, s.expire, s.minimum_ttl), + RRData::SRV { priority, weight, port, target } + => write!(f, + "SRV({{priority: {}, weight: {}, port: {}, target: {}}})", + priority, + weight, + port, + target.to_string()), + RRData::SOA(ref s) + => write!(f, + "SOA({{primary_ns: {}, mailbox: {}, serial: {}, refresh: {}, retry: {}, expire: {}, minimum_ttl: {}}})", + s.primary_ns.to_string(), + s.mailbox.to_string(), + s.serial, + s.refresh, + s.retry, + s.expire, + s.minimum_ttl), RRData::PTR(ref p) => write!(f, "PTR({})", p.to_string()), - RRData::MX{ - preference, exchange - } => write!(f, "MX({{preference: {}, exchange: {}}})", preference, exchange.to_string()), + RRData::MX { preference, exchange } + => write!(f, "MX({{preference: {}, exchange: {}}})", preference, exchange.to_string()), RRData::TXT(t) => write!(f, "TXT({})", t), RRData::Unknown(u) => write!(f, "Unknown({:?})", u), } diff --git a/src/relay/utils.rs b/src/relay/utils.rs index 8f031c50ee4c..e6124192220b 100644 --- a/src/relay/utils.rs +++ b/src/relay/utils.rs @@ -1,8 +1,8 @@ use std::io; use futures::{Async, Future, Poll}; -use tokio_io::AsyncWrite; use tokio_io::io::{write_all, WriteAll}; +use tokio_io::AsyncWrite; /// Write all bytes without returning the internal bytes buffer pub struct WriteBytes diff --git a/tests/socks5.rs b/tests/socks5.rs index c50a224c3a22..e297682d4fe2 100644 --- a/tests/socks5.rs +++ b/tests/socks5.rs @@ -2,8 +2,8 @@ extern crate env_logger; extern crate futures; extern crate log; extern crate shadowsocks; -extern crate tokio_io; extern crate tokio; +extern crate tokio_io; use std::net::{SocketAddr, ToSocketAddrs}; use std::thread; @@ -12,11 +12,11 @@ use std::time::Duration; use futures::Future; use tokio_io::io::{flush, read_to_end, write_all}; -use shadowsocks::{run_local, run_server}; use shadowsocks::config::{Config, ServerConfig}; use shadowsocks::crypto::CipherType; use shadowsocks::relay::socks5::Address; use shadowsocks::relay::tcprelay::client::Socks5Client; +use shadowsocks::{run_local, run_server}; pub struct Socks5TestServer { local_addr: SocketAddr, diff --git a/tests/udp.rs b/tests/udp.rs index 219ca0b28de3..e59cb714456c 100644 --- a/tests/udp.rs +++ b/tests/udp.rs @@ -4,8 +4,8 @@ extern crate bytes; extern crate env_logger; extern crate futures; extern crate shadowsocks; -extern crate tokio_io; extern crate tokio; +extern crate tokio_io; use std::io::Cursor; use std::net::SocketAddr; @@ -17,11 +17,11 @@ use bytes::{BufMut, BytesMut}; use futures::Future; use tokio_io::io::read_to_end; -use shadowsocks::{run_local, run_server}; use shadowsocks::config::{Config, ServerConfig}; use shadowsocks::crypto::CipherType; use shadowsocks::relay::socks5::{Address, UdpAssociateHeader}; use shadowsocks::relay::tcprelay::client::Socks5Client; +use shadowsocks::{run_local, run_server}; const SERVER_ADDR: &'static str = "127.0.0.1:8093"; const LOCAL_ADDR: &'static str = "127.0.0.1:8291"; @@ -132,8 +132,7 @@ fn udp_relay() { println!("Received buf size={} {:?}", amt, &buf[..amt]); let cur = Cursor::new(buf[..amt].to_vec()); - let (cur, header) = UdpAssociateHeader::read_from(cur).wait() - .expect("Invalid UDP header"); + let (cur, header) = UdpAssociateHeader::read_from(cur).wait().expect("Invalid UDP header"); println!("{:?}", header); let header_len = cur.position() as usize; let buf = cur.into_inner(); From 10e9589caae03d321182dd3bfa0b67e62b3356df Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Fri, 11 May 2018 09:11:25 +0800 Subject: [PATCH 19/22] Add test for DNS --- tests/dns.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 tests/dns.rs diff --git a/tests/dns.rs b/tests/dns.rs new file mode 100644 index 000000000000..dc6cdea8bb6e --- /dev/null +++ b/tests/dns.rs @@ -0,0 +1,75 @@ +extern crate dns_parser; +extern crate env_logger; +extern crate rand; +extern crate shadowsocks; + +use std::collections::HashSet; +use std::net::{SocketAddr, UdpSocket}; +use std::thread; +use std::time::Duration; + +use dns_parser::{Builder, Packet, QueryClass, QueryType}; +use shadowsocks::config::{Config, ConfigType}; +use shadowsocks::{run_dns, run_server}; + +const CONFIG: &'static str = r#"{ + "server": "127.0.0.1", + "server_port": 8988, + "local_port": 5030, + "local_address": "127.0.0.1", + "password": "abc", + "timeout": 20, + "method": "aes-256-gcm", + "enable_udp": true + }"#; + +#[test] +fn dns_relay() { + env_logger::init(); + + let server_cfg = Config::load_from_str(CONFIG, ConfigType::Server).unwrap(); + let dns_cfg = Config::load_from_str(CONFIG, ConfigType::Local).unwrap(); + + thread::spawn(move || { + run_server(server_cfg); + }); + + thread::spawn(move || { + run_dns(dns_cfg); + }); + + thread::sleep(Duration::from_secs(1)); + + let dns_addr = "127.0.0.1:5030".parse::().unwrap(); + let local_addr = "0.0.0.0:0".parse::().unwrap(); + let local = UdpSocket::bind(&local_addr).unwrap(); + + const LOOP_ROUND: usize = 10; + + let mut sent_id = HashSet::::with_capacity(LOOP_ROUND); + for _ in 0..LOOP_ROUND { + let mut id = rand::random::(); + while let Some(..) = sent_id.get(&id) { + id = rand::random::(); + } + + sent_id.insert(id); + + let mut builder = Builder::new_query(id, false); + builder.add_question("www.example.com", QueryType::A, QueryClass::IN); + + let payload = builder.build().unwrap(); + + local.send_to(&payload, &dns_addr).unwrap(); + + // println!("SENT {:?}", payload); + + let mut buf = [0u8; 65535]; + let (len, _) = local.recv_from(&mut buf).unwrap(); + + let packet = Packet::parse(&buf[..len]).unwrap(); + + // println!("GOT {:?}", packet); + assert_eq!(packet.header.id, id); + } +} From af1ff736a8d56f7d63077c370a80f5b42fdbc9eb Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Fri, 11 May 2018 21:05:45 +0800 Subject: [PATCH 20/22] Updated ssdns param --- README.md | 20 ++++++++++++++++++-- src/bin/ssdns.rs | 29 ++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5edb6b7b114f..5e67a985f570 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,24 @@ $ ssserver -c /path/to/shadowsocks.json $ ssserver -s "[::]:8388" -m "aes-256-gcm" -k "hello-kitty" --plugin "obfs-server" --plugin-opts "obfs=tls" ``` +DNS Local server + +```bash +# Read configuration from file +$ ssdns -c /path/to/shadowsocks.json + +# Pass all parameters via command line +$ ssdns -s "[::]:8388" -m "aes-256-gcm" -k "hello-kitty" --dns "8.8.8.8:53" +``` + +For DNS relay server, you can set remote DNS server in configuration file with `dns` key in root object. + +```json +{ + "dns": "8.8.8.8:53" +} +``` + ## Supported Ciphers ### Stream Ciphers @@ -186,8 +204,6 @@ $ ssserver -s "[::]:8388" -m "aes-256-gcm" -k "hello-kitty" --plugin "obfs-serve ss://YWVzLTI1Ni1jZmI6cGFzc3dvcmQ@127.0.0.1:8388/?plugin=obfs-local%3Bobfs%3Dhttp%3Bobfs-host%3Dwww.baidu.com ``` -2. `ssdns` is a DNS server which will do DNS queries via ShadowSocks' servers. Currently it only supports UDP DNS. - ## Notes It supports the following features: diff --git a/src/bin/ssdns.rs b/src/bin/ssdns.rs index 5ca0b6901181..7b43c47f27a6 100644 --- a/src/bin/ssdns.rs +++ b/src/bin/ssdns.rs @@ -89,6 +89,10 @@ fn main() { .long("server-url") .takes_value(true) .help("Server address in SIP002 URL")) + .arg(Arg::with_name("DNS") + .long("dns") + .takes_value(true) + .help("Remote DNS server, default is 8.8.8.8:53")) .get_matches(); let mut log_builder = Builder::new(); @@ -131,16 +135,18 @@ 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 + Some(cpath) => { + match Config::load_from_file(cpath, ConfigType::Local) { + Ok(cfg) => { + has_provided_config = true; + cfg + } + Err(err) => { + error!("{:?}", err); + return; + } } - Err(err) => { - error!("{:?}", err); - return; - } - }, + } None => Config::new(), }; @@ -196,6 +202,11 @@ fn main() { return; } + if let Some(dns) = matches.value_of("DNS") { + let dns_addr = dns.parse::().expect("Failed to parse `dns`"); + config.dns = dns_addr; + } + info!("ShadowSocks DNS {}", shadowsocks::VERSION); debug!("Config: {:?}", config); From 4fb20d439591cf7b73f7ca6e5bbeeba5cb86fd18 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Tue, 15 May 2018 08:54:28 +0800 Subject: [PATCH 21/22] Use `trust-dns` and impl Trait 1. Replaced `ToSocketAddrs` with `trust-dns` 2. Uses impl Trait for functions 3. Updated dependencies 4. Fixed bugs --- Cargo.lock | 358 +++++++++++++++++++++++++---- Cargo.toml | 6 +- build/build-release | 3 +- src/bin/ssdns.rs | 22 +- src/lib.rs | 2 +- src/monitor.rs | 67 +++--- src/relay/dns_resolver.rs | 196 +++++++++++----- src/relay/local.rs | 22 +- src/relay/server.rs | 22 +- src/relay/socks5.rs | 173 +++++++------- src/relay/tcprelay/client.rs | 21 +- src/relay/tcprelay/local.rs | 5 +- src/relay/tcprelay/mod.rs | 84 +++---- src/relay/tcprelay/server.rs | 33 +-- src/relay/tcprelay/socks5_local.rs | 29 +-- src/relay/udprelay/dns.rs | 68 +++--- src/relay/udprelay/local.rs | 24 +- src/relay/udprelay/server.rs | 15 +- 18 files changed, 731 insertions(+), 419 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c06c25ef3103..7794ddc1f0be 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)", ] @@ -759,16 +852,43 @@ dependencies = [ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "resolv-conf" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "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.13.0-alpha" +version = "0.12.1" 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)", + "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 9f3c0c7e9c71..aa7175d97237 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 be6cc43feec1..8e4a3624681e 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 7b43c47f27a6..d6510fd118e1 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 7cf810b28084..e3bdc24095b5 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 f3365837b3a9..8ff3069e9636 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); - - match r { - Ok(..) => { - process::exit(0); - } - Err(err) => Err(err), - } - })) + 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), + } + }) } #[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 e0efe9a574cf..b817067f0588 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)])); - } - - let result = { - let forbidden_ip = &config.forbidden_ip; - - 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)]) - } - }; - - return boxed_future(future::done(result)); +fn init_resolver(force_google: bool) -> ResolverFuture { + use std::sync::{Arc, Condvar, Mutex}; + use std::thread; + + // 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(); + + // 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"); + + // 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); + // take the started resolver + let resolver = mem::replace(&mut *resolver, None); + + // 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 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::>() - }; - - 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) + 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 b39a13b1912a..38f7d1323416 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 227ac18abee1..b55a819f5880 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 7a960eb128c8..e6f26f4a0242 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")); - } - - 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, }; - - (conn, header) - }) - }); - - Box::new(fut) + 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")) + } + }; + + Ok((r, command)) + }) + .and_then(|(r, command)| { + Address::read_from(r).map(move |(conn, address)| { + let header = + TcpRequestHeader { command: command, + address: address, }; + + (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]; - - 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: + 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")); + } + + 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 226084e5d5bf..dffbb8fc66c4 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 6dbae4e80385..3413aacf5546 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 8ec2e0706e4f..5d4f1ca8fc60 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) - } - } - - Ok(()) - }) - .map_err(|(err, _)| err); - - boxed_future(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) + } + } + + 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 4de01d81dce7..6b6049b25ef8 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 943092973e8e..cf863ea4b94e 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(); - - trace!("Got connection, addr: {}", socket.peer_addr()?); - trace!("Picked proxy server: {:?}", server_cfg); + listener.incoming().for_each(move |socket| { + let server_cfg = servers.pick_server(); - handle_socks5_client(config.clone(), socket, server_cfg, udp_conf.clone()) - }); + trace!("Got connection, addr: {}", socket.peer_addr()?); + trace!("Picked proxy server: {:?}", server_cfg); - 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 ac7e741e1d56..804428667bff 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 f843c665da75..d8172c097b81 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 7d0a65080371..16b12446e7e4 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(|_| ()))), }; } From 8c2e785fd239e61545dc4269d7c467f4908185bb Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Tue, 15 May 2018 09:00:48 +0800 Subject: [PATCH 22/22] Bug fixed, logging crate in ssdns --- src/bin/ssdns.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/bin/ssdns.rs b/src/bin/ssdns.rs index d6510fd118e1..72d3a1167f83 100644 --- a/src/bin/ssdns.rs +++ b/src/bin/ssdns.rs @@ -108,16 +108,16 @@ fn main() { } 1 => { let log_builder = log_builder.format(move |fmt, r| log_time_module(fmt, without_time, r)); - log_builder.filter(Some("sslocal"), LevelFilter::Debug); + log_builder.filter(Some("ssdns"), LevelFilter::Debug); } 2 => { let log_builder = log_builder.format(move |fmt, r| log_time_module(fmt, without_time, r)); - log_builder.filter(Some("sslocal"), LevelFilter::Debug) + log_builder.filter(Some("ssdns"), LevelFilter::Debug) .filter(Some("shadowsocks"), LevelFilter::Debug); } 3 => { let log_builder = log_builder.format(move |fmt, r| log_time_module(fmt, without_time, r)); - log_builder.filter(Some("sslocal"), LevelFilter::Trace) + log_builder.filter(Some("ssdns"), LevelFilter::Trace) .filter(Some("shadowsocks"), LevelFilter::Trace); } _ => { @@ -135,16 +135,18 @@ 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 + Some(cpath) => { + match Config::load_from_file(cpath, ConfigType::Local) { + Ok(cfg) => { + has_provided_config = true; + cfg + } + Err(err) => { + error!("{:?}", err); + return; + } } - Err(err) => { - error!("{:?}", err); - return; - } - }, + } None => Config::new(), };