phantom_protocol/transport/
udp_transport.rs1#![allow(unsafe_code)]
25
26use super::buffer_pool::BufferPool;
27use super::pacer::Pacer;
28use crate::crypto::aes_session::AesSession;
29use crate::transport::bandwidth_estimator;
30use crate::transport::handshake::{ClientHello, HandshakeResponse, HandshakeServer, ServerReply};
31use std::net::SocketAddr;
32use std::sync::Arc;
33use tokio::io::{self, Result as IoResult};
34use tokio::net::UdpSocket;
35
36pub struct UdpTransport {
38 socket: Arc<UdpSocket>,
39 peer_addr: SocketAddr,
40 session: Arc<AesSession>,
41 buffer_pool: Arc<BufferPool>,
42}
43
44impl UdpTransport {
45 pub async fn bind(local_addr: &str) -> IoResult<Self> {
47 let socket = UdpSocket::bind(local_addr).await?;
48 socket.set_broadcast(false)?;
49
50 let peer_addr = "0.0.0.0:0"
51 .parse()
52 .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
53
54 let session = AesSession::from_shared_secret(&[0u8; 32]).map_err(io::Error::other)?;
55
56 Ok(Self {
57 socket: Arc::new(socket),
58 peer_addr,
59 session: Arc::new(session),
60 buffer_pool: Arc::new(BufferPool::new(65536, 16, 256)),
61 })
62 }
63
64 pub async fn connect(&mut self, peer_addr: SocketAddr, session: AesSession) {
66 self.peer_addr = peer_addr;
67 self.session = Arc::new(session);
68 }
69
70 #[inline]
72 pub async fn send(&self, data: &[u8]) -> IoResult<usize> {
73 let encrypted = self.session.encrypt(&[], data).map_err(io::Error::other)?;
74 self.socket.send_to(&encrypted, self.peer_addr).await
75 }
76
77 #[inline]
79 pub async fn send_zero_copy(&self, data: &[u8]) -> IoResult<usize> {
80 let mut buf = Vec::with_capacity(data.len() + 16);
81 buf.extend_from_slice(data);
82 self.session
83 .encrypt_in_place(&[], &mut buf)
84 .map_err(io::Error::other)?;
85 self.socket.send_to(&buf, self.peer_addr).await
86 }
87
88 #[inline]
90 pub async fn recv(&self) -> IoResult<(Vec<u8>, SocketAddr)> {
91 let mut buf = self.buffer_pool.acquire();
92 buf.resize(65536, 0);
93
94 let (len, addr) = self.socket.recv_from(&mut buf).await?;
95
96 let decrypted = self
97 .session
98 .decrypt(&[], &buf[..len])
99 .map_err(io::Error::other)?;
100
101 Ok((decrypted, addr))
102 }
103
104 #[inline]
106 pub async fn send_batch(&self, packets: &[&[u8]]) -> IoResult<usize> {
107 let mut total = 0;
108 for packet in packets {
109 total += self.send(packet).await?;
110 }
111 Ok(total)
112 }
113
114 pub fn socket(&self) -> &Arc<UdpSocket> {
116 &self.socket
117 }
118
119 pub fn set_pacing_rate(&self, rate_bps: u64) -> IoResult<()> {
131 #[cfg(not(target_os = "linux"))]
134 let _ = rate_bps;
135 #[cfg(target_os = "linux")]
136 {
137 use std::os::unix::io::AsRawFd;
138 let rate_u32 = rate_bps.min(u32::MAX as u64) as u32;
141 let fd = self.socket.as_ref().as_raw_fd();
142 let ret = unsafe {
145 libc::setsockopt(
146 fd,
147 libc::SOL_SOCKET,
148 47, &rate_u32 as *const u32 as *const libc::c_void,
150 std::mem::size_of::<u32>() as libc::socklen_t,
151 )
152 };
153 if ret != 0 {
154 return Err(io::Error::last_os_error());
155 }
156 }
157 Ok(())
158 }
159
160 pub fn buffer_stats(&self) -> super::buffer_pool::PoolStats {
162 self.buffer_pool.stats()
163 }
164}
165
166pub struct UdpHandshakeListener {
168 socket: Arc<UdpSocket>,
169 buffer_pool: Arc<BufferPool>,
170}
171
172impl UdpHandshakeListener {
173 pub async fn bind(local_addr: &str) -> IoResult<Self> {
174 let socket = UdpSocket::bind(local_addr).await?;
175 socket.set_broadcast(false)?;
176
177 Ok(Self {
178 socket: Arc::new(socket),
179 buffer_pool: Arc::new(BufferPool::new(65536, 16, 256)),
180 })
181 }
182
183 pub async fn accept_handshake(&self, server: &HandshakeServer, difficulty: u8) -> IoResult<()> {
185 let mut buf = self.buffer_pool.acquire();
186 buf.resize(65536, 0);
187
188 loop {
189 let (len, addr) = self.socket.recv_from(&mut buf).await?;
190
191 if len < 1200 {
194 continue;
195 }
196
197 let client_hello = match borsh::from_slice::<ClientHello>(&buf[..len]) {
202 Ok(ch) => ch,
203 Err(_) => {
204 continue;
206 }
207 };
208
209 match server.process_client_hello(&client_hello, difficulty, addr.ip()) {
211 HandshakeResponse::Retry(retry_req) => {
212 if let Ok(encoded) = ServerReply::Retry(retry_req).to_wire() {
215 let _ = self.socket.send_to(&encoded, addr).await;
216 }
217 }
218 HandshakeResponse::Success(server_hello, _session, _early_data) => {
219 if let Ok(encoded) = ServerReply::Hello(server_hello).to_wire() {
221 let _ = self.socket.send_to(&encoded, addr).await;
222 }
223 }
225 HandshakeResponse::Reject(reject) => {
226 if let Ok(encoded) = ServerReply::Reject(reject).to_wire() {
229 let _ = self.socket.send_to(&encoded, addr).await;
230 }
231 }
232 HandshakeResponse::Fail(_) => {
233 }
235 }
236
237 break;
239 }
240
241 Ok(())
242 }
243}
244
245pub struct PacedSender {
252 transport: Arc<UdpTransport>,
253 pacer: Arc<Pacer>,
254 estimator: Arc<parking_lot::Mutex<bandwidth_estimator::BandwidthEstimator>>,
255}
256
257impl PacedSender {
258 pub fn new(
260 transport: Arc<UdpTransport>,
261 pacer: Arc<Pacer>,
262 estimator: Arc<parking_lot::Mutex<bandwidth_estimator::BandwidthEstimator>>,
263 ) -> Self {
264 Self {
265 transport,
266 pacer,
267 estimator,
268 }
269 }
270
271 pub async fn send(&self, data: &[u8]) -> IoResult<usize> {
274 let bytes = data.len() as u64;
275
276 loop {
278 if self.pacer.try_consume(bytes) {
279 break;
280 }
281 let wait = self.pacer.time_until_available(bytes);
282 if wait.is_zero() {
283 break;
284 }
285 tokio::time::sleep(wait).await;
286 }
287
288 self.estimator.lock().on_send(bytes);
290
291 self.transport.send(data).await
292 }
293
294 pub async fn send_unpaced(&self, data: &[u8]) -> IoResult<usize> {
296 self.transport.send(data).await
297 }
298
299 pub fn on_ack(&self, sample: bandwidth_estimator::DeliverySample) {
301 let mut est = self.estimator.lock();
302 est.on_ack(sample);
303 let new_rate = est.pacing_rate();
304 self.pacer.set_rate(new_rate);
305 }
306
307 pub fn set_rate(&self, rate_bps: u64) {
309 self.pacer.set_rate(rate_bps);
310 }
311
312 pub fn rate(&self) -> u64 {
314 self.pacer.rate()
315 }
316}
317
318impl std::fmt::Debug for PacedSender {
319 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
320 f.debug_struct("PacedSender")
321 .field("rate_bps", &self.pacer.rate())
322 .field("pacer_enabled", &self.pacer.is_enabled())
323 .finish()
324 }
325}
326
327pub struct FastSender {
329 socket: Arc<UdpSocket>,
330 session: Arc<AesSession>,
331 peer_addr: SocketAddr,
332}
333
334impl FastSender {
335 pub fn new(socket: Arc<UdpSocket>, session: Arc<AesSession>, peer_addr: SocketAddr) -> Self {
336 Self {
337 socket,
338 session,
339 peer_addr,
340 }
341 }
342
343 #[inline]
345 pub async fn send(&self, data: &[u8]) -> IoResult<usize> {
346 let mut buf = Vec::with_capacity(data.len() + 16);
347 buf.extend_from_slice(data);
348 self.session
349 .encrypt_in_place(&[], &mut buf)
350 .map_err(io::Error::other)?;
351 self.socket.send_to(&buf, self.peer_addr).await
352 }
353}
354
355#[cfg(test)]
356mod tests {
357 use super::*;
358
359 #[tokio::test]
360 async fn test_udp_transport_create() {
361 let transport = UdpTransport::bind("127.0.0.1:0").await.unwrap();
362 assert_eq!(transport.buffer_stats().pool_size, 16);
363 }
364
365 #[tokio::test]
366 async fn test_paced_sender_creation() {
367 let transport = Arc::new(UdpTransport::bind("127.0.0.1:0").await.unwrap());
368 let pacer = Arc::new(Pacer::new(1_000_000)); let estimator = Arc::new(parking_lot::Mutex::new(
370 bandwidth_estimator::BandwidthEstimator::new(),
371 ));
372 let sender = PacedSender::new(transport, pacer, estimator);
373
374 assert_eq!(sender.rate(), 1_000_000);
375 sender.set_rate(2_000_000);
376 assert_eq!(sender.rate(), 2_000_000);
377 }
378}