Skip to main content

rust_raknet/
arq.rs

1use crate::sequence::{self, ReliableWindow};
2
3use std::{
4    collections::{HashMap, VecDeque},
5    net::SocketAddr,
6    sync::{
7        Arc,
8        atomic::{AtomicUsize, Ordering},
9    },
10};
11
12use crate::{datatype::*, error::*, fragment::FragmentQ, raknet_log_debug, utils::*};
13
14pub(crate) struct OutgoingFrames {
15    frames: Vec<FrameSetPacket>,
16    pub(crate) coalesced: bool,
17}
18
19impl OutgoingFrames {
20    #[cfg(test)]
21    pub(crate) fn new() -> Self {
22        Self::with_capacity(0)
23    }
24
25    fn with_capacity(capacity: usize) -> Self {
26        Self {
27            frames: Vec::with_capacity(capacity),
28            coalesced: false,
29        }
30    }
31}
32
33impl std::ops::Deref for OutgoingFrames {
34    type Target = Vec<FrameSetPacket>;
35    fn deref(&self) -> &Self::Target {
36        &self.frames
37    }
38}
39
40impl std::ops::DerefMut for OutgoingFrames {
41    fn deref_mut(&mut self) -> &mut Self::Target {
42        &mut self.frames
43    }
44}
45
46impl IntoIterator for OutgoingFrames {
47    type Item = FrameSetPacket;
48    type IntoIter = std::vec::IntoIter<FrameSetPacket>;
49    fn into_iter(self) -> Self::IntoIter {
50        self.frames.into_iter()
51    }
52}
53
54impl<'a> IntoIterator for &'a OutgoingFrames {
55    type Item = &'a FrameSetPacket;
56    type IntoIter = std::slice::Iter<'a, FrameSetPacket>;
57    fn into_iter(self) -> Self::IntoIter {
58        self.frames.iter()
59    }
60}
61
62/// Delivery and ordering guarantees for a RakNet frame.
63#[derive(Clone, Copy, Debug, PartialEq, Eq)]
64#[repr(u8)]
65pub enum Reliability {
66    /// The frame may be lost or arrive out of order.
67    Unreliable = 0x00,
68    /// Only the newest frame in the ordering stream is delivered.
69    UnreliableSequenced = 0x01,
70    /// The frame is retransmitted until acknowledged, without ordering guarantees.
71    Reliable = 0x02,
72    /// The frame is retransmitted and delivered in order within its channel.
73    ReliableOrdered = 0x03,
74    /// The frame is reliable, but older frames in its ordering stream may be skipped.
75    ReliableSequenced = 0x04,
76}
77
78impl Reliability {
79    pub fn to_u8(&self) -> u8 {
80        *self as u8
81    }
82
83    pub fn from(flags: u8) -> Result<Self> {
84        Self::try_from(flags)
85    }
86}
87
88impl TryFrom<u8> for Reliability {
89    type Error = RaknetError;
90
91    fn try_from(flags: u8) -> Result<Self> {
92        match flags {
93            0x00 => Ok(Self::Unreliable),
94            0x01 => Ok(Self::UnreliableSequenced),
95            0x02 => Ok(Self::Reliable),
96            0x03 => Ok(Self::ReliableOrdered),
97            0x04 => Ok(Self::ReliableSequenced),
98            _ => Err(RaknetError::IncorrectReliability),
99        }
100    }
101}
102
103const NEEDS_B_AND_AS_FLAG: u8 = 0x4;
104const CONTINUOUS_SEND_FLAG: u8 = 0x8;
105
106// Received payloads move into the application without another allocation.
107// Reliable sends share their backing allocation with retransmission frames.
108#[derive(Clone, Debug)]
109pub(crate) enum FramePayload {
110    Owned(Vec<u8>),
111    Bytes(bytes::Bytes),
112    Shared {
113        owner: Arc<[u8]>,
114        start: u32,
115        length: u16,
116    },
117}
118
119impl Default for FramePayload {
120    fn default() -> Self {
121        Self::Owned(Vec::new())
122    }
123}
124
125impl FramePayload {
126    fn copy_shared(data: &[u8]) -> Self {
127        Self::Shared {
128            owner: Arc::from(data),
129            start: 0,
130            length: data.len() as u16,
131        }
132    }
133}
134
135impl std::ops::Deref for FramePayload {
136    type Target = [u8];
137    fn deref(&self) -> &[u8] {
138        match self {
139            Self::Owned(data) => data,
140            Self::Bytes(data) => data,
141            Self::Shared {
142                owner,
143                start,
144                length,
145            } => &owner[*start as usize..*start as usize + usize::from(*length)],
146        }
147    }
148}
149
150impl AsRef<[u8]> for FramePayload {
151    fn as_ref(&self) -> &[u8] {
152        self
153    }
154}
155
156impl From<Vec<u8>> for FramePayload {
157    fn from(data: Vec<u8>) -> Self {
158        Self::Owned(data)
159    }
160}
161
162impl From<FramePayload> for Vec<u8> {
163    fn from(data: FramePayload) -> Self {
164        match data {
165            FramePayload::Owned(data) => data,
166            shared => shared.to_vec(),
167        }
168    }
169}
170
171impl PartialEq for FramePayload {
172    fn eq(&self, other: &Self) -> bool {
173        self.as_ref() == other.as_ref()
174    }
175}
176
177// A fragmented send retains its complete allocation until the final fragment
178// is acknowledged. Charge that allocation once, independently of frame clones.
179struct SharedPayload {
180    remaining: AtomicUsize,
181    bytes: usize,
182}
183
184#[derive(Clone)]
185pub struct FrameSetPacket {
186    pub sequence_number: u32,
187    pub flags: u8,
188    pub length_in_bytes: u16,
189    pub reliable_frame_index: u32,
190    pub sequenced_frame_index: u32,
191    pub ordered_frame_index: u32,
192    pub order_channel: u8,
193    pub compound_size: u32,
194    pub compound_id: u16,
195    pub fragment_index: u32,
196    pub(crate) data: FramePayload,
197    shared_payload: Option<Arc<SharedPayload>>,
198}
199
200impl FrameSetPacket {
201    pub fn new(r: Reliability, data: Vec<u8>) -> Self {
202        Self::from_payload(r, data.into())
203    }
204
205    fn from_payload(r: Reliability, data: FramePayload) -> Self {
206        let flag = r.to_u8() << 5;
207
208        Self {
209            sequence_number: 0,
210            flags: flag,
211            length_in_bytes: data.len() as u16,
212            reliable_frame_index: 0,
213            sequenced_frame_index: 0,
214            ordered_frame_index: 0,
215            order_channel: 0,
216            compound_size: 0,
217            compound_id: 0,
218            fragment_index: 0,
219            data,
220            shared_payload: None,
221        }
222    }
223
224    #[cfg(test)]
225    pub fn deserialize(buf: &[u8]) -> Result<(Self, bool)> {
226        let mut reader = RaknetReader::new(buf);
227        let input_len = buf.len() as u64;
228
229        let mut ret = Self {
230            sequence_number: 0,
231            flags: 0,
232            length_in_bytes: 0,
233            reliable_frame_index: 0,
234            sequenced_frame_index: 0,
235            ordered_frame_index: 0,
236            order_channel: 0,
237            compound_size: 0,
238            compound_id: 0,
239            fragment_index: 0,
240            data: FramePayload::default(),
241            shared_payload: None,
242        };
243
244        let packet_id = reader.read_u8()?;
245        if !(0x80..=0x8d).contains(&packet_id) {
246            return Err(RaknetError::PacketHeaderError);
247        }
248        ret.sequence_number = reader.read_u24(Endian::Little)?;
249        ret.flags = reader.read_u8()?;
250
251        let length_in_bits = reader.read_u16(Endian::Big)?;
252        if length_in_bits % 8 != 0 {
253            return Err(RaknetError::PacketParseError);
254        }
255        ret.length_in_bytes = length_in_bits / 8;
256
257        if ret.is_reliable()? {
258            ret.reliable_frame_index = reader.read_u24(Endian::Little)?;
259        }
260
261        if ret.is_sequenced()? {
262            ret.sequenced_frame_index = reader.read_u24(Endian::Little)?;
263        }
264        if ret.is_ordered()? {
265            ret.ordered_frame_index = reader.read_u24(Endian::Little)?;
266            ret.order_channel = reader.read_u8()?;
267        }
268
269        if ret.is_fragment() {
270            ret.compound_size = reader.read_u32(Endian::Big)?;
271            ret.compound_id = reader.read_u16(Endian::Big)?;
272            ret.fragment_index = reader.read_u32(Endian::Big)?;
273        }
274
275        let mut data = vec![0; usize::from(ret.length_in_bytes)];
276        reader.read(&mut data)?;
277        ret.data = data.into();
278
279        if ret.is_fragment() && (ret.compound_size == 0 || ret.fragment_index >= ret.compound_size)
280        {
281            return Err(RaknetError::PacketParseError);
282        }
283
284        Ok((ret, reader.pos() == input_len))
285    }
286
287    pub fn serialize(&self) -> Result<Vec<u8>> {
288        let mut buffer = Vec::new();
289        self.serialize_into(&mut buffer)?;
290        Ok(buffer)
291    }
292
293    pub(crate) fn serialize_into(&self, buffer: &mut Vec<u8>) -> Result<()> {
294        self.validate()?;
295        let size = self._size()?;
296        buffer.clear();
297        buffer.reserve(size);
298        let mut writer = RaknetWriter::from_buffer(std::mem::take(buffer));
299        let result = self
300            .write_header(&mut writer)
301            .and_then(|()| writer.write(self.data.as_ref()));
302        *buffer = writer.get_raw_payload();
303        result
304    }
305
306    pub(crate) fn serialize_group_into(frames: &[Self], output: &mut Vec<u8>) -> Result<()> {
307        let first = frames.first().ok_or(RaknetError::PacketParseError)?;
308        output.clear();
309        for (index, frame) in frames.iter().enumerate() {
310            if frame.sequence_number != first.sequence_number {
311                return Err(RaknetError::PacketParseError);
312            }
313            let mut header = [0; 32];
314            let length = frame.encode_header(&mut header)?;
315            output.extend_from_slice(&header[if index == 0 { 0 } else { 4 }..length]);
316            output.extend_from_slice(frame.data.as_ref());
317        }
318        Ok(())
319    }
320
321    pub(crate) fn validate(&self) -> Result<()> {
322        if self.data.len() != usize::from(self.length_in_bytes)
323            || self.data.len() > usize::from(u16::MAX / 8)
324            || (self.is_fragment()
325                && (self.compound_size == 0 || self.fragment_index >= self.compound_size))
326        {
327            return Err(RaknetError::PacketParseError);
328        }
329
330        self._size()?;
331        Ok(())
332    }
333
334    pub(crate) fn encode_header(&self, header: &mut [u8; 32]) -> Result<usize> {
335        self.validate()?;
336        let mut writer = RaknetWriter::from_buffer(header.as_mut_slice());
337        self.write_header(&mut writer)?;
338        Ok(32 - writer.remaining_mut())
339    }
340
341    fn write_header<B: bytes::BufMut>(&self, writer: &mut RaknetWriter<B>) -> Result<()> {
342        let mut id = 0x80 | NEEDS_B_AND_AS_FLAG;
343
344        // Set the continuation bit for all fragments after the first.
345        if (self.flags & 16) != 0 && self.fragment_index != 0 {
346            id |= CONTINUOUS_SEND_FLAG;
347        }
348
349        writer.write_u8(id)?;
350        writer.write_u24(self.sequence_number, Endian::Little)?;
351
352        // The top three bits encode the reliability mode.
353        writer.write_u8(self.flags)?;
354        writer.write_u16(self.length_in_bytes * 8, Endian::Big)?;
355
356        if self.is_reliable()? {
357            writer.write_u24(self.reliable_frame_index, Endian::Little)?;
358        }
359
360        if self.is_sequenced()? {
361            writer.write_u24(self.sequenced_frame_index, Endian::Little)?;
362        }
363        if self.is_ordered()? {
364            writer.write_u24(self.ordered_frame_index, Endian::Little)?;
365            writer.write_u8(self.order_channel)?;
366        }
367
368        // Bit 4 marks a fragmented frame.
369        if (self.flags & 16) != 0 {
370            writer.write_u32(self.compound_size, Endian::Big)?;
371            writer.write_u16(self.compound_id, Endian::Big)?;
372            writer.write_u32(self.fragment_index, Endian::Big)?;
373        }
374        Ok(())
375    }
376
377    pub fn is_fragment(&self) -> bool {
378        (self.flags & 16) != 0
379    }
380
381    pub fn is_reliable(&self) -> Result<bool> {
382        let r = Reliability::from((self.flags & 224) >> 5)?;
383        Ok(matches!(
384            r,
385            Reliability::Reliable | Reliability::ReliableOrdered | Reliability::ReliableSequenced
386        ))
387    }
388
389    pub fn is_ordered(&self) -> Result<bool> {
390        let r = Reliability::from((self.flags & 224) >> 5)?;
391        Ok(matches!(
392            r,
393            Reliability::UnreliableSequenced
394                | Reliability::ReliableOrdered
395                | Reliability::ReliableSequenced
396        ))
397    }
398
399    pub fn is_sequenced(&self) -> Result<bool> {
400        let r = Reliability::from((self.flags & 224) >> 5)?;
401        Ok(matches!(
402            r,
403            Reliability::UnreliableSequenced | Reliability::ReliableSequenced
404        ))
405    }
406    pub fn reliability(&self) -> Result<Reliability> {
407        Reliability::from((self.flags & 224) >> 5)
408    }
409
410    pub fn _size(&self) -> Result<usize> {
411        let mut ret = 0;
412        // id
413        ret += 1;
414        // sequence number
415        ret += 3;
416        // flags
417        ret += 1;
418        // length_in_bits
419        ret += 2;
420
421        if self.is_reliable()? {
422            // reliable frame index
423            ret += 3;
424        }
425        if self.is_sequenced()? {
426            // sequenced frame index
427            ret += 3;
428        }
429        if self.is_ordered()? {
430            // Ordered frame index and channel.
431            ret += 4;
432        }
433        if (self.flags & 16) != 0 {
434            // Compound size, compound ID, and fragment index.
435            ret += 10;
436        }
437        //body
438        ret += self.data.len();
439        Ok(ret)
440    }
441}
442
443pub struct FrameVec {
444    #[cfg(test)]
445    pub frames: Vec<FrameSetPacket>,
446}
447
448impl FrameVec {
449    #[cfg(test)]
450    pub fn new(buf: &[u8]) -> Result<Self> {
451        let mut frames = Vec::new();
452        Self::decode_into(buf, &mut frames)?;
453        Ok(Self { frames })
454    }
455
456    // Reuse the frame metadata allocation across incoming datagrams.
457    pub(crate) fn decode_into(buf: &[u8], frames: &mut Vec<FrameSetPacket>) -> Result<()> {
458        Self::decode(buf, frames, false)
459    }
460
461    pub(crate) fn decode_owned_into(
462        mut buf: Vec<u8>,
463        frames: &mut Vec<FrameSetPacket>,
464    ) -> Result<()> {
465        Self::decode(&buf, frames, true)?;
466        if let [frame] = frames.as_mut_slice() {
467            // A single-frame datagram can reuse its allocation for the payload.
468            // Compact the body in place without a shared slice owner.
469            let length = usize::from(frame.length_in_bytes);
470            let offset = buf.len() - length;
471            buf.copy_within(offset.., 0);
472            buf.truncate(length);
473            frame.data = buf.into();
474        }
475        Ok(())
476    }
477
478    fn decode(buf: &[u8], frames: &mut Vec<FrameSetPacket>, owned: bool) -> Result<()> {
479        frames.clear();
480        let mut reader = RaknetReader::new(buf);
481        let id = reader.read_u8()?;
482        if !(0x80..=0x8d).contains(&id) {
483            return Err(RaknetError::PacketHeaderError);
484        }
485        let sequence_number = reader.read_u24(Endian::Little)?;
486        if reader.pos() == buf.len() as u64 {
487            return Err(RaknetError::PacketParseError);
488        }
489        while reader.pos() < buf.len() as u64 {
490            let mut frame = FrameSetPacket {
491                sequence_number,
492                flags: 0,
493                length_in_bytes: 0,
494                reliable_frame_index: 0,
495                sequenced_frame_index: 0,
496                ordered_frame_index: 0,
497                order_channel: 0,
498                compound_size: 0,
499                compound_id: 0,
500                fragment_index: 0,
501                data: FramePayload::default(),
502                shared_payload: None,
503            };
504
505            frame.flags = reader.read_u8()?;
506            let length_in_bits = reader.read_u16(Endian::Big)?;
507            if length_in_bits % 8 != 0 {
508                return Err(RaknetError::PacketParseError);
509            }
510            frame.length_in_bytes = length_in_bits / 8;
511
512            if frame.is_reliable()? {
513                frame.reliable_frame_index = reader.read_u24(Endian::Little)?;
514            }
515            if frame.is_sequenced()? {
516                frame.sequenced_frame_index = reader.read_u24(Endian::Little)?;
517            }
518            if frame.is_ordered()? {
519                frame.ordered_frame_index = reader.read_u24(Endian::Little)?;
520                frame.order_channel = reader.read_u8()?;
521            }
522            if frame.is_fragment() {
523                frame.compound_size = reader.read_u32(Endian::Big)?;
524                frame.compound_id = reader.read_u16(Endian::Big)?;
525                frame.fragment_index = reader.read_u32(Endian::Big)?;
526                if frame.compound_size == 0 || frame.fragment_index >= frame.compound_size {
527                    return Err(RaknetError::PacketParseError);
528                }
529            }
530
531            let data = reader.read_slice(usize::from(frame.length_in_bytes))?;
532            // Multi-frame datagrams retain independent payload allocations.
533            // The owned single-frame path moves the original allocation below.
534            if !owned || !frames.is_empty() || reader.pos() != buf.len() as u64 {
535                frame.data = data.to_vec().into();
536            }
537            frames.push(frame);
538        }
539
540        Ok(())
541    }
542}
543
544#[derive(Default)]
545pub struct ACKSet {
546    ack: Vec<(u32, u32)>,
547    nack: Vec<(u32, u32)>,
548    next_expected: u32,
549}
550
551impl ACKSet {
552    pub fn insert(&mut self, s: u32) {
553        // Remove a hole that arrived before the next NACK was emitted.
554        let mut split = None;
555        self.nack.retain_mut(|(start, end)| {
556            if s < *start || s > *end {
557                return true;
558            }
559            if *start == *end {
560                return false;
561            }
562            if s == *start {
563                *start += 1;
564            } else if s == *end {
565                *end -= 1;
566            } else {
567                split = Some((s + 1, *end));
568                *end = s - 1;
569            }
570            true
571        });
572        if let Some(range) = split {
573            self.nack.push(range);
574        }
575        if s == self.next_expected || sequence::newer(s, self.next_expected) {
576            if s != self.next_expected {
577                if s > self.next_expected {
578                    self.nack.push((self.next_expected, s - 1));
579                } else {
580                    self.nack.push((self.next_expected, sequence::MASK));
581                    if s != 0 {
582                        self.nack.push((0, s - 1));
583                    }
584                }
585            }
586            self.next_expected = sequence::next(s);
587        }
588
589        for i in 0..self.ack.len() {
590            let a = self.ack[i];
591            if (a.0..=a.1).contains(&s) {
592                return;
593            }
594            if a.0 != 0 && s == a.0 - 1 {
595                self.ack[i].0 = s;
596                return;
597            }
598            if s == a.1.saturating_add(1) {
599                self.ack[i].1 = s;
600                return;
601            }
602        }
603        self.ack.push((s, s));
604    }
605
606    #[cfg(test)]
607    pub fn get_ack(&mut self) -> Vec<(u32, u32)> {
608        std::mem::take(&mut self.ack)
609    }
610
611    fn take_ack_into(&mut self, output: &mut Vec<(u32, u32)>) {
612        output.clear();
613        std::mem::swap(output, &mut self.ack);
614    }
615
616    fn take_nack_into(&mut self, output: &mut Vec<(u32, u32)>) {
617        output.clear();
618        std::mem::swap(output, &mut self.nack);
619    }
620
621    #[cfg(test)]
622    pub fn get_nack(&mut self) -> Vec<(u32, u32)> {
623        std::mem::take(&mut self.nack)
624    }
625}
626
627/// Channel zero is the common path; other channels allocate only when used.
628#[derive(Default)]
629struct ChannelIndexes {
630    primary: u32,
631    others: HashMap<u8, u32>,
632}
633
634impl ChannelIndexes {
635    fn get(&self, channel: u8) -> u32 {
636        if channel == 0 {
637            self.primary
638        } else {
639            self.others.get(&channel).copied().unwrap_or(0)
640        }
641    }
642
643    fn get_mut(&mut self, channel: u8) -> &mut u32 {
644        if channel == 0 {
645            &mut self.primary
646        } else {
647            self.others.entry(channel).or_default()
648        }
649    }
650
651    #[cfg(test)]
652    fn insert(&mut self, channel: u8, index: u32) {
653        *self.get_mut(channel) = index;
654    }
655}
656
657#[derive(Default)]
658pub struct RecvQ {
659    sequenced_frame_indexes: ChannelIndexes,
660    last_ordered_indexes: ChannelIndexes,
661    sequence_number_ackset: ACKSet,
662    packets: HashMap<u32, FrameSetPacket>,
663    ordered_packets: HashMap<(u8, u32), FrameSetPacket>,
664    fragment_queue: FragmentQ,
665    reliable_window: ReliableWindow,
666    ordered_bytes: usize,
667    ready_ordered: Vec<FrameSetPacket>,
668    ready_bytes: usize,
669}
670
671impl RecvQ {
672    pub fn new() -> Self {
673        Self::default()
674    }
675
676    pub fn insert(&mut self, frame: FrameSetPacket) -> Result<()> {
677        let reliability = frame.reliability()?;
678        self.sequence_number_ackset.insert(frame.sequence_number);
679        if frame.is_reliable()? && !self.reliable_window.accept(frame.reliable_frame_index)? {
680            return Ok(());
681        }
682
683        match reliability {
684            Reliability::Unreliable => {
685                self.packets.entry(frame.sequence_number).or_insert(frame);
686            }
687            Reliability::UnreliableSequenced => {
688                let channel = frame.order_channel;
689                let sequence_index = frame.sequenced_frame_index;
690                let sequence_number = frame.sequence_number;
691                let last_index = self.sequenced_frame_indexes.get_mut(channel);
692                if sequence_index == *last_index || sequence::newer(sequence_index, *last_index) {
693                    self.packets.entry(sequence_number).or_insert(frame);
694                    *last_index = sequence::next(sequence_index);
695                }
696            }
697            Reliability::Reliable => {
698                self.packets.insert(frame.sequence_number, frame);
699            }
700            Reliability::ReliableOrdered => {
701                let expected_index = self.last_ordered_indexes.get(frame.order_channel);
702                if sequence::newer(expected_index, frame.ordered_frame_index) {
703                    return Ok(());
704                }
705                if sequence::distance(frame.ordered_frame_index, expected_index)
706                    >= sequence::RECEIVE_WINDOW
707                {
708                    return Err(RaknetError::PacketParseError);
709                }
710                let complete = if frame.is_fragment() {
711                    self.fragment_queue.insert_and_take_completed(frame)?
712                } else {
713                    Some(frame)
714                };
715                if let Some(frame) = complete {
716                    let key = (frame.order_channel, frame.ordered_frame_index);
717                    if self.ordered_packets.contains_key(&key) {
718                        return Ok(());
719                    }
720                    if self.ordered_packets.len() + self.ready_ordered.len()
721                        >= sequence::RECEIVE_WINDOW as usize
722                        || self.ordered_bytes + self.ready_bytes + frame.data.len()
723                            > 64 * 1024 * 1024
724                    {
725                        return Err(RaknetError::PacketParseError);
726                    }
727                    if frame.ordered_frame_index == expected_index {
728                        let channel = frame.order_channel;
729                        self.ready_bytes += frame.data.len();
730                        self.ready_ordered.push(frame);
731                        let expected = self.last_ordered_indexes.get_mut(channel);
732                        *expected = sequence::next(*expected);
733                        // Contiguous traffic bypasses the reordering hash table.
734                        while !self.ordered_packets.is_empty() {
735                            let Some(frame) = self.ordered_packets.remove(&(channel, *expected))
736                            else {
737                                break;
738                            };
739                            self.ordered_bytes -= frame.data.len();
740                            self.ready_bytes += frame.data.len();
741                            self.ready_ordered.push(frame);
742                            *expected = sequence::next(*expected);
743                        }
744                    } else {
745                        self.ordered_bytes += frame.data.len();
746                        self.ordered_packets.insert(key, frame);
747                    }
748                }
749            }
750
751            Reliability::ReliableSequenced => {
752                let channel = frame.order_channel;
753                let sequence_index = frame.sequenced_frame_index;
754                let sequence_number = frame.sequence_number;
755                let last_index = self.sequenced_frame_indexes.get_mut(channel);
756                if sequence_index == *last_index || sequence::newer(sequence_index, *last_index) {
757                    self.packets.entry(sequence_number).or_insert(frame);
758                    *last_index = sequence::next(sequence_index);
759                }
760            }
761        }
762        Ok(())
763    }
764
765    #[cfg(test)]
766    pub fn get_ack(&mut self) -> Vec<(u32, u32)> {
767        self.sequence_number_ackset.get_ack()
768    }
769
770    #[cfg(test)]
771    pub fn get_nack(&mut self) -> Vec<(u32, u32)> {
772        self.sequence_number_ackset.get_nack()
773    }
774
775    pub(crate) fn take_ack_into(&mut self, output: &mut Vec<(u32, u32)>) {
776        self.sequence_number_ackset.take_ack_into(output);
777    }
778
779    pub(crate) fn take_nack_into(&mut self, output: &mut Vec<(u32, u32)>) {
780        self.sequence_number_ackset.take_nack_into(output);
781    }
782
783    #[cfg(test)]
784    pub fn flush(&mut self, _peer_addr: &SocketAddr) -> Vec<FrameSetPacket> {
785        let mut frames = Vec::new();
786        self.flush_into(&mut frames);
787        frames
788    }
789
790    pub(crate) fn flush_into(&mut self, frames: &mut Vec<FrameSetPacket>) {
791        frames.append(&mut self.ready_ordered);
792        self.ready_bytes = 0;
793        if self.packets.is_empty() {
794            return;
795        }
796        let mut packets: Vec<_> = self.packets.drain().map(|(_, frame)| frame).collect();
797        packets.sort_unstable_by_key(|frame| frame.sequence_number);
798        frames.extend(packets);
799    }
800    pub(crate) fn needs_maintenance(&self) -> bool {
801        !self.sequence_number_ackset.nack.is_empty() || self.fragment_queue.size() != 0
802    }
803
804    pub fn fragments_expired(&self) -> bool {
805        self.fragment_queue.expired()
806    }
807
808    pub fn get_ordered_packet(&self) -> usize {
809        self.ordered_packets.len() + self.ready_ordered.len()
810    }
811
812    pub fn get_fragment_queue_size(&self) -> usize {
813        self.fragment_queue.size()
814    }
815
816    pub fn get_ordered_keys(&self) -> Vec<(u8, u32)> {
817        self.ordered_packets.keys().copied().collect()
818    }
819
820    pub fn get_size(&self) -> usize {
821        self.packets.len()
822    }
823}
824
825#[cfg(feature = "send-policy")]
826struct SendScheduler {
827    capacity_notifier: std::sync::Weak<tokio::sync::Notify>,
828    options: crate::SendOptions,
829    unreliable: VecDeque<FrameSetPacket>,
830    unreliable_bytes: usize,
831    use_legacy: bool,
832    persistent: bool,
833    next_lane: usize,
834}
835
836#[cfg(feature = "recovery-policy")]
837#[derive(Clone, Copy)]
838struct ProbeFallback {
839    sequence: u32,
840    deadline: i64,
841}
842
843#[cfg(feature = "recovery-policy")]
844struct Recovery {
845    options: crate::RecoveryOptions,
846    last_progress: i64,
847    sampled_rtt: bool,
848    probed: bool,
849    probe_packed: bool,
850    pending_probe: Option<ProbeFallback>,
851    probe_replay: Option<u32>,
852}
853
854pub struct SendQ {
855    mtu: u16,
856    ack_sequence_number: u32,
857    sequence_number: u32,
858    reliable_frame_index: u32,
859    sequenced_frame_indexes: ChannelIndexes,
860    ordered_frame_indexes: ChannelIndexes,
861    compound_id: u16,
862    // Each entry stores a frame, send state, last send time, retry count, and prior sequence IDs.
863    packets: VecDeque<FrameSetPacket>,
864    queued_unreliable: usize,
865    buffered_bytes: usize,
866    rto: i64,
867    srtt: i64,
868    #[cfg(feature = "recovery-policy")]
869    recovery: Option<Box<Recovery>>,
870    sent_packet: Vec<(FrameSetPacket, bool, i64, u32, Vec<u32>)>,
871    flight_order_dirty: bool,
872    next_retry: i64,
873    retries_pending: bool,
874    coalesce: bool,
875    coalescing_allowed: bool,
876    grouped_acks: bool,
877    #[cfg(feature = "send-policy")]
878    scheduler: Option<Box<SendScheduler>>,
879}
880
881impl SendQ {
882    pub const DEFAULT_TIMEOUT_MILLS: i64 = 50;
883    const MAX_IN_FLIGHT_PACKETS: usize = 64;
884    const MAX_COALESCED_FRAMES: usize = 8;
885    const MAX_BUFFERED_BYTES: usize = 64 * 1024 * 1024;
886    const SEND_HIGH_WATER: usize = 256 * 1024;
887    const FRAME_BUDGET: usize = 128;
888
889    const RTO_UBOUND: i64 = 12000;
890    const RTO_LBOUND: i64 = 50;
891
892    pub fn new(mtu: u16) -> Self {
893        Self {
894            mtu,
895            ack_sequence_number: sequence::MASK,
896            sequence_number: 0,
897            packets: VecDeque::new(),
898            #[cfg(feature = "send-policy")]
899            scheduler: None,
900            queued_unreliable: 0,
901            buffered_bytes: 0,
902            sent_packet: vec![],
903            flight_order_dirty: false,
904            next_retry: i64::MAX,
905            retries_pending: false,
906            coalesce: false,
907            coalescing_allowed: true,
908            grouped_acks: false,
909            reliable_frame_index: 0,
910            sequenced_frame_indexes: ChannelIndexes::default(),
911            ordered_frame_indexes: ChannelIndexes::default(),
912            compound_id: 0,
913
914            rto: SendQ::DEFAULT_TIMEOUT_MILLS,
915            srtt: SendQ::DEFAULT_TIMEOUT_MILLS,
916            #[cfg(feature = "recovery-policy")]
917            recovery: None,
918        }
919    }
920
921    #[cfg(feature = "recovery-policy")]
922    pub(crate) fn set_recovery_options(&mut self, options: crate::RecoveryOptions, now: i64) {
923        let sampled_rtt = self.recovery.as_ref().is_some_and(|r| r.sampled_rtt);
924        let pending_probe = self.active_probe();
925        let probe_replay = self.recovery.as_ref().and_then(|r| r.probe_replay);
926        self.recovery = (options != crate::RecoveryOptions::default() || pending_probe.is_some())
927            .then(|| {
928                Box::new(Recovery {
929                    options,
930                    last_progress: now,
931                    sampled_rtt,
932                    probed: pending_probe.is_some(),
933                    probe_packed: false,
934                    pending_probe,
935                    probe_replay,
936                })
937            });
938    }
939
940    #[cfg(feature = "recovery-policy")]
941    pub(crate) fn recovery_options(&self) -> crate::RecoveryOptions {
942        self.recovery
943            .as_ref()
944            .map_or_else(Default::default, |r| r.options)
945    }
946
947    #[cfg(feature = "recovery-policy")]
948    fn acknowledge_progress(&mut self, now: i64, sampled_rtt: bool) {
949        let Some(recovery) = &mut self.recovery else {
950            return;
951        };
952        if recovery.pending_probe.is_some_and(|probe| {
953            !self.sent_packet.iter().any(|packet| {
954                packet.0.sequence_number == probe.sequence && packet.3 == 0 && !packet.4.is_empty()
955            })
956        }) {
957            recovery.pending_probe = None;
958        }
959        recovery.sampled_rtt |= sampled_rtt;
960        recovery.last_progress = now;
961        recovery.probed = false;
962        if recovery.options.reset_backoff_on_progress && sampled_rtt {
963            // Retain Karn's exclusion even after reducing the backoff.
964            for packet in &mut self.sent_packet {
965                packet.3 = packet.3.min(1);
966            }
967            self.next_retry = 0;
968        }
969    }
970
971    #[cfg(feature = "recovery-policy")]
972    fn probe_deadline(&self) -> i64 {
973        let Some(recovery) = &self.recovery else {
974            return i64::MAX;
975        };
976        let Some(minimum) = recovery.options.tail_probe_min_delay else {
977            return i64::MAX;
978        };
979        if !recovery.sampled_rtt || recovery.probed || self.sent_packet.is_empty() {
980            return i64::MAX;
981        }
982        // Replay only a single complete datagram. Probing one member of a
983        // packed datagram would create artificial gaps for its other members.
984        if !self.packets.is_empty() || self.sent_packet.len() > Self::MAX_COALESCED_FRAMES {
985            return i64::MAX;
986        }
987        let sequence = self.sent_packet[0].0.sequence_number;
988        if self
989            .sent_packet
990            .iter()
991            .any(|p| !p.1 || p.3 != 0 || !p.4.is_empty() || p.0.sequence_number != sequence)
992        {
993            return i64::MAX;
994        }
995        #[cfg(feature = "send-policy")]
996        if let Some(scheduler) = &self.scheduler {
997            let charge: usize = self.sent_packet.iter().map(|p| p.0._size().unwrap()).sum();
998            if !scheduler.unreliable.is_empty() || charge > scheduler.options.flush_bytes {
999                return i64::MAX;
1000            }
1001        }
1002        let minimum = i64::try_from(minimum.as_millis())
1003            .unwrap_or(i64::MAX)
1004            .max(1);
1005        recovery
1006            .last_progress
1007            .saturating_add(minimum.max(self.srtt.saturating_mul(3).saturating_add(1) / 2))
1008    }
1009
1010    #[cfg(feature = "recovery-policy")]
1011    pub(crate) fn recovery_deadline(&self) -> i64 {
1012        if self.sent_packet.is_empty() {
1013            return i64::MAX;
1014        }
1015        self.next_retry
1016            .min(self.probe_deadline())
1017            .min(self.probe_retry_deadline())
1018    }
1019
1020    #[cfg(feature = "recovery-policy")]
1021    fn active_probe(&self) -> Option<ProbeFallback> {
1022        self.recovery.as_ref()?.pending_probe.filter(|probe| {
1023            self.sent_packet.iter().any(|packet| {
1024                packet.0.sequence_number == probe.sequence && packet.3 == 0 && !packet.4.is_empty()
1025            })
1026        })
1027    }
1028
1029    #[cfg(feature = "recovery-policy")]
1030    fn probe_retry_deadline(&self) -> i64 {
1031        self.active_probe().map_or(i64::MAX, |probe| probe.deadline)
1032    }
1033
1034    #[cfg(feature = "recovery-policy")]
1035    fn probe_tail(&mut self, now: i64) {
1036        let deadline = self.probe_deadline();
1037        // A delayed wakeup must retain normal timeout recovery and its packing fallback.
1038        if deadline == i64::MAX || now < deadline || now >= self.next_retry {
1039            return;
1040        }
1041        // Preserve every frame of the original datagram under one new ID.
1042        // Existing alias ACK handling retires either transmission exactly once.
1043        let fallback = self.sent_packet[0]
1044            .2
1045            .saturating_add(Self::retry_timeout(self.rto, self.sent_packet[0].3));
1046        let previous = self.sent_packet[0].0.sequence_number;
1047        let sequence = self.sequence_number;
1048        self.sequence_number = sequence::next(sequence);
1049        for packet in &mut self.sent_packet {
1050            packet.0.sequence_number = sequence;
1051            packet.1 = false;
1052            if packet.4.len() == 64 {
1053                packet.4.remove(0);
1054            }
1055            packet.4.push(previous);
1056        }
1057        let recovery = self.recovery.as_mut().unwrap();
1058        recovery.probed = true;
1059        recovery.probe_replay = Some(sequence);
1060        recovery.pending_probe = Some(ProbeFallback {
1061            sequence,
1062            deadline: fallback,
1063        });
1064        recovery.probe_packed = self.sent_packet.len() > 1;
1065        self.grouped_acks |= recovery.probe_packed;
1066        self.flight_order_dirty = true;
1067        self.retries_pending = true;
1068    }
1069
1070    #[cfg(feature = "recovery-policy")]
1071    fn take_probe_replay(&mut self) -> Option<u32> {
1072        self.recovery
1073            .as_mut()
1074            .and_then(|recovery| recovery.probe_replay.take())
1075    }
1076
1077    #[cfg(feature = "recovery-policy")]
1078    fn take_probe_packing(&mut self) -> bool {
1079        self.recovery
1080            .as_mut()
1081            .is_some_and(|r| std::mem::take(&mut r.probe_packed))
1082    }
1083
1084    fn required_bytes(&self, reliability: Reliability, len: usize) -> Result<usize> {
1085        let payload = usize::from(self.mtu)
1086            .checked_sub(60)
1087            .filter(|n| *n > 0)
1088            .ok_or(RaknetError::PacketSizeExceedMTU)?;
1089        let frames = if reliability == Reliability::ReliableOrdered && len > payload {
1090            let frames = len.div_ceil(payload);
1091            if frames > crate::fragment::MAX_FRAGMENTS {
1092                return Err(RaknetError::PacketSizeExceedMTU);
1093            }
1094            frames
1095        } else {
1096            1
1097        };
1098        let bytes = frames
1099            .checked_mul(Self::FRAME_BUDGET)
1100            .and_then(|n| n.checked_add(len))
1101            .filter(|n| *n <= Self::MAX_BUFFERED_BYTES)
1102            .ok_or(RaknetError::PacketSizeExceedMTU)?;
1103        Ok(bytes)
1104    }
1105
1106    pub fn has_capacity(&self, reliability: Reliability, len: usize) -> Result<bool> {
1107        let required = self.required_bytes(reliability, len)?;
1108        // Admit a single large message while applying backpressure to bursts.
1109        #[cfg(feature = "send-policy")]
1110        {
1111            self.has_reserved_capacity(reliability, required)
1112        }
1113        #[cfg(not(feature = "send-policy"))]
1114        {
1115            Ok(self.buffered_bytes.saturating_add(required) <= Self::SEND_HIGH_WATER.max(required))
1116        }
1117    }
1118
1119    pub(crate) fn enable_coalescing(&mut self) {
1120        self.coalesce = self.coalescing_allowed;
1121    }
1122
1123    pub(crate) fn allows_coalescing(&self) -> bool {
1124        self.coalescing_allowed
1125    }
1126
1127    pub(crate) fn has_batch_capacity(
1128        &self,
1129        reliability: Reliability,
1130        mut lengths: impl Iterator<Item = usize>,
1131    ) -> Result<bool> {
1132        let required = lengths.try_fold(0usize, |total, length| {
1133            total
1134                .checked_add(self.required_bytes(reliability, length)?)
1135                .filter(|&bytes| bytes <= Self::MAX_BUFFERED_BYTES)
1136                .ok_or(RaknetError::PacketSizeExceedMTU)
1137        })?;
1138        #[cfg(feature = "send-policy")]
1139        {
1140            self.has_batch_required_capacity(reliability, required)
1141        }
1142        #[cfg(not(feature = "send-policy"))]
1143        {
1144            Ok(self.buffered_bytes.saturating_add(required) <= Self::SEND_HIGH_WATER.max(required))
1145        }
1146    }
1147
1148    pub fn insert(&mut self, reliability: Reliability, buf: &[u8]) -> Result<()> {
1149        self.insert_with_order_channel(reliability, buf, 0)
1150    }
1151
1152    pub fn insert_with_order_channel(
1153        &mut self,
1154        reliability: Reliability,
1155        buf: &[u8],
1156        order_channel: u8,
1157    ) -> Result<()> {
1158        self.insert_payload(reliability, buf, order_channel, None)
1159    }
1160
1161    pub(crate) fn insert_bytes(
1162        &mut self,
1163        reliability: Reliability,
1164        data: &bytes::Bytes,
1165        order_channel: u8,
1166    ) -> Result<()> {
1167        self.insert_payload(reliability, data, order_channel, Some(data))
1168    }
1169
1170    fn insert_payload(
1171        &mut self,
1172        reliability: Reliability,
1173        buf: &[u8],
1174        order_channel: u8,
1175        owned: Option<&bytes::Bytes>,
1176    ) -> Result<()> {
1177        let reserved = self.required_bytes(reliability, buf.len())?;
1178        if reserved > Self::MAX_BUFFERED_BYTES - self.buffered_bytes {
1179            return Err(RaknetError::PacketSizeExceedMTU);
1180        }
1181        let max_payload = self
1182            .mtu
1183            .checked_sub(60)
1184            .map(usize::from)
1185            .filter(|size| *size > 0)
1186            .ok_or(RaknetError::PacketSizeExceedMTU)?;
1187
1188        match reliability {
1189            Reliability::Unreliable => {
1190                if buf.len() > max_payload {
1191                    return Err(RaknetError::PacketSizeExceedMTU);
1192                }
1193
1194                let frame = FrameSetPacket::from_payload(
1195                    reliability,
1196                    owned.map_or_else(
1197                        || FramePayload::Owned(buf.to_vec()),
1198                        |data| FramePayload::Bytes(data.clone()),
1199                    ),
1200                );
1201                #[cfg(feature = "send-policy")]
1202                self.push_unreliable(frame);
1203                #[cfg(not(feature = "send-policy"))]
1204                self.packets.push_back(frame);
1205            }
1206            Reliability::UnreliableSequenced => {
1207                if buf.len() > max_payload {
1208                    return Err(RaknetError::PacketSizeExceedMTU);
1209                }
1210
1211                let sequenced_frame_index = {
1212                    let index = self.sequenced_frame_indexes.get_mut(order_channel);
1213                    let current = *index;
1214                    *index = sequence::next(*index);
1215                    current
1216                };
1217                let ordered_frame_index = self.ordered_frame_indexes.get(order_channel);
1218                let mut frame = FrameSetPacket::from_payload(
1219                    reliability,
1220                    owned.map_or_else(
1221                        || FramePayload::Owned(buf.to_vec()),
1222                        |data| FramePayload::Bytes(data.clone()),
1223                    ),
1224                );
1225                frame.order_channel = order_channel;
1226                frame.ordered_frame_index = ordered_frame_index;
1227                frame.sequenced_frame_index = sequenced_frame_index;
1228                #[cfg(feature = "send-policy")]
1229                self.push_unreliable(frame);
1230                #[cfg(not(feature = "send-policy"))]
1231                self.packets.push_back(frame);
1232            }
1233            Reliability::Reliable => {
1234                if buf.len() > max_payload {
1235                    return Err(RaknetError::PacketSizeExceedMTU);
1236                }
1237
1238                let mut frame = FrameSetPacket::from_payload(
1239                    reliability,
1240                    owned.map_or_else(
1241                        || FramePayload::copy_shared(buf),
1242                        |data| FramePayload::Bytes(data.clone()),
1243                    ),
1244                );
1245                frame.reliable_frame_index = self.reliable_frame_index;
1246                self.packets.push_back(frame);
1247                self.reliable_frame_index = sequence::next(self.reliable_frame_index);
1248            }
1249            Reliability::ReliableOrdered => {
1250                if buf.len() <= max_payload {
1251                    let mut frame = FrameSetPacket::from_payload(
1252                        reliability,
1253                        owned.map_or_else(
1254                            || FramePayload::copy_shared(buf),
1255                            |data| FramePayload::Bytes(data.clone()),
1256                        ),
1257                    );
1258                    frame.order_channel = order_channel;
1259                    frame.reliable_frame_index = self.reliable_frame_index;
1260                    frame.ordered_frame_index = *self.ordered_frame_indexes.get_mut(order_channel);
1261                    self.packets.push_back(frame);
1262                    self.reliable_frame_index = sequence::next(self.reliable_frame_index);
1263                } else {
1264                    let compound_size = buf.len().div_ceil(max_payload);
1265                    let compound_size = u32::try_from(compound_size)
1266                        .map_err(|_| RaknetError::PacketSizeExceedMTU)?;
1267                    let ordered_frame_index = *self.ordered_frame_indexes.get_mut(order_channel);
1268
1269                    let data: Option<Arc<[u8]>> = owned.is_none().then(|| Arc::from(buf));
1270                    let shared_payload = Arc::new(SharedPayload {
1271                        remaining: AtomicUsize::new(compound_size as usize),
1272                        bytes: buf.len(),
1273                    });
1274                    for (fragment_index, chunk) in buf.chunks(max_payload).enumerate() {
1275                        let start = fragment_index * max_payload;
1276                        let mut frame = FrameSetPacket::from_payload(
1277                            reliability,
1278                            match owned {
1279                                Some(data) => {
1280                                    FramePayload::Bytes(data.slice(start..start + chunk.len()))
1281                                }
1282                                None => FramePayload::Shared {
1283                                    owner: data.as_ref().unwrap().clone(),
1284                                    start: start as u32,
1285                                    length: chunk.len() as u16,
1286                                },
1287                            },
1288                        );
1289                        frame.shared_payload = Some(shared_payload.clone());
1290                        frame.flags |= 16;
1291                        frame.compound_size = compound_size;
1292                        frame.compound_id = self.compound_id;
1293                        frame.fragment_index = fragment_index as u32;
1294                        frame.order_channel = order_channel;
1295                        frame.reliable_frame_index = self.reliable_frame_index;
1296                        frame.ordered_frame_index = ordered_frame_index;
1297                        self.packets.push_back(frame);
1298                        self.reliable_frame_index = sequence::next(self.reliable_frame_index);
1299                    }
1300                    self.compound_id = self.compound_id.wrapping_add(1);
1301                }
1302                let index = self.ordered_frame_indexes.get_mut(order_channel);
1303                *index = sequence::next(*index);
1304            }
1305            Reliability::ReliableSequenced => {
1306                if buf.len() > max_payload {
1307                    return Err(RaknetError::PacketSizeExceedMTU);
1308                }
1309
1310                let sequenced_frame_index = {
1311                    let index = self.sequenced_frame_indexes.get_mut(order_channel);
1312                    let current = *index;
1313                    *index = sequence::next(*index);
1314                    current
1315                };
1316                let ordered_frame_index = self.ordered_frame_indexes.get(order_channel);
1317                let mut frame = FrameSetPacket::from_payload(
1318                    reliability,
1319                    owned.map_or_else(
1320                        || FramePayload::copy_shared(buf),
1321                        |data| FramePayload::Bytes(data.clone()),
1322                    ),
1323                );
1324                frame.order_channel = order_channel;
1325                frame.reliable_frame_index = self.reliable_frame_index;
1326                frame.sequenced_frame_index = sequenced_frame_index;
1327                frame.ordered_frame_index = ordered_frame_index;
1328                self.packets.push_back(frame);
1329                self.reliable_frame_index = sequence::next(self.reliable_frame_index);
1330            }
1331        };
1332        self.buffered_bytes += reserved;
1333        #[cfg(not(feature = "send-policy"))]
1334        if matches!(
1335            reliability,
1336            Reliability::Unreliable | Reliability::UnreliableSequenced
1337        ) {
1338            self.queued_unreliable += 1;
1339        }
1340        Ok(())
1341    }
1342
1343    fn update_rto(&mut self, rtt: i64) {
1344        let previous = self.rto;
1345        (self.srtt, self.rto) = Self::latency_sample(self.srtt, rtt);
1346        if self.rto != previous {
1347            self.next_retry = 0;
1348        }
1349    }
1350
1351    fn latency_sample(srtt: i64, rtt: i64) -> (i64, i64) {
1352        let srtt = (srtt * 4 + rtt) / 5;
1353        (
1354            srtt,
1355            (srtt * 3 / 2).clamp(Self::RTO_LBOUND, Self::RTO_UBOUND),
1356        )
1357    }
1358
1359    pub(crate) fn mtu(&self) -> u16 {
1360        self.mtu
1361    }
1362
1363    pub fn get_rto(&self) -> i64 {
1364        self.rto
1365    }
1366
1367    pub fn nack(&mut self, sequence: u32, tick: i64) {
1368        for i in 0..self.sent_packet.len() {
1369            let item = &mut self.sent_packet[i];
1370            if item.1 && item.0.sequence_number == sequence {
1371                // Preserve ordinary pacing once this connection has observed
1372                // loss, including feedback received before batching is enabled.
1373                self.coalescing_allowed = false;
1374                self.coalesce = false;
1375                raknet_log_debug!(
1376                    "packet {}-{}-{} nack {} times",
1377                    item.0.sequence_number,
1378                    item.0.reliable_frame_index,
1379                    item.0.ordered_frame_index,
1380                    item.3 + 1
1381                );
1382                let previous = item.0.sequence_number;
1383                self.flight_order_dirty = true;
1384                item.0.sequence_number = self.sequence_number;
1385                self.sequence_number = sequence::next(self.sequence_number);
1386                item.1 = false;
1387                self.retries_pending = true;
1388                item.2 = tick;
1389
1390                if item.4.len() == 64 {
1391                    item.4.remove(0);
1392                }
1393                item.4.push(previous);
1394            }
1395        }
1396    }
1397
1398    pub fn ack(&mut self, sequence: u32, tick: i64) {
1399        if self.grouped_acks && self.sent_packet.len() > 1 {
1400            self.ack_ranges(&[(sequence, sequence)], tick);
1401            return;
1402        }
1403        // Ignore ACKs outside the actual send history before advancing any state.
1404        let Some(index) = self
1405            .sent_packet
1406            .iter()
1407            .position(|item| item.0.sequence_number == sequence || item.4.contains(&sequence))
1408        else {
1409            return;
1410        };
1411        let item = self.sent_packet.remove(index);
1412        #[cfg(feature = "recovery-policy")]
1413        self.acknowledge_progress(tick, item.3 == 0 && item.4.is_empty());
1414        if self.grouped_acks && self.sent_packet.is_empty() {
1415            self.grouped_acks = false;
1416        }
1417        let released_payload = match &item.0.shared_payload {
1418            Some(payload) if payload.remaining.fetch_sub(1, Ordering::Relaxed) == 1 => {
1419                payload.bytes
1420            }
1421            Some(_) => 0,
1422            None => item.0.data.len(),
1423        };
1424        self.buffered_bytes -= released_payload + Self::FRAME_BUDGET;
1425        if sequence::newer(sequence, self.ack_sequence_number) {
1426            let span = sequence::distance(sequence, self.ack_sequence_number);
1427            let missing: Vec<_> = self
1428                .sent_packet
1429                .iter()
1430                .filter_map(|item| {
1431                    let distance =
1432                        sequence::distance(item.0.sequence_number, self.ack_sequence_number);
1433                    (distance > 0 && distance < span).then_some(item.0.sequence_number)
1434                })
1435                .collect();
1436            for id in missing {
1437                self.nack(id, tick);
1438            }
1439            self.ack_sequence_number = sequence;
1440        }
1441        // A retransmitted frame has an ambiguous RTT sample (Karn's algorithm).
1442        let unambiguous = item.3 == 0;
1443        #[cfg(feature = "recovery-policy")]
1444        let unambiguous = unambiguous && item.4.is_empty();
1445        if unambiguous {
1446            self.update_rto(tick.saturating_sub(item.2).max(0));
1447        }
1448    }
1449
1450    #[inline]
1451    pub fn ack_ranges(&mut self, ranges: &[(u32, u32)], tick: i64) {
1452        if self.grouped_acks {
1453            self.ack_ranges_inner::<true>(ranges, tick);
1454        } else {
1455            self.ack_ranges_inner::<false>(ranges, tick);
1456        }
1457    }
1458
1459    fn ack_ranges_inner<const GROUPED: bool>(&mut self, ranges: &[(u32, u32)], tick: i64) {
1460        if let [(start, end)] = ranges {
1461            if start == end && (!GROUPED || self.sent_packet.len() <= 1) {
1462                self.ack(*start, tick);
1463                return;
1464            }
1465        }
1466        // Compact the bounded flight window once. Removing each acknowledged
1467        // frame separately repeatedly shifts the remaining frame metadata.
1468        let previous = self.ack_sequence_number;
1469        let mut newest = previous;
1470        let mut latency = (self.srtt, self.rto);
1471        let mut released_bytes = 0;
1472        let mut previous_sample = None;
1473        #[cfg(feature = "recovery-policy")]
1474        let mut sampled_rtt = false;
1475        self.sent_packet.retain_mut(|item| {
1476            let acknowledged_id = std::iter::once(item.0.sequence_number)
1477                .chain(item.4.iter().copied())
1478                .find(|id| {
1479                    ranges
1480                        .iter()
1481                        .any(|&(start, end)| start <= *id && *id <= end)
1482                });
1483            let Some(id) = acknowledged_id else {
1484                return true;
1485            };
1486            let payload_bytes = match &item.0.shared_payload {
1487                Some(payload) if payload.remaining.fetch_sub(1, Ordering::Relaxed) == 1 => {
1488                    payload.bytes
1489                }
1490                Some(_) => 0,
1491                None => item.0.data.len(),
1492            };
1493            released_bytes += payload_bytes + Self::FRAME_BUDGET;
1494            if sequence::newer(id, newest) {
1495                newest = id;
1496            }
1497            // Initial members of a frame set are contiguous. Retransmitted
1498            // frames never contribute RTT samples (Karn's algorithm).
1499            let unambiguous = item.3 == 0;
1500            #[cfg(feature = "recovery-policy")]
1501            let unambiguous = unambiguous && item.4.is_empty();
1502            if unambiguous && (!GROUPED || previous_sample != Some(id)) {
1503                if GROUPED {
1504                    previous_sample = Some(id);
1505                }
1506                #[cfg(feature = "recovery-policy")]
1507                {
1508                    sampled_rtt = true;
1509                }
1510                latency = Self::latency_sample(latency.0, tick.saturating_sub(item.2).max(0));
1511            }
1512            false
1513        });
1514        self.buffered_bytes -= released_bytes;
1515        #[cfg(feature = "recovery-policy")]
1516        if released_bytes != 0 {
1517            self.acknowledge_progress(tick, sampled_rtt);
1518        }
1519        if GROUPED && self.sent_packet.is_empty() {
1520            self.grouped_acks = false;
1521        }
1522
1523        if self.rto != latency.1 {
1524            self.next_retry = 0;
1525        }
1526        (self.srtt, self.rto) = latency;
1527        if newest != previous {
1528            let span = sequence::distance(newest, previous);
1529            let missing: Vec<_> = self
1530                .sent_packet
1531                .iter()
1532                .filter_map(|item| {
1533                    let distance = sequence::distance(item.0.sequence_number, previous);
1534                    (distance > 0 && distance < span).then_some(item.0.sequence_number)
1535                })
1536                .collect();
1537            for id in missing {
1538                self.nack(id, tick);
1539            }
1540            self.ack_sequence_number = newest;
1541        }
1542    }
1543
1544    pub fn nack_ranges(&mut self, ranges: &[(u32, u32)], tick: i64) {
1545        if let [(start, end)] = ranges {
1546            if start == end {
1547                self.nack(*start, tick);
1548                return;
1549            }
1550        }
1551        let missing: Vec<_> = self
1552            .sent_packet
1553            .iter()
1554            .filter_map(|item| {
1555                let id = item.0.sequence_number;
1556                ranges
1557                    .iter()
1558                    .any(|&(start, end)| start <= id && id <= end)
1559                    .then_some(id)
1560            })
1561            .collect();
1562        for id in missing {
1563            self.nack(id, tick);
1564        }
1565    }
1566
1567    fn retry_timeout(rto: i64, retries: u32) -> i64 {
1568        let mut timeout = rto;
1569        for _ in 0..retries.min(32) {
1570            timeout = ((timeout as f64 * 1.5) as i64).min(Self::RTO_UBOUND);
1571        }
1572        timeout
1573    }
1574
1575    fn tick(&mut self, tick: i64) {
1576        #[cfg(feature = "recovery-policy")]
1577        if self.recovery.is_some() {
1578            self.probe_tail(tick);
1579        }
1580        #[cfg(feature = "recovery-policy")]
1581        let probe = self.active_probe();
1582        #[cfg(feature = "recovery-policy")]
1583        let retry = self.next_retry.min(probe.map_or(i64::MAX, |p| p.deadline));
1584        #[cfg(not(feature = "recovery-policy"))]
1585        let retry = self.next_retry;
1586        if tick < retry {
1587            return;
1588        }
1589        self.next_retry = i64::MAX;
1590        for i in 0..self.sent_packet.len() {
1591            let p = &mut self.sent_packet[i];
1592
1593            let cur_rto = Self::retry_timeout(self.rto, p.3);
1594
1595            let expired = tick - p.2 >= cur_rto;
1596            #[cfg(feature = "recovery-policy")]
1597            let expired = expired
1598                || probe.is_some_and(|probe| {
1599                    probe.sequence == p.0.sequence_number && tick >= probe.deadline
1600                });
1601            if p.1 && expired {
1602                self.coalescing_allowed = false;
1603                self.coalesce = false;
1604                let previous = p.0.sequence_number;
1605                self.flight_order_dirty = true;
1606                p.0.sequence_number = self.sequence_number;
1607                self.sequence_number = sequence::next(self.sequence_number);
1608                p.1 = false;
1609                self.retries_pending = true;
1610                if p.4.len() == 64 {
1611                    p.4.remove(0);
1612                }
1613                p.4.push(previous);
1614            } else if p.1 {
1615                self.next_retry = self.next_retry.min(p.2.saturating_add(cur_rto));
1616            }
1617        }
1618        #[cfg(feature = "recovery-policy")]
1619        if probe.is_some_and(|probe| tick >= probe.deadline) {
1620            self.recovery.as_mut().unwrap().pending_probe = None;
1621        }
1622    }
1623
1624    pub fn flush(&mut self, tick: i64, peer_addr: &SocketAddr) -> OutgoingFrames {
1625        #[cfg(feature = "recovery-policy")]
1626        if self.sent_packet.is_empty() {
1627            // A retired flight must not leave an obsolete deadline on the next one.
1628            self.next_retry = i64::MAX;
1629            if self
1630                .recovery
1631                .as_ref()
1632                .is_some_and(|r| r.options == crate::RecoveryOptions::default())
1633            {
1634                self.recovery = None;
1635            }
1636            if let Some(recovery) = &mut self.recovery {
1637                recovery.last_progress = tick;
1638                recovery.probed = false;
1639                recovery.pending_probe = None;
1640                recovery.probe_replay = None;
1641            }
1642        }
1643        #[cfg(feature = "send-policy")]
1644        if self
1645            .scheduler
1646            .as_ref()
1647            .is_some_and(|s| !s.use_legacy || !s.unreliable.is_empty())
1648        {
1649            return self.flush_scheduled(tick);
1650        }
1651        self.tick(tick);
1652
1653        // Reserve queued batches once; a full reliable flight window reserves
1654        // nothing. The compact vector keeps async frame transfers cheap.
1655        let capacity = self.packets.len().min(
1656            Self::MAX_IN_FLIGHT_PACKETS.saturating_sub(self.sent_packet.len())
1657                + self.queued_unreliable,
1658        );
1659        let mut ret = OutgoingFrames::with_capacity(capacity);
1660        #[cfg(feature = "recovery-policy")]
1661        {
1662            ret.coalesced = self.take_probe_packing();
1663        }
1664        // New sends preserve numeric order until the 24-bit sequence wraps.
1665        // ACK removal preserves it too; only resequencing requires sorting.
1666        if self.flight_order_dirty {
1667            self.sent_packet
1668                .sort_unstable_by_key(|packet| packet.0.sequence_number);
1669            self.flight_order_dirty = false;
1670        }
1671
1672        #[cfg(feature = "recovery-policy")]
1673        let probe_sequence = self.take_probe_replay();
1674        if self.retries_pending {
1675            for packet in &mut self.sent_packet {
1676                if !packet.1 {
1677                    raknet_log_debug!(
1678                        "{} , packet {}-{}-{} resend {} times",
1679                        peer_addr,
1680                        packet.0.sequence_number,
1681                        packet.0.reliable_frame_index,
1682                        packet.0.ordered_frame_index,
1683                        packet.3 + 1
1684                    );
1685                    ret.push(packet.0.clone());
1686                    packet.1 = true;
1687                    packet.2 = tick;
1688                    #[cfg(feature = "recovery-policy")]
1689                    if probe_sequence != Some(packet.0.sequence_number) {
1690                        packet.3 = packet.3.saturating_add(1);
1691                    }
1692                    #[cfg(not(feature = "recovery-policy"))]
1693                    {
1694                        packet.3 = packet.3.saturating_add(1);
1695                    }
1696                    self.next_retry = self
1697                        .next_retry
1698                        .min(tick.saturating_add(Self::retry_timeout(self.rto, packet.3)));
1699                }
1700            }
1701            self.retries_pending = false;
1702        }
1703
1704        let mut group_sequence = None;
1705        let mut group_bytes = 0;
1706        let mut group_frames = 0;
1707        let datagram_budget = usize::from(self.mtu).saturating_sub(28);
1708        let queued_count = self.packets.len();
1709        for _ in 0..queued_count {
1710            if self.sent_packet.len() >= Self::MAX_IN_FLIGHT_PACKETS && self.queued_unreliable == 0
1711            {
1712                break;
1713            }
1714            let Some(mut packet) = self.packets.pop_front() else {
1715                break;
1716            };
1717            let reliable = packet.is_reliable().unwrap_or(false);
1718            if reliable && self.sent_packet.len() >= Self::MAX_IN_FLIGHT_PACKETS {
1719                self.packets.push_back(packet);
1720                continue;
1721            }
1722
1723            if self.coalesce {
1724                let packable = matches!(packet.reliability(), Ok(Reliability::ReliableOrdered))
1725                    && !packet.is_fragment();
1726                let frame_bytes = packet._size().expect("queued frames were validated") - 4;
1727                if packable
1728                    && group_sequence.is_some()
1729                    && group_frames < Self::MAX_COALESCED_FRAMES
1730                    && group_bytes + frame_bytes <= datagram_budget
1731                {
1732                    packet.sequence_number = group_sequence.unwrap();
1733                    group_bytes += frame_bytes;
1734                    group_frames += 1;
1735                    self.grouped_acks = true;
1736                    ret.coalesced = true;
1737                } else {
1738                    packet.sequence_number = self.sequence_number;
1739                    self.sequence_number = sequence::next(self.sequence_number);
1740                    group_sequence = packable.then_some(packet.sequence_number);
1741                    group_bytes = 4 + frame_bytes;
1742                    // Keep a 16-message application window spread across at
1743                    // least two datagrams so later packets can expose a loss.
1744                    group_frames = 1;
1745                }
1746            } else {
1747                packet.sequence_number = self.sequence_number;
1748                self.sequence_number = sequence::next(self.sequence_number);
1749            }
1750
1751            if reliable {
1752                ret.push(packet.clone());
1753                if self
1754                    .sent_packet
1755                    .last()
1756                    .is_some_and(|previous| previous.0.sequence_number > packet.sequence_number)
1757                {
1758                    self.flight_order_dirty = true;
1759                }
1760                self.sent_packet.push((packet, true, tick, 0, Vec::new()));
1761                self.next_retry = self.next_retry.min(tick.saturating_add(self.rto));
1762            } else {
1763                self.queued_unreliable -= 1;
1764                self.buffered_bytes -= packet.data.len() + Self::FRAME_BUDGET;
1765                ret.push(packet);
1766            }
1767        }
1768
1769        ret
1770    }
1771
1772    pub fn is_empty(&self) -> bool {
1773        #[cfg(feature = "send-policy")]
1774        {
1775            self.packets.is_empty()
1776                && self.sent_packet.is_empty()
1777                && self
1778                    .scheduler
1779                    .as_ref()
1780                    .is_none_or(|s| s.unreliable.is_empty())
1781        }
1782        #[cfg(not(feature = "send-policy"))]
1783        {
1784            self.packets.is_empty() && self.sent_packet.is_empty()
1785        }
1786    }
1787
1788    pub fn get_reliable_queue_size(&self) -> usize {
1789        self.packets.len()
1790    }
1791
1792    pub fn get_sent_queue_size(&self) -> usize {
1793        self.sent_packet.len()
1794    }
1795}
1796
1797#[test]
1798fn malformed_datagrams_are_rejected() {
1799    assert!(FrameVec::new(&[0x80, 0, 0]).is_err());
1800    assert!(FrameVec::new(&[0x10, 0, 0, 0]).is_err());
1801}
1802
1803#[test]
1804fn send_queue_rejects_an_invalid_mtu() {
1805    let mut send_queue = SendQ::new(59);
1806    assert!(send_queue.insert(Reliability::Reliable, &[0xfe]).is_err());
1807}
1808
1809#[cfg(feature = "send-policy")]
1810impl SendQ {
1811    /// Validate batch sizes and determine packing eligibility in one pass.
1812    /// Oversized messages still validate their fragmentation budget, but cannot
1813    /// be packed. Avoid rescanning an entire batch that will use ordinary sends.
1814    pub(crate) fn batch_can_coalesce(
1815        &self,
1816        reliability: Reliability,
1817        mut lengths: impl Iterator<Item = usize>,
1818    ) -> Result<bool> {
1819        let allowed = self.allows_coalescing() && reliability == Reliability::ReliableOrdered;
1820        if reliability == Reliability::ReliableOrdered && !allowed {
1821            self.has_batch_capacity(reliability, lengths)?;
1822            return Ok(false);
1823        }
1824        let max_payload = usize::from(self.mtu).saturating_sub(60);
1825        let datagram_budget = usize::from(self.mtu).saturating_sub(28);
1826        let mut previous = None;
1827        let mut packable = false;
1828        let required = lengths.try_fold(0usize, |total, length| {
1829            if reliability != Reliability::ReliableOrdered && length > max_payload {
1830                return Err(RaknetError::PacketSizeExceedMTU);
1831            }
1832            if allowed && !packable && length <= max_payload {
1833                packable = previous.is_some_and(|last: usize| {
1834                    last <= max_payload
1835                        && last.saturating_add(length).saturating_add(24) <= datagram_budget
1836                });
1837            }
1838            previous = Some(length);
1839            total
1840                .checked_add(self.required_bytes(reliability, length)?)
1841                .filter(|&bytes| bytes <= Self::MAX_BUFFERED_BYTES)
1842                .ok_or(RaknetError::PacketSizeExceedMTU)
1843        })?;
1844        self.has_batch_required_capacity(reliability, required)?;
1845        Ok(allowed && packable)
1846    }
1847
1848    fn has_batch_required_capacity(
1849        &self,
1850        reliability: Reliability,
1851        required: usize,
1852    ) -> Result<bool> {
1853        // Unreliable batches use the streaming path. Their aggregate may
1854        // exceed the pending reserve even though every member fits and drains.
1855        if matches!(
1856            reliability,
1857            Reliability::Unreliable | Reliability::UnreliableSequenced
1858        ) && self
1859            .send_options()
1860            .is_some_and(|options| required > options.unreliable_queue_bytes)
1861        {
1862            return Ok(false);
1863        }
1864        self.has_reserved_capacity(reliability, required)
1865    }
1866
1867    fn ensure_scheduler(&mut self) -> &mut SendScheduler {
1868        if self.scheduler.is_none() {
1869            let mut unreliable = VecDeque::with_capacity(self.queued_unreliable);
1870            let mut unreliable_bytes = 0;
1871            for _ in 0..self.packets.len() {
1872                let frame = self.packets.pop_front().unwrap();
1873                if frame.is_reliable().unwrap_or(false) {
1874                    self.packets.push_back(frame);
1875                } else {
1876                    unreliable_bytes += frame.data.len() + Self::FRAME_BUDGET;
1877                    unreliable.push_back(frame);
1878                }
1879            }
1880            self.queued_unreliable = 0;
1881            self.scheduler = Some(Box::new(SendScheduler {
1882                capacity_notifier: std::sync::Weak::new(),
1883                options: crate::SendOptions::default(),
1884                unreliable,
1885                unreliable_bytes,
1886                use_legacy: usize::from(self.mtu) * Self::MAX_IN_FLIGHT_PACKETS
1887                    <= crate::SendOptions::default().flush_bytes,
1888                persistent: true,
1889                next_lane: 2,
1890            }));
1891        }
1892        self.scheduler.as_mut().unwrap()
1893    }
1894
1895    fn push_unreliable(&mut self, mut frame: FrameSetPacket) {
1896        if let Some(scheduler) = &mut self.scheduler {
1897            scheduler.unreliable_bytes += frame.data.len() + Self::FRAME_BUDGET;
1898            scheduler.unreliable.push_back(frame);
1899        } else {
1900            frame.sequence_number = self.sequence_number;
1901            self.sequence_number = sequence::next(self.sequence_number);
1902            self.queued_unreliable += 1;
1903            self.packets.push_back(frame);
1904        }
1905    }
1906
1907    /// Bind queue-release notifications only after a policy is enabled.
1908    pub(crate) fn register_capacity_notifier(&mut self, notifier: &Arc<tokio::sync::Notify>) {
1909        let Some(scheduler) = &mut self.scheduler else {
1910            return;
1911        };
1912        if !std::ptr::eq(scheduler.capacity_notifier.as_ptr(), Arc::as_ptr(notifier)) {
1913            scheduler.capacity_notifier = Arc::downgrade(notifier);
1914        }
1915    }
1916
1917    pub(crate) fn set_send_options(&mut self, options: crate::SendOptions) -> Result<()> {
1918        let mtu = usize::from(self.mtu);
1919        if options.in_flight_bytes < mtu
1920            || options.flush_bytes < mtu
1921            || options.unreliable_queue_bytes < mtu
1922        {
1923            return Err(RaknetError::PacketSizeExceedMTU);
1924        }
1925        let scheduler = self.ensure_scheduler();
1926        scheduler.options = options;
1927        scheduler.persistent = true;
1928        let defaults = crate::SendOptions::default();
1929        scheduler.use_legacy = options.in_flight_frames == defaults.in_flight_frames
1930            && options.in_flight_bytes == defaults.in_flight_bytes
1931            && options.flush_bytes == defaults.flush_bytes
1932            && mtu * Self::MAX_IN_FLIGHT_PACKETS <= options.flush_bytes;
1933        Ok(())
1934    }
1935
1936    pub(crate) fn send_options(&self) -> Option<crate::SendOptions> {
1937        self.scheduler.as_ref().map(|s| s.options)
1938    }
1939
1940    #[inline]
1941    fn has_reserved_capacity(&self, reliability: Reliability, required: usize) -> Result<bool> {
1942        if self.scheduler.is_none() {
1943            return Ok(
1944                self.buffered_bytes.saturating_add(required) <= Self::SEND_HIGH_WATER.max(required)
1945            );
1946        }
1947        let unreliable = matches!(
1948            reliability,
1949            Reliability::Unreliable | Reliability::UnreliableSequenced
1950        );
1951        if !unreliable {
1952            // The common reliable-only case needs neither the full options
1953            // copy nor reservation arithmetic. Valid budgets leave room for
1954            // the unreliable reserve, including when no unreliable data waits.
1955            let budget = match &self.scheduler {
1956                None if required <= Self::MAX_BUFFERED_BYTES - 64 * 1024 => {
1957                    Some(Self::SEND_HIGH_WATER.max(required))
1958                }
1959                None => None,
1960                Some(s)
1961                    if s.unreliable_bytes == 0 && required <= s.options.reliable_queue_bytes =>
1962                {
1963                    Some(s.options.reliable_queue_bytes)
1964                }
1965                Some(_) => None,
1966            };
1967            if let Some(budget) = budget {
1968                return Ok(self.buffered_bytes.saturating_add(required) <= budget);
1969            }
1970        }
1971        let options = self.send_options().unwrap();
1972        let used_unreliable = self.scheduler.as_ref().map_or(0, |s| s.unreliable_bytes);
1973        let (used, limit) = if unreliable {
1974            if required > options.unreliable_queue_bytes {
1975                return Err(RaknetError::PacketSizeExceedMTU);
1976            }
1977            (used_unreliable, options.unreliable_queue_bytes)
1978        } else {
1979            let hard_limit = Self::MAX_BUFFERED_BYTES - options.unreliable_queue_bytes;
1980            if required > hard_limit {
1981                return Err(RaknetError::PacketSizeExceedMTU);
1982            }
1983            (
1984                self.buffered_bytes - used_unreliable,
1985                options.reliable_queue_bytes.max(required).min(hard_limit),
1986            )
1987        };
1988        Ok(used.saturating_add(required) <= limit
1989            && self.buffered_bytes.saturating_add(required) <= Self::MAX_BUFFERED_BYTES)
1990    }
1991
1992    fn flush_scheduled(&mut self, tick: i64) -> OutgoingFrames {
1993        self.tick(tick);
1994        if self.flight_order_dirty {
1995            self.sent_packet
1996                .sort_unstable_by_key(|packet| packet.0.sequence_number);
1997            self.flight_order_dirty = false;
1998        }
1999        // Taking the sidecar keeps the frame queues and connection indexes under
2000        // one mutable owner. Unconfigured sockets never allocate this state.
2001        let mut scheduler = self.scheduler.take().unwrap();
2002        let options = scheduler.options;
2003        // Compute only in configured scheduling. ACK handling remains the
2004        // original path with no per-frame policy or byte-ledger checks.
2005        let mut flight_bytes: usize = self.sent_packet.iter().map(|p| p.0._size().unwrap()).sum();
2006        let capacity = self.packets.len().min(
2007            options
2008                .in_flight_frames
2009                .saturating_sub(self.sent_packet.len()),
2010        ) + scheduler.unreliable.len();
2011        let mut output = OutgoingFrames::with_capacity(capacity.min(256));
2012        #[cfg(feature = "recovery-policy")]
2013        {
2014            output.coalesced = self.take_probe_packing();
2015        }
2016        let quantum = usize::from(self.mtu) * 4;
2017        let mut bytes = 0;
2018        let mut unreliable_drained = false;
2019        #[cfg(feature = "recovery-policy")]
2020        let probe_sequence = self.take_probe_replay();
2021        let mut retry_cursor = 0;
2022        let mut group_sequence = None;
2023        let mut group_bytes = 0;
2024        let mut group_frames = 0;
2025        let datagram_budget = usize::from(self.mtu).saturating_sub(28);
2026        'rounds: loop {
2027            let mut progressed = false;
2028            let start = scheduler.next_lane;
2029            for offset in 0..3 {
2030                let lane = (start + offset) % 3;
2031                let mut lane_bytes = 0;
2032                while lane_bytes < quantum {
2033                    let charge = match lane {
2034                        0 => scheduler
2035                            .unreliable
2036                            .front()
2037                            .map(|frame| frame._size().unwrap()),
2038                        1 => {
2039                            if !self.retries_pending {
2040                                break;
2041                            }
2042                            while retry_cursor < self.sent_packet.len()
2043                                && self.sent_packet[retry_cursor].1
2044                            {
2045                                retry_cursor += 1;
2046                            }
2047                            self.sent_packet
2048                                .get(retry_cursor)
2049                                .map(|item| item.0._size().unwrap())
2050                        }
2051                        _ => self.packets.front().and_then(|frame| {
2052                            let size = frame._size().unwrap();
2053                            (self.sent_packet.len() < options.in_flight_frames
2054                                && flight_bytes + size <= options.in_flight_bytes)
2055                                .then_some(size)
2056                        }),
2057                    };
2058                    let Some(charge) = charge else {
2059                        break;
2060                    };
2061                    // Skip a class that cannot fit the remaining burst; smaller
2062                    // realtime messages in another class can still make progress.
2063                    if bytes + charge > options.flush_bytes {
2064                        break;
2065                    }
2066                    match lane {
2067                        0 => {
2068                            let mut packet = scheduler.unreliable.pop_front().unwrap();
2069                            packet.sequence_number = self.sequence_number;
2070                            self.sequence_number = sequence::next(self.sequence_number);
2071                            let reserved = packet.data.len() + Self::FRAME_BUDGET;
2072                            self.buffered_bytes -= reserved;
2073                            scheduler.unreliable_bytes -= reserved;
2074                            unreliable_drained = true;
2075                            output.push(packet);
2076                            group_sequence = None;
2077                        }
2078                        1 => {
2079                            let item = &mut self.sent_packet[retry_cursor];
2080                            output.push(item.0.clone());
2081                            item.1 = true;
2082                            item.2 = tick;
2083                            #[cfg(feature = "recovery-policy")]
2084                            if probe_sequence != Some(item.0.sequence_number) {
2085                                item.3 = item.3.saturating_add(1);
2086                            }
2087                            #[cfg(not(feature = "recovery-policy"))]
2088                            {
2089                                item.3 = item.3.saturating_add(1);
2090                            }
2091                            self.next_retry = self
2092                                .next_retry
2093                                .min(tick.saturating_add(Self::retry_timeout(self.rto, item.3)));
2094                            retry_cursor += 1;
2095                            group_sequence = None;
2096                        }
2097                        _ => {
2098                            let mut packet = self.packets.pop_front().unwrap();
2099                            let packable = self.coalesce
2100                                && matches!(packet.reliability(), Ok(Reliability::ReliableOrdered))
2101                                && !packet.is_fragment();
2102                            let frame_bytes = charge - 4;
2103                            if packable
2104                                && group_sequence.is_some()
2105                                && group_frames < Self::MAX_COALESCED_FRAMES
2106                                && group_bytes + frame_bytes <= datagram_budget
2107                            {
2108                                packet.sequence_number = group_sequence.unwrap();
2109                                group_bytes += frame_bytes;
2110                                group_frames += 1;
2111                                self.grouped_acks = true;
2112                                output.coalesced = true;
2113                            } else {
2114                                packet.sequence_number = self.sequence_number;
2115                                self.sequence_number = sequence::next(self.sequence_number);
2116                                group_sequence = packable.then_some(packet.sequence_number);
2117                                group_bytes = charge;
2118                                group_frames = 1;
2119                            }
2120                            output.push(packet.clone());
2121                            if self
2122                                .sent_packet
2123                                .last()
2124                                .is_some_and(|p| p.0.sequence_number > packet.sequence_number)
2125                            {
2126                                self.flight_order_dirty = true;
2127                            }
2128                            self.sent_packet.push((packet, true, tick, 0, Vec::new()));
2129                            flight_bytes += charge;
2130                            self.next_retry = self.next_retry.min(tick.saturating_add(self.rto));
2131                        }
2132                    }
2133                    progressed = true;
2134                    bytes += charge;
2135                    lane_bytes += charge;
2136                    scheduler.next_lane = (lane + 1) % 3;
2137                    if bytes == options.flush_bytes {
2138                        break 'rounds;
2139                    }
2140                }
2141            }
2142            if !progressed {
2143                break;
2144            }
2145        }
2146        self.retries_pending = self.sent_packet.iter().any(|item| !item.1);
2147        if unreliable_drained {
2148            if let Some(capacity) = scheduler.capacity_notifier.upgrade() {
2149                capacity.notify_waiters();
2150            }
2151        }
2152        if scheduler.persistent || !scheduler.use_legacy || !scheduler.unreliable.is_empty() {
2153            self.scheduler = Some(scheduler);
2154        }
2155        output
2156    }
2157}
2158
2159#[tokio::test]
2160async fn test_recvq_orders_channels_independently() {
2161    let mut recvq = RecvQ::new();
2162
2163    let mut later_on_channel_one = FrameSetPacket::new(Reliability::ReliableOrdered, vec![1]);
2164    later_on_channel_one.sequence_number = 0;
2165    later_on_channel_one.order_channel = 1;
2166    later_on_channel_one.ordered_frame_index = 1;
2167    recvq.insert(later_on_channel_one).unwrap();
2168
2169    let mut first_on_channel_two = FrameSetPacket::new(Reliability::ReliableOrdered, vec![2]);
2170    first_on_channel_two.sequence_number = 1;
2171    first_on_channel_two.reliable_frame_index = 1;
2172    first_on_channel_two.order_channel = 2;
2173    first_on_channel_two.ordered_frame_index = 0;
2174    recvq.insert(first_on_channel_two).unwrap();
2175
2176    let ready = recvq.flush(&"127.0.0.1:0".parse().unwrap());
2177    assert_eq!(ready.len(), 1);
2178    assert_eq!(ready[0].order_channel, 2);
2179
2180    let mut first_on_channel_one = FrameSetPacket::new(Reliability::ReliableOrdered, vec![0]);
2181    first_on_channel_one.sequence_number = 2;
2182    first_on_channel_one.reliable_frame_index = 2;
2183    first_on_channel_one.order_channel = 1;
2184    first_on_channel_one.ordered_frame_index = 0;
2185    recvq.insert(first_on_channel_one).unwrap();
2186
2187    let ready = recvq.flush(&"127.0.0.1:0".parse().unwrap());
2188    assert_eq!(ready.len(), 2);
2189    assert_eq!(ready[0].ordered_frame_index, 0);
2190    assert_eq!(ready[1].ordered_frame_index, 1);
2191    assert!(ready.iter().all(|frame| frame.order_channel == 1));
2192}
2193
2194#[tokio::test]
2195async fn test_sendq_maintains_ordered_indexes_per_channel() {
2196    let mut sendq = SendQ::new(1500);
2197    sendq
2198        .insert_with_order_channel(Reliability::ReliableOrdered, &[0xfe, 1], 3)
2199        .unwrap();
2200    sendq
2201        .insert_with_order_channel(Reliability::ReliableOrdered, &[0xfe, 2], 9)
2202        .unwrap();
2203
2204    let sent = sendq.flush(0, &"127.0.0.1:0".parse().unwrap());
2205    assert_eq!(sent.len(), 2);
2206    assert_eq!(sent[0].order_channel, 3);
2207    assert_eq!(sent[0].ordered_frame_index, 0);
2208    assert_eq!(sent[1].order_channel, 9);
2209    assert_eq!(sent[1].ordered_frame_index, 0);
2210}
2211
2212#[tokio::test]
2213async fn test_ackset() {
2214    let mut ackset = ACKSet::default();
2215
2216    ackset.insert(0);
2217    ackset.insert(1);
2218    ackset.insert(2);
2219    ackset.insert(4);
2220
2221    let acks = ackset.get_ack();
2222
2223    assert!(acks == vec![(0, 2), (4, 4)]);
2224
2225    let mut ackset = ACKSet::default();
2226
2227    ackset.insert(0);
2228    ackset.insert(1);
2229    ackset.insert(2);
2230    ackset.insert(6);
2231
2232    let acks = ackset.get_ack();
2233
2234    assert!(acks == vec![(0, 2), (6, 6)]);
2235
2236    let acks = ackset.get_ack();
2237
2238    assert!(acks == vec![]);
2239
2240    ackset.insert(0);
2241    ackset.insert(2);
2242
2243    let acks = ackset.get_ack();
2244
2245    assert!(acks == vec![(0, 0), (2, 2)]);
2246}
2247
2248#[tokio::test]
2249async fn test_frame_serialize_deserialize() {
2250    // Captured first frame datagram from a Bedrock 1.18.12 client.
2251    let p: Vec<u8> = [
2252        132, 0, 0, 0, 64, 0, 144, 0, 0, 0, 9, 146, 33, 7, 47, 57, 18, 128, 111, 0, 0, 0, 0, 20,
2253        200, 47, 41, 0,
2254    ]
2255    .to_vec();
2256
2257    let a = FrameSetPacket::deserialize(&p).unwrap();
2258    assert!(a.0.serialize().unwrap() == p);
2259}
2260
2261#[tokio::test]
2262async fn test_recvq() {
2263    let mut r = RecvQ::new();
2264    let mut p = FrameSetPacket::new(Reliability::Reliable, vec![]);
2265    p.sequence_number = 0;
2266    p.ordered_frame_index = 0;
2267    r.insert(p).unwrap();
2268
2269    let mut p = FrameSetPacket::new(Reliability::Reliable, vec![]);
2270    p.sequence_number = 1;
2271    p.reliable_frame_index = 1;
2272    p.ordered_frame_index = 1;
2273    r.insert(p).unwrap();
2274
2275    let ret = r.flush(&"0.0.0.0:0".parse().unwrap());
2276    assert!(ret.len() == 2);
2277}
2278
2279#[tokio::test]
2280async fn test_recvq_fragment() {
2281    let mut r = RecvQ::new();
2282    let mut p = FrameSetPacket::new(Reliability::ReliableOrdered, vec![1]);
2283    p.flags |= 16;
2284    p.sequence_number = 0;
2285    p.ordered_frame_index = 0;
2286    p.compound_id = 1;
2287    p.compound_size = 3;
2288    p.fragment_index = 0;
2289    p.order_channel = 7;
2290    r.insert(p).unwrap();
2291
2292    let mut p = FrameSetPacket::new(Reliability::ReliableOrdered, vec![2]);
2293    p.flags |= 16;
2294    p.sequence_number = 1;
2295    p.reliable_frame_index = 1;
2296    p.ordered_frame_index = 0;
2297    p.compound_id = 1;
2298    p.compound_size = 3;
2299    p.fragment_index = 1;
2300    p.order_channel = 7;
2301    r.insert(p).unwrap();
2302
2303    let mut p = FrameSetPacket::new(Reliability::ReliableOrdered, vec![3]);
2304    p.flags |= 16;
2305    p.sequence_number = 2;
2306    p.reliable_frame_index = 2;
2307    p.ordered_frame_index = 0;
2308    p.compound_id = 1;
2309    p.compound_size = 3;
2310    p.fragment_index = 2;
2311    p.order_channel = 7;
2312    r.insert(p).unwrap();
2313
2314    let ret = r.flush(&"0.0.0.0:0".parse().unwrap());
2315    assert!(ret.len() == 1);
2316    assert_eq!(ret[0].data.as_ref(), &[1, 2, 3]);
2317    assert_eq!(ret[0].order_channel, 7);
2318}
2319
2320#[tokio::test]
2321async fn test_sendq() {
2322    let mut s = SendQ::new(1500);
2323    let p = FrameSetPacket::new(Reliability::Reliable, vec![]);
2324    s.insert(Reliability::Reliable, &p.serialize().unwrap())
2325        .unwrap();
2326
2327    let p = FrameSetPacket::new(Reliability::Reliable, vec![]);
2328    s.insert(Reliability::Reliable, &p.serialize().unwrap())
2329        .unwrap();
2330
2331    let sockaddr: SocketAddr = "127.0.0.1:8000".parse().unwrap();
2332    let ret = s.flush(0, &sockaddr);
2333    assert!(ret.len() == 2);
2334
2335    s.ack(0, 0);
2336    s.ack(1, 0);
2337
2338    let ret = s.flush(300, &sockaddr);
2339    assert!(ret.is_empty());
2340}
2341
2342#[test]
2343fn send_queue_pipelines_reliable_packets_with_a_bounded_window() {
2344    let mut sendq = SendQ::new(1500);
2345    let peer = "127.0.0.1:8000".parse().unwrap();
2346
2347    for index in 0..SendQ::MAX_IN_FLIGHT_PACKETS + 1 {
2348        sendq
2349            .insert(Reliability::ReliableOrdered, &[0xfe, index as u8])
2350            .unwrap();
2351        let sent = sendq.flush(0, &peer);
2352        if index < SendQ::MAX_IN_FLIGHT_PACKETS {
2353            assert_eq!(sent.len(), 1);
2354            assert_eq!(sent[0].ordered_frame_index, index as u32);
2355        } else {
2356            assert!(sent.is_empty());
2357        }
2358    }
2359
2360    assert_eq!(sendq.get_sent_queue_size(), SendQ::MAX_IN_FLIGHT_PACKETS);
2361    assert_eq!(sendq.get_reliable_queue_size(), 1);
2362
2363    sendq.ack(0, 1);
2364    let sent = sendq.flush(1, &peer);
2365    assert_eq!(sent.len(), 1);
2366    assert_eq!(
2367        sent[0].ordered_frame_index,
2368        SendQ::MAX_IN_FLIGHT_PACKETS as u32
2369    );
2370    assert_eq!(sendq.get_sent_queue_size(), SendQ::MAX_IN_FLIGHT_PACKETS);
2371    assert_eq!(sendq.get_reliable_queue_size(), 0);
2372}
2373
2374#[test]
2375fn send_queue_retransmits_immediately_after_nack() {
2376    let mut sendq = SendQ::new(1500);
2377    let peer = "127.0.0.1:8000".parse().unwrap();
2378    sendq.insert(Reliability::Reliable, &[0xfe]).unwrap();
2379
2380    let first = sendq.flush(0, &peer);
2381    assert_eq!(first.len(), 1);
2382    assert_eq!(first[0].sequence_number, 0);
2383
2384    sendq.nack(0, 1);
2385    let retransmitted = sendq.flush(1, &peer);
2386    assert_eq!(retransmitted.len(), 1);
2387    assert_eq!(retransmitted[0].sequence_number, 1);
2388}
2389
2390#[tokio::test]
2391async fn test_client_packet1() {
2392    let a = [
2393        140, 3, 0, 0, 112, 44, 192, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 254, 236,
2394        189, 203, 114, 234, 74, 183, 239, 185, 79, 175, 170, 30, 99, 159, 110, 125, 59, 36, 1, 222,
2395        166, 122, 19, 35, 97, 48, 18, 19, 161, 11, 82, 69, 197, 23, 128, 248, 38, 32, 9, 107, 218,
2396        152, 91, 69, 61, 79, 53, 234, 141, 78, 243, 52, 234, 5, 170, 119, 90, 149, 41, 165, 48, 41,
2397        11, 12, 2, 95, 214, 154, 255, 198, 47, 86, 120, 77, 15, 75, 202, 203, 24, 57, 46, 153, 249,
2398        223, 255, 199, 127, 253, 47, 255, 246, 111, 255, 229, 255, 253, 111, 255, 227, 191, 254,
2399        63, 255, 243, 191, 253, 219, 255, 249, 239, 163, 201, 96, 58, 255, 247, 255, 237, 127, 255,
2400        247, 241, 166, 53, 25, 54, 70, 211, 206, 180, 165, 152, 91, 181, 172, 221, 53, 159, 155,
2401        243, 95, 162, 215, 107, 222, 52, 125, 177, 105, 247, 61, 165, 107, 5, 205, 158, 84, 29,
2402        244, 250, 209, 111, 85, 214, 106, 166, 21, 52, 122, 91, 93, 209, 77, 165, 222, 51, 117,
2403        215, 21, 20, 197, 109, 148, 55, 166, 220, 122, 234, 216, 101, 105, 108, 43, 157, 241, 180,
2404        218, 49, 26, 250, 189, 165, 184, 243, 129, 242, 171, 50, 170, 7, 247, 109, 241, 113, 173,
2405        221, 235, 205, 225, 60, 18, 218, 226, 196, 234, 134, 186, 57, 240, 43, 83, 43, 112, 167,
2406        150, 57, 89, 13, 75, 90, 205, 146, 244, 123, 183, 46, 111, 199, 182, 176, 214, 182, 147,
2407        141, 214, 16, 187, 227, 134, 38, 247, 234, 150, 219, 107, 84, 231, 78, 201, 17, 186, 115,
2408        189, 174, 139, 154, 51, 82, 212, 210, 192, 178, 30, 13, 49, 216, 186, 179, 218, 203, 192,
2409        143, 238, 61, 177, 37, 186, 211, 234, 147, 41, 105, 91, 87, 169, 61, 142, 239, 22, 207,
2410        170, 28, 205, 199, 117, 253, 121, 32, 107, 117, 213, 119, 166, 255, 234, 62, 254, 7, 249,
2411        238, 153, 219, 111, 9, 3, 219, 141, 28, 73, 17, 92, 83, 17, 189, 198, 100, 57, 10, 3, 97,
2412        76, 190, 221, 187, 39, 127, 167, 183, 154, 186, 253, 201, 170, 57, 35, 239, 61, 235, 150,
2413        58, 117, 103, 173, 25, 242, 186, 125, 215, 138, 220, 134, 245, 226, 53, 200, 239, 90, 53,
2414        209, 9, 215, 145, 35, 44, 130, 241, 153, 109, 214, 145, 45, 117, 32, 5, 229, 177, 185, 158,
2415        121, 210, 122, 48, 154, 7, 150, 105, 107, 162, 106, 233, 146, 41, 87, 23, 61, 163, 117,
2416        167, 149, 92, 167, 83, 215, 94, 220, 70, 165, 111, 6, 214, 196, 110, 8, 37, 237, 222, 107,
2417        184, 161, 76, 191, 243, 217, 19, 149, 142, 213, 112, 55, 134, 226, 54, 29, 163, 213, 29,
2418        218, 214, 203, 72, 246, 90, 154, 31, 61, 246, 76, 209, 234, 133, 74, 223, 158, 183, 126,
2419        15, 77, 241, 119, 199, 168, 117, 134, 194, 162, 163, 7, 90, 167, 59, 183, 218, 110, 67, 40,
2420        143, 130, 32, 178, 239, 181, 208, 233, 63, 110, 123, 91, 85, 26, 223, 221, 174, 45, 163,
2421        41, 245, 238, 107, 247, 170, 18, 149, 123, 155, 170, 173, 90, 206, 148, 124, 243, 139, 19,
2422        58, 211, 206, 76, 150, 180, 250, 72, 234, 212, 127, 73, 154, 161, 84, 239, 126, 253, 199,
2423        63, 158, 123, 119, 119, 203, 126, 120, 247, 220, 113, 55, 245, 97, 189, 212, 172, 255, 136,
2424        30, 159, 164, 122, 255, 95, 245, 141, 220, 159, 41, 149, 169, 218, 173, 174, 5, 249, 247,
2425        83, 205, 188, 185, 81, 220, 113, 251, 229, 101, 213, 249, 245, 123, 212, 248, 71, 239, 105,
2426        48, 151, 68, 103, 32, 175, 215, 63, 220, 113, 216, 169, 252, 243, 247, 211, 118, 230, 255,
2427        179, 210, 173, 173, 123, 230, 203, 63, 170, 163, 127, 12, 52, 39, 26, 247, 158, 182, 147,
2428        113, 52, 154, 4, 75, 219, 122, 168, 223, 120, 255, 152, 223, 138, 173, 135, 122, 79, 43,
2429        245, 27, 255, 254, 191, 210, 81, 92, 214, 250, 38, 29, 197, 90, 79, 9, 74, 164, 149, 221,
2430        158, 188, 88, 218, 126, 112, 51, 152, 213, 234, 93, 50, 12, 117, 255, 89, 208, 77, 171,
2431        214, 21, 2, 217, 182, 189, 154, 110, 76, 20, 163, 177, 136, 198, 247, 129, 234, 148, 188,
2432        103, 210, 74, 21, 203, 82, 102, 158, 161, 152, 94, 80, 251, 57, 52, 253, 77, 151, 244, 139,
2433        93, 255, 181, 29, 134, 250, 139, 37, 182, 44, 199, 154, 44, 180, 173, 94, 210, 67, 119,
2434        162, 217, 238, 168, 45, 173, 75, 166, 89, 49, 221, 121, 75, 181, 252, 201, 68, 13, 106, 11,
2435        215, 174, 172, 116, 193, 151, 122, 225, 164, 101, 88, 214, 131, 99, 121, 131, 81, 24, 45,
2436        12, 251, 177, 162, 202, 149, 101, 79, 168, 52, 76, 161, 114, 231, 153, 11, 127, 104, 76,
2437        54, 182, 29, 56, 35, 201, 157, 140, 103, 90, 91, 221, 186, 229, 126, 182, 7, 196, 213, 210,
2438        154, 41, 118, 115, 186, 154, 58, 246, 122, 78, 70, 227, 84, 183, 212, 109, 167, 222, 37,
2439        35, 153, 14, 228, 156, 142, 145, 201, 36, 38, 19, 59, 212, 151, 67, 179, 178, 28, 134, 90,
2440        64, 196, 74, 234, 204, 41, 107, 51, 191, 172, 209, 137, 62, 107, 10, 228, 191, 2, 249, 125,
2441        129, 14, 232, 81, 73, 141, 155, 111, 40, 69, 68, 110, 68, 59, 60, 24, 223, 255, 72, 255,
2442        46, 249, 125, 89, 84, 233, 223, 37, 127, 107, 52, 215, 35, 55, 12, 102, 78, 95, 15, 186,
2443        125, 75, 24, 52, 170, 155, 65, 95, 175, 52, 103, 145, 48, 154, 91, 1, 253, 123, 78, 191,
2444        187, 255, 78, 165, 68, 54, 240, 73, 243, 8, 244, 119, 205, 123, 107, 58, 108, 4, 179, 158,
2445        100, 85, 232, 39, 25, 230, 196, 245, 4, 171, 102, 155, 147, 246, 80, 140, 90, 227, 240,
2446        113, 213, 21, 20, 221, 54, 221, 182, 38, 91, 74, 215, 212, 90, 186, 18, 204, 187, 166, 181,
2447        26, 26, 90, 93, 187, 91, 180, 212, 128, 40, 129, 198, 194, 232, 88, 171, 229, 80, 28, 109,
2448        92, 203, 43, 121, 115, 125, 221, 19, 162, 178, 102, 138, 174, 109, 77, 12, 215, 168, 217,
2449        186, 36, 151, 71, 164, 139, 61, 223, 26, 12, 132, 245, 114, 68, 148, 196, 64, 138, 106,
2450        166, 160, 77, 6, 210, 66, 232, 137, 122, 107, 228, 59, 226, 184, 111, 169, 35, 203, 85, 61,
2451        165, 86, 25, 247, 221, 126, 215, 94, 76, 186, 118, 180, 30, 207, 38, 91, 77, 209, 219, 61,
2452        203, 213, 186, 225, 164, 231, 206, 213, 167, 14, 153, 252, 142, 45, 170, 227, 198, 164, 57,
2453        188, 143, 30, 109, 197, 93, 147, 103, 205, 173, 251, 214, 202, 178, 221, 27, 39, 80, 250,
2454        134, 160, 210, 46, 50, 255, 53, 31, 119, 199, 195, 137, 182, 49, 141, 199, 40, 108, 191,
2455        244, 212, 222, 63, 198, 213, 255, 188, 239, 206, 102, 155, 223, 102, 235, 159, 255, 252,
2456        241, 16, 244, 194, 233, 68, 170, 7, 27, 189, 211, 250, 189, 104, 143, 255, 241, 159, 66,
2457        221, 121, 169, 73, 98, 189, 90, 107, 78, 23, 29, 229, 215, 96, 54, 27, 153, 183, 182, 223,
2458        155, 223, 55, 127, 24, 227, 219, 167, 217, 237, 188, 31, 74, 154, 226, 255, 115, 220, 169,
2459        143, 165, 231, 135, 95, 245, 217, 118, 174, 201, 134, 255, 88, 121, 92, 132, 129, 123, 251,
2460        175, 250, 204, 189, 169, 46, 138, 78, 144, 126, 109, 161, 10, 170, 240, 32, 248, 27, 83,
2461        156, 172, 6, 162, 90, 233, 223, 85, 151, 214, 182, 21, 88, 37, 79, 242, 238, 149, 118, 143,
2462        152, 10, 131, 232, 111, 91, 209, 2, 85, 113, 239, 29, 99, 178, 37, 170, 76, 210, 173, 232,
2463        201, 104, 84, 183, 230, 220, 122, 26, 248, 138, 209, 149, 148, 167, 65, 73, 111, 91, 50,
2464        249, 194, 153, 85, 241, 204, 245, 218, 242, 215, 130, 121, 31, 84, 188, 192, 171, 13, 36,
2465        165, 54, 152, 43, 55, 157, 123, 85, 176, 228, 69, 203, 242, 197, 187, 129, 210, 10, 71,
2466        155, 231, 50, 25, 45, 147, 161, 185, 46, 15, 228, 201, 243, 56, 156, 56, 214, 92, 9, 212,
2467        134, 103, 142, 230, 53, 203, 157, 71, 83, 211, 242, 126, 118, 55, 196,
2468    ];
2469
2470    let b = FrameVec::new(&a).unwrap();
2471    assert!(b.frames.len() == 1);
2472    assert!(b.frames[0].is_fragment());
2473}
2474
2475#[tokio::test]
2476async fn test_client_packet2() {
2477    // Connection Request - reliable [ reliable_frame_index = 0 ]
2478    let p0 = [
2479        132, 0, 0, 0, 64, 0, 144, 0, 0, 0, 9, 162, 70, 235, 28, 218, 182, 26, 192, 0, 0, 0, 0, 16,
2480        151, 43, 113, 0,
2481    ];
2482    // Connection Request - reliable [ reliable_frame_index = 0 ]
2483    let p1 = [
2484        132, 1, 0, 0, 64, 0, 144, 0, 0, 0, 9, 162, 70, 235, 28, 218, 182, 26, 192, 0, 0, 0, 0, 16,
2485        151, 43, 113, 0,
2486    ];
2487    // 2 frames Incompatible Protocol(extract data?) Connected ping - reliable ordered [ reliable_frame_index = 1 ]
2488    let p2 = [
2489        132, 2, 0, 0, 96, 9, 64, 1, 0, 0, 0, 0, 0, 0, 19, 4, 83, 237, 234, 82, 74, 188, 6, 23, 0,
2490        225, 138, 0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0, 196, 178, 112, 86, 5, 59, 97, 219, 15, 0,
2491        0, 0, 6, 23, 0, 225, 138, 0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0, 188, 210, 59, 150, 246,
2492        167, 182, 213, 33, 0, 0, 0, 6, 23, 0, 225, 138, 0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0,
2493        132, 194, 47, 23, 175, 46, 78, 138, 23, 0, 0, 0, 6, 23, 0, 225, 138, 0, 0, 0, 0, 254, 128,
2494        0, 0, 0, 0, 0, 0, 136, 219, 85, 240, 191, 125, 172, 233, 10, 0, 0, 0, 6, 23, 0, 225, 138,
2495        0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0, 80, 211, 212, 44, 191, 227, 124, 40, 13, 0, 0, 0,
2496        6, 23, 0, 225, 138, 0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0, 77, 13, 19, 149, 102, 140, 134,
2497        77, 16, 0, 0, 0, 4, 83, 237, 239, 254, 225, 138, 4, 63, 87, 214, 254, 225, 138, 4, 83, 236,
2498        159, 254, 225, 138, 4, 63, 87, 46, 254, 225, 138, 4, 63, 87, 56, 128, 225, 138, 4, 63, 87,
2499        56, 123, 225, 138, 4, 255, 255, 255, 255, 0, 0, 4, 255, 255, 255, 255, 0, 0, 4, 255, 255,
2500        255, 255, 0, 0, 4, 255, 255, 255, 255, 0, 0, 4, 255, 255, 255, 255, 0, 0, 4, 255, 255, 255,
2501        255, 0, 0, 4, 255, 255, 255, 255, 0, 0, 4, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2502        0, 0, 0, 0, 0, 16, 151, 56, 146, 0, 0, 72, 0, 0, 0, 0, 0, 16, 151, 56, 146,
2503    ];
2504    // 1 frames Connected ping - unreliable
2505    let p3 = [132, 3, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 16, 151, 56, 161];
2506    // 1 frames game packet - reliable ordered [is_fragment reliable_frame_index = 2 ordered_frame_index = 1 ]
2507    let p4 = [
2508        140, 4, 0, 0, 112, 44, 192, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 254, 236,
2509        189, 203, 114, 234, 202, 214, 239, 249, 157, 94, 85, 61, 198, 119, 186, 181, 79, 72, 2,
2510        188, 77, 245, 140, 145, 48, 24, 137, 137, 208, 5, 169, 162, 98, 7, 32, 246, 4, 36, 97, 77,
2511        155, 201, 173, 162, 158, 231, 188, 81, 53, 171, 89, 47, 80, 189, 211, 170, 148, 148, 194,
2512        164, 156, 96, 16, 248, 178, 214, 252, 55, 126, 177, 194, 107, 122, 88, 82, 94, 198, 200,
2513        113, 201, 204, 255, 231, 127, 252, 215, 255, 242, 31, 255, 241, 95, 254, 223, 255, 251,
2514        127, 252, 215, 255, 254, 63, 255, 199, 127, 252, 159, 255, 57, 154, 12, 166, 243, 255, 252,
2515        223, 254, 247, 255, 28, 111, 90, 147, 97, 99, 52, 237, 76, 91, 138, 185, 85, 203, 218, 125,
2516        243, 165, 57, 255, 41, 122, 189, 230, 77, 211, 23, 155, 118, 223, 83, 186, 86, 208, 236,
2517        73, 213, 65, 175, 31, 253, 82, 101, 173, 102, 90, 65, 163, 183, 213, 21, 221, 84, 234, 61,
2518        83, 119, 93, 65, 81, 172, 70, 107, 233, 25, 138, 210, 179, 149, 23, 79, 18, 205, 142, 41,
2519        8, 163, 134, 179, 177, 77, 87, 182, 131, 86, 121, 80, 106, 213, 135, 125, 179, 162, 139,
2520        122, 203, 241, 131, 138, 109, 4, 93, 51, 168, 173, 135, 74, 75, 29, 214, 29, 97, 104, 4,
2521        55, 222, 182, 86, 26, 205, 189, 242, 192, 127, 217, 90, 219, 174, 48, 40, 233, 115, 171,
2522        49, 105, 141, 109, 189, 63, 182, 91, 63, 70, 141, 167, 237, 120, 166, 148, 213, 173, 92,
2523        30, 110, 149, 78, 91, 12, 66, 93, 241, 5, 93, 208, 45, 45, 156, 56, 143, 130, 18, 90, 194,
2524        147, 104, 55, 116, 209, 8, 163, 103, 211, 94, 151, 134, 91, 189, 50, 174, 235, 191, 135,
2525        138, 213, 237, 218, 21, 211, 182, 252, 233, 191, 187, 79, 255, 141, 124, 247, 204, 237,
2526        183, 132, 129, 237, 70, 142, 164, 8, 174, 169, 136, 94, 99, 178, 28, 133, 129, 48, 38, 223,
2527        238, 61, 180, 68, 183, 183, 154, 186, 253, 201, 170, 57, 123, 90, 107, 179, 110, 169, 83,
2528        119, 214, 154, 33, 175, 219, 247, 173, 200, 109, 88, 191, 189, 6, 249, 93, 171, 38, 58,
2529        225, 58, 114, 132, 69, 48, 62, 179, 205, 58, 178, 165, 14, 164, 160, 60, 54, 215, 51, 79,
2530        90, 15, 70, 243, 192, 50, 109, 77, 84, 45, 93, 50, 229, 234, 162, 103, 180, 238, 181, 146,
2531        235, 116, 234, 218, 111, 183, 81, 233, 155, 129, 53, 177, 27, 66, 73, 123, 240, 26, 110,
2532        40, 139, 238, 180, 250, 226, 137, 74, 199, 106, 184, 27, 67, 113, 155, 142, 209, 234, 14,
2533        109, 235, 247, 72, 246, 90, 154, 31, 61, 245, 76, 209, 234, 133, 74, 223, 158, 183, 126,
2534        13, 77, 241, 87, 199, 168, 117, 134, 194, 162, 163, 7, 90, 167, 59, 183, 218, 110, 67, 40,
2535        143, 130, 32, 178, 31, 180, 208, 233, 63, 109, 123, 91, 85, 26, 223, 223, 174, 45, 163, 41,
2536        245, 30, 106, 15, 170, 18, 149, 123, 155, 170, 173, 90, 206, 148, 124, 243, 111, 39, 116,
2537        166, 157, 153, 44, 105, 245, 145, 212, 169, 255, 148, 52, 67, 169, 222, 255, 252, 111, 237,
2538        167, 127, 74, 191, 234, 254, 100, 169, 140, 42, 171, 201, 92, 173, 142, 252, 127, 77, 86,
2539        247, 77, 251, 95, 254, 175, 127, 215, 127, 223, 246, 42, 255, 26, 253, 235, 165, 108, 133,
2540        255, 246, 151, 203, 202, 211, 250, 151, 175, 12, 203, 193, 124, 221, 155, 255, 67, 126,
2541        190, 109, 253, 99, 242, 243, 95, 211, 167, 219, 187, 237, 157, 107, 254, 43, 24, 107, 81,
2542        79, 22, 171, 225, 38, 252, 183, 240, 24, 4, 255, 114, 31, 21, 213, 235, 11, 195, 81, 239,
2543        159, 253, 161, 97, 169, 222, 77, 215, 41, 173, 164, 231, 254, 68, 157, 151, 199, 131, 31,
2544        15, 51, 229, 63, 255, 215, 120, 20, 151, 181, 190, 25, 143, 98, 173, 167, 4, 37, 210, 202,
2545        110, 79, 94, 44, 109, 63, 184, 25, 204, 106, 245, 174, 165, 184, 186, 255, 34, 232, 166,
2546        85, 235, 10, 129, 108, 219, 94, 77, 55, 38, 138, 209, 88, 68, 227, 135, 64, 117, 74, 222,
2547        11, 105, 165, 138, 101, 41, 51, 50, 138, 77, 47, 168, 253, 24, 154, 254, 166, 75, 250, 197,
2548        174, 255, 220, 14, 67, 253, 183, 37, 182, 44, 199, 154, 44, 180, 173, 94, 210, 67, 119,
2549        162, 217, 238, 168, 45, 173, 75, 166, 89, 49, 221, 121, 75, 181, 252, 201, 68, 13, 106, 11,
2550        215, 174, 172, 116, 193, 151, 122, 225, 164, 101, 88, 214, 163, 99, 121, 131, 81, 24, 45,
2551        12, 251, 169, 162, 202, 149, 101, 79, 168, 52, 76, 161, 114, 239, 153, 11, 127, 104, 76,
2552        54, 182, 29, 56, 35, 201, 157, 140, 103, 90, 91, 221, 186, 229, 126, 190, 7, 196, 213, 210,
2553        154, 41, 118, 115, 186, 154, 58, 246, 122, 78, 70, 227, 84, 183, 212, 109, 167, 222, 37,
2554        35, 57, 30, 200, 156, 142, 145, 201, 36, 38, 19, 59, 212, 151, 67, 179, 178, 28, 134, 90,
2555        64, 196, 74, 234, 204, 41, 107, 51, 191, 172, 197, 19, 125, 214, 20, 200, 127, 5, 242, 251,
2556        66, 60, 160, 71, 37, 53, 105, 190, 161, 20, 17, 185, 81, 220, 225, 193, 248, 225, 46, 251,
2557        187, 228, 247, 101, 81, 141, 255, 46, 249, 91, 163, 185, 30, 185, 97, 48, 115, 250, 122,
2558        208, 237, 91, 194, 160, 81, 221, 12, 250, 122, 165, 57, 139, 132, 209, 220, 10, 226, 191,
2559        231, 244, 187, 251, 239, 84, 74, 101, 3, 159, 52, 143, 16, 255, 174, 249, 96, 77, 135, 141,
2560        96, 214, 147, 172, 74, 252, 73, 134, 57, 113, 61, 193, 170, 217, 230, 164, 61, 20, 163,
2561        214, 56, 124, 90, 117, 5, 69, 39, 10, 164, 173, 201, 150, 210, 53, 181, 150, 174, 4, 243,
2562        174, 105, 173, 134, 134, 86, 215, 238, 23, 45, 53, 208, 156, 81, 99, 97, 116, 172, 213,
2563        114, 40, 142, 54, 174, 229, 149, 188, 185, 190, 238, 9, 81, 89, 51, 69, 215, 182, 38, 134,
2564        107, 212, 108, 93, 146, 203, 35, 210, 197, 158, 111, 13, 6, 194, 122, 57, 18, 91, 226, 64,
2565        138, 106, 166, 160, 77, 6, 210, 66, 232, 17, 165, 52, 242, 29, 113, 220, 183, 212, 145,
2566        229, 170, 158, 82, 171, 140, 251, 110, 191, 107, 47, 38, 93, 59, 90, 143, 103, 147, 173,
2567        166, 232, 237, 158, 229, 106, 221, 112, 210, 115, 231, 234, 115, 135, 76, 126, 199, 22,
2568        213, 113, 99, 210, 28, 62, 68, 79, 182, 226, 174, 201, 179, 230, 214, 67, 107, 101, 217,
2569        238, 141, 19, 40, 125, 67, 80, 227, 46, 50, 255, 61, 31, 119, 199, 195, 137, 182, 49, 141,
2570        167, 40, 108, 255, 238, 169, 189, 127, 140, 171, 255, 124, 232, 206, 102, 155, 95, 102,
2571        235, 95, 255, 186, 123, 12, 122, 225, 116, 34, 213, 131, 141, 222, 105, 253, 90, 180, 199,
2572        255, 248, 167, 80, 119, 126, 215, 36, 177, 94, 173, 53, 167, 139, 142, 242, 115, 48, 155,
2573        141, 204, 91, 219, 239, 205, 31, 154, 119, 198, 248, 246, 121, 118, 59, 239, 135, 146, 166,
2574        248, 255, 26, 119, 234, 99, 233, 229, 241, 103, 125, 182, 157, 107, 178, 225, 63, 85, 158,
2575        22, 97, 224, 222, 254, 187, 62, 115, 111, 170, 139, 162, 19, 164, 95, 91, 168, 130, 42, 60,
2576        10, 254, 198, 20, 39, 171, 129, 168, 86, 250, 247, 213, 165, 181, 109, 5, 86, 201, 147,
2577        188, 7, 165, 221, 35, 166, 194, 176, 2, 215, 86, 180, 64, 85, 220, 7, 199, 152, 108, 137,
2578        42, 147, 116, 43, 122, 54, 26, 213, 173, 57, 183, 158, 7, 190, 98, 116, 37, 229, 153, 168,
2579        243, 182, 37, 147, 47, 156, 89, 21, 207, 92, 175, 45, 127, 45, 152, 15, 65, 197, 11, 188,
2580        218, 64, 82, 106, 131, 185, 114, 211, 121, 80, 5, 75, 94, 180, 44, 95, 188, 31, 40, 173,
2581        112, 180, 121, 41, 147, 209, 50, 25, 154, 235, 242, 64, 158, 188, 140, 137, 154, 183, 230,
2582        74, 160, 54, 60, 115, 52, 175, 89, 238, 60, 154, 154, 150, 247, 163, 187,
2583    ];
2584    // 1 frames Incompatible Protocol(extract data?) - reliable ordered [reliable_frame_index = 1 ordered_frame_index = 0] == p2
2585    let p5 = [
2586        140, 5, 0, 0, 96, 9, 64, 1, 0, 0, 0, 0, 0, 0, 19, 4, 83, 237, 234, 82, 74, 188, 6, 23, 0,
2587        225, 138, 0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0, 196, 178, 112, 86, 5, 59, 97, 219, 15, 0,
2588        0, 0, 6, 23, 0, 225, 138, 0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0, 188, 210, 59, 150, 246,
2589        167, 182, 213, 33, 0, 0, 0, 6, 23, 0, 225, 138, 0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0,
2590        132, 194, 47, 23, 175, 46, 78, 138, 23, 0, 0, 0, 6, 23, 0, 225, 138, 0, 0, 0, 0, 254, 128,
2591        0, 0, 0, 0, 0, 0, 136, 219, 85, 240, 191, 125, 172, 233, 10, 0, 0, 0, 6, 23, 0, 225, 138,
2592        0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0, 80, 211, 212, 44, 191, 227, 124, 40, 13, 0, 0, 0,
2593        6, 23, 0, 225, 138, 0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0, 77, 13, 19, 149, 102, 140, 134,
2594        77, 16, 0, 0, 0, 4, 83, 237, 239, 254, 225, 138, 4, 63, 87, 214, 254, 225, 138, 4, 83, 236,
2595        159, 254, 225, 138, 4, 63, 87, 46, 254, 225, 138, 4, 63, 87, 56, 128, 225, 138, 4, 63, 87,
2596        56, 123, 225, 138, 4, 255, 255, 255, 255, 0, 0, 4, 255, 255, 255, 255, 0, 0, 4, 255, 255,
2597        255, 255, 0, 0, 4, 255, 255, 255, 255, 0, 0, 4, 255, 255, 255, 255, 0, 0, 4, 255, 255, 255,
2598        255, 0, 0, 4, 255, 255, 255, 255, 0, 0, 4, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2599        0, 0, 0, 0, 0, 16, 151, 56, 146,
2600    ];
2601    // 1 frames game packet - reliable ordered [is_fragment reliable_frame_index = 2 ordered_frame_index = 1 ] == p4
2602    let p6 = [
2603        140, 6, 0, 0, 112, 44, 192, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 254, 236,
2604        189, 203, 114, 234, 202, 214, 239, 249, 157, 94, 85, 61, 198, 119, 186, 181, 79, 72, 2,
2605        188, 77, 245, 140, 145, 48, 24, 137, 137, 208, 5, 169, 162, 98, 7, 32, 246, 4, 36, 97, 77,
2606        155, 201, 173, 162, 158, 231, 188, 81, 53, 171, 89, 47, 80, 189, 211, 170, 148, 148, 194,
2607        164, 156, 96, 16, 248, 178, 214, 252, 55, 126, 177, 194, 107, 122, 88, 82, 94, 198, 200,
2608        113, 201, 204, 255, 231, 127, 252, 215, 255, 242, 31, 255, 241, 95, 254, 223, 255, 251,
2609        127, 252, 215, 255, 254, 63, 255, 199, 127, 252, 159, 255, 57, 154, 12, 166, 243, 255, 252,
2610        223, 254, 247, 255, 28, 111, 90, 147, 97, 99, 52, 237, 76, 91, 138, 185, 85, 203, 218, 125,
2611        243, 165, 57, 255, 41, 122, 189, 230, 77, 211, 23, 155, 118, 223, 83, 186, 86, 208, 236,
2612        73, 213, 65, 175, 31, 253, 82, 101, 173, 102, 90, 65, 163, 183, 213, 21, 221, 84, 234, 61,
2613        83, 119, 93, 65, 81, 172, 70, 107, 233, 25, 138, 210, 179, 149, 23, 79, 18, 205, 142, 41,
2614        8, 163, 134, 179, 177, 77, 87, 182, 131, 86, 121, 80, 106, 213, 135, 125, 179, 162, 139,
2615        122, 203, 241, 131, 138, 109, 4, 93, 51, 168, 173, 135, 74, 75, 29, 214, 29, 97, 104, 4,
2616        55, 222, 182, 86, 26, 205, 189, 242, 192, 127, 217, 90, 219, 174, 48, 40, 233, 115, 171,
2617        49, 105, 141, 109, 189, 63, 182, 91, 63, 70, 141, 167, 237, 120, 166, 148, 213, 173, 92,
2618        30, 110, 149, 78, 91, 12, 66, 93, 241, 5, 93, 208, 45, 45, 156, 56, 143, 130, 18, 90, 194,
2619        147, 104, 55, 116, 209, 8, 163, 103, 211, 94, 151, 134, 91, 189, 50, 174, 235, 191, 135,
2620        138, 213, 237, 218, 21, 211, 182, 252, 233, 191, 187, 79, 255, 141, 124, 247, 204, 237,
2621        183, 132, 129, 237, 70, 142, 164, 8, 174, 169, 136, 94, 99, 178, 28, 133, 129, 48, 38, 223,
2622        238, 61, 180, 68, 183, 183, 154, 186, 253, 201, 170, 57, 123, 90, 107, 179, 110, 169, 83,
2623        119, 214, 154, 33, 175, 219, 247, 173, 200, 109, 88, 191, 189, 6, 249, 93, 171, 38, 58,
2624        225, 58, 114, 132, 69, 48, 62, 179, 205, 58, 178, 165, 14, 164, 160, 60, 54, 215, 51, 79,
2625        90, 15, 70, 243, 192, 50, 109, 77, 84, 45, 93, 50, 229, 234, 162, 103, 180, 238, 181, 146,
2626        235, 116, 234, 218, 111, 183, 81, 233, 155, 129, 53, 177, 27, 66, 73, 123, 240, 26, 110,
2627        40, 139, 238, 180, 250, 226, 137, 74, 199, 106, 184, 27, 67, 113, 155, 142, 209, 234, 14,
2628        109, 235, 247, 72, 246, 90, 154, 31, 61, 245, 76, 209, 234, 133, 74, 223, 158, 183, 126,
2629        13, 77, 241, 87, 199, 168, 117, 134, 194, 162, 163, 7, 90, 167, 59, 183, 218, 110, 67, 40,
2630        143, 130, 32, 178, 31, 180, 208, 233, 63, 109, 123, 91, 85, 26, 223, 223, 174, 45, 163, 41,
2631        245, 30, 106, 15, 170, 18, 149, 123, 155, 170, 173, 90, 206, 148, 124, 243, 111, 39, 116,
2632        166, 157, 153, 44, 105, 245, 145, 212, 169, 255, 148, 52, 67, 169, 222, 255, 252, 111, 237,
2633        167, 127, 74, 191, 234, 254, 100, 169, 140, 42, 171, 201, 92, 173, 142, 252, 127, 77, 86,
2634        247, 77, 251, 95, 254, 175, 127, 215, 127, 223, 246, 42, 255, 26, 253, 235, 165, 108, 133,
2635        255, 246, 151, 203, 202, 211, 250, 151, 175, 12, 203, 193, 124, 221, 155, 255, 67, 126,
2636        190, 109, 253, 99, 242, 243, 95, 211, 167, 219, 187, 237, 157, 107, 254, 43, 24, 107, 81,
2637        79, 22, 171, 225, 38, 252, 183, 240, 24, 4, 255, 114, 31, 21, 213, 235, 11, 195, 81, 239,
2638        159, 253, 161, 97, 169, 222, 77, 215, 41, 173, 164, 231, 254, 68, 157, 151, 199, 131, 31,
2639        15, 51, 229, 63, 255, 215, 120, 20, 151, 181, 190, 25, 143, 98, 173, 167, 4, 37, 210, 202,
2640        110, 79, 94, 44, 109, 63, 184, 25, 204, 106, 245, 174, 165, 184, 186, 255, 34, 232, 166,
2641        85, 235, 10, 129, 108, 219, 94, 77, 55, 38, 138, 209, 88, 68, 227, 135, 64, 117, 74, 222,
2642        11, 105, 165, 138, 101, 41, 51, 50, 138, 77, 47, 168, 253, 24, 154, 254, 166, 75, 250, 197,
2643        174, 255, 220, 14, 67, 253, 183, 37, 182, 44, 199, 154, 44, 180, 173, 94, 210, 67, 119,
2644        162, 217, 238, 168, 45, 173, 75, 166, 89, 49, 221, 121, 75, 181, 252, 201, 68, 13, 106, 11,
2645        215, 174, 172, 116, 193, 151, 122, 225, 164, 101, 88, 214, 163, 99, 121, 131, 81, 24, 45,
2646        12, 251, 169, 162, 202, 149, 101, 79, 168, 52, 76, 161, 114, 239, 153, 11, 127, 104, 76,
2647        54, 182, 29, 56, 35, 201, 157, 140, 103, 90, 91, 221, 186, 229, 126, 190, 7, 196, 213, 210,
2648        154, 41, 118, 115, 186, 154, 58, 246, 122, 78, 70, 227, 84, 183, 212, 109, 167, 222, 37,
2649        35, 57, 30, 200, 156, 142, 145, 201, 36, 38, 19, 59, 212, 151, 67, 179, 178, 28, 134, 90,
2650        64, 196, 74, 234, 204, 41, 107, 51, 191, 172, 197, 19, 125, 214, 20, 200, 127, 5, 242, 251,
2651        66, 60, 160, 71, 37, 53, 105, 190, 161, 20, 17, 185, 81, 220, 225, 193, 248, 225, 46, 251,
2652        187, 228, 247, 101, 81, 141, 255, 46, 249, 91, 163, 185, 30, 185, 97, 48, 115, 250, 122,
2653        208, 237, 91, 194, 160, 81, 221, 12, 250, 122, 165, 57, 139, 132, 209, 220, 10, 226, 191,
2654        231, 244, 187, 251, 239, 84, 74, 101, 3, 159, 52, 143, 16, 255, 174, 249, 96, 77, 135, 141,
2655        96, 214, 147, 172, 74, 252, 73, 134, 57, 113, 61, 193, 170, 217, 230, 164, 61, 20, 163,
2656        214, 56, 124, 90, 117, 5, 69, 39, 10, 164, 173, 201, 150, 210, 53, 181, 150, 174, 4, 243,
2657        174, 105, 173, 134, 134, 86, 215, 238, 23, 45, 53, 208, 156, 81, 99, 97, 116, 172, 213,
2658        114, 40, 142, 54, 174, 229, 149, 188, 185, 190, 238, 9, 81, 89, 51, 69, 215, 182, 38, 134,
2659        107, 212, 108, 93, 146, 203, 35, 210, 197, 158, 111, 13, 6, 194, 122, 57, 18, 91, 226, 64,
2660        138, 106, 166, 160, 77, 6, 210, 66, 232, 17, 165, 52, 242, 29, 113, 220, 183, 212, 145,
2661        229, 170, 158, 82, 171, 140, 251, 110, 191, 107, 47, 38, 93, 59, 90, 143, 103, 147, 173,
2662        166, 232, 237, 158, 229, 106, 221, 112, 210, 115, 231, 234, 115, 135, 76, 126, 199, 22,
2663        213, 113, 99, 210, 28, 62, 68, 79, 182, 226, 174, 201, 179, 230, 214, 67, 107, 101, 217,
2664        238, 141, 19, 40, 125, 67, 80, 227, 46, 50, 255, 61, 31, 119, 199, 195, 137, 182, 49, 141,
2665        167, 40, 108, 255, 238, 169, 189, 127, 140, 171, 255, 124, 232, 206, 102, 155, 95, 102,
2666        235, 95, 255, 186, 123, 12, 122, 225, 116, 34, 213, 131, 141, 222, 105, 253, 90, 180, 199,
2667        255, 248, 167, 80, 119, 126, 215, 36, 177, 94, 173, 53, 167, 139, 142, 242, 115, 48, 155,
2668        141, 204, 91, 219, 239, 205, 31, 154, 119, 198, 248, 246, 121, 118, 59, 239, 135, 146, 166,
2669        248, 255, 26, 119, 234, 99, 233, 229, 241, 103, 125, 182, 157, 107, 178, 225, 63, 85, 158,
2670        22, 97, 224, 222, 254, 187, 62, 115, 111, 170, 139, 162, 19, 164, 95, 91, 168, 130, 42, 60,
2671        10, 254, 198, 20, 39, 171, 129, 168, 86, 250, 247, 213, 165, 181, 109, 5, 86, 201, 147,
2672        188, 7, 165, 221, 35, 166, 194, 176, 2, 215, 86, 180, 64, 85, 220, 7, 199, 152, 108, 137,
2673        42, 147, 116, 43, 122, 54, 26, 213, 173, 57, 183, 158, 7, 190, 98, 116, 37, 229, 153, 168,
2674        243, 182, 37, 147, 47, 156, 89, 21, 207, 92, 175, 45, 127, 45, 152, 15, 65, 197, 11, 188,
2675        218, 64, 82, 106, 131, 185, 114, 211, 121, 80, 5, 75, 94, 180, 44, 95, 188, 31, 40, 173,
2676        112, 180, 121, 41, 147, 209, 50, 25, 154, 235, 242, 64, 158, 188, 140, 137, 154, 183, 230,
2677        74, 160, 54, 60, 115, 52, 175, 89, 238, 60, 154, 154, 150, 247, 163, 187,
2678    ];
2679    let ps: Vec<Vec<u8>> = vec![
2680        p0.to_vec(),
2681        p1.to_vec(),
2682        p2.to_vec(),
2683        p3.to_vec(),
2684        p4.to_vec(),
2685        p5.to_vec(),
2686        p6.to_vec(),
2687    ];
2688
2689    let mut n = 0;
2690
2691    let mut rq = RecvQ::new();
2692    for i in ps {
2693        let v = FrameVec::new(&i).unwrap();
2694        for i in v.frames {
2695            rq.insert(i).unwrap();
2696            if !rq.flush(&"0.0.0.0:0".parse().unwrap()).is_empty() {
2697                n += 1;
2698            }
2699        }
2700    }
2701
2702    // p1 retransmits p0 with a new datagram ID but the same reliable frame ID.
2703    assert_eq!(n, 4);
2704}
2705
2706#[cfg(test)]
2707#[path = "arq_tests.rs"]
2708mod regressions;
2709
2710#[test]
2711fn rejects_messages_exceeding_the_receivers_fragment_limit() {
2712    let sendq = SendQ::new(576);
2713    let limit = crate::fragment::MAX_FRAGMENTS * (576 - 60);
2714    assert!(
2715        sendq
2716            .required_bytes(Reliability::ReliableOrdered, limit)
2717            .is_ok()
2718    );
2719    assert!(matches!(
2720        sendq.required_bytes(Reliability::ReliableOrdered, limit + 1),
2721        Err(RaknetError::PacketSizeExceedMTU)
2722    ));
2723}
2724
2725#[test]
2726fn exact_mtu_payload_is_not_marked_as_split() {
2727    let mut sendq = SendQ::new(576);
2728    let payload = vec![0xfe; 516];
2729    sendq
2730        .insert(Reliability::ReliableOrdered, &payload)
2731        .unwrap();
2732    let frames = sendq.flush(0, &"127.0.0.1:19132".parse().unwrap());
2733    assert_eq!(frames.len(), 1);
2734    assert_eq!(frames[0].flags & 16, 0);
2735    assert_eq!(frames[0].data.as_ref(), payload);
2736    sendq.ack(frames[0].sequence_number, 1);
2737    assert!(sendq.is_empty());
2738    assert_eq!(sendq.buffered_bytes, 0);
2739}
2740
2741#[cfg(test)]
2742mod allocation_regressions {
2743    use super::*;
2744
2745    #[test]
2746    fn frame_decoder_reuses_storage_and_discards_previous_frames() {
2747        let packet = FrameSetPacket::new(Reliability::ReliableOrdered, vec![0xfe; 800]);
2748        let encoded = packet.serialize().unwrap();
2749        let mut frames = Vec::new();
2750        FrameVec::decode_into(&encoded, &mut frames).unwrap();
2751        let capacity = frames.capacity();
2752        assert_eq!(frames[0].data.as_ref(), &[0xfe; 800]);
2753        frames.clear();
2754        FrameVec::decode_into(&encoded, &mut frames).unwrap();
2755        assert_eq!(frames.len(), 1);
2756        assert_eq!(frames.capacity(), capacity);
2757        assert!(FrameVec::decode_into(&[0x84], &mut frames).is_err());
2758        assert!(frames.is_empty());
2759    }
2760
2761    #[test]
2762    fn ordered_delivery_retains_the_receive_queue_allocation() {
2763        let mut queue = RecvQ::new();
2764        let mut delivered = Vec::new();
2765        for index in 0..16 {
2766            let mut frame = FrameSetPacket::new(Reliability::ReliableOrdered, vec![0xfe]);
2767            frame.sequence_number = index;
2768            frame.reliable_frame_index = index;
2769            frame.ordered_frame_index = index;
2770            queue.insert(frame).unwrap();
2771            queue.flush_into(&mut delivered);
2772            assert_eq!(delivered.len(), 1);
2773            delivered.clear();
2774            assert!(queue.ready_ordered.capacity() > 0);
2775        }
2776    }
2777}
2778
2779#[cfg(test)]
2780mod serialization_reuse_tests {
2781    use super::*;
2782
2783    #[test]
2784    fn reused_fragment_buffer_preserves_the_wire_format() {
2785        let mut frame = FrameSetPacket::new(Reliability::ReliableOrdered, vec![0xfe; 16]);
2786        frame.flags |= 16;
2787        frame.sequence_number = 0xabcdef;
2788        frame.reliable_frame_index = 0x123456;
2789        frame.ordered_frame_index = 0x654321;
2790        frame.order_channel = 7;
2791        frame.compound_size = 3;
2792        frame.compound_id = 0x1234;
2793        frame.fragment_index = 1;
2794        let mut expected = vec![
2795            0x8c, 0xef, 0xcd, 0xab, 0x70, 0, 0x80, 0x56, 0x34, 0x12, 0x21, 0x43, 0x65, 7, 0, 0, 0,
2796            3, 0x12, 0x34, 0, 0, 0, 1,
2797        ];
2798        expected.extend_from_slice(&[0xfe; 16]);
2799        let mut buffer = Vec::with_capacity(128);
2800        buffer.extend_from_slice(&[0xff; 64]);
2801        for _ in 0..100 {
2802            frame.serialize_into(&mut buffer).unwrap();
2803            assert_eq!(buffer, expected);
2804            assert_eq!(buffer.capacity(), 128);
2805        }
2806        frame.compound_size = 0;
2807        assert!(frame.serialize_into(&mut buffer).is_err());
2808        assert_eq!(buffer, expected);
2809    }
2810}
2811
2812#[cfg(test)]
2813mod shared_fragment_tests {
2814    use super::*;
2815
2816    #[test]
2817    fn retransmitted_fragment_accepts_old_ack_without_releasing_the_budget_twice() {
2818        let peer = "127.0.0.1:19132".parse().unwrap();
2819        let mut queue = SendQ::new(1400);
2820        queue
2821            .insert(Reliability::ReliableOrdered, &[0xfe; 4096])
2822            .unwrap();
2823        let frames = queue.flush(0, &peer);
2824        let old_id = frames[3].sequence_number;
2825        queue.nack(old_id, 1);
2826        let retry = queue.flush(1, &peer);
2827        assert_eq!(retry.len(), 1);
2828        let new_id = retry[0].sequence_number;
2829        queue.ack(old_id, 2);
2830        let budget = queue.buffered_bytes;
2831        queue.ack(old_id, 2);
2832        queue.ack(new_id, 2);
2833        assert_eq!(queue.buffered_bytes, budget);
2834        for frame in &frames[..3] {
2835            queue.ack(frame.sequence_number, 2);
2836        }
2837        assert_eq!(queue.buffered_bytes, 0);
2838    }
2839
2840    #[test]
2841    fn fragment_slices_share_one_allocation_and_keep_its_budget_until_final_ack() {
2842        let peer = "127.0.0.1:19132".parse().unwrap();
2843        let mut queue = SendQ::new(1400);
2844        let payload = vec![0xfe; 4096];
2845        queue
2846            .insert(Reliability::ReliableOrdered, &payload)
2847            .unwrap();
2848        let frames = queue.flush(0, &peer);
2849        assert_eq!(frames.len(), 4);
2850        let owner = frames[0].shared_payload.as_ref().unwrap();
2851        for frame in &frames {
2852            assert!(Arc::ptr_eq(owner, frame.shared_payload.as_ref().unwrap()));
2853        }
2854        let restored: Vec<_> = frames
2855            .iter()
2856            .flat_map(|frame| frame.data.iter().copied())
2857            .collect();
2858        assert_eq!(restored, payload);
2859        let initial = queue.buffered_bytes;
2860        for (index, frame) in frames.iter().enumerate() {
2861            queue.ack(frame.sequence_number, 1);
2862            queue.ack(frame.sequence_number, 1);
2863            if index + 1 < frames.len() {
2864                assert_eq!(
2865                    queue.buffered_bytes,
2866                    initial - (index + 1) * SendQ::FRAME_BUDGET
2867                );
2868            }
2869        }
2870        assert_eq!(queue.buffered_bytes, 0);
2871        assert_eq!(owner.remaining.load(Ordering::Relaxed), 0);
2872    }
2873}
2874
2875#[cfg(test)]
2876mod flight_order_tests {
2877    use super::*;
2878
2879    #[test]
2880    fn retries_and_sequence_wrap_keep_the_existing_numeric_order() {
2881        let peer = "127.0.0.1:19132".parse().unwrap();
2882        let mut queue = SendQ::new(1400);
2883        queue.sequence_number = sequence::MASK;
2884        queue.insert(Reliability::ReliableOrdered, &[0xfe]).unwrap();
2885        queue.insert(Reliability::ReliableOrdered, &[0xfe]).unwrap();
2886        let initial = queue.flush(0, &peer);
2887        assert_eq!(
2888            initial
2889                .iter()
2890                .map(|frame| frame.sequence_number)
2891                .collect::<Vec<_>>(),
2892            [sequence::MASK, 0]
2893        );
2894        assert!(queue.flight_order_dirty);
2895        assert!(queue.flush(1, &peer).is_empty());
2896        assert_eq!(
2897            queue
2898                .sent_packet
2899                .iter()
2900                .map(|packet| packet.0.sequence_number)
2901                .collect::<Vec<_>>(),
2902            [0, sequence::MASK]
2903        );
2904        assert!(!queue.flight_order_dirty);
2905        queue.nack(sequence::MASK, 2);
2906        assert!(queue.flight_order_dirty);
2907        let retry = queue.flush(2, &peer);
2908        assert_eq!(retry.len(), 1);
2909        assert_eq!(retry[0].sequence_number, 1);
2910        assert!(!queue.flight_order_dirty);
2911        assert_eq!(
2912            queue
2913                .sent_packet
2914                .iter()
2915                .map(|packet| packet.0.sequence_number)
2916                .collect::<Vec<_>>(),
2917            [0, 1]
2918        );
2919        queue.ack(sequence::MASK, 3);
2920        queue.ack(0, 3);
2921        assert!(queue.is_empty());
2922        assert_eq!(queue.buffered_bytes, 0);
2923    }
2924}
2925
2926#[cfg(test)]
2927mod owned_decode_tests {
2928    use super::*;
2929
2930    #[test]
2931    fn a_single_frame_moves_the_udp_allocation_into_its_payload() {
2932        let frame = FrameSetPacket::new(Reliability::ReliableOrdered, vec![0xfe; 800]);
2933        let packet = frame.serialize().unwrap();
2934        let pointer = packet.as_ptr();
2935        let mut decoded = Vec::new();
2936        FrameVec::decode_owned_into(packet, &mut decoded).unwrap();
2937        assert_eq!(decoded.len(), 1);
2938        assert_eq!(decoded[0].data.as_ptr(), pointer);
2939        assert_eq!(decoded[0].data.as_ref(), frame.data.as_ref());
2940        let data: Vec<u8> = decoded.pop().unwrap().data.into();
2941        assert_eq!(data.as_ptr(), pointer);
2942    }
2943
2944    #[test]
2945    fn multiple_frames_and_invalid_lengths_keep_the_borrowed_decoder_contract() {
2946        let first = FrameSetPacket::new(Reliability::ReliableOrdered, vec![0xfe; 800]);
2947        let second = FrameSetPacket::new(Reliability::Unreliable, vec![0xfe; 64]);
2948        let mut packet = first.serialize().unwrap();
2949        packet.extend_from_slice(&second.serialize().unwrap()[4..]);
2950        let mut expected = Vec::new();
2951        FrameVec::decode_into(&packet, &mut expected).unwrap();
2952        let mut actual = Vec::new();
2953        FrameVec::decode_owned_into(packet.clone(), &mut actual).unwrap();
2954        assert_eq!(actual.len(), 2);
2955        for (actual, expected) in actual.iter().zip(&expected) {
2956            assert_eq!(actual.serialize().unwrap(), expected.serialize().unwrap());
2957        }
2958        for length in 0..packet.len() {
2959            let mut borrowed = Vec::new();
2960            let mut owned = Vec::new();
2961            assert_eq!(
2962                FrameVec::decode_into(&packet[..length], &mut borrowed).is_ok(),
2963                FrameVec::decode_owned_into(packet[..length].to_vec(), &mut owned).is_ok()
2964            );
2965        }
2966    }
2967}
2968
2969#[cfg(test)]
2970mod scheduling_regressions {
2971    use super::*;
2972
2973    #[test]
2974    fn cached_deadlines_match_a_full_scan_across_ack_loss_and_wrap() {
2975        let peer = "127.0.0.1:19132".parse().unwrap();
2976        let mut cached = SendQ::new(1400);
2977        cached.sequence_number = sequence::MASK - 80;
2978        let mut scanned = SendQ::new(1400);
2979        scanned.sequence_number = cached.sequence_number;
2980        let mut rng = 0x12345678u32;
2981        for tick in 0..4000 {
2982            rng = rng.wrapping_mul(1664525).wrapping_add(1013904223);
2983            if rng & 3 == 0 {
2984                for queue in [&mut cached, &mut scanned] {
2985                    queue
2986                        .insert(Reliability::ReliableOrdered, &[0xfe, 42])
2987                        .unwrap();
2988                }
2989            }
2990            if !cached.sent_packet.is_empty() && rng & 7 == 1 {
2991                let index = (rng as usize >> 8) % cached.sent_packet.len();
2992                let sequence = cached.sent_packet[index].0.sequence_number;
2993                for queue in [&mut cached, &mut scanned] {
2994                    if rng & 16 == 0 {
2995                        queue.ack(sequence, tick);
2996                    } else {
2997                        queue.nack(sequence, tick);
2998                    }
2999                }
3000            }
3001            // The oracle deliberately does the old full scan on every flush.
3002            scanned.next_retry = 0;
3003            scanned.retries_pending = true;
3004            let actual: Vec<_> = cached
3005                .flush(tick, &peer)
3006                .iter()
3007                .map(|f| f.serialize().unwrap())
3008                .collect();
3009            let expected: Vec<_> = scanned
3010                .flush(tick, &peer)
3011                .iter()
3012                .map(|f| f.serialize().unwrap())
3013                .collect();
3014            assert_eq!(actual, expected, "tick {tick}");
3015            assert_eq!(cached.buffered_bytes, scanned.buffered_bytes);
3016        }
3017    }
3018
3019    #[test]
3020    fn lower_rto_invalidates_the_deadline_and_retries_keep_the_backoff() {
3021        let peer = "127.0.0.1:19132".parse().unwrap();
3022        let mut queue = SendQ::new(1400);
3023        queue.srtt = 133;
3024        queue.rto = 200;
3025        for _ in 0..2 {
3026            queue.insert(Reliability::ReliableOrdered, &[0xfe]).unwrap();
3027        }
3028        queue.flush(0, &peer);
3029        queue.ack(0, 50);
3030        assert_eq!(queue.rto, 174);
3031        assert!(queue.flush(173, &peer).is_empty());
3032        assert_eq!(queue.flush(174, &peer).len(), 1);
3033        assert!(queue.flush(434, &peer).is_empty());
3034        assert_eq!(queue.flush(435, &peer).len(), 1);
3035        queue.ack(1, 436);
3036        assert!(queue.is_empty());
3037    }
3038
3039    #[test]
3040    fn ack_storage_is_recycled_without_replaying_old_ranges() {
3041        let mut set = ACKSet::default();
3042        let mut output = Vec::new();
3043        for index in 0..100 {
3044            set.insert(index);
3045            set.take_ack_into(&mut output);
3046            assert_eq!(output, [(index, index)]);
3047        }
3048        set.take_ack_into(&mut output);
3049        assert!(output.is_empty());
3050        assert!(set.ack.capacity() > 0);
3051    }
3052}
3053
3054#[cfg(test)]
3055mod owned_payload_tests {
3056    use super::*;
3057
3058    #[test]
3059    fn owned_sends_match_borrowed_wire_bytes_and_share_retry_storage() {
3060        let peer = "127.0.0.1:19132".parse().unwrap();
3061        for mode in [
3062            Reliability::Unreliable,
3063            Reliability::UnreliableSequenced,
3064            Reliability::Reliable,
3065            Reliability::ReliableOrdered,
3066            Reliability::ReliableSequenced,
3067        ] {
3068            for size in [64, 800, 4096] {
3069                let data = bytes::Bytes::from(vec![0xfe; size]);
3070                let mut owned = SendQ::new(1400);
3071                let mut borrowed = SendQ::new(1400);
3072                let a = owned.insert_bytes(mode, &data, 7);
3073                let b = borrowed.insert_with_order_channel(mode, &data, 7);
3074                assert_eq!(a.is_ok(), b.is_ok());
3075                if a.is_err() {
3076                    continue;
3077                }
3078                let frames = owned.flush(0, &peer);
3079                let expected = borrowed.flush(0, &peer);
3080                assert_eq!(
3081                    frames
3082                        .iter()
3083                        .map(|f| f.serialize().unwrap())
3084                        .collect::<Vec<_>>(),
3085                    expected
3086                        .iter()
3087                        .map(|f| f.serialize().unwrap())
3088                        .collect::<Vec<_>>()
3089                );
3090                let mut offset = 0;
3091                for frame in &frames {
3092                    assert_eq!(frame.data.as_ptr(), data[offset..].as_ptr());
3093                    offset += frame.data.len();
3094                }
3095                if mode != Reliability::Unreliable && mode != Reliability::UnreliableSequenced {
3096                    owned.nack(frames[0].sequence_number, 1);
3097                    let retry = owned.flush(1, &peer);
3098                    assert_eq!(retry[0].data.as_ptr(), data.as_ptr());
3099                    // Old ACK IDs still release each payload budget once.
3100                    owned.ack_ranges(&[(0, (frames.len() - 1) as u32)], 2);
3101                    assert!(owned.is_empty());
3102                    assert_eq!(owned.buffered_bytes, 0);
3103                }
3104            }
3105        }
3106    }
3107}