Use a pure rust mDNS responder instead of relying on Avahi / dns-sd.

Fixes #33, #70
This commit is contained in:
Paul Lietar 2016-05-07 12:55:59 +01:00
parent decce02373
commit b25585a41b
7 changed files with 147 additions and 42 deletions

140
Cargo.lock generated
View file

@ -5,7 +5,6 @@ dependencies = [
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
"dns-sd 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"eventual 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "eventual 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
@ -17,6 +16,7 @@ dependencies = [
"linear-map 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "linear-map 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lmdb-rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "lmdb-rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mdns 0.1.0 (git+http://github.com/plietar/rust-mdns)",
"num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)",
"portaudio 0.2.0 (git+https://github.com/mvdnes/portaudio-rs)", "portaudio 0.2.0 (git+https://github.com/mvdnes/portaudio-rs)",
@ -73,6 +73,11 @@ name = "bitflags"
version = "0.3.3" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "0.5.0" version = "0.5.0"
@ -88,6 +93,16 @@ name = "byteorder"
version = "0.5.3" version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "clippy" name = "clippy"
version = "0.0.78" version = "0.0.78"
@ -122,12 +137,13 @@ dependencies = [
] ]
[[package]] [[package]]
name = "dns-sd" name = "dns-parser"
version = "0.1.3" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+http://github.com/plietar/dns-parser#1dfc065504f8e18390fff988dd45d3072157e3b7"
dependencies = [ dependencies = [
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -313,6 +329,24 @@ name = "matches"
version = "0.1.2" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mdns"
version = "0.1.0"
source = "git+http://github.com/plietar/rust-mdns#a1bc7a031766c4e321152be4d0acd069a42f887d"
dependencies = [
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dns-parser 0.3.2 (git+http://github.com/plietar/dns-parser)",
"eventual 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"multimap 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rotor 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "0.1.11" version = "0.1.11"
@ -329,6 +363,59 @@ dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "mio"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (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.2 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.1.2"
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)",
"net2 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.7 (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 = "multimap"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "net2"
version = "0.2.24"
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.13 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.7 (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.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "1.2.3" version = "1.2.3"
@ -547,6 +634,16 @@ dependencies = [
"quasi_codegen 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "quasi_codegen 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "quick-error"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quick-error"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "quine-mc_cluskey" name = "quine-mc_cluskey"
version = "0.2.2" version = "0.2.2"
@ -577,6 +674,18 @@ name = "regex-syntax"
version = "0.3.3" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rotor"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-error 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "rpassword" name = "rpassword"
version = "0.2.2" version = "0.2.2"
@ -691,6 +800,11 @@ dependencies = [
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "slab"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "solicit" name = "solicit"
version = "0.4.4" version = "0.4.4"
@ -933,6 +1047,11 @@ dependencies = [
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "vorbis" name = "vorbis"
version = "0.0.14" version = "0.0.14"
@ -977,3 +1096,12 @@ name = "winapi-build"
version = "0.1.1" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]

View file

@ -44,8 +44,6 @@ shannon = { git = "https://github.com/plietar/rust-shannon" }
vorbis = "~0.0.14" vorbis = "~0.0.14"
tremor = { git = "https://github.com/plietar/rust-tremor", optional = true } tremor = { git = "https://github.com/plietar/rust-tremor", optional = true }
dns-sd = { version = "~0.1.1", optional = true }
portaudio = { git = "https://github.com/mvdnes/portaudio-rs", optional = true } portaudio = { git = "https://github.com/mvdnes/portaudio-rs", optional = true }
libpulse-sys = { git = "https://github.com/astro/libpulse-sys", optional = true } libpulse-sys = { git = "https://github.com/astro/libpulse-sys", optional = true }
@ -56,6 +54,8 @@ clippy = { version = "*", optional = true }
openssl = { version = "0.7", optional = true } openssl = { version = "0.7", optional = true }
mdns = { git = "http://github.com/plietar/rust-mdns" }
[build-dependencies] [build-dependencies]
vergen = "~0.1.0" vergen = "~0.1.0"
protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros" } protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros" }
@ -63,9 +63,9 @@ json_macros = { git = "https://github.com/plietar/json_macros" }
serde_codegen = { version = "0.7", optional = true } serde_codegen = { version = "0.7", optional = true }
[features] [features]
discovery = ["dns-sd"]
with-syntex = ["serde_codegen", "protobuf_macros/with-syntex", "json_macros/with-syntex"] with-syntex = ["serde_codegen", "protobuf_macros/with-syntex", "json_macros/with-syntex"]
nightly = ["serde_macros"] nightly = ["serde_macros"]
with-tremor = ["tremor"] with-tremor = ["tremor"]
facebook = ["hyper/ssl", "openssl"] facebook = ["hyper/ssl", "openssl"]
portaudio-backend = ["portaudio"] portaudio-backend = ["portaudio"]

View file

@ -42,16 +42,7 @@ target/release/librespot --appkey APPKEY --username USERNAME --cache CACHEDIR --
## Discovery mode ## Discovery mode
*librespot* can be run in discovery mode, in which case no password is required at startup. *librespot* can be run in discovery mode, in which case no password is required at startup.
dns-sd or avahi's compatibility layer is required for this. On debian/ubuntu this is the For that, simply omit the `--username` argument.
`libavahi-compat-libdnssd-dev` package. On Fedora, this is the
`avahi-compat-libdns_sd-devel` package. It come preinstalled on OS X.
It must be enabled at build time :
```shell
cargo build --release --features discovery
```
When running *librespot* simply omit the `--username` argument.
## Facebook Accounts ## Facebook Accounts
*librespot* can be built with Facebook authentication support. OpenSSL is required for this. *librespot* can be built with Facebook authentication support. OpenSSL is required for this.

View file

@ -1,7 +1,6 @@
use crypto; use crypto;
use crypto::mac::Mac; use crypto::mac::Mac;
use crypto::digest::Digest; use crypto::digest::Digest;
use dns_sd::DNSService;
use hyper; use hyper;
use hyper::net::NetworkListener; use hyper::net::NetworkListener;
use num::BigUint; use num::BigUint;
@ -11,6 +10,7 @@ use rustc_serialize::base64::{self, ToBase64, FromBase64};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::sync::{mpsc, Mutex}; use std::sync::{mpsc, Mutex};
use mdns;
use authentication::Credentials; use authentication::Credentials;
use diffie_hellman::{DH_GENERATOR, DH_PRIME}; use diffie_hellman::{DH_GENERATOR, DH_PRIME};
@ -176,13 +176,12 @@ pub fn discovery_login(device_name: &str, device_id: &str) -> Result<Credentials
let mut server = hyper::Server::new(listener).handle(handler).unwrap(); let mut server = hyper::Server::new(listener).handle(handler).unwrap();
let _svc = DNSService::register(Some(device_name), let responder = mdns::Responder::new().unwrap();
"_spotify-connect._tcp", let _svc = responder.register(
None, "_spotify-connect._tcp".to_owned(),
None, device_name.to_owned(),
port, port,
&["VERSION=1.0", "CPath=/"] &["VERSION=1.0", "CPath=/"]);
).unwrap();
let cred = rx.recv().unwrap(); let cred = rx.recv().unwrap();
server.close().unwrap(); server.close().unwrap();

View file

@ -168,14 +168,8 @@ fn deserialize_base64<D>(de: &mut D) -> Result<Vec<u8>, D::Error>
v.from_base64().map_err(|e| serde::Error::custom(e.to_string())) v.from_base64().map_err(|e| serde::Error::custom(e.to_string()))
} }
#[cfg(feature = "discovery")]
mod discovery; mod discovery;
#[cfg(feature = "discovery")]
pub use self::discovery::discovery_login; pub use self::discovery::discovery_login;
#[cfg(not(feature = "discovery"))]
pub fn discovery_login(_device_name: &str, _device_id: &str) -> Result<Credentials, ()> {
Err(())
}
#[cfg(feature = "facebook")] #[cfg(feature = "facebook")]
mod facebook; mod facebook;

View file

@ -19,6 +19,7 @@ extern crate getopts;
extern crate hyper; extern crate hyper;
extern crate linear_map; extern crate linear_map;
extern crate lmdb_rs; extern crate lmdb_rs;
extern crate mdns;
extern crate num; extern crate num;
extern crate protobuf; extern crate protobuf;
extern crate shannon; extern crate shannon;
@ -39,9 +40,6 @@ extern crate vorbis;
#[cfg(feature = "with-tremor")] #[cfg(feature = "with-tremor")]
extern crate tremor as vorbis; extern crate tremor as vorbis;
#[cfg(feature = "dns-sd")]
extern crate dns_sd;
#[cfg(feature = "openssl")] #[cfg(feature = "openssl")]
extern crate openssl; extern crate openssl;

View file

@ -133,15 +133,10 @@ pub fn get_credentials(session: &Session, matches: &getopts::Matches) -> Credent
(None, _, Some(credentials)) (None, _, Some(credentials))
=> credentials, => credentials,
(None, _, None) if cfg!(feature = "discovery") => { (None, _, None) => {
info!("No username provided and no stored credentials, starting discovery ..."); info!("No username provided and no stored credentials, starting discovery ...");
discovery_login(&session.config().device_name, session.device_id()).unwrap() discovery_login(&session.config().device_name, session.device_id()).unwrap()
} }
(None, _, None) => {
error!("No credentials provided");
exit(1)
}
} }
} }