From aae78b57c7a848780e4afed2da7a69f32f1549cb Mon Sep 17 00:00:00 2001 From: Igor Katson Date: Mon, 26 Aug 2024 18:57:51 +0100 Subject: [PATCH 1/2] SO_REUSEADDR on upnp socket --- Cargo.lock | 1 + crates/upnp-serve/Cargo.toml | 1 + crates/upnp-serve/src/ssdp.rs | 12 ++++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6930d26..de6d2d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3609,6 +3609,7 @@ dependencies = [ "parking_lot", "quick-xml", "reqwest", + "socket2", "tokio", "tokio-util", "tower-http", diff --git a/crates/upnp-serve/Cargo.toml b/crates/upnp-serve/Cargo.toml index 67f6ea7..3c2601f 100644 --- a/crates/upnp-serve/Cargo.toml +++ b/crates/upnp-serve/Cargo.toml @@ -22,6 +22,7 @@ url = "2.5.2" parking_lot = "0.12.3" tokio-util = "0.7.11" reqwest = { version = "0.12.7", default-features = false } +socket2 = "0.5.7" [dev-dependencies] tracing-subscriber = "0.3.18" diff --git a/crates/upnp-serve/src/ssdp.rs b/crates/upnp-serve/src/ssdp.rs index 8d6416b..1d03643 100644 --- a/crates/upnp-serve/src/ssdp.rs +++ b/crates/upnp-serve/src/ssdp.rs @@ -108,12 +108,20 @@ pub struct SsdpRunner { impl SsdpRunner { pub async fn new(opts: SsdpRunnerOptions) -> anyhow::Result { let bind_addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, UPNP_PORT); + let sock = socket2::Socket::new(socket2::Domain::IPV4, socket2::Type::DGRAM, None) + .context("error creating socket")?; + sock.set_reuse_port(true) + .context("error setting SO_REUSEPORT")?; + trace!(addr=?bind_addr, "binding UDP"); - let socket = tokio::net::UdpSocket::bind(bind_addr) - .await + sock.bind(&bind_addr.into()) .context(bind_addr) .context("error binding")?; + sock.set_nonblocking(true)?; + let socket = tokio::net::UdpSocket::from_std(sock.into()) + .context("error converting socket2 socket to tokio")?; + trace!(multiaddr=?UPNP_BROADCAST_IP, interface=?Ipv4Addr::UNSPECIFIED, "joining multicast v4 group"); socket .join_multicast_v4(UPNP_BROADCAST_IP, Ipv4Addr::UNSPECIFIED) From c74d5f0866ec70f76d0b73761a5ab05c6514c389 Mon Sep 17 00:00:00 2001 From: Igor Katson Date: Mon, 26 Aug 2024 19:19:37 +0100 Subject: [PATCH 2/2] Windows so_reuseport --- crates/upnp-serve/src/ssdp.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/upnp-serve/src/ssdp.rs b/crates/upnp-serve/src/ssdp.rs index 1d03643..c88f737 100644 --- a/crates/upnp-serve/src/ssdp.rs +++ b/crates/upnp-serve/src/ssdp.rs @@ -110,8 +110,12 @@ impl SsdpRunner { let bind_addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, UPNP_PORT); let sock = socket2::Socket::new(socket2::Domain::IPV4, socket2::Type::DGRAM, None) .context("error creating socket")?; + #[cfg(not(target_os = "windows"))] sock.set_reuse_port(true) .context("error setting SO_REUSEPORT")?; + #[cfg(target_os = "windows")] + sock.set_reuse_address(true) + .context("error setting SO_REUSEADDR")?; trace!(addr=?bind_addr, "binding UDP"); sock.bind(&bind_addr.into())