mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Add an option to specify IPs that zeroconf will bind to (#1071)
* added an option to specify ip addresses to which mDNS should bind (ignored by `DNS-SD`) * changed command line option to `zeroconf-interface` to be consistent with `zeroconf-port` use builder pattern to DRY up the code used macro to print warning message * fixing register error * renamed `bind_ip` variables to match the option to `zeroconf_ip`, to be more consistent * Changed user help Modified comments Added block for condition to clean the code Added new modification to the change log Co-authored-by: setime <timeframe1@gmx.de>
This commit is contained in:
parent
b0db6502b5
commit
bf7cbbaadd
3 changed files with 73 additions and 14 deletions
|
@ -68,6 +68,7 @@ https://github.com/librespot-org/librespot
|
||||||
|
|
||||||
- [all] Check that array indexes are within bounds (panic safety)
|
- [all] Check that array indexes are within bounds (panic safety)
|
||||||
- [all] Wrap errors in librespot `Error` type (breaking)
|
- [all] Wrap errors in librespot `Error` type (breaking)
|
||||||
|
- [connect] Add option on which zeroconf will bind. Defaults to all interfaces. Ignored by DNS-SD.
|
||||||
- [connect] Add session events
|
- [connect] Add session events
|
||||||
- [connect] Add `repeat`, `set_position_ms` and `set_volume` to `spirc.rs`
|
- [connect] Add `repeat`, `set_position_ms` and `set_volume` to `spirc.rs`
|
||||||
- [contrib] Add `event_handler_example.py`
|
- [contrib] Add `event_handler_example.py`
|
||||||
|
|
|
@ -47,6 +47,7 @@ pub struct Discovery {
|
||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
server_config: server::Config,
|
server_config: server::Config,
|
||||||
port: u16,
|
port: u16,
|
||||||
|
zeroconf_ip: Vec<std::net::IpAddr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Errors that can occur while setting up a [`Discovery`] instance.
|
/// Errors that can occur while setting up a [`Discovery`] instance.
|
||||||
|
@ -87,6 +88,7 @@ impl Builder {
|
||||||
client_id: client_id.into(),
|
client_id: client_id.into(),
|
||||||
},
|
},
|
||||||
port: 0,
|
port: 0,
|
||||||
|
zeroconf_ip: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +104,12 @@ impl Builder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the ip addresses on which it should listen to incoming connections. The default is all interfaces.
|
||||||
|
pub fn zeroconf_ip(mut self, zeroconf_ip: Vec<std::net::IpAddr>) -> Self {
|
||||||
|
self.zeroconf_ip = zeroconf_ip;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the port on which it should listen to incoming connections.
|
/// Sets the port on which it should listen to incoming connections.
|
||||||
/// The default value `0` means any port.
|
/// The default value `0` means any port.
|
||||||
pub fn port(mut self, port: u16) -> Self {
|
pub fn port(mut self, port: u16) -> Self {
|
||||||
|
@ -117,9 +125,12 @@ impl Builder {
|
||||||
let mut port = self.port;
|
let mut port = self.port;
|
||||||
let name = self.server_config.name.clone().into_owned();
|
let name = self.server_config.name.clone().into_owned();
|
||||||
let server = DiscoveryServer::new(self.server_config, &mut port)??;
|
let server = DiscoveryServer::new(self.server_config, &mut port)??;
|
||||||
|
let _zeroconf_ip = self.zeroconf_ip;
|
||||||
|
let svc;
|
||||||
|
|
||||||
#[cfg(feature = "with-dns-sd")]
|
#[cfg(feature = "with-dns-sd")]
|
||||||
let svc = dns_sd::DNSService::register(
|
{
|
||||||
|
svc = dns_sd::DNSService::register(
|
||||||
Some(name.as_ref()),
|
Some(name.as_ref()),
|
||||||
"_spotify-connect._tcp",
|
"_spotify-connect._tcp",
|
||||||
None,
|
None,
|
||||||
|
@ -127,14 +138,25 @@ impl Builder {
|
||||||
port,
|
port,
|
||||||
&["VERSION=1.0", "CPath=/"],
|
&["VERSION=1.0", "CPath=/"],
|
||||||
)?;
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "with-dns-sd"))]
|
#[cfg(not(feature = "with-dns-sd"))]
|
||||||
let svc = libmdns::Responder::spawn(&tokio::runtime::Handle::current())?.register(
|
{
|
||||||
|
let _svc = if !_zeroconf_ip.is_empty() {
|
||||||
|
libmdns::Responder::spawn_with_ip_list(
|
||||||
|
&tokio::runtime::Handle::current(),
|
||||||
|
_zeroconf_ip,
|
||||||
|
)?
|
||||||
|
} else {
|
||||||
|
libmdns::Responder::spawn(&tokio::runtime::Handle::current())?
|
||||||
|
};
|
||||||
|
svc = _svc.register(
|
||||||
"_spotify-connect._tcp".to_owned(),
|
"_spotify-connect._tcp".to_owned(),
|
||||||
name,
|
name,
|
||||||
port,
|
port,
|
||||||
&["VERSION=1.0", "CPath=/"],
|
&["VERSION=1.0", "CPath=/"],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Discovery { server, _svc: svc })
|
Ok(Discovery { server, _svc: svc })
|
||||||
}
|
}
|
||||||
|
|
36
src/main.rs
36
src/main.rs
|
@ -185,6 +185,7 @@ struct Setup {
|
||||||
zeroconf_port: u16,
|
zeroconf_port: u16,
|
||||||
player_event_program: Option<String>,
|
player_event_program: Option<String>,
|
||||||
emit_sink_events: bool,
|
emit_sink_events: bool,
|
||||||
|
zeroconf_ip: Vec<std::net::IpAddr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_setup() -> Setup {
|
fn get_setup() -> Setup {
|
||||||
|
@ -240,6 +241,7 @@ fn get_setup() -> Setup {
|
||||||
const VOLUME_CTRL: &str = "volume-ctrl";
|
const VOLUME_CTRL: &str = "volume-ctrl";
|
||||||
const VOLUME_RANGE: &str = "volume-range";
|
const VOLUME_RANGE: &str = "volume-range";
|
||||||
const ZEROCONF_PORT: &str = "zeroconf-port";
|
const ZEROCONF_PORT: &str = "zeroconf-port";
|
||||||
|
const ZEROCONF_INTERFACE: &str = "zeroconf-interface";
|
||||||
|
|
||||||
// Mostly arbitrary.
|
// Mostly arbitrary.
|
||||||
const AP_PORT_SHORT: &str = "a";
|
const AP_PORT_SHORT: &str = "a";
|
||||||
|
@ -258,6 +260,7 @@ fn get_setup() -> Setup {
|
||||||
const DISABLE_GAPLESS_SHORT: &str = "g";
|
const DISABLE_GAPLESS_SHORT: &str = "g";
|
||||||
const DISABLE_CREDENTIAL_CACHE_SHORT: &str = "H";
|
const DISABLE_CREDENTIAL_CACHE_SHORT: &str = "H";
|
||||||
const HELP_SHORT: &str = "h";
|
const HELP_SHORT: &str = "h";
|
||||||
|
const ZEROCONF_INTERFACE_SHORT: &str = "i";
|
||||||
const CACHE_SIZE_LIMIT_SHORT: &str = "M";
|
const CACHE_SIZE_LIMIT_SHORT: &str = "M";
|
||||||
const MIXER_TYPE_SHORT: &str = "m";
|
const MIXER_TYPE_SHORT: &str = "m";
|
||||||
const ENABLE_VOLUME_NORMALISATION_SHORT: &str = "N";
|
const ENABLE_VOLUME_NORMALISATION_SHORT: &str = "N";
|
||||||
|
@ -570,6 +573,12 @@ fn get_setup() -> Setup {
|
||||||
AUTOPLAY,
|
AUTOPLAY,
|
||||||
"Explicitly set autoplay {on|off}. Defaults to following the client setting.",
|
"Explicitly set autoplay {on|off}. Defaults to following the client setting.",
|
||||||
"OVERRIDE",
|
"OVERRIDE",
|
||||||
|
)
|
||||||
|
.optopt(
|
||||||
|
ZEROCONF_INTERFACE_SHORT,
|
||||||
|
ZEROCONF_INTERFACE,
|
||||||
|
"Comma-separated interface IP addresses on which zeroconf will bind. Defaults to all interfaces. Ignored by DNS-SD.",
|
||||||
|
"IP"
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "passthrough-decoder")]
|
#[cfg(feature = "passthrough-decoder")]
|
||||||
|
@ -1168,6 +1177,31 @@ fn get_setup() -> Setup {
|
||||||
None => SessionConfig::default().autoplay,
|
None => SessionConfig::default().autoplay,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let zeroconf_ip: Vec<std::net::IpAddr> = if opt_present(ZEROCONF_INTERFACE) {
|
||||||
|
if let Some(zeroconf_ip) = opt_str(ZEROCONF_INTERFACE) {
|
||||||
|
zeroconf_ip
|
||||||
|
.split(',')
|
||||||
|
.map(|s| {
|
||||||
|
s.trim().parse::<std::net::IpAddr>().unwrap_or_else(|_| {
|
||||||
|
invalid_error_msg(
|
||||||
|
ZEROCONF_INTERFACE,
|
||||||
|
ZEROCONF_INTERFACE_SHORT,
|
||||||
|
s,
|
||||||
|
"IPv4 and IPv6 addresses",
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
warn!("Unable to use zeroconf-interface option, default to all interfaces.");
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
};
|
||||||
|
|
||||||
let connect_config = {
|
let connect_config = {
|
||||||
let connect_default_config = ConnectConfig::default();
|
let connect_default_config = ConnectConfig::default();
|
||||||
|
|
||||||
|
@ -1608,6 +1642,7 @@ fn get_setup() -> Setup {
|
||||||
zeroconf_port,
|
zeroconf_port,
|
||||||
player_event_program,
|
player_event_program,
|
||||||
emit_sink_events,
|
emit_sink_events,
|
||||||
|
zeroconf_ip,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1640,6 +1675,7 @@ async fn main() {
|
||||||
.name(setup.connect_config.name.clone())
|
.name(setup.connect_config.name.clone())
|
||||||
.device_type(setup.connect_config.device_type)
|
.device_type(setup.connect_config.device_type)
|
||||||
.port(setup.zeroconf_port)
|
.port(setup.zeroconf_port)
|
||||||
|
.zeroconf_ip(setup.zeroconf_ip)
|
||||||
.launch()
|
.launch()
|
||||||
{
|
{
|
||||||
Ok(d) => discovery = Some(d),
|
Ok(d) => discovery = Some(d),
|
||||||
|
|
Loading…
Reference in a new issue