diff options
| author | Eskil Queseth <eskilq@kth.se> | 2020-11-03 22:13:37 +0100 |
|---|---|---|
| committer | Eskil Queseth <eskilq@kth.se> | 2020-11-03 22:13:37 +0100 |
| commit | 4dd73f7b837572211b71483d62bbdfb1227d2aee (patch) | |
| tree | b0ae8e001e1ada802a95fd1a2fc2b59272f45f27 /mumd/src/network/udp.rs | |
| parent | 71941137265669013ef64473748c4fde6bc48f1c (diff) | |
| parent | d6496cb0f6abba855b04338fa8bc5aaa89487c29 (diff) | |
| download | mum-4dd73f7b837572211b71483d62bbdfb1227d2aee.tar.gz | |
Merge branch 'main' into mute
Diffstat (limited to 'mumd/src/network/udp.rs')
| -rw-r--r-- | mumd/src/network/udp.rs | 49 |
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); +} |
