summaryrefslogtreecommitdiff
path: root/server/src/network/mdns.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-09-21 15:31:18 +0200
committermetamuffin <metamuffin@disroot.org>2024-09-21 15:31:18 +0200
commit34190a70b1efa0972ef58b88d356f985c46b89ae (patch)
treed8cf5b98a4d0aed34bff048fb1e15a87f106f6db /server/src/network/mdns.rs
parent41c95fc5b6b1c8bc4b944d889414a4197a23837b (diff)
downloadhurrycurry-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.rs61
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(())
+}