diff options
author | metamuffin <metamuffin@disroot.org> | 2024-09-21 15:31:18 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-09-21 15:31:18 +0200 |
commit | 34190a70b1efa0972ef58b88d356f985c46b89ae (patch) | |
tree | d8cf5b98a4d0aed34bff048fb1e15a87f106f6db /server/src/network/mdns.rs | |
parent | 41c95fc5b6b1c8bc4b944d889414a4197a23837b (diff) | |
download | hurrycurry-34190a70b1efa0972ef58b88d356f985c46b89ae.tar hurrycurry-34190a70b1efa0972ef58b88d356f985c46b89ae.tar.bz2 hurrycurry-34190a70b1efa0972ef58b88d356f985c46b89ae.tar.zst |
server: mdns and upnp
Diffstat (limited to 'server/src/network/mdns.rs')
-rw-r--r-- | server/src/network/mdns.rs | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/server/src/network/mdns.rs b/server/src/network/mdns.rs new file mode 100644 index 00000000..870ae7ec --- /dev/null +++ b/server/src/network/mdns.rs @@ -0,0 +1,61 @@ +use crate::server::Server; +use anyhow::Result; +use get_if_addrs::get_if_addrs; +use hurrycurry_protocol::VERSION; +use log::{info, warn}; +use mdns_sd::{ServiceDaemon, ServiceInfo}; +use rand::random; +use std::{collections::HashMap, sync::Arc, time::Duration}; +use tokio::{sync::RwLock, time::interval}; + +pub async fn mdns_loop(name: String, port: u16, state: Arc<RwLock<Server>>) { + let d = match ServiceDaemon::new() { + Ok(d) => d, + Err(e) => { + warn!("mDNS daemon failed to start: {e}"); + return; + } + }; + let mut interval = interval(Duration::from_secs(60)); + let hostname = format!("hks-{}.local.", random::<u64>()); + loop { + interval.tick().await; + if let Err(e) = update_service(&d, &state, &name, &hostname, port).await { + warn!("mDNS service update failed: {e}"); + } + info!("updated mDNS service record"); + } +} + +async fn update_service( + d: &ServiceDaemon, + state: &Arc<RwLock<Server>>, + name: &str, + hostname: &str, + port: u16, +) -> Result<()> { + let addrs = get_if_addrs()? + .into_iter() + .map(|e| e.addr.ip()) + .filter(|a| !a.is_loopback()) + .collect::<Vec<_>>(); + + let players = state.read().await.count_chefs(); + + d.register(ServiceInfo::new( + "_hurrycurry._tcp.local.", + name, + hostname, + &*addrs, + port, + HashMap::from_iter([ + ("players".to_string(), players.to_string()), + ("version".to_string(), env!("CARGO_PKG_VERSION").to_string()), + ( + "protocol".to_string(), + format!("{}.{}", VERSION.0, VERSION.1), + ), + ]), + )?)?; + Ok(()) +} |