aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src/network
diff options
context:
space:
mode:
authorEskil Queseth <eskilq@kth.se>2020-10-31 02:27:26 +0100
committerEskil Queseth <eskilq@kth.se>2020-10-31 02:27:26 +0100
commit11c823701b12f10933b40044a12cc4048ccf8bd2 (patch)
treeb3d0b6c844383f8a45cd5081459928b75136ab95 /mumd/src/network
parent8fb4edd72dfcb2b71e91eedc5861360101374967 (diff)
downloadmum-11c823701b12f10933b40044a12cc4048ccf8bd2.tar.gz
add support for mumctl server list
Diffstat (limited to 'mumd/src/network')
-rw-r--r--mumd/src/network/tcp.rs6
-rw-r--r--mumd/src/network/udp.rs45
2 files changed, 48 insertions, 3 deletions
diff --git a/mumd/src/network/tcp.rs b/mumd/src/network/tcp.rs
index cd11690..131f066 100644
--- a/mumd/src/network/tcp.rs
+++ b/mumd/src/network/tcp.rs
@@ -27,7 +27,7 @@ type TcpSender = SplitSink<
type TcpReceiver =
SplitStream<Framed<TlsStream<TcpStream>, ControlCodec<Serverbound, Clientbound>>>;
-pub(crate) type TcpEventCallback = Box<dyn FnOnce(&TcpEventData)>;
+pub(crate) type TcpEventCallback = Box<dyn FnOnce(TcpEventData)>;
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub enum TcpEvent {
@@ -228,7 +228,7 @@ async fn listen(
if let Some(vec) = event_queue.lock().unwrap().get_mut(&TcpEvent::Connected) {
let old = std::mem::take(vec);
for handler in old {
- handler(&TcpEventData::Connected(&msg));
+ handler(TcpEventData::Connected(&msg));
}
}
let mut state = state.lock().unwrap();
@@ -282,7 +282,7 @@ async fn listen(
if let Some(vec) = event_queue.lock().unwrap().get_mut(&TcpEvent::Disconnected) {
let old = std::mem::take(vec);
for handler in old {
- handler(&TcpEventData::Disconnected);
+ handler(TcpEventData::Disconnected);
}
}
},
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<UdpFramed<ClientCryptState>, (VoicePacket<Serverbound>, SocketAddr)>;
type UdpReceiver = SplitStream<UdpFramed<ClientCryptState>>;
@@ -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<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);
+} \ No newline at end of file