aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src/network/udp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'mumd/src/network/udp.rs')
-rw-r--r--mumd/src/network/udp.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/mumd/src/network/udp.rs b/mumd/src/network/udp.rs
index 4f96c4c..f97807d 100644
--- a/mumd/src/network/udp.rs
+++ b/mumd/src/network/udp.rs
@@ -6,9 +6,13 @@ use bytes::Bytes;
use futures::{join, pin_mut, select, FutureExt, SinkExt, StreamExt};
use futures_util::stream::{SplitSink, SplitStream};
use mumble_protocol::crypt::ClientCryptState;
+use mumble_protocol::ping::{PingPacket, PongPacket};
use mumble_protocol::voice::{VoicePacket, VoicePacketPayload};
use mumble_protocol::Serverbound;
+use std::collections::HashMap;
+use std::convert::TryFrom;
use std::net::{Ipv6Addr, SocketAddr};
+use std::rc::Rc;
use std::sync::{Arc, Mutex};
use tokio::net::UdpSocket;
use tokio::sync::{mpsc, oneshot, watch};
@@ -225,3 +229,48 @@ async fn send_voice(
debug!("UDP sender process killed");
}
+
+pub async fn handle_pings(
+ mut ping_request_receiver: mpsc::UnboundedReceiver<(
+ u64,
+ SocketAddr,
+ Box<dyn FnOnce(PongPacket)>,
+ )>,
+) {
+ 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);
+}