From 9d5e2e9fed36b2503522fde9c3b811d1deeac0b9 Mon Sep 17 00:00:00 2001 From: Paul Lietar Date: Wed, 18 Jan 2017 05:57:36 +0000 Subject: [PATCH] Rewrite connection layer to use tokio --- Cargo.lock | 254 +++++++++++++++++++++--------------- Cargo.toml | 4 + src/album_cover.rs | 2 +- src/audio_file2.rs | 2 +- src/audio_key.rs | 2 +- src/connection.rs | 98 -------------- src/connection/adaptor.rs | 85 ++++++++++++ src/connection/codec.rs | 94 +++++++++++++ src/connection/handshake.rs | 193 +++++++++++++++++++++++++++ src/connection/mod.rs | 74 +++++++++++ src/lib.in.rs | 1 + src/lib.rs | 5 +- src/mercury.rs | 2 +- src/session.rs | 177 ++++++------------------- 14 files changed, 645 insertions(+), 348 deletions(-) delete mode 100644 src/connection.rs create mode 100644 src/connection/adaptor.rs create mode 100644 src/connection/codec.rs create mode 100644 src/connection/handshake.rs create mode 100644 src/connection/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 1fdfe738..03b486a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,7 @@ dependencies = [ "ctrlc 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "eventual 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "json_macros 0.3.1 (git+https://github.com/plietar/json_macros)", @@ -20,18 +21,20 @@ dependencies = [ "mdns 0.2.0 (git+https://github.com/plietar/rust-mdns)", "num 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "portaudio 0.2.0 (git+https://github.com/mvdnes/portaudio-rs)", - "protobuf 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf_macros 0.6.0 (git+https://github.com/plietar/rust-protobuf-macros)", "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", "shannon 0.1.1 (git+https://github.com/plietar/rust-shannon)", "tempfile 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-proto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tremor 0.1.0 (git+https://github.com/plietar/rust-tremor)", "url 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -51,7 +54,7 @@ name = "alsa" version = "0.0.1" source = "git+https://github.com/plietar/rust-alsa#8c63543fa0ccd971cf15f5675293d19febd6f79e" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -72,10 +75,10 @@ dependencies = [ [[package]] name = "aster" -version = "0.36.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -126,8 +129,8 @@ name = "cookie" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -136,7 +139,7 @@ version = "2.0.1" 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)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -171,12 +174,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "syncbox 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -215,14 +218,14 @@ dependencies = [ "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -278,7 +281,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -287,7 +290,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -295,14 +298,14 @@ name = "libpulse-sys" version = "0.0.0" source = "git+https://github.com/astro/libpulse-sys#3e167c0d75dae1ce3946eec7526f6afd92adda0f" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "librespot-protocol" version = "0.1.0" dependencies = [ - "protobuf 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -316,7 +319,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "liblmdb-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -334,18 +337,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mdns" version = "0.2.0" -source = "git+https://github.com/plietar/rust-mdns#2078310b61794994d727ed20ff315709937059a0" +source = "git+https://github.com/plietar/rust-mdns#8ea956858dcd900b02d795f35f884034d15cf8e8" dependencies = [ - "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "dns-parser 0.3.2 (git+https://github.com/plietar/dns-parser)", - "futures 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "multimap 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "multimap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -353,7 +356,7 @@ name = "memchr" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -371,7 +374,7 @@ 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)", "lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -393,7 +396,7 @@ dependencies = [ [[package]] name = "multimap" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -403,20 +406,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.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.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "nix" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "nix" version = "0.7.0" @@ -424,7 +418,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -498,10 +492,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -510,7 +504,7 @@ version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -525,7 +519,7 @@ version = "0.2.0" source = "git+https://github.com/mvdnes/portaudio-rs#2e1630843551a229bfe6cae6291fd157349bad60" dependencies = [ "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "portaudio_sys 0.1.1 (git+https://github.com/mvdnes/portaudio-rs)", ] @@ -534,23 +528,23 @@ name = "portaudio_sys" version = "0.1.1" source = "git+https://github.com/mvdnes/portaudio-rs#2e1630843551a229bfe6cae6291fd157349bad60" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "protobuf" -version = "1.0.24" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "protobuf_macros" version = "0.6.0" -source = "git+https://github.com/plietar/rust-protobuf-macros#4f34371e4fdd5dca7db86e91ba8b902ae55c739c" +source = "git+https://github.com/plietar/rust-protobuf-macros#09c079a96bd4b6b429abc74334215cfcb67e45dc" dependencies = [ - "aster 0.36.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", + "aster 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -611,9 +605,14 @@ name = "rand" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "redox_syscall" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "regex" version = "0.1.80" @@ -637,7 +636,7 @@ version = "0.3.0" 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)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -648,10 +647,10 @@ version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -679,7 +678,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -713,7 +712,7 @@ dependencies = [ "dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -730,7 +729,7 @@ version = "0.1.1" source = "git+https://github.com/plietar/rust-shannon#613aa1e752b3247a30d2c866bb45f0170e9df8d6" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "shannon-sys 0.1.0 (git+https://github.com/plietar/rust-shannon)", ] @@ -740,7 +739,7 @@ version = "0.1.0" source = "git+https://github.com/plietar/rust-shannon#613aa1e752b3247a30d2c866bb45f0170e9df8d6" dependencies = [ "gcc 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -748,6 +747,11 @@ name = "slab" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "smallvec" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "solicit" version = "0.4.4" @@ -763,7 +767,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -786,11 +790,11 @@ dependencies = [ [[package]] name = "syntex" -version = "0.52.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_errors 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -798,7 +802,7 @@ name = "syntex_errors" version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_pos 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -811,7 +815,7 @@ name = "syntex_errors" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_pos 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -821,15 +825,15 @@ dependencies = [ [[package]] name = "syntex_errors" -version = "0.52.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_pos 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -850,7 +854,7 @@ dependencies = [ [[package]] name = "syntex_pos" -version = "0.52.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -862,7 +866,7 @@ version = "0.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -877,7 +881,7 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -888,26 +892,31 @@ dependencies = [ [[package]] name = "syntex_syntax" -version = "0.52.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_errors 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_pos 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "take" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "tempfile" version = "2.1.4" 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)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -927,7 +936,7 @@ name = "termios" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -936,7 +945,7 @@ version = "2.0.0" 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)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -949,26 +958,51 @@ dependencies = [ [[package]] name = "time" -version = "0.1.35" +version = "0.1.36" 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)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-core" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-proto" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-service" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "traitobject" version = "0.0.1" @@ -979,7 +1013,7 @@ name = "tremor" version = "0.1.0" source = "git+https://github.com/plietar/rust-tremor#5958cc302e78f535dad90e9665da981ddff4000a" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "tremor-sys 0.1.0 (git+https://github.com/plietar/rust-tremor)", ] @@ -989,7 +1023,7 @@ version = "0.1.0" source = "git+https://github.com/plietar/rust-tremor#5958cc302e78f535dad90e9665da981ddff4000a" dependencies = [ "gcc 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1025,6 +1059,11 @@ name = "unicode-xid" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "url" version = "0.5.10" @@ -1039,7 +1078,7 @@ dependencies = [ [[package]] name = "url" -version = "1.2.4" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1065,7 +1104,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1078,7 +1117,7 @@ name = "vorbis" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "vorbis-encoder 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1092,7 +1131,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1104,7 +1143,7 @@ version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1115,7 +1154,7 @@ version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1145,7 +1184,7 @@ dependencies = [ "checksum alsa 0.0.1 (git+https://github.com/plietar/rust-alsa)" = "" "checksum aster 0.27.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258989846dd255a1e0eeef92d425d345477c9999433cecc9f0879f4549d5e5c9" "checksum aster 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88bb8ecdf6a7eaddb7bfd872ebf5e085d343ca42ce98c582dba8046e3450b524" -"checksum aster 0.36.0 (registry+https://github.com/rust-lang/crates.io-index)" = "365684a2d8153bde2ca60826e54c8d3df76e06578ed868f8baaf91ae811af07b" +"checksum aster 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)" = "022822e5621c840afed9d4fbdf52104bfc2ff6f0f64016a6bbe4e10d7ec70535" "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d" "checksum bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "32866f4d103c4e438b1db1158aa1b1a80ee078e5d77a59a2f906fd62a577389c" @@ -1160,7 +1199,7 @@ dependencies = [ "checksum dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd841b58510c9618291ffa448da2e4e0f699d984d436122372f446dae62263d" "checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f" "checksum eventual 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b9bda6d089b434ca50f3d6feb5fca421309b8bac97b8be9af51cff879fa3f54b" -"checksum futures 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "177a82a61dd7e528022ce97f24e54b499dd2fee4d4646a0f283c5fb500dbfe20" +"checksum futures 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3e0b237aed5d8b61bc7d6ee1b8ebd719d0a934a38d363c5e56daf34bb634d9b2" "checksum gcc 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)" = "3689e1982a563af74960ae3a4758aa632bb8fd984cfc3cc3b60ee6109477ab6e" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" "checksum hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58" @@ -1173,7 +1212,7 @@ dependencies = [ "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b" "checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b" -"checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70" +"checksum libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "684f330624d8c3784fb9558ca46c4ce488073a8d22450415c5eb4f4cfb0d11b5" "checksum liblmdb-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b56d07dcf983f9b6679f768df73c72671d0087bd66329baabb63325f4f592677" "checksum libpulse-sys 0.0.0 (git+https://github.com/astro/libpulse-sys)" = "" "checksum linear-map 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f947d2a0ca958037e42a430bc7ea4369f97b60a2002bd927b84404509cc64cf" @@ -1185,9 +1224,8 @@ dependencies = [ "checksum mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5c93a4bd787ddc6e7833c519b73a50883deb5863d76d9b71eb8216fb7f94e66" "checksum mio 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5b493dc9fd96bd2077f2117f178172b0765db4dfda3ea4d8000401e6d65d3e80" "checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1" -"checksum multimap 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e85cb6b79f81830421066428f1f8f47032d77843dc569040a7d056b80f95d5d4" +"checksum multimap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9223f4774d08e06185e44e555b9a7561243d387bac49c78a6205c42d6975fbf2" "checksum net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "5edf9cb6be97212423aed9413dd4729d62b370b5e1c571750e882cebbbc1e3e2" -"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79" "checksum nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0d95c5fa8b641c10ad0b8887454ebaafa3c92b5cd5350f8fc693adafd178e7b" "checksum num 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "bde7c03b09e7c6a301ee81f6ddf66d7a28ec305699e3d3b056d2fc56470e3120" "checksum num-bigint 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "88b14378471f7c2adc5262f05b4701ef53e8da376453a8d8fee48e51db745e49" @@ -1196,12 +1234,12 @@ dependencies = [ "checksum num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "287a1c9969a847055e1122ec0ea7a5c5d6f72aad97934e131c83d5c08ab4e45c" "checksum num-rational 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "54ff603b8334a72fbb27fe66948aac0abaaa40231b3cecd189e76162f6f38aaf" "checksum num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "a16a42856a256b39c6d3484f097f6713e14feacd9bfb02290917904fae46c81c" -"checksum num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55aabf4e2d6271a2e4e4c0f2ea1f5b07cc589cc1a9e9213013b54a76678ca4f3" +"checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39" "checksum ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a95b8c172e17df1a41bf8d666301d3b2c4efeb90d9d0415e2a4dc0668b35fdb2" "checksum pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8cee804ecc7eaf201a4a207241472cc870e825206f6c031e3ee2a72fa425f2fa" "checksum portaudio 0.2.0 (git+https://github.com/mvdnes/portaudio-rs)" = "" "checksum portaudio_sys 0.1.1 (git+https://github.com/mvdnes/portaudio-rs)" = "" -"checksum protobuf 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec4c2fe04370298218a09ab53a534febf54c160c5554e4de987b6d73c916d5d" +"checksum protobuf 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229112a9213bf62a59f0702871a6e4872fe928161fc7a08f17cdd6c8c7988bf7" "checksum protobuf_macros 0.6.0 (git+https://github.com/plietar/rust-protobuf-macros)" = "" "checksum quasi 0.20.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94a532453b931a4483a5b2e40f0fe04aee35b6bc2c0eeec876f1bd2358a134d3" "checksum quasi 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ab7992920bf5bc5f1ed6fdc49090bf665cd00b3aa4b78c16ac3465286257db1" @@ -1210,6 +1248,7 @@ dependencies = [ "checksum quasi_macros 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "adc2b36285ea5e54e4e267f83896267ff8c5aba4f66b2e7d186ed6d968f3715f" "checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c" "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" +"checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753" "checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" "checksum rpassword 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab6e42be826e215f30ff830904f8f4a0933c6e2ae890e1af8b408f5bae60081e" @@ -1218,7 +1257,7 @@ dependencies = [ "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" -"checksum serde 0.8.21 (registry+https://github.com/rust-lang/crates.io-index)" = "7b7c6bf11cf766473ea1d53eb4e3bc4e80f31f50082fc24077cf06f600279a66" +"checksum serde 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e4aab5b62fb90ac9c99d5a55caa7c37e06a15d1b189ccc2b117782655fd11f" "checksum serde_codegen 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "da68810d845f8e33a80243c28794650397056cbe7aea4c9c7516f55d1061c94e" "checksum serde_codegen_internals 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1b0115c5c602e81c61b787fb0f0fa76a614f8dbe9100b2b59b7d590155672c80" "checksum serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3f7d3c184d35801fb8b32b46a7d58d57dbcc150b0eb2b46a1eb79645e8ecfd5b" @@ -1226,27 +1265,31 @@ dependencies = [ "checksum shannon 0.1.1 (git+https://github.com/plietar/rust-shannon)" = "" "checksum shannon-sys 0.1.0 (git+https://github.com/plietar/rust-shannon)" = "" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" +"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" "checksum solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2" "checksum syncbox 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "05bc2b72659ac27a2d0e7c4166c8596578197c4c41f767deab12c81f523b85c7" "checksum syntex 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84f37b94d7ee762bcac58741f73a95465cf87188c3b93f10df9245aff821b2b4" "checksum syntex 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bd253b0d7d787723a33384d426f0ebec7f8edccfaeb2022d0177162bb134da0" -"checksum syntex 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b1b66e8c1e25a6c4007a38a225411b776a06e8c3030d6fc4d200a038bf02065" +"checksum syntex 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b186e277908427269816c542c912b45253ed11808a09780bd224679770ce351" "checksum syntex_errors 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0d95d2141ae79f312a01c6934d9984f9d7f5cfaf0c74aae5fbbc234a6dcb77a" "checksum syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84822a1178204a191239ad844599f8c85c128cf9f4173397def4eb46b55b0aa1" -"checksum syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e52bffe6202cfb67587784cf23e0ec5bf26d331eef4922a16d5c42e12aa1e9b" +"checksum syntex_errors 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09c050df675f9be2acbc2082c1d9cf1d3014837ad5f5302b7d4697e4ad031984" "checksum syntex_pos 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2cbf0598c5970f2dca122a4e6f7e93bf42f2d0b2dd88c3ea112413152864df" "checksum syntex_pos 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a43abded5057c75bac8555e46ec913ce502efb418267b1ab8e9783897470c7db" -"checksum syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "955ef4b16af4c468e4680d1497f873ff288f557d338180649e18f915af5e15ac" +"checksum syntex_pos 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60b7ba34c8017f1972f23f926aae82d66901978bd724ca1372671f67329ee0ee" "checksum syntex_syntax 0.44.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5a89ee386d492cdd3855becec489c25797bb91bcbb3c2478c41969b24cb318a2" "checksum syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef781e4b60f03431f1b5b59843546ce60ae029a787770cf8e0969ac1fd063a5" -"checksum syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76a302e717e348aa372ff577791c3832395650073b8d8432f8b3cb170b34afde" +"checksum syntex_syntax 0.55.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58b199e4f76605987ba81d9c949f2274e236388fa1b476fd00f4b72bb7bd9dfc" +"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempfile 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9270837a93bad1b1dac18fe67e786b3c960513af86231f6f4f57fddd594ff0c8" "checksum term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3deff8a2b3b6607d6d7cc32ac25c0b33709453ca9cceac006caac51e963cf94a" "checksum termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a" "checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" "checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" -"checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af" -"checksum tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "52416b3e937abac22a543a7f1c66bd37feb60137ff1ab42390fa02df85347e58" +"checksum time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "211b63c112206356ef1ff9b19355f43740fc3f85960c598a93d3a3d3ba7beade" +"checksum tokio-core 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0800e9475303171ffbc79394079ef503b6d00949649799208f4fc8f1eca20892" +"checksum tokio-proto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c0d6031f94d78d7b4d509d4a7c5e1cdf524a17e7b08d1c188a83cf720e69808" +"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07eaeb7689bb7fca7ce15628319635758eda769fed481ecfe6686ddef2600616" "checksum tremor 0.1.0 (git+https://github.com/plietar/rust-tremor)" = "" "checksum tremor-sys 0.1.0 (git+https://github.com/plietar/rust-tremor)" = "" @@ -1255,8 +1298,9 @@ dependencies = [ "checksum unicode-bidi 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b61814f3e7fd0e0f15370f767c7c943e08bc2e3214233ae8f88522b334ceb778" "checksum unicode-normalization 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5e94e9f6961090fcc75180629c4ef33e5310d6ed2c0dd173f4ca63c9043b669e" "checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum url 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4a3440c1ed62af4a2aee71c6fb78ef32ddcb75cfa24bf42f45e07c02b6d6a2f6" -"checksum url 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f024e241a55f5c88401595adc1d4af0c9649e91da82d0e190fe55950231ae575" +"checksum url 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbcb1997952b5a73b438a90940834621a8002e59640a8d92a1c05ef8fa58a1da" "checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" "checksum uuid 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "885acc3b17fdef6230d1f7765dff1106dfd5e75a93c2f26459fbf600ed6dcc14" "checksum vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c3365f36c57e5df714a34be40902b27a992eeddb9996eca52d0584611cf885d" diff --git a/Cargo.toml b/Cargo.toml index dc88c7e5..69548efa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,10 @@ protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros" } mdns = { git = "https://github.com/plietar/rust-mdns" } +futures = "0.1.8" +tokio-proto = "0.1.0" +tokio-core = "0.1.2" + [build-dependencies] vergen = "0.1.0" protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros" } diff --git a/src/album_cover.rs b/src/album_cover.rs index d453ccb5..3c56a46e 100644 --- a/src/album_cover.rs +++ b/src/album_cover.rs @@ -18,7 +18,7 @@ impl stream::Handler for AlbumCover { req.write_u16::(channel_id).unwrap(); req.write_u16::(0).unwrap(); req.write(&self.file_id.0).unwrap(); - session.send_packet(0x19, &req).unwrap(); + session.send_packet(0x19, req); stream::Response::Continue(self) } diff --git a/src/audio_file2.rs b/src/audio_file2.rs index d90b5668..db0179e6 100644 --- a/src/audio_file2.rs +++ b/src/audio_file2.rs @@ -55,7 +55,7 @@ impl stream::Handler for AudioFile { data.write_u32::(self.offset as u32 / 4).unwrap(); data.write_u32::((self.offset + CHUNK_SIZE) as u32 / 4).unwrap(); - session.send_packet(0x8, &data).unwrap(); + session.send_packet(0x8, data); stream::Response::Continue(self) } diff --git a/src/audio_key.rs b/src/audio_key.rs index a27faf80..da9c3a73 100644 --- a/src/audio_key.rs +++ b/src/audio_key.rs @@ -38,7 +38,7 @@ impl AudioKeyManager { data.write_u32::(seq).unwrap(); data.write_u16::(0x0000).unwrap(); - session.send_packet(0xc, &data).unwrap(); + session.send_packet(0xc, data); seq } diff --git a/src/connection.rs b/src/connection.rs deleted file mode 100644 index 20bacd53..00000000 --- a/src/connection.rs +++ /dev/null @@ -1,98 +0,0 @@ -use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt}; -use shannon::ShannonStream; -use std::convert; -use std::io; -use std::io::{Read, Write}; -use std::net::TcpStream; -use std::result; - -#[derive(Debug)] -pub enum Error { - IoError(io::Error), - Other, -} - -pub type Result = result::Result; - -impl convert::From for Error { - fn from(err: io::Error) -> Error { - Error::IoError(err) - } -} - -pub struct PlainConnection { - stream: TcpStream, -} - -#[derive(Clone)] -pub struct CipherConnection { - stream: ShannonStream, -} - -impl PlainConnection { - pub fn connect(ap: &str) -> Result { - Ok(PlainConnection { - stream: try!(TcpStream::connect(ap)), - }) - } - - pub fn send_packet(&mut self, data: &[u8]) -> Result> { - self.send_packet_prefix(&[], data) - } - - pub fn send_packet_prefix(&mut self, prefix: &[u8], data: &[u8]) -> Result> { - let size = prefix.len() + 4 + data.len(); - let mut buf = Vec::with_capacity(size); - - try!(buf.write(prefix)); - try!(buf.write_u32::(size as u32)); - try!(buf.write(data)); - try!(self.stream.write(&buf)); - try!(self.stream.flush()); - - Ok(buf) - } - - pub fn recv_packet(&mut self) -> Result> { - let size = try!(self.stream.read_u32::()) as usize; - let mut buffer = vec![0u8; size]; - - BigEndian::write_u32(&mut buffer, size as u32); - try!(self.stream.read_exact(&mut buffer[4..])); - - Ok(buffer) - } - - pub fn into_stream(self) -> TcpStream { - self.stream - } -} - -impl CipherConnection { - pub fn new(stream: TcpStream, recv_key: &[u8], send_key: &[u8]) -> CipherConnection { - CipherConnection { stream: ShannonStream::new(stream, recv_key, send_key) } - } - - pub fn send_packet(&mut self, cmd: u8, data: &[u8]) -> Result<()> { - try!(self.stream.write_u8(cmd)); - try!(self.stream.write_u16::(data.len() as u16)); - try!(self.stream.write(data)); - - try!(self.stream.finish_send()); - try!(self.stream.flush()); - - Ok(()) - } - - pub fn recv_packet(&mut self) -> Result<(u8, Vec)> { - let cmd = try!(self.stream.read_u8()); - let size = try!(self.stream.read_u16::()) as usize; - - let mut data = vec![0; size]; - try!(self.stream.read_exact(&mut data)); - - try!(self.stream.finish_recv()); - - Ok((cmd, data)) - } -} diff --git a/src/connection/adaptor.rs b/src/connection/adaptor.rs new file mode 100644 index 00000000..a8458c7b --- /dev/null +++ b/src/connection/adaptor.rs @@ -0,0 +1,85 @@ +use futures::future::ok; +use futures::sync::mpsc; +use futures::{Future, Sink, Stream, BoxFuture, IntoFuture}; +use std::thread; +use tokio_core::reactor::Core; +use tokio_core::reactor::Handle; + +pub struct SinkAdaptor(Option>); +pub struct StreamAdaptor(Option>>); + +impl SinkAdaptor { + pub fn send(&mut self, item: T) { + let sender = self.0.take().unwrap(); + let sending = sender.send(item); + self.0 = Some(sending.wait().unwrap()); + } +} + +impl StreamAdaptor { + pub fn recv(&mut self) -> Result { + let receiver = self.0.take().unwrap(); + let receiving = receiver.into_future(); + + let (packet, receiver) = receiving.wait().map_err(|(e, _)| e).unwrap(); + + self.0 = Some(receiver); + + packet.unwrap() + } +} + +fn adapt_sink(sink: S, rx: mpsc::Receiver) -> BoxFuture<(), ()> + where S: Sink + Send + 'static, + S::SinkItem: Send, + S::SinkError: Send, +{ + rx.map_err(|_| -> S::SinkError { panic!("") }) + .forward(sink) + .map(|_| ()).map_err(|_| ()) + .boxed() +} + +fn adapt_stream(stream: S, tx: mpsc::Sender>) -> BoxFuture<(), ()> + where S: Stream + Send + 'static, + S::Item: Send, + S::Error: Send, +{ + stream.then(ok::<_, mpsc::SendError<_>>) + .forward(tx) + .map(|_| ()).map_err(|_| ()) + .boxed() +} + +pub fn adapt(f: F) -> (SinkAdaptor, StreamAdaptor) + where F: FnOnce(&Handle) -> U + Send + 'static, + U: IntoFuture, + S: Sink + Stream + Send + 'static, + S::Item: Send + 'static, + S::Error: Send + 'static, + S::SinkItem: Send + 'static, + S::SinkError: Send + 'static, +{ + + let (receiver_tx, receiver_rx) = mpsc::channel(0); + let (sender_tx, sender_rx) = mpsc::channel(0); + + + thread::spawn(move || { + let mut core = Core::new().unwrap(); + let handle = core.handle(); + let task = + f(&handle).into_future() + .map(|connection| connection.split()) + .map_err(|_| ()) + .and_then(|(sink, stream)| { + (adapt_sink(sink, sender_rx), + adapt_stream(stream, receiver_tx)) + }); + + core.run(task).unwrap(); + }); + + (SinkAdaptor(Some(sender_tx)), + StreamAdaptor(Some(receiver_rx))) +} diff --git a/src/connection/codec.rs b/src/connection/codec.rs new file mode 100644 index 00000000..968c74e5 --- /dev/null +++ b/src/connection/codec.rs @@ -0,0 +1,94 @@ +use byteorder::{BigEndian, ByteOrder, WriteBytesExt}; +use shannon::Shannon; +use std::io; +use tokio_core::io::{Codec, EasyBuf}; + +const HEADER_SIZE: usize = 3; +const MAC_SIZE: usize = 4; + +#[derive(Debug)] +enum DecodeState { + Header, + Payload(u8, usize), +} + +pub struct APCodec { + encode_nonce: u32, + encode_cipher: Shannon, + + decode_nonce: u32, + decode_cipher: Shannon, + decode_state: DecodeState, +} + +impl APCodec { + pub fn new(send_key: &[u8], recv_key: &[u8]) -> APCodec { + APCodec { + encode_nonce: 0, + encode_cipher: Shannon::new(send_key), + + decode_nonce: 0, + decode_cipher: Shannon::new(recv_key), + decode_state: DecodeState::Header, + } + } +} + +impl Codec for APCodec { + type Out = (u8, Vec); + type In = (u8, EasyBuf); + + fn encode(&mut self, item: (u8, Vec), buf: &mut Vec) -> io::Result<()> { + let (cmd, payload) = item; + let offset = buf.len(); + + buf.write_u8(cmd).unwrap(); + buf.write_u16::(payload.len() as u16).unwrap(); + buf.extend_from_slice(&payload); + + self.encode_cipher.nonce_u32(self.encode_nonce); + self.encode_nonce += 1; + + self.encode_cipher.encrypt(&mut buf[offset..]); + + let mac = self.encode_cipher.finish(MAC_SIZE as u32); + buf.extend_from_slice(&mac); + + Ok(()) + } + + fn decode(&mut self, buf: &mut EasyBuf) -> io::Result> { + if let DecodeState::Header = self.decode_state { + if buf.len() >= HEADER_SIZE { + let mut header = [0u8; HEADER_SIZE]; + header.copy_from_slice(buf.drain_to(HEADER_SIZE).as_slice()); + + self.decode_cipher.nonce_u32(self.decode_nonce); + self.decode_nonce += 1; + + self.decode_cipher.decrypt(&mut header); + + let cmd = header[0]; + let size = BigEndian::read_u16(&header[1..]) as usize; + self.decode_state = DecodeState::Payload(cmd, size); + } + } + + if let DecodeState::Payload(cmd, size) = self.decode_state { + if buf.len() >= size + MAC_SIZE { + self.decode_state = DecodeState::Header; + + let mut payload = buf.drain_to(size + MAC_SIZE); + + self.decode_cipher.decrypt(&mut payload.get_mut()[..size]); + let mac = payload.split_off(size); + self.decode_cipher.check_mac(mac.as_slice())?; + + return Ok(Some((cmd, payload))); + } + } + + + Ok(None) + } +} diff --git a/src/connection/handshake.rs b/src/connection/handshake.rs new file mode 100644 index 00000000..83b0b37a --- /dev/null +++ b/src/connection/handshake.rs @@ -0,0 +1,193 @@ +use crypto::sha1::Sha1; +use crypto::hmac::Hmac; +use crypto::mac::Mac;use byteorder::{BigEndian, ByteOrder, WriteBytesExt}; +use protobuf::{self, Message, MessageStatic}; +use rand::thread_rng; +use std::io::{self, Read, Write}; +use std::marker::PhantomData; +use tokio_core::io::{Io, Framed, write_all, WriteAll, read_exact, ReadExact, Window}; +use futures::{Poll, Async, Future}; + +use diffie_hellman::DHLocalKeys; +use protocol; +use protocol::keyexchange::{ClientHello, APResponseMessage, ClientResponsePlaintext}; +use util; +use super::codec::APCodec; + +pub struct Handshake { + keys: DHLocalKeys, + state: HandshakeState, +} + +enum HandshakeState { + ClientHello(WriteAll>), + APResponse(RecvPacket), + ClientResponse(Option, WriteAll>), +} + +pub fn handshake(connection: T) -> Handshake { + let local_keys = DHLocalKeys::random(&mut thread_rng()); + let client_hello = client_hello(connection, local_keys.public_key()); + + Handshake { + keys: local_keys, + state: HandshakeState::ClientHello(client_hello), + } +} + +impl Future for Handshake { + type Item = Framed; + type Error = io::Error; + + fn poll(&mut self) -> Poll { + use self::HandshakeState::*; + loop { + self.state = match self.state { + ClientHello(ref mut write) => { + let (connection, accumulator) = try_ready!(write.poll()); + + let read = recv_packet(connection, accumulator); + APResponse(read) + } + + APResponse(ref mut read) => { + let (connection, message, accumulator) = try_ready!(read.poll()); + let remote_key = message.get_challenge() + .get_login_crypto_challenge() + .get_diffie_hellman() + .get_gs() + .to_owned(); + + let shared_secret = self.keys.shared_secret(&remote_key); + let (challenge, send_key, recv_key) = compute_keys(&shared_secret, + &accumulator); + let codec = APCodec::new(&send_key, &recv_key); + + let write = client_response(connection, challenge); + ClientResponse(Some(codec), write) + } + + ClientResponse(ref mut codec, ref mut write) => { + let (connection, _) = try_ready!(write.poll()); + let codec = codec.take().unwrap(); + let framed = connection.framed(codec); + return Ok(Async::Ready(framed)); + } + } + } + } +} + +fn client_hello(connection: T, gc: Vec) -> WriteAll> { + let packet = protobuf_init!(ClientHello::new(), { + build_info => { + product: protocol::keyexchange::Product::PRODUCT_PARTNER, + platform: protocol::keyexchange::Platform::PLATFORM_LINUX_X86, + version: 0x10800000000, + }, + cryptosuites_supported => [ + protocol::keyexchange::Cryptosuite::CRYPTO_SUITE_SHANNON, + ], + login_crypto_hello.diffie_hellman => { + gc: gc, + server_keys_known: 1, + }, + client_nonce: util::rand_vec(&mut thread_rng(), 0x10), + padding: vec![0x1e], + }); + + let mut buffer = vec![0, 4]; + let size = 2 + 4 + packet.compute_size(); + buffer.write_u32::(size).unwrap(); + packet.write_to_vec(&mut buffer).unwrap(); + + write_all(connection, buffer) +} + +fn client_response(connection: T, challenge: Vec) -> WriteAll> { + let packet = protobuf_init!(ClientResponsePlaintext::new(), { + login_crypto_response.diffie_hellman => { + hmac: challenge + }, + pow_response => {}, + crypto_response => {}, + }); + + let mut buffer = vec![]; + let size = 4 + packet.compute_size(); + buffer.write_u32::(size).unwrap(); + packet.write_to_vec(&mut buffer).unwrap(); + + write_all(connection, buffer) +} + +enum RecvPacket { + Header(ReadExact>>, PhantomData), + Body(ReadExact>>, PhantomData), +} + +fn recv_packet(connection: T, acc: Vec) -> RecvPacket + where T: Read, + M: MessageStatic +{ + RecvPacket::Header(read_into_accumulator(connection, 4, acc), PhantomData) +} + +impl Future for RecvPacket + where T: Read, + M: MessageStatic +{ + type Item = (T, M, Vec); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + use self::RecvPacket::*; + loop { + *self = match *self { + Header(ref mut read, _) => { + let (connection, header) = try_ready!(read.poll()); + let size = BigEndian::read_u32(header.as_ref()) as usize; + + let acc = header.into_inner(); + let read = read_into_accumulator(connection, size - 4, acc); + RecvPacket::Body(read, PhantomData) + } + + Body(ref mut read, _) => { + let (connection, data) = try_ready!(read.poll()); + let message = protobuf::parse_from_bytes(data.as_ref()).unwrap(); + + let acc = data.into_inner(); + return Ok(Async::Ready((connection, message, acc))); + } + } + } + } +} + +fn read_into_accumulator(connection: T, size: usize, mut acc: Vec) -> ReadExact>> { + let offset = acc.len(); + acc.resize(offset + size, 0); + + let mut window = Window::new(acc); + window.set_start(offset); + + read_exact(connection, window) +} + +fn compute_keys(shared_secret: &[u8], packets: &[u8]) -> (Vec, Vec, Vec) { + let mut data = Vec::with_capacity(0x64); + let mut mac = Hmac::new(Sha1::new(), &shared_secret); + + for i in 1..6 { + mac.input(packets); + mac.input(&[i]); + data.extend_from_slice(&mac.result().code()); + mac.reset(); + } + + mac = Hmac::new(Sha1::new(), &data[..0x14]); + mac.input(packets); + + (mac.result().code().to_vec(), data[0x14..0x34].to_vec(), data[0x34..0x54].to_vec()) +} diff --git a/src/connection/mod.rs b/src/connection/mod.rs new file mode 100644 index 00000000..3ceb6380 --- /dev/null +++ b/src/connection/mod.rs @@ -0,0 +1,74 @@ +mod codec; +mod handshake; +pub mod adaptor; + +pub use self::codec::APCodec; +pub use self::handshake::handshake; + +use futures::{Future, Sink, Stream, BoxFuture}; +use std::io; +use std::net::ToSocketAddrs; +use tokio_core::net::TcpStream; +use tokio_core::reactor::Handle; +use tokio_core::io::Framed; +use protobuf::{self, Message}; + +use authentication::Credentials; +use version; + +pub type Transport = Framed; + +pub fn connect(addr: A, handle: &Handle) -> BoxFuture { + let addr = addr.to_socket_addrs().unwrap().next().unwrap(); + let socket = TcpStream::connect(&addr, handle); + let connection = socket.and_then(|socket| { + handshake(socket) + }); + + connection.boxed() +} + +pub fn authenticate(transport: Transport, credentials: Credentials, device_id: String) -> BoxFuture<(Transport, Credentials), io::Error> { + use protocol::authentication::{APWelcome, ClientResponseEncrypted, CpuFamily, Os}; + + let packet = protobuf_init!(ClientResponseEncrypted::new(), { + login_credentials => { + username: credentials.username, + typ: credentials.auth_type, + auth_data: credentials.auth_data, + }, + system_info => { + cpu_family: CpuFamily::CPU_UNKNOWN, + os: Os::OS_UNKNOWN, + system_information_string: "librespot".to_owned(), + device_id: device_id, + }, + version_string: version::version_string(), + }); + + let cmd = 0xab; + let data = packet.write_to_bytes().unwrap(); + + transport.send((cmd, data)).and_then(|transport| { + transport.into_future().map_err(|(err, _stream)| err) + }).and_then(|(packet, transport)| { + match packet { + Some((0xac, data)) => { + let welcome_data: APWelcome = + protobuf::parse_from_bytes(data.as_ref()).unwrap(); + + let reusable_credentials = Credentials { + username: welcome_data.get_canonical_username().to_owned(), + auth_type: welcome_data.get_reusable_auth_credentials_type(), + auth_data: welcome_data.get_reusable_auth_credentials().to_owned(), + }; + + Ok((transport, reusable_credentials)) + } + + Some((0xad, _)) => panic!("Authentication failed"), + Some((cmd, _)) => panic!("Unexpected packet {:?}", cmd), + None => panic!("EOF"), + } + }).boxed() +} diff --git a/src/lib.in.rs b/src/lib.in.rs index c3152879..8b6ddfe4 100644 --- a/src/lib.in.rs +++ b/src/lib.in.rs @@ -1,5 +1,6 @@ pub mod apresolve; pub mod authentication; +pub mod connection; pub mod mercury; pub mod session; pub mod spirc; diff --git a/src/lib.rs b/src/lib.rs index 31671d0c..d8f3378b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,10 @@ extern crate shannon; extern crate tempfile; extern crate url; +#[macro_use] extern crate futures; +extern crate tokio_core; +extern crate tokio_proto; + extern crate librespot_protocol as protocol; #[cfg(not(feature = "with-tremor"))] @@ -52,7 +56,6 @@ pub mod audio_file2; pub mod audio_file; pub mod audio_key; pub mod cache; -pub mod connection; pub mod diffie_hellman; pub mod link; pub mod metadata; diff --git a/src/mercury.rs b/src/mercury.rs index 37a908c6..9923fd6c 100644 --- a/src/mercury.rs +++ b/src/mercury.rs @@ -84,7 +84,7 @@ impl MercuryManager { _ => 0xb2, }; - session.send_packet(cmd, &data).unwrap(); + session.send_packet(cmd, data); self.pending.insert(seq.to_vec(), MercuryPending { diff --git a/src/session.rs b/src/session.rs index 59167614..af976685 100644 --- a/src/session.rs +++ b/src/session.rs @@ -1,31 +1,27 @@ use crypto::digest::Digest; use crypto::sha1::Sha1; -use crypto::hmac::Hmac; -use crypto::mac::Mac; use eventual; use eventual::Future; use eventual::Async; -use protobuf::{self, Message}; -use rand::thread_rng; -use std::io::{Read, Write, Cursor}; +use std::io::{self, Read, Cursor}; use std::result::Result; use std::sync::{Mutex, RwLock, Arc, mpsc}; use std::str::FromStr; +use futures::Future as Future_; +use futures::Stream; +use futures::sync::oneshot; use album_cover::AlbumCover; use apresolve::apresolve; -use audio_key::{AudioKeyManager, AudioKey, AudioKeyError}; use audio_file::AudioFile; +use audio_key::{AudioKeyManager, AudioKey, AudioKeyError}; use authentication::Credentials; use cache::Cache; -use connection::{self, PlainConnection, CipherConnection}; -use diffie_hellman::DHLocalKeys; +use connection::{self, adaptor}; use mercury::{MercuryManager, MercuryRequest, MercuryResponse}; use metadata::{MetadataManager, MetadataRef, MetadataTrait}; -use protocol; use stream::StreamManager; -use util::{self, SpotifyId, FileId, ReadSeek}; -use version; +use util::{SpotifyId, FileId, ReadSeek}; use stream; @@ -70,8 +66,8 @@ pub struct SessionInternal { metadata: Mutex, stream: Mutex, audio_key: Mutex, - rx_connection: Mutex>, - tx_connection: Mutex>, + rx_connection: Mutex), io::Error>>>, + tx_connection: Mutex)>>>, } #[derive(Clone)] @@ -104,143 +100,44 @@ impl Session { })) } - fn connect(&self) -> CipherConnection { - let local_keys = DHLocalKeys::random(&mut thread_rng()); - - let ap = apresolve(); - - info!("Connecting to AP {}", ap); - let mut connection = PlainConnection::connect(&ap).unwrap(); - - let request = protobuf_init!(protocol::keyexchange::ClientHello::new(), { - build_info => { - product: protocol::keyexchange::Product::PRODUCT_PARTNER, - platform: protocol::keyexchange::Platform::PLATFORM_LINUX_X86, - version: 0x10800000000, - }, - cryptosuites_supported => [ - protocol::keyexchange::Cryptosuite::CRYPTO_SUITE_SHANNON, - ], - login_crypto_hello.diffie_hellman => { - gc: local_keys.public_key(), - server_keys_known: 1, - }, - client_nonce: util::rand_vec(&mut thread_rng(), 0x10), - padding: vec![0x1e], - }); - - let init_client_packet = connection.send_packet_prefix(&[0, 4], - &request.write_to_bytes().unwrap()) - .unwrap(); - let init_server_packet = connection.recv_packet().unwrap(); - - let response: protocol::keyexchange::APResponseMessage = - protobuf::parse_from_bytes(&init_server_packet[4..]).unwrap(); - - let remote_key = response.get_challenge() - .get_login_crypto_challenge() - .get_diffie_hellman() - .get_gs(); - - let shared_secret = local_keys.shared_secret(remote_key); - let (challenge, send_key, recv_key) = { - let mut data = Vec::with_capacity(0x64); - let mut mac = Hmac::new(Sha1::new(), &shared_secret); - - for i in 1..6 { - mac.input(&init_client_packet); - mac.input(&init_server_packet); - mac.input(&[i]); - data.write(&mac.result().code()).unwrap(); - mac.reset(); - } - - mac = Hmac::new(Sha1::new(), &data[..0x14]); - mac.input(&init_client_packet); - mac.input(&init_server_packet); - - (mac.result().code().to_vec(), - data[0x14..0x34].to_vec(), - data[0x34..0x54].to_vec()) - }; - - let packet = protobuf_init!(protocol::keyexchange::ClientResponsePlaintext::new(), { - login_crypto_response.diffie_hellman => { - hmac: challenge - }, - pow_response => {}, - crypto_response => {}, - }); - - - connection.send_packet(&packet.write_to_bytes().unwrap()).unwrap(); - - CipherConnection::new(connection.into_stream(), - &send_key, - &recv_key) - } - pub fn login(&self, credentials: Credentials) -> Result { - let packet = protobuf_init!(protocol::authentication::ClientResponseEncrypted::new(), { - login_credentials => { - username: credentials.username, - typ: credentials.auth_type, - auth_data: credentials.auth_data, - }, - system_info => { - cpu_family: protocol::authentication::CpuFamily::CPU_UNKNOWN, - os: protocol::authentication::Os::OS_UNKNOWN, - system_information_string: "librespot".to_owned(), - device_id: self.device_id().to_owned(), - }, - version_string: version::version_string(), + let addr = apresolve(); + let device_id = self.device_id().to_owned(); + + let (creds_tx, creds_rx) = oneshot::channel(); + + info!("Connecting to AP {}", addr); + + let (tx, rx) = adaptor::adapt(move |handle| { + let connection = connection::connect(&addr as &str, &handle); + let authentication = connection.and_then(|connection| { + connection::authenticate(connection, credentials, device_id) + }); + + authentication.map(|(transport, creds)| { + creds_tx.complete(creds); + transport.map(|(cmd, data)| (cmd, data.as_ref().to_owned())) + }) }); - let mut connection = self.connect(); - connection.send_packet(0xab, &packet.write_to_bytes().unwrap()).unwrap(); - let (cmd, data) = connection.recv_packet().unwrap(); + let reusable_credentials = creds_rx.wait().unwrap(); - match cmd { - 0xac => { - let welcome_data: protocol::authentication::APWelcome = - protobuf::parse_from_bytes(&data).unwrap(); + self.0.data.write().unwrap().canonical_username = reusable_credentials.username.clone(); + *self.0.rx_connection.lock().unwrap() = Some(rx); + *self.0.tx_connection.lock().unwrap() = Some(tx); - let username = welcome_data.get_canonical_username().to_owned(); - self.0.data.write().unwrap().canonical_username = username.clone(); - *self.0.rx_connection.lock().unwrap() = Some(connection.clone()); - *self.0.tx_connection.lock().unwrap() = Some(connection); + info!("Authenticated !"); - info!("Authenticated !"); + self.0.cache.put_credentials(&reusable_credentials); - let reusable_credentials = Credentials { - username: username, - auth_type: welcome_data.get_reusable_auth_credentials_type(), - auth_data: welcome_data.get_reusable_auth_credentials().to_owned(), - }; - - self.0.cache.put_credentials(&reusable_credentials); - - Ok(reusable_credentials) - } - - 0xad => { - let msg: protocol::keyexchange::APLoginFailed = - protobuf::parse_from_bytes(&data).unwrap(); - error!("Authentication failed, {:?}", msg); - Err(()) - } - _ => { - error!("Unexpected message {:x}", cmd); - Err(()) - } - } + Ok(reusable_credentials) } pub fn poll(&self) { let (cmd, data) = self.recv(); match cmd { - 0x4 => self.send_packet(0x49, &data).unwrap(), + 0x4 => self.send_packet(0x49, data), 0x4a => (), 0x9 | 0xa => self.0.stream.lock().unwrap().handle(cmd, data, self), 0xd | 0xe => self.0.audio_key.lock().unwrap().handle(cmd, data, self), @@ -253,11 +150,11 @@ impl Session { } pub fn recv(&self) -> (u8, Vec) { - self.0.rx_connection.lock().unwrap().as_mut().unwrap().recv_packet().unwrap() + self.0.rx_connection.lock().unwrap().as_mut().unwrap().recv().unwrap() } - pub fn send_packet(&self, cmd: u8, data: &[u8]) -> connection::Result<()> { - self.0.tx_connection.lock().unwrap().as_mut().unwrap().send_packet(cmd, data) + pub fn send_packet(&self, cmd: u8, data: Vec) { + self.0.tx_connection.lock().unwrap().as_mut().unwrap().send((cmd, data)) } pub fn audio_key(&self, track: SpotifyId, file_id: FileId) -> Future {