diff --git a/src/vc_server.rs b/src/vc_server.rs index 8801aef..8da599f 100644 --- a/src/vc_server.rs +++ b/src/vc_server.rs @@ -2,9 +2,9 @@ use std::{net::SocketAddr, sync::Arc}; use anyhow::Context; use ed25519_dalek::VerifyingKey; -use tokio::net::UdpSocket; +use tokio::{net::UdpSocket, sync::Mutex}; -use crate::{protocol::ClientMethod, server::Server}; +use crate::{crypto::SessionCipher, protocol::ClientMethod, server::Server}; use tokio::time::Instant; @@ -31,16 +31,18 @@ impl Server { let pin_bytes: [u8; 8] = buf[..8].try_into().unwrap(); let pin = u64::from_be_bytes(pin_bytes); - let (sender_pubkey, channel_id, payload) = { + // is_first_packet distinguishes the plaintext pin-bootstrap packet + // from subsequent encrypted audio packets. + let (sender_pubkey, channel_id, payload, is_first_packet) = { let mut pins = self.voice_pins.lock().await; if let Some((pubkey, channel_id)) = pins.remove(&pin) { - (pubkey, channel_id, &buf[8..len]) + (pubkey, channel_id, &buf[8..len], true) } else { drop(pins); match self.find_voice_sender(&addr).await { - Some((pubkey, channel_id)) => (pubkey, channel_id, &buf[..]), + Some((pubkey, channel_id)) => (pubkey, channel_id, &buf[..len], false), None => { continue; } @@ -69,8 +71,31 @@ impl Server { drop(voice); - self.relay_voice(&sender_pubkey, &channel_id, payload) - .await?; + // The pin-bearing bootstrap packet carries no payload to decrypt — + // it's purely "here's my pin, bind my address." Everything after + // this first packet is the real, encrypted audio stream. + if is_first_packet { + continue; + } + + let decrypted_payload = match user.cihper.lock().await.decrypt(payload) { + Ok(pt) => pt, + Err(e) => { + eprintln!("[vc] dropping packet: decryption failed: {e}"); + continue; + } + }; + + let s = self.clone(); + + tokio::spawn(async move { + if let Err(e) = s + .relay_voice(&sender_pubkey, &channel_id, &decrypted_payload) + .await + { + eprintln!("{e}"); + } + }); } } @@ -125,7 +150,7 @@ impl Server { continue; } - let _ = self.udp_send_to(&voice.addr, payload).await; + let _ = self.udp_send_to(&user.cihper, &voice.addr, payload).await; } Ok(()) @@ -137,10 +162,17 @@ impl Server { .context("Failed to get voice socket") } - pub async fn udp_send_to(&self, addr: &SocketAddr, payload: &[u8]) -> anyhow::Result<()> { + pub async fn udp_send_to( + &self, + cipher: &Arc>, + addr: &SocketAddr, + payload: &[u8], + ) -> anyhow::Result<()> { let socket = self.get_voice_socket()?; - socket.send_to(payload, addr).await?; + socket + .send_to(&cipher.lock().await.encrypt(payload)?, addr) + .await?; Ok(()) }