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