From 11c823701b12f10933b40044a12cc4048ccf8bd2 Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Sat, 31 Oct 2020 02:27:26 +0100 Subject: add support for mumctl server list --- mumd/src/network/udp.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'mumd/src/network/udp.rs') diff --git a/mumd/src/network/udp.rs b/mumd/src/network/udp.rs index 4f96c4c..febf7f1 100644 --- a/mumd/src/network/udp.rs +++ b/mumd/src/network/udp.rs @@ -13,6 +13,10 @@ use std::sync::{Arc, Mutex}; use tokio::net::UdpSocket; use tokio::sync::{mpsc, oneshot, watch}; use tokio_util::udp::UdpFramed; +use std::collections::HashMap; +use mumble_protocol::ping::{PingPacket, PongPacket}; +use std::rc::Rc; +use std::convert::TryFrom; type UdpSender = SplitSink, (VoicePacket, SocketAddr)>; type UdpReceiver = SplitStream>; @@ -225,3 +229,44 @@ async fn send_voice( debug!("UDP sender process killed"); } + +pub async fn handle_pings( + mut ping_request_receiver: mpsc::UnboundedReceiver<(u64, SocketAddr, Box)>, +) { + let udp_socket = UdpSocket::bind((Ipv6Addr::from(0u128), 0u16)) + .await + .expect("Failed to bind UDP socket"); + + let (mut receiver, mut sender) = udp_socket.split(); + + let pending = Rc::new(Mutex::new(HashMap::new())); + + let sender_handle = async { + while let Some((id, socket_addr, handle)) = ping_request_receiver.recv().await { + let packet = PingPacket { id }; + let packet: [u8; 12] = packet.into(); + sender.send_to(&packet, &socket_addr).await.unwrap(); + pending.lock().unwrap().insert(id, handle); + } + }; + + let receiver_handle = async { + let mut buf = vec![0; 24]; + while let Ok(read) = receiver.recv(&mut buf).await { + assert_eq!(read, 24); + + let packet = match PongPacket::try_from(buf.as_slice()) { + Ok(v) => v, + Err(_) => panic!(), + }; + + if let Some(handler) = pending.lock().unwrap().remove(&packet.id) { + handler(packet); + } + } + }; + + debug!("Waiting for ping requests"); + + join!(sender_handle, receiver_handle); +} \ No newline at end of file -- cgit v1.2.1