Skip to main content

rust_raknet/
socket.rs

1use rand::Rng;
2use std::{
3    net::SocketAddr,
4    sync::{
5        Arc,
6        atomic::{AtomicI64, AtomicU8},
7    },
8};
9use tokio::{
10    net::UdpSocket,
11    sync::{Mutex, Notify, RwLock, mpsc::channel},
12    time::{sleep, timeout},
13};
14
15use crate::{
16    error::{RaknetError, Result},
17    raknet_log_error, raknet_log_info,
18};
19use std::sync::atomic::{AtomicBool, Ordering};
20use tokio::sync::mpsc::{Receiver, Sender};
21
22use crate::{arq::*, packet::*, raknet_log_debug, utils::*};
23
24const MAINTENANCE_IDLE_MILLIS: i64 = 500;
25
26#[derive(Default)]
27struct Maintenance {
28    wakeup: Notify,
29    idle: AtomicBool,
30    enabled: AtomicBool,
31}
32
33enum DatagramInput {
34    Channel {
35        receiver: Receiver<Vec<u8>>,
36        packet: Vec<u8>,
37    },
38    Direct(Box<DirectDatagrams>),
39}
40
41struct DirectDatagrams {
42    socket: Arc<UdpSocket>,
43    peer: SocketAddr,
44    packet: Box<[u8; 2048]>,
45    queued: Box<[u8; 2048]>,
46    length: usize,
47    queued_length: usize,
48    error: Option<std::io::Error>,
49}
50
51impl From<Receiver<Vec<u8>>> for DatagramInput {
52    fn from(receiver: Receiver<Vec<u8>>) -> Self {
53        Self::Channel {
54            receiver,
55            packet: Vec::new(),
56        }
57    }
58}
59
60impl DatagramInput {
61    fn decode_into(&mut self, frames: &mut Vec<FrameSetPacket>) -> Result<()> {
62        match self {
63            Self::Channel { packet, .. } => {
64                FrameVec::decode_owned_into(std::mem::take(packet), frames)
65            }
66            Self::Direct(input) => FrameVec::decode_into(&input.packet[..input.length], frames),
67        }
68    }
69
70    fn direct(socket: Arc<UdpSocket>, peer: SocketAddr) -> Self {
71        Self::Direct(Box::new(DirectDatagrams {
72            socket,
73            peer,
74            packet: Box::new([0; 2048]),
75            queued: Box::new([0; 2048]),
76            length: 0,
77            queued_length: 0,
78            error: None,
79        }))
80    }
81
82    fn enable_fragment_worker(&mut self, close: Arc<tokio::sync::Semaphore>) {
83        if !matches!(self, Self::Direct(_)) {
84            return;
85        }
86        // Preserve the previous client's bounded queue for sustained reassembly.
87        // Small-frame clients keep the fused path and allocate no receive task.
88        let (sender, receiver) = channel(100);
89        let Self::Direct(input) = std::mem::replace(self, receiver.into()) else {
90            unreachable!();
91        };
92        let DirectDatagrams {
93            socket,
94            peer,
95            mut packet,
96            queued,
97            queued_length,
98            error,
99            ..
100        } = *input;
101        tokio::spawn(async move {
102            if error.is_some() {
103                close.close();
104                return;
105            }
106            if queued_length != 0 && sender.send(queued[..queued_length].to_vec()).await.is_err() {
107                return;
108            }
109            drop(queued);
110            loop {
111                let received = tokio::select! {
112                    _ = close.acquire() => break,
113                    result = socket.recv_from(packet.as_mut()) => result,
114                };
115                let (length, source) = match received {
116                    Ok(received) => received,
117                    Err(error) => {
118                        #[cfg(target_family = "windows")]
119                        if error.raw_os_error() == Some(10040) {
120                            continue;
121                        }
122                        raknet_log_debug!("fragment receiver failed: {error}");
123                        close.close();
124                        break;
125                    }
126                };
127                if length == 0 || source != peer {
128                    continue;
129                }
130                let data = packet[..length].to_vec();
131                tokio::select! {
132                    _ = close.acquire() => break,
133                    result = sender.send(data) => {
134                        if result.is_err() {
135                            break;
136                        }
137                    }
138                }
139            }
140        });
141    }
142
143    async fn recv(&mut self) -> std::io::Result<bool> {
144        match self {
145            Self::Channel { receiver, packet } => {
146                let Some(received) = receiver.recv().await else {
147                    return Ok(false);
148                };
149                *packet = received;
150                Ok(true)
151            }
152            Self::Direct(input) => {
153                if let Some(error) = input.error.take() {
154                    return Err(error);
155                }
156                if input.queued_length != 0 {
157                    // Buffered reads still consume a cooperative task budget.
158                    tokio::task::consume_budget().await;
159                    std::mem::swap(&mut input.packet, &mut input.queued);
160                    input.length = std::mem::take(&mut input.queued_length);
161                    return Ok(true);
162                }
163                loop {
164                    let result = input.socket.recv_from(input.packet.as_mut()).await;
165                    match result {
166                        Ok((length, source)) if source == input.peer && length != 0 => {
167                            input.length = length;
168                            return Ok(true);
169                        }
170                        Ok(_) => {}
171                        Err(error) => {
172                            #[cfg(target_family = "windows")]
173                            if error.raw_os_error() == Some(10040) {
174                                continue;
175                            }
176                            return Err(error);
177                        }
178                    }
179                }
180            }
181        }
182    }
183
184    fn packet(&self) -> &[u8] {
185        match self {
186            Self::Channel { packet, .. } => packet,
187            Self::Direct(input) => &input.packet[..input.length],
188        }
189    }
190
191    fn should_flush_ack(&mut self) -> bool {
192        match self {
193            Self::Channel { receiver, .. } => receiver.is_empty(),
194            Self::Direct(input) => {
195                if input.queued_length != 0 {
196                    return false;
197                }
198                if input.error.is_some() {
199                    return true;
200                }
201                // Read ahead only when a datagram is already available. ACKs
202                // never wait for another packet or a timer. Bound foreign traffic.
203                for _ in 0..32 {
204                    match input.socket.try_recv_from(input.queued.as_mut()) {
205                        Ok((length, source)) if source == input.peer && length != 0 => {
206                            input.queued_length = length;
207                            return false;
208                        }
209                        Ok(_) => {}
210                        Err(error) if error.kind() == std::io::ErrorKind::WouldBlock => {
211                            return true;
212                        }
213                        Err(error) => {
214                            #[cfg(target_family = "windows")]
215                            if error.raw_os_error() == Some(10040) {
216                                continue;
217                            }
218                            input.error = Some(error);
219                            return true;
220                        }
221                    }
222                }
223                true
224            }
225        }
226    }
227}
228
229enum ControlAction {
230    Continue,
231    HandshakeComplete,
232    Disconnect,
233}
234
235/// A RakNet connection backed by a UDP socket.
236pub struct RaknetSocket {
237    udp: std::sync::Weak<UdpSocket>,
238    local_addr: SocketAddr,
239    peer_addr: SocketAddr,
240    user_data_receiver: Arc<Mutex<Receiver<Vec<u8>>>>,
241    recvq: Arc<Mutex<RecvQ>>,
242    sendq: Arc<RwLock<SendQ>>,
243    close_notifier: Arc<tokio::sync::Semaphore>,
244    last_heartbeat_time: Arc<AtomicI64>,
245    enable_loss: Arc<AtomicBool>,
246    loss_rate: Arc<AtomicU8>,
247    handshake_complete: Arc<tokio::sync::Semaphore>,
248    send_capacity: Arc<Notify>,
249    maintenance: Arc<Maintenance>,
250    raknet_version: u8,
251    mtu: u16,
252}
253
254impl RaknetSocket {
255    /// Pause maintenance after 500 ms of quiet traffic and empty queues.
256    ///
257    /// Disabled by default to preserve the periodic schedule under load.
258    /// This can save CPU with many idle peers, but changes maintenance timing.
259    /// Sending or receiving work wakes a paused connection. Disabling this
260    /// option immediately resumes periodic maintenance.
261    pub fn set_idle_maintenance(&self, enabled: bool) {
262        self.maintenance.enabled.store(enabled, Ordering::Release);
263        if !enabled {
264            self.maintenance.wakeup.notify_one();
265        }
266    }
267
268    /// Return the negotiated nominal RakNet MTU in bytes.
269    pub fn mtu(&self) -> u16 {
270        self.mtu
271    }
272
273    pub(crate) fn close_signal(&self) -> Arc<tokio::sync::Semaphore> {
274        self.close_notifier.clone()
275    }
276
277    async fn wait_for_handshake(&self) -> Result<()> {
278        if self.close_notifier.is_closed() {
279            return Err(RaknetError::ConnectionClosed);
280        }
281        if self.handshake_complete.available_permits() == 0 {
282            tokio::select! {
283                _ = self.close_notifier.acquire() => return Err(RaknetError::ConnectionClosed),
284                permit = self.handshake_complete.acquire() => {
285                    drop(permit.map_err(|_| RaknetError::ConnectionClosed)?);
286                }
287            }
288        }
289        Ok(())
290    }
291
292    /// Create a RakNet socket for an established UDP connection.
293    ///
294    /// This constructor is used internally by [`RaknetListener`].
295    pub async fn from(
296        addr: &SocketAddr,
297        s: &Arc<UdpSocket>,
298        receiver: Receiver<Vec<u8>>,
299        mtu: u16,
300        collecter: Arc<Mutex<Sender<SocketAddr>>>,
301        raknet_version: u8,
302    ) -> Self {
303        let local_addr = s.local_addr().unwrap_or(*addr);
304        let (user_data_sender, user_data_receiver) = channel::<Vec<u8>>(100);
305
306        let ret = RaknetSocket {
307            udp: Arc::downgrade(s),
308            peer_addr: *addr,
309            local_addr,
310            user_data_receiver: Arc::new(Mutex::new(user_data_receiver)),
311            recvq: Arc::new(Mutex::new(RecvQ::new())),
312            sendq: Arc::new(RwLock::new(SendQ::new(mtu))),
313            close_notifier: Arc::new(tokio::sync::Semaphore::new(0)),
314            last_heartbeat_time: Arc::new(AtomicI64::new(monotonic_millis())),
315            enable_loss: Arc::new(AtomicBool::new(false)),
316            loss_rate: Arc::new(AtomicU8::new(0)),
317            handshake_complete: Arc::new(tokio::sync::Semaphore::new(0)),
318            send_capacity: Arc::new(Notify::new()),
319            maintenance: Arc::new(Maintenance::default()),
320            raknet_version,
321            mtu,
322        };
323        ret.start_receiver(s, receiver, user_data_sender);
324        ret.start_tick(s, Some(collecter));
325        ret
326    }
327
328    async fn handle(
329        frame: FrameSetPacket,
330        peer_addr: &SocketAddr,
331        local_addr: &SocketAddr,
332        sendq: &RwLock<SendQ>,
333        user_data_sender: &Sender<Vec<u8>>,
334    ) -> Result<ControlAction> {
335        let Some(&packet_id) = frame.data.first() else {
336            return Err(RaknetError::PacketHeaderError);
337        };
338
339        match PacketID::from(packet_id)? {
340            PacketID::ConnectionRequest => {
341                let packet = read_packet_connection_request(frame.data.as_ref())?;
342
343                let packet_reply = ConnectionRequestAccepted {
344                    client_address: *peer_addr,
345                    system_index: 0,
346                    request_timestamp: packet.time,
347                    accepted_timestamp: cur_timestamp_millis(),
348                };
349
350                let buf = write_packet_connection_request_accepted(&packet_reply)?;
351                sendq
352                    .write()
353                    .await
354                    .insert(Reliability::ReliableOrdered, &buf)?;
355            }
356            PacketID::ConnectionRequestAccepted => {
357                let packet = read_packet_connection_request_accepted(frame.data.as_ref())?;
358
359                let packet_reply = NewIncomingConnection {
360                    server_address: *local_addr,
361                    request_timestamp: packet.request_timestamp,
362                    accepted_timestamp: cur_timestamp_millis(),
363                };
364
365                let mut sendq = sendq.write().await;
366
367                let buf = write_packet_new_incomming_connection(&packet_reply)?;
368                sendq.insert(Reliability::ReliableOrdered, &buf)?;
369
370                let ping = ConnectedPing {
371                    client_timestamp: cur_timestamp_millis(),
372                };
373
374                // Bedrock sends a connected ping immediately after the connection is accepted.
375                let buf = write_packet_connected_ping(&ping)?;
376                sendq.insert(Reliability::Unreliable, &buf)?;
377                return Ok(ControlAction::HandshakeComplete);
378            }
379            PacketID::NewIncomingConnection => {
380                let _packet = read_packet_new_incomming_connection(frame.data.as_ref())?;
381                return Ok(ControlAction::HandshakeComplete);
382            }
383            PacketID::ConnectedPing => {
384                let packet = read_packet_connected_ping(frame.data.as_ref())?;
385
386                let packet_reply = ConnectedPong {
387                    client_timestamp: packet.client_timestamp,
388                    server_timestamp: cur_timestamp_millis(),
389                };
390
391                let buf = write_packet_connected_pong(&packet_reply)?;
392                sendq.write().await.insert(Reliability::Unreliable, &buf)?;
393            }
394            PacketID::ConnectedPong => {}
395            PacketID::Disconnect => {
396                return Ok(ControlAction::Disconnect);
397            }
398            _ => {
399                match user_data_sender.send(frame.data.into()).await {
400                    Ok(_) => {}
401                    Err(_) => {
402                        return Ok(ControlAction::Disconnect);
403                    }
404                };
405            }
406        }
407        Ok(ControlAction::Continue)
408    }
409
410    async fn send_ack_ranges(
411        socket: &UdpSocket,
412        sequences: &[(u32, u32)],
413        packet: &mut Vec<u8>,
414        peer: &SocketAddr,
415        enable_loss: bool,
416        loss_rate: u8,
417    ) -> Result<()> {
418        if sequences.is_empty() {
419            return Ok(());
420        }
421        write_control_ranges_into(PacketID::Ack, sequences, packet)?;
422        Self::sendto(socket, packet, peer, enable_loss, loss_rate)
423            .await
424            .map(|_| ())
425            .map_err(|_| RaknetError::SocketError)
426    }
427
428    async fn transmit_frames(
429        socket: &UdpSocket,
430        frames: OutgoingFrames,
431        peer: &SocketAddr,
432        enable_loss: bool,
433        loss_rate: u8,
434    ) -> Result<()> {
435        if frames.len() <= 1 {
436            for frame in &frames {
437                Self::send_frame(socket, frame, peer, enable_loss, loss_rate).await?;
438            }
439            return Ok(());
440        }
441        if frames.coalesced {
442            let mut wire = Vec::new();
443            let mut start = 0;
444            while start < frames.len() {
445                let mut end = start + 1;
446                while end < frames.len()
447                    && frames[end].sequence_number == frames[start].sequence_number
448                {
449                    end += 1;
450                }
451                FrameSetPacket::serialize_group_into(&frames[start..end], &mut wire)?;
452                Self::sendto(socket, &wire, peer, enable_loss, loss_rate)
453                    .await
454                    .map_err(|_| RaknetError::SocketError)?;
455                start = end;
456            }
457            return Ok(());
458        }
459        #[cfg(target_os = "linux")]
460        if frames.len() > 1 && !enable_loss {
461            if let Err(error) = crate::udp::send_frames(socket, &frames, peer).await {
462                raknet_log_error!("UDP batch send failed: {}", error);
463            }
464            return Ok(());
465        }
466        // Reuse one contiguous buffer on platforms without batched syscalls.
467        let mut packet = Vec::new();
468        for frame in &frames {
469            frame.serialize_into(&mut packet)?;
470            Self::sendto(socket, &packet, peer, enable_loss, loss_rate)
471                .await
472                .map_err(|_| RaknetError::SocketError)?;
473        }
474        Ok(())
475    }
476
477    async fn transmit_replies(
478        socket: &Arc<UdpSocket>,
479        frames: OutgoingFrames,
480        peer: &SocketAddr,
481        close: &Arc<tokio::sync::Semaphore>,
482        bulk_sender: &mut Option<Sender<(Vec<u8>, bool, u8)>>,
483        enable_loss: bool,
484        loss_rate: u8,
485    ) -> Result<()> {
486        // A fragment batch can keep the flight window full even when it is small.
487        // Delegate it and larger queue drains so ACK reception can progress.
488        // Ordinary connections allocate no send task until delegation is needed.
489        if frames.coalesced {
490            return Self::transmit_frames(socket, frames, peer, enable_loss, loss_rate).await;
491        }
492        if bulk_sender.is_none()
493            && frames.len() <= 8
494            && frames.iter().all(|frame| !frame.is_fragment())
495        {
496            return Self::transmit_frames(socket, frames, peer, enable_loss, loss_rate).await;
497        }
498        let sender = bulk_sender.get_or_insert_with(|| {
499            let (sender, mut receiver) = channel::<(Vec<u8>, bool, u8)>(10);
500            let socket = socket.clone();
501            let close = close.clone();
502            let peer = *peer;
503            tokio::spawn(async move {
504                loop {
505                    tokio::select! {
506                        packet = receiver.recv() => {
507                            let Some((data, enable_loss, loss_rate)) = packet else { break; };
508                            if Self::sendto(&socket, &data, &peer, enable_loss, loss_rate).await.is_err() {
509                                break;
510                            }
511                        }
512                        _ = close.acquire() => break,
513                    }
514                }
515            });
516            sender
517        });
518        for frame in &frames {
519            // Queued datagrams own only their wire bytes, rather than retaining
520            // an entire fragmented application's shared backing allocation.
521            sender
522                .send((frame.serialize()?, enable_loss, loss_rate))
523                .await
524                .map_err(|_| RaknetError::ConnectionClosed)?;
525        }
526        Ok(())
527    }
528
529    async fn send_frame(
530        socket: &UdpSocket,
531        frame: &FrameSetPacket,
532        target: &SocketAddr,
533        enable_loss: bool,
534        loss_rate: u8,
535    ) -> Result<()> {
536        // The slices form one datagram; they are never sent independently.
537        #[cfg(not(any(target_os = "redox", target_os = "wasi", target_os = "horizon")))]
538        {
539            let mut header = [0; 32];
540            let length = frame.encode_header(&mut header)?;
541            if frame.data.len() <= 128 {
542                // Tiny frames use a contiguous stack buffer to avoid allocation
543                // and the extra syscall overhead of vectored I/O.
544                let mut packet = [0; 160];
545                packet[..length].copy_from_slice(&header[..length]);
546                let end = length + frame.data.len();
547                packet[length..end].copy_from_slice(&frame.data);
548                return Self::sendto(socket, &packet[..end], target, enable_loss, loss_rate)
549                    .await
550                    .map(|_| ())
551                    .map_err(|_| RaknetError::SocketError);
552            }
553            if enable_loss && rand::thread_rng().gen_range(0..10) < loss_rate.min(10) {
554                return Ok(());
555            }
556            let slices = [
557                std::io::IoSlice::new(&header[..length]),
558                std::io::IoSlice::new(&frame.data),
559            ];
560            let address = socket2::SockAddr::from(*target);
561            let result = socket
562                .async_io(tokio::io::Interest::WRITABLE, || {
563                    loop {
564                        match socket2::SockRef::from(socket).send_to_vectored(&slices, &address) {
565                            Err(error) if error.kind() == std::io::ErrorKind::Interrupted => {
566                                continue;
567                            }
568                            result => return result,
569                        }
570                    }
571                })
572                .await;
573            if let Err(error) = result {
574                // Reliable frames remain pending for the normal retry path.
575                raknet_log_error!("udp socket send_to error: {}", error);
576            }
577            Ok(())
578        }
579        #[cfg(any(target_os = "redox", target_os = "wasi", target_os = "horizon"))]
580        {
581            let data = frame.serialize()?;
582            Self::sendto(socket, &data, target, enable_loss, loss_rate)
583                .await
584                .map(|_| ())
585                .map_err(|_| RaknetError::SocketError)
586        }
587    }
588
589    async fn sendto(
590        s: &UdpSocket,
591        buf: &[u8],
592        target: &SocketAddr,
593        enable_loss: bool,
594        loss_rate: u8,
595    ) -> tokio::io::Result<usize> {
596        if enable_loss {
597            let mut rng = rand::thread_rng();
598            let loss_rate = loss_rate.min(10);
599            let i: u8 = rng.gen_range(0..10);
600            if i < loss_rate {
601                raknet_log_debug!("loss packet");
602                return Ok(0);
603            }
604        }
605        match s.send_to(buf, target).await {
606            Ok(p) => Ok(p),
607            Err(e) => {
608                raknet_log_error!("udp socket send_to error : {}", e);
609                Ok(0)
610            }
611        }
612    }
613
614    /// Connect to a RakNet server.
615    ///
616    /// # Example
617    /// ```ignore
618    /// let socket = RaknetSocket::connect("127.0.0.1:19132".parse().unwrap()).await.unwrap();
619    /// socket.send(&[0xfe], Reliability::ReliableOrdered).await.unwrap();
620    /// let buf = socket.recv().await.unwrap();
621    /// if buf[0] == 0xfe{
622    ///    //do something
623    /// }
624    /// ```
625
626    pub async fn connect(addr: &SocketAddr) -> Result<Self> {
627        Self::connect_with_version(addr, RAKNET_PROTOCOL_VERSION).await
628    }
629
630    pub async fn connect_with_version(addr: &SocketAddr, raknet_version: u8) -> Result<Self> {
631        Self::connect_with_version_and_mtu(addr, raknet_version, RAKNET_CLIENT_MTU).await
632    }
633
634    /// Connect with an explicit RakNet version and nominal MTU in bytes.
635    ///
636    /// The requested MTU must be between 61 and 1,492 bytes. The server may
637    /// negotiate a smaller value. Choose a size the network path can carry;
638    /// the ordinary connection APIs retain their 1,400-byte default.
639    pub async fn connect_with_version_and_mtu(
640        addr: &SocketAddr,
641        raknet_version: u8,
642        requested_mtu: u16,
643    ) -> Result<Self> {
644        if !(61..=RAKNET_MAX_MTU).contains(&requested_mtu) {
645            return Err(RaknetError::PacketSizeExceedMTU);
646        }
647        // Bedrock peers expect a negative signed GUID on the wire.
648        let guid: u64 = rand::random::<u64>() | (1_u64 << 63);
649
650        let s = UdpSocket::bind(if addr.is_ipv4() {
651            "0.0.0.0:0"
652        } else {
653            "[::]:0"
654        })
655        .await
656        .map_err(|_| RaknetError::BindAddressError)?;
657
658        let packet = OpenConnectionRequest1 {
659            protocol_version: raknet_version,
660            mtu_size: requested_mtu,
661        };
662
663        let buf = write_packet_connection_open_request_1(&packet)?;
664
665        let mut remote_addr: SocketAddr;
666        let mut reply1_size: usize;
667
668        let mut reply1_buf = [0u8; 2048];
669
670        loop {
671            match s.send_to(&buf, addr).await {
672                Ok(p) => p,
673                Err(e) => {
674                    raknet_log_error!("udp socket sendto error {}", e);
675                    tokio::time::sleep(std::time::Duration::from_secs(2)).await;
676                    continue;
677                }
678            };
679            let (size, src) = match match timeout(
680                std::time::Duration::from_secs(2),
681                s.recv_from(&mut reply1_buf),
682            )
683            .await
684            {
685                Ok(p) => p,
686                Err(_) => {
687                    raknet_log_debug!("wait reply1 timeout");
688                    continue;
689                }
690            } {
691                Ok(p) => p,
692                Err(e) => {
693                    raknet_log_error!("recvfrom error : {}", e);
694                    continue;
695                }
696            };
697
698            if size == 0 || src != *addr {
699                continue;
700            }
701            remote_addr = src;
702            reply1_size = size;
703
704            if reply1_buf[0] != PacketID::OpenConnectionReply1.to_u8() {
705                if reply1_buf[0] == PacketID::IncompatibleProtocolVersion.to_u8() {
706                    let _packet =
707                        match read_packet_incompatible_protocol_version(&reply1_buf[..size]) {
708                            Ok(p) => p,
709                            Err(_) => return Err(RaknetError::NotSupportVersion),
710                        };
711
712                    return Err(RaknetError::NotSupportVersion);
713                } else {
714                    raknet_log_debug!("incorrect reply1");
715                    continue;
716                }
717            }
718
719            break;
720        }
721
722        let reply1 = match read_packet_connection_open_reply_1(&reply1_buf[..reply1_size]) {
723            Ok(p) => p,
724            Err(_) => return Err(RaknetError::PacketParseError),
725        };
726
727        if !(61..=requested_mtu).contains(&reply1.mtu_size) {
728            return Err(RaknetError::IncorrectReply);
729        }
730
731        let packet = OpenConnectionRequest2 {
732            address: remote_addr,
733            mtu: reply1.mtu_size,
734            guid,
735        };
736
737        let buf = write_packet_connection_open_request_2(&packet)?;
738
739        let negotiated_mtu = loop {
740            match s.send_to(&buf, addr).await {
741                Ok(_) => {}
742                Err(e) => {
743                    raknet_log_error!("udp socket sendto error {}", e);
744                    tokio::time::sleep(std::time::Duration::from_secs(2)).await;
745                    continue;
746                }
747            };
748
749            let mut buf = [0u8; 2048];
750            let (size, source) =
751                match match timeout(std::time::Duration::from_secs(2), s.recv_from(&mut buf)).await
752                {
753                    Ok(p) => p,
754                    Err(_) => {
755                        raknet_log_debug!("wait reply2 timeout");
756                        continue;
757                    }
758                } {
759                    Ok(p) => p,
760                    Err(e) => {
761                        raknet_log_error!("recvfrom error : {}", e);
762                        continue;
763                    }
764                };
765
766            if size == 0 || source != *addr {
767                continue;
768            }
769
770            if buf[0] == PacketID::OpenConnectionReply1.to_u8() {
771                raknet_log_debug!("repeat receive reply1");
772                continue;
773            }
774
775            if matches!(
776                PacketID::from(buf[0]),
777                Ok(PacketID::AlreadyConnected | PacketID::Disconnect)
778            ) {
779                return Err(RaknetError::ConnectionClosed);
780            }
781            if buf[0] != PacketID::OpenConnectionReply2.to_u8() {
782                raknet_log_debug!("incorrect reply2");
783                continue;
784            }
785
786            let reply2 = match read_packet_connection_open_reply_2(&buf[..size]) {
787                Ok(p) => p,
788                Err(_) => return Err(RaknetError::PacketParseError),
789            };
790
791            if !(61..=reply1.mtu_size).contains(&reply2.mtu) {
792                return Err(RaknetError::IncorrectReply);
793            }
794            break reply2.mtu;
795        };
796
797        let sendq = Arc::new(RwLock::new(SendQ::new(negotiated_mtu)));
798
799        let packet = ConnectionRequest {
800            guid,
801            time: cur_timestamp_millis(),
802            use_encryption: 0x00,
803        };
804
805        let buf = write_packet_connection_request(&packet)?;
806
807        let mut sendq1 = sendq.write().await;
808        sendq1.insert(Reliability::ReliableOrdered, &buf)?;
809        std::mem::drop(sendq1);
810
811        let (user_data_sender, user_data_receiver) = channel::<Vec<u8>>(100);
812
813        let s = Arc::new(s);
814        let connected = Arc::new(tokio::sync::Semaphore::new(0));
815        let receiver = DatagramInput::direct(s.clone(), *addr);
816
817        let ret = RaknetSocket {
818            udp: Arc::downgrade(&s),
819            peer_addr: *addr,
820            local_addr: s.local_addr().map_err(|_| RaknetError::SocketError)?,
821            user_data_receiver: Arc::new(Mutex::new(user_data_receiver)),
822            recvq: Arc::new(Mutex::new(RecvQ::new())),
823            sendq,
824            close_notifier: connected,
825            last_heartbeat_time: Arc::new(AtomicI64::new(monotonic_millis())),
826            enable_loss: Arc::new(AtomicBool::new(false)),
827            loss_rate: Arc::new(AtomicU8::new(0)),
828            handshake_complete: Arc::new(tokio::sync::Semaphore::new(0)),
829            send_capacity: Arc::new(Notify::new()),
830            maintenance: Arc::new(Maintenance::default()),
831            raknet_version,
832            mtu: negotiated_mtu,
833        };
834
835        ret.start_receiver(&s, receiver, user_data_sender);
836        ret.start_tick(&s, None);
837
838        // Start the connected handshake immediately; the ticker remains the
839        // fallback for reliable retransmission rather than the initial sender.
840        let frames = ret.sendq.write().await.flush(monotonic_millis(), addr);
841        if let Err(error) = Self::transmit_frames(&s, frames, addr, false, 0).await {
842            if !matches!(error, RaknetError::SocketError) {
843                return Err(error);
844            }
845            // A transient UDP send failure leaves the reliable request in flight.
846            raknet_log_debug!("initial connected request will retry: {}", error);
847        }
848        raknet_log_debug!("waiting for handshake");
849        ret.wait_for_handshake().await?;
850
851        Ok(ret)
852    }
853
854    fn start_receiver(
855        &self,
856        s: &Arc<UdpSocket>,
857        receiver: impl Into<DatagramInput>,
858        user_data_sender: Sender<Vec<u8>>,
859    ) {
860        let mut receiver = receiver.into();
861        let connected = self.close_notifier.clone();
862        let peer_addr = self.peer_addr;
863        let local_addr = self.local_addr;
864        let sendq = self.sendq.clone();
865        let recvq = self.recvq.clone();
866        let last_heartbeat_time = self.last_heartbeat_time.clone();
867        let handshake_complete = self.handshake_complete.clone();
868        let send_capacity = self.send_capacity.clone();
869        let maintenance = self.maintenance.clone();
870        let s = s.clone();
871        let enable_loss = self.enable_loss.clone();
872        let loss_rate = self.loss_rate.clone();
873        tokio::spawn(async move {
874            let mut bulk_sender = None;
875            // Application backpressure must not prevent ACK/NACK processing.
876            let mut pending_data = std::collections::VecDeque::<Vec<u8>>::new();
877            let mut pending_bytes = 0usize;
878            let mut received_since_ack = 0usize;
879            let mut decoded_frames = Vec::new();
880            let mut ready_frames = Vec::new();
881            let mut acks = Vec::new();
882            let mut ack_packet = Vec::new();
883            loop {
884                // Coalesce ACKs only while datagrams are already queued. Never
885                // wait for a timer or another datagram to acknowledge accepted data.
886                if received_since_ack != 0
887                    && (receiver.should_flush_ack() || received_since_ack >= 32)
888                {
889                    recvq.lock().await.take_ack_into(&mut acks);
890                    if let Err(error) = Self::send_ack_ranges(
891                        &s,
892                        &acks,
893                        &mut ack_packet,
894                        &peer_addr,
895                        enable_loss.load(Ordering::Relaxed),
896                        loss_rate.load(Ordering::Relaxed),
897                    )
898                    .await
899                    {
900                        raknet_log_debug!("failed to send ACK: {}", error);
901                    }
902                    received_since_ack = 0;
903                }
904                let received = if pending_data.is_empty() {
905                    tokio::select! {
906                        _ = connected.acquire() => break,
907                        message = receiver.recv() => message,
908                    }
909                } else {
910                    tokio::select! {
911                        biased;
912                        _ = connected.acquire() => break,
913                        permit = user_data_sender.reserve() => {
914                            let Ok(permit) = permit else { connected.close(); break; };
915                            if let Some(data) = pending_data.pop_front() {
916                                pending_bytes -= data.len();
917                                permit.send(data);
918                            }
919                            continue;
920                        }
921                        message = receiver.recv() => message,
922                    }
923                };
924                match received {
925                    Ok(true) => {}
926                    Ok(false) => {
927                        connected.close();
928                        break;
929                    }
930                    Err(error) => {
931                        raknet_log_debug!("datagram receive failed: {}", error);
932                        connected.close();
933                        break;
934                    }
935                }
936                let buf = receiver.packet();
937                let Some(&packet_id) = buf.first() else {
938                    continue;
939                };
940
941                if received_since_ack != 0 {
942                    received_since_ack += 1;
943                }
944                last_heartbeat_time.store(monotonic_millis(), Ordering::Relaxed);
945                let packet_kind = match PacketID::from(packet_id) {
946                    Ok(kind) => kind,
947                    Err(error) => {
948                        raknet_log_debug!("ignoring packet with invalid ID: {:?}", error);
949                        continue;
950                    }
951                };
952
953                if packet_kind == PacketID::Disconnect {
954                    connected.close();
955                    break;
956                }
957
958                if packet_kind == PacketID::Ack {
959                    let ack = match read_packet_ack(&buf) {
960                        Ok(ack) => ack,
961                        Err(error) => {
962                            raknet_log_debug!("ignoring malformed ACK: {}", error);
963                            continue;
964                        }
965                    };
966                    debug_assert_eq!(ack.record_count as usize, ack.sequences.len());
967                    let now = monotonic_millis();
968                    let outgoing_frames = {
969                        let mut sendq = sendq.write().await;
970                        sendq.ack_ranges(&ack.sequences, now);
971                        sendq.flush(now, &peer_addr)
972                    };
973                    send_capacity.notify_waiters();
974                    if let Err(error) = RaknetSocket::transmit_replies(
975                        &s,
976                        outgoing_frames,
977                        &peer_addr,
978                        &connected,
979                        &mut bulk_sender,
980                        enable_loss.load(Ordering::Relaxed),
981                        loss_rate.load(Ordering::Relaxed),
982                    )
983                    .await
984                    {
985                        raknet_log_debug!("failed to queue frames after ACK: {}", error);
986                    }
987                    continue;
988                }
989
990                if packet_kind == PacketID::Nack {
991                    let nack = match read_packet_nack(&buf) {
992                        Ok(nack) => nack,
993                        Err(error) => {
994                            raknet_log_debug!("ignoring malformed NACK: {}", error);
995                            continue;
996                        }
997                    };
998                    debug_assert_eq!(nack.record_count as usize, nack.sequences.len());
999                    let now = monotonic_millis();
1000                    let outgoing_frames = {
1001                        let mut sendq = sendq.write().await;
1002                        sendq.nack_ranges(&nack.sequences, now);
1003                        sendq.flush(now, &peer_addr)
1004                    };
1005                    if let Err(error) = RaknetSocket::transmit_replies(
1006                        &s,
1007                        outgoing_frames,
1008                        &peer_addr,
1009                        &connected,
1010                        &mut bulk_sender,
1011                        enable_loss.load(Ordering::Relaxed),
1012                        loss_rate.load(Ordering::Relaxed),
1013                    )
1014                    .await
1015                    {
1016                        raknet_log_debug!("failed to queue frames after NACK: {}", error);
1017                    }
1018                    continue;
1019                }
1020
1021                if packet_kind != PacketID::FrameSetPacketBegin {
1022                    raknet_log_debug!("ignoring unsupported packet ID: {packet_id}");
1023                    continue;
1024                }
1025
1026                // Leave excess datagrams unacknowledged so reliable senders retry.
1027                // Already accepted data remains owned until delivered or disconnected.
1028                if pending_bytes >= 1024 * 1024 || pending_data.len() >= 4096 {
1029                    continue;
1030                }
1031
1032                if let Err(error) = receiver.decode_into(&mut decoded_frames) {
1033                    raknet_log_debug!("ignoring malformed frame set: {}", error);
1034                    continue;
1035                }
1036                if decoded_frames.iter().any(FrameSetPacket::is_fragment) {
1037                    receiver.enable_fragment_worker(connected.clone());
1038                }
1039                if received_since_ack == 0 {
1040                    received_since_ack = 1;
1041                }
1042                ready_frames.clear();
1043                let invalid = {
1044                    let mut recvq = recvq.lock().await;
1045                    let mut invalid = false;
1046                    for frame in decoded_frames.drain(..) {
1047                        if let Err(error) = recvq.insert(frame) {
1048                            raknet_log_debug!(
1049                                "receive window or reassembly rejected frame: {}",
1050                                error
1051                            );
1052                            invalid = true;
1053                            break;
1054                        }
1055                        recvq.flush_into(&mut ready_frames);
1056                    }
1057                    if receiver.should_flush_ack() || received_since_ack >= 32 {
1058                        received_since_ack = 0;
1059                        recvq.take_ack_into(&mut acks);
1060                    } else {
1061                        acks.clear();
1062                    }
1063                    if recvq.needs_maintenance() && maintenance.idle.swap(false, Ordering::AcqRel) {
1064                        maintenance.wakeup.notify_one();
1065                    }
1066                    invalid
1067                };
1068
1069                if invalid {
1070                    connected.close();
1071                    break;
1072                }
1073                let mut should_close = false;
1074                for frame in ready_frames.drain(..) {
1075                    if frame.data.first() == Some(&PacketID::Game.to_u8()) {
1076                        let data: Vec<u8> = frame.data.into();
1077                        // There is a single application-channel producer. Try the
1078                        // common path without registering another async waiter.
1079                        let data = if pending_data.is_empty() {
1080                            match user_data_sender.try_send(data) {
1081                                Ok(()) => continue,
1082                                Err(tokio::sync::mpsc::error::TrySendError::Full(data)) => data,
1083                                Err(tokio::sync::mpsc::error::TrySendError::Closed(_)) => {
1084                                    connected.close();
1085                                    should_close = true;
1086                                    break;
1087                                }
1088                            }
1089                        } else {
1090                            data
1091                        };
1092                        pending_bytes += data.len();
1093                        pending_data.push_back(data);
1094                        continue;
1095                    }
1096                    let result = tokio::select! {
1097                        _ = connected.acquire() => break,
1098                        result = RaknetSocket::handle(
1099                        frame,
1100                        &peer_addr,
1101                        &local_addr,
1102                        &sendq,
1103                        &user_data_sender,
1104                    )
1105                        => result,
1106                    };
1107                    match result {
1108                        Ok(
1109                            action @ (ControlAction::Continue | ControlAction::HandshakeComplete),
1110                        ) => {
1111                            // Flush control replies before exposing handshake readiness.
1112                            // Reliable frames remain queued until acknowledged.
1113                            let frames = sendq.write().await.flush(monotonic_millis(), &peer_addr);
1114                            if !frames.is_empty() && maintenance.idle.swap(false, Ordering::AcqRel)
1115                            {
1116                                maintenance.wakeup.notify_one();
1117                            }
1118                            if let Err(error) = Self::transmit_frames(
1119                                &s,
1120                                frames,
1121                                &peer_addr,
1122                                enable_loss.load(Ordering::Relaxed),
1123                                loss_rate.load(Ordering::Relaxed),
1124                            )
1125                            .await
1126                            {
1127                                raknet_log_debug!("failed to send control reply: {}", error);
1128                                if !matches!(error, RaknetError::SocketError) {
1129                                    connected.close();
1130                                    should_close = true;
1131                                    break;
1132                                }
1133                            }
1134                            if matches!(action, ControlAction::HandshakeComplete) {
1135                                raknet_log_debug!("handshake complete");
1136                                handshake_complete.add_permits(1);
1137                            }
1138                        }
1139                        Ok(ControlAction::Disconnect) => {
1140                            raknet_log_info!("peer disconnected");
1141                            connected.close();
1142                            should_close = true;
1143                            break;
1144                        }
1145                        Err(error) => {
1146                            raknet_log_debug!("dropping frame: {}", error);
1147                        }
1148                    }
1149                }
1150
1151                if let Err(error) = Self::send_ack_ranges(
1152                    &s,
1153                    &acks,
1154                    &mut ack_packet,
1155                    &peer_addr,
1156                    enable_loss.load(Ordering::Relaxed),
1157                    loss_rate.load(Ordering::Relaxed),
1158                )
1159                .await
1160                {
1161                    raknet_log_debug!("failed to send ACK: {}", error);
1162                }
1163
1164                if should_close {
1165                    break;
1166                }
1167            }
1168
1169            raknet_log_debug!("{} receive worker closed", peer_addr);
1170        });
1171    }
1172
1173    fn start_tick(&self, s: &Arc<UdpSocket>, collecter: Option<Arc<Mutex<Sender<SocketAddr>>>>) {
1174        let connected = self.close_notifier.clone();
1175        let s = s.clone();
1176        let peer_addr = self.peer_addr;
1177        let sendq = self.sendq.clone();
1178        let recvq = self.recvq.clone();
1179        let maintenance = self.maintenance.clone();
1180        let mut last_monitor_tick = monotonic_millis();
1181        let enable_loss = self.enable_loss.clone();
1182        let loss_rate = self.loss_rate.clone();
1183        let last_heartbeat_time = self.last_heartbeat_time.clone();
1184        tokio::spawn(async move {
1185            let mut nacks = Vec::new();
1186            let mut nack_packet = Vec::new();
1187            let mut idle = false;
1188            loop {
1189                let delay = if idle {
1190                    (RECEIVE_TIMEOUT
1191                        - (monotonic_millis() - last_heartbeat_time.load(Ordering::Relaxed)))
1192                    .max(1) as u64
1193                } else {
1194                    SendQ::DEFAULT_TIMEOUT_MILLS as u64
1195                };
1196                tokio::select! {
1197                    _ = sleep(std::time::Duration::from_millis(delay)) => {},
1198                    _ = maintenance.wakeup.notified(), if idle => {},
1199                    _ = connected.acquire() => {},
1200                }
1201                // Arm before the existing queue checks. A producer racing with
1202                // an idle decision leaves a Notify permit for the next wait.
1203                // A briefly empty queue does not make a busy connection idle.
1204                // Keep the periodic schedule until traffic has been quiet for
1205                // half a second, avoiding repeated sleep/wake transitions.
1206                let quiet = maintenance.enabled.load(Ordering::Relaxed)
1207                    && monotonic_millis() - last_heartbeat_time.load(Ordering::Relaxed)
1208                        >= MAINTENANCE_IDLE_MILLIS;
1209                if quiet {
1210                    maintenance.idle.store(true, Ordering::Release);
1211                }
1212
1213                // Send NACK ranges.
1214                let receive_idle = {
1215                    let mut recvq = recvq.lock().await;
1216                    if recvq.fragments_expired() {
1217                        connected.close();
1218                        break;
1219                    }
1220                    recvq.take_nack_into(&mut nacks);
1221                    !recvq.needs_maintenance()
1222                };
1223                if !nacks.is_empty() {
1224                    match write_control_ranges_into(PacketID::Nack, &nacks, &mut nack_packet) {
1225                        Ok(()) => {
1226                            if let Err(error) = RaknetSocket::sendto(
1227                                &s,
1228                                &nack_packet,
1229                                &peer_addr,
1230                                enable_loss.load(Ordering::Relaxed),
1231                                loss_rate.load(Ordering::Relaxed),
1232                            )
1233                            .await
1234                            {
1235                                raknet_log_error!("failed to send NACK: {}", error);
1236                            }
1237                        }
1238                        Err(error) => raknet_log_error!("failed to encode NACK: {}", error),
1239                    }
1240                }
1241
1242                // Compute idleness while holding the locks already needed for
1243                // maintenance, rather than adding two more locks per active tick.
1244                let (outgoing_frames, send_idle) = {
1245                    let mut sendq = sendq.write().await;
1246                    let frames = sendq.flush(monotonic_millis(), &peer_addr);
1247                    (frames, sendq.is_empty())
1248                };
1249                idle = quiet && receive_idle && send_idle;
1250                if !idle {
1251                    maintenance.idle.store(false, Ordering::Release);
1252                }
1253                for frame in &outgoing_frames {
1254                    if let Err(error) = Self::send_frame(
1255                        &s,
1256                        frame,
1257                        &peer_addr,
1258                        enable_loss.load(Ordering::Relaxed),
1259                        loss_rate.load(Ordering::Relaxed),
1260                    )
1261                    .await
1262                    {
1263                        raknet_log_error!("failed to send frame: {}", error);
1264                    }
1265                }
1266
1267                // Periodically report queue and latency state.
1268                if monotonic_millis() - last_monitor_tick > 10000 {
1269                    last_monitor_tick = monotonic_millis();
1270                    if crate::log::ENABLE_RAKNET_LOG.load(Ordering::Relaxed) & 1 != 0 {
1271                        let (send_queue_size, sent_queue_size, rto) = {
1272                            let sendq = sendq.read().await;
1273                            (
1274                                sendq.get_reliable_queue_size(),
1275                                sendq.get_sent_queue_size(),
1276                                sendq.get_rto(),
1277                            )
1278                        };
1279                        let (recvq_size, fragment_size, ordered_size, ordered_keys) = {
1280                            let recvq = recvq.lock().await;
1281                            (
1282                                recvq.get_size(),
1283                                recvq.get_fragment_queue_size(),
1284                                recvq.get_ordered_packet(),
1285                                recvq.get_ordered_keys(),
1286                            )
1287                        };
1288                        raknet_log_debug!(
1289                            "peer addr: {} | send queue: {} | sent queue: {} | RTO: {} | receive queue: {} | fragments: {} | ordered queue: {} - {:?}",
1290                            peer_addr,
1291                            send_queue_size,
1292                            sent_queue_size,
1293                            rto,
1294                            recvq_size,
1295                            fragment_size,
1296                            ordered_size,
1297                            ordered_keys
1298                        );
1299                    }
1300                }
1301
1302                // Close the connection after 60 seconds without receiving a packet.
1303                if monotonic_millis() - last_heartbeat_time.load(Ordering::Relaxed)
1304                    > RECEIVE_TIMEOUT
1305                {
1306                    raknet_log_debug!("recv timeout");
1307                    connected.close();
1308                    break;
1309                }
1310
1311                if connected.is_closed() {
1312                    for _ in 0..10 {
1313                        RaknetSocket::sendto(
1314                            &s,
1315                            &[PacketID::Disconnect.to_u8()],
1316                            &peer_addr,
1317                            enable_loss.load(Ordering::Relaxed),
1318                            loss_rate.load(Ordering::Relaxed),
1319                        )
1320                        .await
1321                        .ok();
1322                    }
1323                    break;
1324                }
1325            }
1326
1327            match collecter {
1328                Some(p) => {
1329                    match p.lock().await.send(peer_addr).await {
1330                        Ok(_) => {}
1331                        Err(e) => {
1332                            raknet_log_error!("channel send error : {}", e);
1333                        }
1334                    };
1335                }
1336                None => {}
1337            }
1338            raknet_log_debug!("{} , ticker finished", peer_addr);
1339        });
1340    }
1341
1342    /// Close the RakNet connection.
1343    /// The connection also closes when the socket is dropped. This method is idempotent.
1344    ///
1345    /// # Example
1346    /// ```ignore
1347    /// let (latency, motd) = socket::RaknetSocket::ping("127.0.0.1:19132".parse().unwrap()).await.unwrap();
1348    /// assert!((0..10).contains(&latency));
1349    /// ```
1350    pub async fn close(&self) -> Result<()> {
1351        if !self.close_notifier.is_closed() {
1352            self.sendq
1353                .write()
1354                .await
1355                .insert(Reliability::Reliable, &[PacketID::Disconnect.to_u8()])?;
1356            self.close_notifier.close();
1357        }
1358        Ok(())
1359    }
1360
1361    /// Ping a RakNet server and return the round-trip time and MOTD.
1362    ///
1363    /// # Example
1364    /// ```ignore
1365    /// let (latency, motd) = socket::RaknetSocket::ping("127.0.0.1:19132".parse().unwrap()).await.unwrap();
1366    /// assert!((0..10).contains(&latency));
1367    /// ```
1368    pub async fn ping(addr: &SocketAddr) -> Result<(i64, String)> {
1369        let s = UdpSocket::bind(if addr.is_ipv4() {
1370            "0.0.0.0:0"
1371        } else {
1372            "[::]:0"
1373        })
1374        .await
1375        .map_err(|_| RaknetError::BindAddressError)?;
1376
1377        loop {
1378            let packet = PacketUnconnectedPing {
1379                time: cur_timestamp_millis(),
1380                guid: rand::random(),
1381            };
1382
1383            let buf = write_packet_ping(&packet)?;
1384
1385            match s.send_to(buf.as_slice(), addr).await {
1386                Ok(_) => {}
1387                Err(e) => {
1388                    raknet_log_error!("udp socket sendto error {}", e);
1389                    return Err(RaknetError::SocketError);
1390                }
1391            };
1392
1393            let mut buf = [0u8; 1024];
1394
1395            match match tokio::time::timeout(
1396                std::time::Duration::from_secs(5),
1397                s.recv_from(&mut buf),
1398            )
1399            .await
1400            {
1401                Ok(p) => p,
1402                Err(_) => {
1403                    continue;
1404                }
1405            } {
1406                Ok(p) => p,
1407                Err(_) => return Err(RaknetError::SocketError),
1408            };
1409
1410            if let Ok(p) = read_packet_pong(&buf) {
1411                return Ok((p.time - packet.time, p.motd));
1412            };
1413
1414            tokio::time::sleep(std::time::Duration::from_secs(2)).await;
1415        }
1416    }
1417
1418    /// Send a Bedrock game packet.
1419    ///
1420    /// The packet must begin with `0xfe`. `ReliableOrdered` messages are fragmented
1421    /// when necessary; other modes must fit the negotiated MTU. Messages exceeding
1422    /// 65,536 fragments or the 64 MiB send budget (including fragment overhead) return
1423    /// [`RaknetError::PacketSizeExceedMTU`]. A full send queue applies asynchronous
1424    /// backpressure until capacity is available or the connection closes.
1425    ///
1426    /// # Example
1427    /// ```ignore
1428    /// let socket = RaknetSocket::connect("127.0.0.1:19132".parse().unwrap()).await.unwrap();
1429    /// socket.send(&[0xfe], Reliability::ReliableOrdered).await.unwrap();
1430    /// ```
1431    pub async fn send(&self, buf: &[u8], reliability: Reliability) -> Result<()> {
1432        self.send_with_order_channel(buf, reliability, 0).await
1433    }
1434
1435    /// Send a packet on a specific RakNet ordering channel.
1436    ///
1437    /// Each ordering channel has an independent reliable-ordered sequence.
1438    /// The channel is relevant to ordered and sequenced reliability modes;
1439    /// unordered modes do not carry an ordering channel on the wire.
1440    pub async fn send_with_order_channel(
1441        &self,
1442        buf: &[u8],
1443        reliability: Reliability,
1444        order_channel: u8,
1445    ) -> Result<()> {
1446        self.send_payload(buf, reliability, order_channel, None)
1447            .await
1448    }
1449
1450    /// Send an owned, immutable payload without copying it into the retry queue.
1451    pub async fn send_bytes(&self, data: bytes::Bytes, reliability: Reliability) -> Result<()> {
1452        self.send_bytes_with_order_channel(data, reliability, 0)
1453            .await
1454    }
1455
1456    /// Send an owned payload on a RakNet ordering channel.
1457    pub async fn send_bytes_with_order_channel(
1458        &self,
1459        data: bytes::Bytes,
1460        reliability: Reliability,
1461        order_channel: u8,
1462    ) -> Result<()> {
1463        self.send_payload(&data, reliability, order_channel, Some(&data))
1464            .await
1465    }
1466
1467    /// Send an already available batch without waiting to collect more messages.
1468    ///
1469    /// Small ReliableOrdered messages can share standard RakNet frame sets up
1470    /// to the negotiated MTU. Loss feedback or a retransmission timeout restores
1471    /// individual sends for this connection. Other modes retain individual
1472    /// datagrams. A batch is validated before sending any member.
1473    /// Cancellation can send a prefix;
1474    /// already queued reliable messages continue delivery. Empty batches are a no-op.
1475    pub async fn send_batch(&self, messages: &[&[u8]], reliability: Reliability) -> Result<()> {
1476        self.send_batch_with_order_channel(messages, reliability, 0)
1477            .await
1478    }
1479
1480    /// Send a borrowed batch on one ordering channel.
1481    pub async fn send_batch_with_order_channel(
1482        &self,
1483        messages: &[&[u8]],
1484        reliability: Reliability,
1485        order_channel: u8,
1486    ) -> Result<()> {
1487        self.send_batch_payload(messages, &[], reliability, order_channel)
1488            .await
1489    }
1490
1491    /// Send owned buffers without copying their payload into the retry queue.
1492    pub async fn send_bytes_batch(
1493        &self,
1494        messages: &[bytes::Bytes],
1495        reliability: Reliability,
1496    ) -> Result<()> {
1497        self.send_bytes_batch_with_order_channel(messages, reliability, 0)
1498            .await
1499    }
1500
1501    /// Send an owned batch on one ordering channel.
1502    pub async fn send_bytes_batch_with_order_channel(
1503        &self,
1504        messages: &[bytes::Bytes],
1505        reliability: Reliability,
1506        order_channel: u8,
1507    ) -> Result<()> {
1508        self.send_batch_payload(&[], messages, reliability, order_channel)
1509            .await
1510    }
1511
1512    async fn send_batch_payload(
1513        &self,
1514        borrowed: &[&[u8]],
1515        owned: &[bytes::Bytes],
1516        reliability: Reliability,
1517        order_channel: u8,
1518    ) -> Result<()> {
1519        let count = borrowed.len() + owned.len();
1520        if count == 0 {
1521            return Ok(());
1522        }
1523        if count == 1 {
1524            return match owned.first() {
1525                Some(message) => {
1526                    self.send_payload(message, reliability, order_channel, Some(message))
1527                        .await
1528                }
1529                None => {
1530                    self.send_payload(borrowed[0], reliability, order_channel, None)
1531                        .await
1532                }
1533            };
1534        }
1535        let lengths = || {
1536            borrowed
1537                .iter()
1538                .map(|message| message.len())
1539                .chain(owned.iter().map(bytes::Bytes::len))
1540        };
1541        if borrowed
1542            .iter()
1543            .any(|message| message.first() != Some(&0xfe))
1544            || owned.iter().any(|message| message.first() != Some(&0xfe))
1545        {
1546            return Err(RaknetError::PacketHeaderError);
1547        }
1548        // Validate every member before reserving memory or assigning indexes.
1549        #[cfg(feature = "send-policy")]
1550        let can_coalesce = {
1551            let queue = self.sendq.read().await;
1552            if queue.send_options().is_some() {
1553                queue.batch_can_coalesce(reliability, lengths())?
1554            } else {
1555                queue.has_batch_capacity(reliability, lengths())?;
1556                let mtu = usize::from(queue.mtu());
1557                for length in lengths() {
1558                    if reliability != Reliability::ReliableOrdered
1559                        && length > mtu.saturating_sub(60)
1560                    {
1561                        return Err(RaknetError::PacketSizeExceedMTU);
1562                    }
1563                }
1564                queue.allows_coalescing()
1565                    && reliability == Reliability::ReliableOrdered
1566                    && lengths().zip(lengths().skip(1)).any(|(a, b)| {
1567                        a <= mtu.saturating_sub(60)
1568                            && b <= mtu.saturating_sub(60)
1569                            && a.saturating_add(b).saturating_add(24) <= mtu.saturating_sub(28)
1570                    })
1571            }
1572        };
1573        #[cfg(not(feature = "send-policy"))]
1574        let can_coalesce = {
1575            let queue = self.sendq.read().await;
1576            queue.has_batch_capacity(reliability, lengths())?;
1577            let mtu = usize::from(queue.mtu());
1578            for length in lengths() {
1579                if reliability != Reliability::ReliableOrdered && length > mtu.saturating_sub(60) {
1580                    return Err(RaknetError::PacketSizeExceedMTU);
1581                }
1582            }
1583            queue.allows_coalescing()
1584                && reliability == Reliability::ReliableOrdered
1585                && lengths().zip(lengths().skip(1)).any(|(a, b)| {
1586                    a <= mtu.saturating_sub(60)
1587                        && b <= mtu.saturating_sub(60)
1588                        && a.saturating_add(b).saturating_add(24) <= mtu.saturating_sub(28)
1589                })
1590        };
1591        // Avoid changing the pacing of ordinary messages when batching cannot
1592        // reduce the datagram count. No extra task or timer is introduced.
1593        if !can_coalesce {
1594            for &message in borrowed {
1595                self.send_payload(message, reliability, order_channel, None)
1596                    .await?;
1597            }
1598            for message in owned {
1599                self.send_payload(message, reliability, order_channel, Some(message))
1600                    .await?;
1601            }
1602            return Ok(());
1603        }
1604        if self.close_notifier.is_closed() {
1605            return Err(RaknetError::ConnectionClosed);
1606        }
1607        if self.handshake_complete.available_permits() == 0 {
1608            self.wait_for_handshake().await?;
1609        }
1610        loop {
1611            let available = self.send_capacity.notified();
1612            tokio::pin!(available);
1613            available.as_mut().enable();
1614            let frames = {
1615                let mut queue = self.sendq.write().await;
1616                if queue.has_batch_capacity(reliability, lengths())? {
1617                    if reliability == Reliability::ReliableOrdered {
1618                        queue.enable_coalescing();
1619                    }
1620                    for &message in borrowed {
1621                        queue.insert_with_order_channel(reliability, message, order_channel)?;
1622                    }
1623                    for message in owned {
1624                        queue.insert_bytes(reliability, message, order_channel)?;
1625                    }
1626                    Some(queue.flush(monotonic_millis(), &self.peer_addr))
1627                } else {
1628                    None
1629                }
1630            };
1631            if let Some(frames) = frames {
1632                if self.maintenance.idle.swap(false, Ordering::AcqRel) {
1633                    self.maintenance.wakeup.notify_one();
1634                }
1635                let udp = self.udp.upgrade().ok_or(RaknetError::ConnectionClosed)?;
1636                return Self::transmit_frames(
1637                    &udp,
1638                    frames,
1639                    &self.peer_addr,
1640                    self.enable_loss.load(Ordering::Relaxed),
1641                    self.loss_rate.load(Ordering::Relaxed),
1642                )
1643                .await;
1644            }
1645            tokio::select! {
1646                _ = self.close_notifier.acquire() => return Err(RaknetError::ConnectionClosed),
1647                _ = &mut available => {}
1648            }
1649        }
1650    }
1651
1652    async fn send_payload(
1653        &self,
1654        buf: &[u8],
1655        reliability: Reliability,
1656        order_channel: u8,
1657        owned: Option<&bytes::Bytes>,
1658    ) -> Result<()> {
1659        if buf.is_empty() {
1660            return Err(RaknetError::PacketHeaderError);
1661        }
1662
1663        if buf[0] != 0xfe {
1664            return Err(RaknetError::PacketHeaderError);
1665        }
1666
1667        if self.close_notifier.is_closed() {
1668            return Err(RaknetError::ConnectionClosed);
1669        }
1670
1671        // Offline negotiation can create the server socket before the connected
1672        // handshake arrives. Do not let application data overtake that handshake.
1673        if self.handshake_complete.available_permits() == 0 {
1674            self.wait_for_handshake().await?;
1675        }
1676        loop {
1677            let frames = {
1678                let mut sendq = self.sendq.write().await;
1679                if sendq.has_capacity(reliability, buf.len())? {
1680                    match owned {
1681                        Some(data) => sendq.insert_bytes(reliability, data, order_channel)?,
1682                        None => sendq.insert_with_order_channel(reliability, buf, order_channel)?,
1683                    }
1684                    Some(sendq.flush(monotonic_millis(), &self.peer_addr))
1685                } else {
1686                    None
1687                }
1688            };
1689            if let Some(frames) = frames {
1690                if self.maintenance.idle.load(Ordering::Relaxed)
1691                    && self.maintenance.idle.swap(false, Ordering::AcqRel)
1692                {
1693                    self.maintenance.wakeup.notify_one();
1694                }
1695                // Send from the caller task to avoid an extra channel hop on
1696                // the application path. Reliable frames remain in the send queue
1697                // until acknowledged, including when this future is cancelled.
1698                let udp = self.udp.upgrade().ok_or(RaknetError::ConnectionClosed)?;
1699                let enable_loss = self.enable_loss.load(Ordering::Relaxed);
1700                let loss_rate = self.loss_rate.load(Ordering::Relaxed);
1701                return Self::transmit_frames(
1702                    &udp,
1703                    frames,
1704                    &self.peer_addr,
1705                    enable_loss,
1706                    loss_rate,
1707                )
1708                .await;
1709            }
1710            let available = self.send_capacity.notified();
1711            tokio::pin!(available);
1712            available.as_mut().enable();
1713            // Register before rechecking capacity so an intervening ACK cannot
1714            // be missed. No polling delay is added to a newly available slot.
1715            if self
1716                .sendq
1717                .read()
1718                .await
1719                .has_capacity(reliability, buf.len())?
1720            {
1721                continue;
1722            }
1723            tokio::select! {
1724                _ = self.close_notifier.acquire() => return Err(RaknetError::ConnectionClosed),
1725                _ = &mut available => {}
1726            }
1727        }
1728    }
1729
1730    /// Wait until all reliable packets have been acknowledged.
1731    ///
1732    /// # Example
1733    /// ```ignore
1734    /// let socket = RaknetSocket::connect("127.0.0.1:19132".parse().unwrap()).await.unwrap();
1735    /// socket.send(&[0xfe], Reliability::ReliableOrdered).await.unwrap();
1736    /// socket.flush().await.unwrap();
1737    /// ```
1738    pub async fn flush(&self) -> Result<()> {
1739        loop {
1740            // Register before checking the queue so an intervening ACK wakes
1741            // every concurrent flush caller, including an unpolled waiter.
1742            let acknowledged = self.send_capacity.notified();
1743            tokio::pin!(acknowledged);
1744            acknowledged.as_mut().enable();
1745            if self.close_notifier.is_closed() {
1746                return Err(RaknetError::ConnectionClosed);
1747            }
1748            if self.sendq.read().await.is_empty() {
1749                return Ok(());
1750            }
1751            tokio::select! {
1752                _ = self.close_notifier.acquire() => return Err(RaknetError::ConnectionClosed),
1753                _ = &mut acknowledged => {}
1754            }
1755        }
1756    }
1757
1758    /// Receive the next game packet.
1759    ///
1760    /// # Example
1761    /// ```ignore
1762    /// let socket = RaknetSocket::connect("127.0.0.1:19132".parse().unwrap()).await.unwrap();
1763    /// let buf = socket.recv().await.unwrap();
1764    /// if buf[0] == 0xfe{
1765    ///    //do something
1766    /// }
1767    /// ```
1768    pub async fn recv(&self) -> Result<Vec<u8>> {
1769        match self.user_data_receiver.lock().await.recv().await {
1770            Some(p) => Ok(p),
1771            None => {
1772                if self.close_notifier.is_closed() {
1773                    return Err(RaknetError::ConnectionClosed);
1774                }
1775                Err(RaknetError::SocketError)
1776            }
1777        }
1778    }
1779
1780    /// Receive a game payload as an immutable buffer that can be forwarded with
1781    /// `send_bytes` without copying its application bytes.
1782    pub async fn recv_bytes(&self) -> Result<bytes::Bytes> {
1783        self.recv().await.map(bytes::Bytes::from)
1784    }
1785
1786    /// Receive one message, then drain up to `limit` messages already available.
1787    /// Clears `output` and never waits to fill a batch. Work is capped at 64
1788    /// messages per call; a zero limit returns immediately.
1789    pub async fn recv_batch(&self, output: &mut Vec<Vec<u8>>, limit: usize) -> Result<usize> {
1790        self.recv_batch_map(output, limit, |message| message).await
1791    }
1792
1793    /// Receive an immediately available batch for forwarding with send_bytes_batch.
1794    pub async fn recv_bytes_batch(
1795        &self,
1796        output: &mut Vec<bytes::Bytes>,
1797        limit: usize,
1798    ) -> Result<usize> {
1799        self.recv_batch_map(output, limit, bytes::Bytes::from).await
1800    }
1801
1802    async fn recv_batch_map<T>(
1803        &self,
1804        output: &mut Vec<T>,
1805        limit: usize,
1806        map: impl Fn(Vec<u8>) -> T,
1807    ) -> Result<usize> {
1808        output.clear();
1809        if limit == 0 {
1810            return Ok(0);
1811        }
1812        let mut receiver = self.user_data_receiver.lock().await;
1813        let first = receiver.recv().await.ok_or_else(|| {
1814            if self.close_notifier.is_closed() {
1815                RaknetError::ConnectionClosed
1816            } else {
1817                RaknetError::SocketError
1818            }
1819        })?;
1820        output.push(map(first));
1821        while output.len() < limit.min(64) {
1822            match receiver.try_recv() {
1823                Ok(message) => output.push(map(message)),
1824                Err(_) => break,
1825            }
1826        }
1827        Ok(output.len())
1828    }
1829
1830    /// Return the remote peer's UDP address.
1831    ///
1832    /// # Example
1833    /// ```ignore
1834    /// let socket = RaknetSocket::connect("127.0.0.1:19132".parse().unwrap()).await.unwrap();
1835    /// assert_eq!(socket.peer_addr().unwrap(), SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 19132)));
1836    /// ```
1837    pub fn peer_addr(&self) -> Result<SocketAddr> {
1838        Ok(self.peer_addr)
1839    }
1840
1841    /// Return the local UDP address used by this connection.
1842    ///
1843    /// # Example
1844    /// ```ignore
1845    /// let mut socket = RaknetSocket::connect("127.0.0.1:19132".parse().unwrap()).await.unwrap();
1846    /// assert_eq!(socket.local_addr().unwrap().ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
1847    /// ```
1848    pub fn local_addr(&self) -> Result<SocketAddr> {
1849        Ok(self.local_addr)
1850    }
1851
1852    /// Return the RakNet protocol version used by this connection.
1853    pub fn raknet_version(&self) -> Result<u8> {
1854        Ok(self.raknet_version)
1855    }
1856
1857    /// Enable simulated packet loss for testing.
1858    ///
1859    /// `stage` ranges from 0 (no loss) to 10 (all packets dropped).
1860    /// # Example
1861    /// ```ignore
1862    /// let mut socket = RaknetSocket::connect("127.0.0.1:19132".parse().unwrap()).await.unwrap();
1863    /// // Simulate 20% packet loss.
1864    /// socket.set_loss_rate(2);
1865    /// ```
1866    pub fn set_loss_rate(&mut self, stage: u8) {
1867        self.enable_loss.store(true, Ordering::Relaxed);
1868        self.loss_rate.store(stage, Ordering::Relaxed);
1869    }
1870}
1871
1872impl Drop for RaknetSocket {
1873    fn drop(&mut self) {
1874        self.close_notifier.close();
1875    }
1876}
1877
1878#[cfg(test)]
1879mod ack_batch_tests {
1880    use super::*;
1881
1882    #[tokio::test]
1883    async fn channel_acks_flush_when_the_last_ready_datagram_is_consumed() {
1884        let (sender, receiver) = channel(2);
1885        let mut input = DatagramInput::from(receiver);
1886        assert!(input.should_flush_ack());
1887        sender.send(vec![0xfe, 1]).await.unwrap();
1888        assert!(!input.should_flush_ack());
1889        assert!(input.recv().await.unwrap());
1890        assert_eq!(input.packet(), &[0xfe, 1]);
1891        assert!(input.should_flush_ack());
1892        sender.send(vec![0xfe, 2]).await.unwrap();
1893        sender.send(vec![0xfe, 3]).await.unwrap();
1894        assert!(input.recv().await.unwrap());
1895        assert!(!input.should_flush_ack());
1896        assert!(input.recv().await.unwrap());
1897        assert!(input.should_flush_ack());
1898    }
1899
1900    #[tokio::test]
1901    async fn queued_frames_coalesce_acks_without_waiting_for_control_packets() {
1902        timeout(std::time::Duration::from_secs(2), async {
1903            let udp = Arc::new(UdpSocket::bind("127.0.0.1:0").await.unwrap());
1904            let peer = UdpSocket::bind("127.0.0.1:0").await.unwrap();
1905            let addr = peer.local_addr().unwrap();
1906            let (input, receiver) = channel(100);
1907            for index in 0..40 {
1908                let mut frame =
1909                    FrameSetPacket::new(Reliability::ReliableOrdered, vec![0xfe, index as u8]);
1910                frame.sequence_number = index;
1911                frame.reliable_frame_index = index;
1912                frame.ordered_frame_index = index;
1913                input.send(frame.serialize().unwrap()).await.unwrap();
1914            }
1915            input
1916                .send(
1917                    write_packet_ack(&Ack {
1918                        record_count: 1,
1919                        sequences: vec![(0, 0)],
1920                    })
1921                    .unwrap(),
1922                )
1923                .await
1924                .unwrap();
1925            let (collector, _collected) = channel(1);
1926            let socket = RaknetSocket::from(
1927                &addr,
1928                &udp,
1929                receiver,
1930                1400,
1931                Arc::new(Mutex::new(collector)),
1932                11,
1933            )
1934            .await;
1935            let mut acknowledged = [false; 40];
1936            let mut ack_packets = 0;
1937            let mut buffer = [0; 2048];
1938            while acknowledged.iter().any(|value| !value) {
1939                let (size, _) = peer.recv_from(&mut buffer).await.unwrap();
1940                if buffer[0] != PacketID::Ack.to_u8() {
1941                    continue;
1942                }
1943                ack_packets += 1;
1944                for (start, end) in read_packet_ack(&buffer[..size]).unwrap().sequences {
1945                    for index in start..=end {
1946                        acknowledged[index as usize] = true;
1947                    }
1948                }
1949            }
1950            assert_eq!(ack_packets, 2);
1951            for index in 0..40 {
1952                assert_eq!(socket.recv().await.unwrap(), vec![0xfe, index]);
1953            }
1954            socket.close().await.unwrap();
1955        })
1956        .await
1957        .expect("accepted data was left unacknowledged");
1958    }
1959}
1960
1961#[cfg(test)]
1962mod direct_input_tests {
1963    use super::*;
1964
1965    #[tokio::test]
1966    async fn direct_input_filters_foreign_peers_and_keeps_read_ahead_until_consumed() {
1967        timeout(std::time::Duration::from_secs(2), async {
1968            let socket = Arc::new(UdpSocket::bind("127.0.0.1:0").await.unwrap());
1969            let address = socket.local_addr().unwrap();
1970            let peer = UdpSocket::bind("127.0.0.1:0").await.unwrap();
1971            let foreign = UdpSocket::bind("127.0.0.1:0").await.unwrap();
1972            let mut input = DatagramInput::direct(socket, peer.local_addr().unwrap());
1973            foreign.send_to(&[0xfe, 99], address).await.unwrap();
1974            peer.send_to(&[0xfe, 1], address).await.unwrap();
1975            peer.send_to(&[0xfe, 2], address).await.unwrap();
1976            assert!(input.recv().await.unwrap());
1977            assert_eq!(input.packet(), &[0xfe, 1]);
1978            assert!(!input.should_flush_ack());
1979            assert!(!input.should_flush_ack());
1980            assert_eq!(input.packet(), &[0xfe, 1]);
1981            assert!(input.recv().await.unwrap());
1982            assert_eq!(input.packet(), &[0xfe, 2]);
1983            assert!(input.should_flush_ack());
1984        })
1985        .await
1986        .expect("direct datagram input stalled");
1987    }
1988}
1989
1990#[cfg(test)]
1991mod vectored_send_tests {
1992    use super::*;
1993
1994    #[tokio::test]
1995    async fn vectored_send_matches_serialized_wire_bytes() {
1996        let sender = UdpSocket::bind("127.0.0.1:0").await.unwrap();
1997        let receiver = UdpSocket::bind("127.0.0.1:0").await.unwrap();
1998        let address = receiver.local_addr().unwrap();
1999        for reliability in [
2000            Reliability::Unreliable,
2001            Reliability::UnreliableSequenced,
2002            Reliability::Reliable,
2003            Reliability::ReliableOrdered,
2004            Reliability::ReliableSequenced,
2005        ] {
2006            for size in [0, 64, 128, 129, 1300] {
2007                for fragmented in [false, true] {
2008                    let mut frame = FrameSetPacket::new(reliability, vec![0xfe; size]);
2009                    frame.sequence_number = 0x123456;
2010                    frame.reliable_frame_index = 0x654321;
2011                    frame.sequenced_frame_index = 0xabcdef;
2012                    frame.ordered_frame_index = 0x112233;
2013                    frame.order_channel = 31;
2014                    if fragmented {
2015                        frame.flags |= 16;
2016                        frame.compound_size = 3;
2017                        frame.compound_id = 12345;
2018                        frame.fragment_index = 2;
2019                    }
2020                    let expected = frame.serialize().unwrap();
2021                    RaknetSocket::send_frame(&sender, &frame, &address, false, 0)
2022                        .await
2023                        .unwrap();
2024                    let mut packet = [0; 2048];
2025                    let (length, _) = timeout(
2026                        std::time::Duration::from_secs(1),
2027                        receiver.recv_from(&mut packet),
2028                    )
2029                    .await
2030                    .unwrap()
2031                    .unwrap();
2032                    assert_eq!(&packet[..length], expected);
2033                    assert!(
2034                        matches!(receiver.try_recv_from(&mut packet), Err(error) if error.kind() == std::io::ErrorKind::WouldBlock)
2035                    );
2036                }
2037            }
2038        }
2039    }
2040}
2041
2042#[cfg(test)]
2043mod tuning_tests {
2044    use super::*;
2045    use crate::RaknetListener;
2046
2047    #[tokio::test]
2048    async fn fragment_worker_preserves_prefetch_filters_peers_and_stops_on_close() {
2049        timeout(std::time::Duration::from_secs(3), async {
2050            let socket = Arc::new(UdpSocket::bind("127.0.0.1:0").await.unwrap());
2051            let peer = UdpSocket::bind("127.0.0.1:0").await.unwrap();
2052            let foreign = UdpSocket::bind("127.0.0.1:0").await.unwrap();
2053            let address = socket.local_addr().unwrap();
2054            let mut input = DatagramInput::direct(socket, peer.local_addr().unwrap());
2055            peer.send_to(&[0xfe, 1], address).await.unwrap();
2056            assert!(input.recv().await.unwrap());
2057            assert_eq!(input.packet(), &[0xfe, 1]);
2058            peer.send_to(&[0xfe, 2], address).await.unwrap();
2059            assert!(!input.should_flush_ack());
2060            let close = Arc::new(tokio::sync::Semaphore::new(0));
2061            input.enable_fragment_worker(close.clone());
2062            input.enable_fragment_worker(close.clone());
2063            foreign.send_to(&[0xfe, 99], address).await.unwrap();
2064            peer.send_to(&[0xfe, 3], address).await.unwrap();
2065            for expected in [2, 3] {
2066                assert!(input.recv().await.unwrap());
2067                assert_eq!(input.packet(), &[0xfe, expected]);
2068            }
2069            close.close();
2070            assert!(!input.recv().await.unwrap());
2071        })
2072        .await
2073        .unwrap();
2074    }
2075
2076    #[tokio::test]
2077    async fn small_fragment_reply_batches_start_the_bounded_sender() {
2078        timeout(std::time::Duration::from_secs(3), async {
2079            let socket = Arc::new(UdpSocket::bind("127.0.0.1:0").await.unwrap());
2080            let peer = UdpSocket::bind("127.0.0.1:0").await.unwrap();
2081            let address = peer.local_addr().unwrap();
2082            let mut queue = SendQ::new(1400);
2083            queue
2084                .insert(Reliability::ReliableOrdered, &[0xfe; 4096])
2085                .unwrap();
2086            let frames = queue.flush(0, &address);
2087            assert_eq!(frames.len(), 4);
2088            let expected: Vec<_> = frames
2089                .iter()
2090                .map(|frame| frame.serialize().unwrap())
2091                .collect();
2092            let close = Arc::new(tokio::sync::Semaphore::new(0));
2093            let mut sender = None;
2094            RaknetSocket::transmit_replies(
2095                &socket,
2096                frames,
2097                &address,
2098                &close,
2099                &mut sender,
2100                false,
2101                0,
2102            )
2103            .await
2104            .unwrap();
2105            assert!(sender.is_some());
2106            let mut packet = [0; 2048];
2107            for expected in expected {
2108                let (length, _) = peer.recv_from(&mut packet).await.unwrap();
2109                assert_eq!(&packet[..length], expected);
2110            }
2111            close.close();
2112            sender.unwrap().closed().await;
2113        })
2114        .await
2115        .unwrap();
2116    }
2117
2118    #[tokio::test]
2119    async fn mtu_negotiation_clamps_to_both_peers_and_preserves_fragmented_echoes() {
2120        timeout(std::time::Duration::from_secs(5), async {
2121            for version in [10, 11] {
2122                for (maximum, requested, expected) in
2123                    [(1428, 1492, 1428), (1492, 576, 576), (1400, 1492, 1400)]
2124                {
2125                    let mut listener = RaknetListener::bind_with_maximum_mtu(
2126                        &"127.0.0.1:0".parse().unwrap(),
2127                        maximum,
2128                    )
2129                    .await
2130                    .unwrap();
2131                    listener.listen().await;
2132                    let client = RaknetSocket::connect_with_version_and_mtu(
2133                        &listener.local_addr().unwrap(),
2134                        version,
2135                        requested,
2136                    )
2137                    .await
2138                    .unwrap();
2139                    let server = listener.accept().await.unwrap();
2140                    assert_eq!(client.mtu(), expected);
2141                    assert_eq!(server.mtu(), expected);
2142                    let payload = vec![0xfe; 4096];
2143                    client
2144                        .send(&payload, Reliability::ReliableOrdered)
2145                        .await
2146                        .unwrap();
2147                    assert_eq!(server.recv().await.unwrap(), payload);
2148                    server
2149                        .send(&payload, Reliability::ReliableOrdered)
2150                        .await
2151                        .unwrap();
2152                    assert_eq!(client.recv().await.unwrap(), payload);
2153                    client.close().await.unwrap();
2154                    server.close().await.unwrap();
2155                    listener.close().await.unwrap();
2156                }
2157            }
2158        })
2159        .await
2160        .expect("MTU negotiation stalled");
2161    }
2162
2163    #[tokio::test]
2164    async fn invalid_mtu_values_fail_before_binding_or_connecting() {
2165        let address = "127.0.0.1:0".parse().unwrap();
2166        for mtu in [0, 60, 1493, u16::MAX] {
2167            assert!(matches!(
2168                RaknetSocket::connect_with_version_and_mtu(&address, 11, mtu).await,
2169                Err(RaknetError::PacketSizeExceedMTU)
2170            ));
2171            assert!(matches!(
2172                RaknetListener::bind_with_maximum_mtu(&address, mtu).await,
2173                Err(RaknetError::PacketSizeExceedMTU)
2174            ));
2175        }
2176    }
2177
2178    #[tokio::test]
2179    async fn bulk_dispatch_is_lazy_preserves_wire_bytes_and_stops_on_close() {
2180        timeout(std::time::Duration::from_secs(2), async {
2181            let socket = Arc::new(UdpSocket::bind("127.0.0.1:0").await.unwrap());
2182            let peer = UdpSocket::bind("127.0.0.1:0").await.unwrap();
2183            let address = peer.local_addr().unwrap();
2184            let close = Arc::new(tokio::sync::Semaphore::new(0));
2185            let mut sender = None;
2186            let mut frames = OutgoingFrames::new();
2187            frames.push(FrameSetPacket::new(
2188                Reliability::ReliableOrdered,
2189                vec![0xfe; 800],
2190            ));
2191            let expected = frames[0].serialize().unwrap();
2192            RaknetSocket::transmit_replies(
2193                &socket,
2194                frames,
2195                &address,
2196                &close,
2197                &mut sender,
2198                false,
2199                0,
2200            )
2201            .await
2202            .unwrap();
2203            assert!(sender.is_none());
2204            let mut packet = [0; 2048];
2205            let (length, _) = peer.recv_from(&mut packet).await.unwrap();
2206            assert_eq!(&packet[..length], expected);
2207            let mut frames = OutgoingFrames::new();
2208            let mut expected = Vec::new();
2209            for index in 1..=32 {
2210                let mut frame = FrameSetPacket::new(Reliability::ReliableOrdered, vec![0xfe; 800]);
2211                frame.sequence_number = index;
2212                expected.push(frame.serialize().unwrap());
2213                frames.push(frame);
2214            }
2215            RaknetSocket::transmit_replies(
2216                &socket,
2217                frames,
2218                &address,
2219                &close,
2220                &mut sender,
2221                false,
2222                0,
2223            )
2224            .await
2225            .unwrap();
2226            for expected in expected {
2227                let (length, _) = peer.recv_from(&mut packet).await.unwrap();
2228                assert_eq!(&packet[..length], expected);
2229            }
2230            close.close();
2231            sender.unwrap().closed().await;
2232        })
2233        .await
2234        .expect("bulk sender did not stop");
2235    }
2236}
2237
2238#[cfg(test)]
2239mod maintenance_tests {
2240    use super::*;
2241    use crate::RaknetListener;
2242
2243    #[tokio::test]
2244    async fn a_lost_control_reply_wakes_an_idle_connection_for_retries() {
2245        timeout(std::time::Duration::from_secs(3), async {
2246            let udp = Arc::new(UdpSocket::bind("127.0.0.1:0").await.unwrap());
2247            let peer = UdpSocket::bind("127.0.0.1:0").await.unwrap();
2248            let (input, receiver) = channel(1);
2249            let (collector, _collected) = channel(1);
2250            let mut socket = RaknetSocket::from(
2251                &peer.local_addr().unwrap(),
2252                &udp,
2253                receiver,
2254                1400,
2255                Arc::new(Mutex::new(collector)),
2256                11,
2257            )
2258            .await;
2259            assert!(!socket.maintenance.enabled.load(Ordering::Acquire));
2260            socket.set_idle_maintenance(true);
2261            sleep(std::time::Duration::from_millis(600)).await;
2262            assert!(socket.maintenance.idle.load(Ordering::Acquire));
2263            socket.set_loss_rate(10);
2264            let request = ConnectionRequest {
2265                guid: 42,
2266                time: cur_timestamp_millis(),
2267                use_encryption: 0,
2268            };
2269            let frame = FrameSetPacket::new(
2270                Reliability::ReliableOrdered,
2271                write_packet_connection_request(&request).unwrap(),
2272            );
2273            input.send(frame.serialize().unwrap()).await.unwrap();
2274            while socket.sendq.read().await.get_sent_queue_size() == 0 {
2275                tokio::task::yield_now().await;
2276            }
2277            // The first reply and its ACK are deliberately lost. Recovery must
2278            // come from the maintenance task, without another incoming packet.
2279            sleep(std::time::Duration::from_millis(20)).await;
2280            let mut packet = [0; 2048];
2281            assert_eq!(
2282                peer.try_recv_from(&mut packet).unwrap_err().kind(),
2283                std::io::ErrorKind::WouldBlock
2284            );
2285            socket.set_loss_rate(0);
2286            let (length, _) = timeout(
2287                std::time::Duration::from_secs(1),
2288                peer.recv_from(&mut packet),
2289            )
2290            .await
2291            .unwrap()
2292            .unwrap();
2293            let (reply, _) = FrameSetPacket::deserialize(&packet[..length]).unwrap();
2294            assert_eq!(reply.data[0], PacketID::ConnectionRequestAccepted.to_u8());
2295            read_packet_connection_request_accepted(&reply.data).unwrap();
2296            socket.close().await.unwrap();
2297        })
2298        .await
2299        .expect("lost control reply stalled idle maintenance");
2300    }
2301
2302    #[tokio::test]
2303    async fn idle_connections_wake_for_owned_sends_and_loss_recovery() {
2304        timeout(std::time::Duration::from_secs(3), async {
2305            let mut listener = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
2306                .await
2307                .unwrap()
2308                .with_idle_maintenance(true);
2309            listener.listen().await;
2310            let mut client = RaknetSocket::connect(&listener.local_addr().unwrap())
2311                .await
2312                .unwrap();
2313            let server = listener.accept().await.unwrap();
2314            assert!(!client.maintenance.enabled.load(Ordering::Acquire));
2315            assert!(server.maintenance.enabled.load(Ordering::Acquire));
2316            client.set_idle_maintenance(true);
2317            client.flush().await.unwrap();
2318            server.flush().await.unwrap();
2319            sleep(std::time::Duration::from_millis(600)).await;
2320            assert!(client.maintenance.idle.load(Ordering::Acquire));
2321            client.set_loss_rate(10);
2322            let payload = bytes::Bytes::from(vec![0xfe; 4096]);
2323            client
2324                .send_bytes_with_order_channel(payload.clone(), Reliability::ReliableOrdered, 7)
2325                .await
2326                .unwrap();
2327            sleep(std::time::Duration::from_millis(10)).await;
2328            client.set_loss_rate(0);
2329            assert_eq!(
2330                timeout(std::time::Duration::from_millis(500), server.recv_bytes())
2331                    .await
2332                    .unwrap()
2333                    .unwrap(),
2334                payload
2335            );
2336            client.flush().await.unwrap();
2337            server
2338                .send_bytes(payload.clone(), Reliability::ReliableOrdered)
2339                .await
2340                .unwrap();
2341            assert_eq!(client.recv_bytes().await.unwrap(), payload);
2342            client.set_idle_maintenance(false);
2343            server.set_idle_maintenance(false);
2344            sleep(std::time::Duration::from_millis(100)).await;
2345            assert!(!client.maintenance.enabled.load(Ordering::Acquire));
2346            assert!(!client.maintenance.idle.load(Ordering::Acquire));
2347            assert!(!server.maintenance.idle.load(Ordering::Acquire));
2348            listener.close().await.unwrap();
2349        })
2350        .await
2351        .expect("idle maintenance or owned send stalled");
2352    }
2353}
2354
2355#[cfg(feature = "send-policy")]
2356impl RaknetSocket {
2357    /// Configure this connection's reliable flight window and queue budgets.
2358    /// Existing messages remain queued; lowering limits does not discard data.
2359    /// Apply before starting bulk traffic to establish the unreliable reserve.
2360    pub async fn set_send_options(&self, options: crate::SendOptions) -> Result<()> {
2361        if self.close_notifier.is_closed() {
2362            return Err(RaknetError::ConnectionClosed);
2363        }
2364        {
2365            let mut queue = self.sendq.write().await;
2366            queue.set_send_options(options)?;
2367            queue.register_capacity_notifier(&self.send_capacity);
2368        }
2369        self.send_capacity.notify_waiters();
2370        self.maintenance.idle.store(false, Ordering::Release);
2371        self.maintenance.wakeup.notify_one();
2372        Ok(())
2373    }
2374
2375    /// Return configured limits, or `None` for the original queue policy.
2376    pub async fn send_options(&self) -> Option<crate::SendOptions> {
2377        self.sendq.read().await.send_options()
2378    }
2379}