Merge pull request #232 from ikatson/upnp-multicast-multiaddr
UPNP: join all multicast groups from all interfaces (not just the default one picked by the kernel)
This commit is contained in:
commit
cdd21cb5ca
1 changed files with 26 additions and 10 deletions
|
|
@ -5,6 +5,7 @@ use std::{
|
||||||
|
|
||||||
use anyhow::{bail, Context};
|
use anyhow::{bail, Context};
|
||||||
use bstr::BStr;
|
use bstr::BStr;
|
||||||
|
use network_interface::NetworkInterfaceConfig;
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::UdpSocket;
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use tracing::{debug, trace, warn};
|
use tracing::{debug, trace, warn};
|
||||||
|
|
@ -125,10 +126,27 @@ impl SsdpRunner {
|
||||||
let socket = tokio::net::UdpSocket::from_std(sock.into())
|
let socket = tokio::net::UdpSocket::from_std(sock.into())
|
||||||
.context("error converting socket2 socket to tokio")?;
|
.context("error converting socket2 socket to tokio")?;
|
||||||
|
|
||||||
trace!(multiaddr=?UPNP_BROADCAST_IP, interface=?Ipv4Addr::UNSPECIFIED, "joining multicast v4 group");
|
let default_multiast_membership_ip = std::iter::once(Ipv4Addr::UNSPECIFIED);
|
||||||
socket
|
let all_multicast_membership_ips = network_interface::NetworkInterface::show()
|
||||||
.join_multicast_v4(UPNP_BROADCAST_IP, Ipv4Addr::UNSPECIFIED)
|
.into_iter()
|
||||||
.context("error joining multicast group")?;
|
.flatten()
|
||||||
|
.flat_map(|nic| nic.addr.into_iter())
|
||||||
|
.filter_map(|addr| {
|
||||||
|
let ip = addr.ip();
|
||||||
|
match ip {
|
||||||
|
std::net::IpAddr::V4(addr) if addr.is_private() && !addr.is_loopback() => {
|
||||||
|
Some(addr)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for ifaddr in default_multiast_membership_ip.chain(all_multicast_membership_ips) {
|
||||||
|
trace!(multiaddr=?UPNP_BROADCAST_IP, interface=?ifaddr, "joining multicast v4 group");
|
||||||
|
if let Err(e) = socket.join_multicast_v4(UPNP_BROADCAST_IP, ifaddr) {
|
||||||
|
debug!(error=?e, multiaddr=?UPNP_BROADCAST_IP, interface=?ifaddr, "error joining multicast v4 group");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self { opts, socket })
|
Ok(Self { opts, socket })
|
||||||
}
|
}
|
||||||
|
|
@ -191,15 +209,13 @@ Content-Length: 0\r\n\r\n"
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|ni| ni.addr)
|
.flat_map(|ni| ni.addr)
|
||||||
.filter_map(|addr| {
|
.filter_map(|addr| {
|
||||||
let ip = addr.ip();
|
match addr.ip() {
|
||||||
if ip.is_ipv4() && !ip.is_loopback() {
|
std::net::IpAddr::V4(a) if !a.is_loopback() && a.is_private() => Some(a),
|
||||||
Some(ip)
|
_ => None
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|ip| async move {
|
.map(|ip| async move {
|
||||||
let addr = SocketAddr::new(ip, 0);
|
let addr = SocketAddrV4::new(ip, 0);
|
||||||
let sock = match tokio::net::UdpSocket::bind(addr).await {
|
let sock = match tokio::net::UdpSocket::bind(addr).await {
|
||||||
Ok(sock) => sock,
|
Ok(sock) => sock,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue