1use std::{collections::VecDeque, time::Instant};
2
3use bitfold_core::error::{ErrorKind, Result};
4use bitfold_protocol::{
5 command::ProtocolCommand,
6 command_codec::CommandDecoder,
7 packet::{DeliveryGuarantee, IncomingPackets, OrderingGuarantee, Packet, PacketType},
8};
9
10use super::Peer;
11use crate::{
12 channel_state::ChannelState, fragment_buffer::CommandFragmentBuffer, peer_state::PeerState,
13 pmtu_discovery::PmtuDiscovery,
14};
15
16impl Peer {
17 pub fn process_command_packet(
22 &mut self,
23 data: &[u8],
24 time: Instant,
25 ) -> Result<IncomingPackets> {
26 self.record_data_received(data.len());
28
29 let payload = if self.config.use_checksums {
31 CommandDecoder::validate_and_strip_checksum(data)
32 .map_err(|e| ErrorKind::CouldNotReadHeader(e.to_string()))?
33 } else {
34 data
35 };
36
37 let decompressed = CommandDecoder::decompress(payload)
39 .map_err(|e| ErrorKind::CouldNotReadHeader(e.to_string()))?;
40
41 let command_packet = CommandDecoder::decode_packet(&decompressed)
42 .map_err(|e| ErrorKind::CouldNotReadHeader(e.to_string()))?;
43
44 self.record_packet_received();
46
47 let mut all_packets = std::collections::VecDeque::new();
48
49 for command in &command_packet.commands {
50 let packets = self.process_command(command, time)?;
51 for packet in packets.into_iter() {
52 all_packets.push_back(packet);
53 }
54 }
55
56 Ok(IncomingPackets::many(all_packets))
57 }
58
59 pub fn process_command(
63 &mut self,
64 command: &ProtocolCommand,
65 time: Instant,
66 ) -> Result<IncomingPackets> {
67 self.last_heard = time;
68
69 match command {
70 ProtocolCommand::Acknowledge { sequence, received_mask, .. } => {
71 self.acknowledge_handler.process_incoming(
72 *sequence,
73 *sequence,
74 *received_mask,
75 time,
76 );
77 Ok(IncomingPackets::zero())
78 }
79 ProtocolCommand::Ping { timestamp } => {
80 self.enqueue_pong_command(*timestamp);
82 Ok(IncomingPackets::zero())
83 }
84 ProtocolCommand::Pong { .. } => {
85 Ok(IncomingPackets::zero())
87 }
88 ProtocolCommand::SendReliable { channel_id, sequence, ordered, data } => {
89 self.acknowledge_handler.process_incoming(*sequence, *sequence, 0, time);
91
92 self.enqueue_ack_command(None);
94 if *ordered {
95 let channel_state =
97 self.channel_states.entry(*channel_id).or_insert_with(ChannelState::new);
98
99 let ordered_packets = channel_state.process_ordered(
100 *sequence,
101 bitfold_core::shared::SharedBytes::from_arc(
102 data.clone().into_full_arc().unwrap_or_else(|| {
103 std::sync::Arc::<[u8]>::from(
104 data.as_slice().to_vec().into_boxed_slice(),
105 )
106 }),
107 ),
108 );
109
110 let mut packets = VecDeque::new();
112 for packet_data in ordered_packets {
113 packets.push_back((
114 Packet::new(
115 self.remote_address,
116 {
117 if let Some(full) = packet_data.clone().into_full_arc() {
118 full
119 } else {
120 std::sync::Arc::<[u8]>::from(
121 packet_data.as_slice().to_vec().into_boxed_slice(),
122 )
123 }
124 },
125 DeliveryGuarantee::Reliable,
126 OrderingGuarantee::Ordered(None),
127 *channel_id,
128 ),
129 PacketType::Packet,
130 ));
131 }
132
133 Ok(IncomingPackets::many(packets))
134 } else {
135 Ok(IncomingPackets::one(
137 Packet::new(
138 self.remote_address,
139 data.clone().into_full_arc().unwrap_or_else(|| {
140 std::sync::Arc::<[u8]>::from(
141 data.as_slice().to_vec().into_boxed_slice(),
142 )
143 }),
144 DeliveryGuarantee::Reliable,
145 OrderingGuarantee::None,
146 *channel_id,
147 ),
148 PacketType::Packet,
149 ))
150 }
151 }
152 ProtocolCommand::SendUnreliable { channel_id, data } => {
153 Ok(IncomingPackets::one(
155 Packet::new(
156 self.remote_address,
157 data.clone().into_full_arc().unwrap_or_else(|| {
158 std::sync::Arc::<[u8]>::from(
159 data.as_slice().to_vec().into_boxed_slice(),
160 )
161 }),
162 DeliveryGuarantee::Unreliable,
163 OrderingGuarantee::None,
164 *channel_id,
165 ),
166 PacketType::Packet,
167 ))
168 }
169 ProtocolCommand::SendUnreliableSequenced { channel_id, sequence, data } => {
170 let channel_state =
172 self.channel_states.entry(*channel_id).or_insert_with(ChannelState::new);
173
174 if let Some(packet_data) = channel_state.process_sequenced(
176 *sequence,
177 bitfold_core::shared::SharedBytes::from_arc(
178 data.clone().into_full_arc().unwrap_or_else(|| {
179 std::sync::Arc::<[u8]>::from(
180 data.as_slice().to_vec().into_boxed_slice(),
181 )
182 }),
183 ),
184 ) {
185 Ok(IncomingPackets::one(
186 Packet::new(
187 self.remote_address,
188 {
189 if let Some(full) = packet_data.clone().into_full_arc() {
190 full
191 } else {
192 std::sync::Arc::<[u8]>::from(
193 packet_data.as_slice().to_vec().into_boxed_slice(),
194 )
195 }
196 },
197 DeliveryGuarantee::Unreliable,
198 OrderingGuarantee::Sequenced(None),
199 *channel_id,
200 ),
201 PacketType::Packet,
202 ))
203 } else {
204 Ok(IncomingPackets::zero())
206 }
207 }
208 ProtocolCommand::SendUnsequenced { channel_id, unsequenced_group, data } => {
209 if self.is_unsequenced_duplicate(*unsequenced_group) {
211 Ok(IncomingPackets::zero())
213 } else {
214 self.mark_unsequenced_received(*unsequenced_group);
216
217 Ok(IncomingPackets::one(
219 Packet::new(
220 self.remote_address,
221 data.clone().into_full_arc().unwrap_or_else(|| {
222 std::sync::Arc::<[u8]>::from(
223 data.as_slice().to_vec().into_boxed_slice(),
224 )
225 }),
226 DeliveryGuarantee::Unreliable,
227 OrderingGuarantee::Unsequenced,
228 *channel_id,
229 ),
230 PacketType::Packet,
231 ))
232 }
233 }
234 ProtocolCommand::SendFragment {
235 channel_id,
236 sequence,
237 ordered,
238 fragment_id,
239 fragment_count,
240 data,
241 } => {
242 self.acknowledge_handler.process_incoming(*sequence, *sequence, 0, time);
244
245 let buffer = self.command_fragments.entry(*sequence).or_insert_with(|| {
247 CommandFragmentBuffer::new(*channel_id, *fragment_count, *ordered, time)
248 });
249
250 buffer.add_fragment(
252 *fragment_id,
253 data.clone().into_full_arc().unwrap_or_else(|| {
254 std::sync::Arc::<[u8]>::from(data.as_slice().to_vec().into_boxed_slice())
255 }),
256 );
257
258 if buffer.is_complete() {
260 if let Some(buffer) = self.command_fragments.remove(sequence) {
262 let channel_id = buffer.channel_id();
263 let is_ordered = buffer.is_ordered();
264 if let Some(reassembled) = buffer.reassemble() {
265 self.enqueue_ack_command(None);
267
268 if is_ordered {
269 let channel_state = self
271 .channel_states
272 .entry(channel_id)
273 .or_insert_with(ChannelState::new);
274
275 let ready_packets = channel_state.process_ordered(
276 *sequence,
277 bitfold_core::shared::SharedBytes::from_vec(reassembled),
278 );
279 if ready_packets.is_empty() {
280 return Ok(IncomingPackets::zero());
281 } else if ready_packets.len() == 1 {
282 return Ok(IncomingPackets::one(
283 Packet::new(
284 self.remote_address,
285 ready_packets[0]
286 .clone()
287 .into_full_arc()
288 .unwrap_or_else(|| {
289 std::sync::Arc::<[u8]>::from(
290 ready_packets[0]
291 .as_slice()
292 .to_vec()
293 .into_boxed_slice(),
294 )
295 }),
296 DeliveryGuarantee::Reliable,
297 OrderingGuarantee::None,
298 channel_id,
299 ),
300 PacketType::Packet,
301 ));
302 } else {
303 let mut vec = std::collections::VecDeque::new();
304 for payload in ready_packets {
305 vec.push_back((
306 Packet::new(
307 self.remote_address,
308 {
309 if let Some(full) =
310 payload.clone().into_full_arc()
311 {
312 full
313 } else {
314 std::sync::Arc::<[u8]>::from(
315 payload
316 .as_slice()
317 .to_vec()
318 .into_boxed_slice(),
319 )
320 }
321 },
322 DeliveryGuarantee::Reliable,
323 OrderingGuarantee::None,
324 channel_id,
325 ),
326 PacketType::Packet,
327 ));
328 }
329 return Ok(IncomingPackets::many(vec));
330 }
331 } else {
332 return Ok(IncomingPackets::one(
334 Packet::new(
335 self.remote_address,
336 std::sync::Arc::<[u8]>::from(
337 reassembled.into_boxed_slice(),
338 ),
339 DeliveryGuarantee::Reliable,
340 OrderingGuarantee::None,
341 channel_id,
342 ),
343 PacketType::Packet,
344 ));
345 }
346 }
347 }
348 }
349
350 Ok(IncomingPackets::zero())
352 }
353 ProtocolCommand::SendUnreliableFragment {
354 channel_id,
355 sequence,
356 fragment_id,
357 fragment_count,
358 data,
359 } => {
360 let buffer = self.command_fragments.entry(*sequence).or_insert_with(|| {
363 CommandFragmentBuffer::new(*channel_id, *fragment_count, false, time)
364 });
365
366 buffer.add_fragment(
368 *fragment_id,
369 data.clone().into_full_arc().unwrap_or_else(|| {
370 std::sync::Arc::<[u8]>::from(data.as_slice().to_vec().into_boxed_slice())
371 }),
372 );
373
374 if buffer.is_complete() {
376 if let Some(buffer) = self.command_fragments.remove(sequence) {
378 let channel_id = buffer.channel_id();
379 if let Some(reassembled) = buffer.reassemble() {
380 return Ok(IncomingPackets::one(
382 Packet::new(
383 self.remote_address,
384 std::sync::Arc::<[u8]>::from(reassembled.into_boxed_slice()),
385 DeliveryGuarantee::Unreliable,
386 OrderingGuarantee::None,
387 channel_id,
388 ),
389 PacketType::Packet,
390 ));
391 }
392 }
393 }
394
395 Ok(IncomingPackets::zero())
397 }
398 ProtocolCommand::Disconnect { reason: _ } => {
399 self.state = PeerState::Zombie;
401 Ok(IncomingPackets::zero())
402 }
403 ProtocolCommand::Connect {
404 channels,
405 mtu: _,
406 protocol_version: _,
407 outgoing_session_id,
408 connect_id,
409 } => {
410 if self.state == PeerState::Idle {
413 use rand::Rng;
414 let mut rng = rand::rng();
415
416 self.incoming_session_id = *outgoing_session_id;
418 self.peer_id = rng.random();
420 self.connect_id = *connect_id;
422
423 self.state = PeerState::AcknowledgingConnect;
425
426 let verify_command = ProtocolCommand::VerifyConnect {
428 peer_id: self.peer_id,
429 channels: *channels.min(&self.config.channel_count), mtu: 1400, incoming_session_id: self.outgoing_session_id, outgoing_session_id: self.incoming_session_id, window_size: self.window_size(), };
435 self.command_queue.enqueue(verify_command);
436 }
437 Ok(IncomingPackets::zero())
438 }
439 ProtocolCommand::VerifyConnect {
440 peer_id,
441 channels: _,
442 mtu: _,
443 incoming_session_id,
444 outgoing_session_id,
445 window_size,
446 } => {
447 if self.state == PeerState::Connecting {
449 self.peer_id = *peer_id;
451 self.incoming_session_id = *incoming_session_id;
452
453 if self.config.use_window_flow_control {
455 self.set_window_size((*window_size).min(self.window_size()));
456 }
457 if *outgoing_session_id != self.outgoing_session_id {
459 return Err(ErrorKind::CouldNotReadHeader(
461 "Session ID mismatch".to_string(),
462 ));
463 }
464
465 self.state = PeerState::ConnectionSucceeded;
467
468 }
471 Ok(IncomingPackets::zero())
472 }
473 ProtocolCommand::BandwidthLimit { incoming, outgoing } => {
474 self.config.incoming_bandwidth_limit = *incoming;
476 self.config.outgoing_bandwidth_limit = *outgoing;
477 self.bandwidth_throttle.set_incoming_bandwidth_limit(*incoming);
478 self.bandwidth_throttle.set_outgoing_bandwidth_limit(*outgoing);
479 tracing::debug!(
480 "Applied BandwidthLimit: incoming={}B/s outgoing={}B/s",
481 incoming,
482 outgoing
483 );
484 Ok(IncomingPackets::zero())
485 }
486 ProtocolCommand::ThrottleConfigure { interval, acceleration, deceleration } => {
487 self.acknowledge_handler.congestion_mut().configure_throttle(
489 *interval,
490 *acceleration,
491 *deceleration,
492 );
493 tracing::debug!(
494 "Throttle configured: interval={}ms, accel={}, decel={}",
495 interval,
496 acceleration,
497 deceleration
498 );
499 Ok(IncomingPackets::zero())
500 }
501 ProtocolCommand::PMTUProbe { size, token, .. } => {
502 let reply = PmtuDiscovery::create_reply(*size, *token);
504 self.enqueue_command(reply);
505 Ok(IncomingPackets::zero())
506 }
507 ProtocolCommand::PMTUReply { size, token } => {
508 self.pmtu.process_reply(*size, *token, time);
510 Ok(IncomingPackets::zero())
511 }
512 }
513 }
514}
515
516#[cfg(test)]
517mod tests {
518 use bitfold_core::config::Config;
519 use bitfold_protocol::command::ProtocolCommand;
520
521 use super::*;
522
523 fn create_virtual_connection() -> Peer {
524 Peer::new(get_fake_addr(), &Config::default(), Instant::now())
525 }
526
527 fn get_fake_addr() -> std::net::SocketAddr {
528 "127.0.0.1:0".parse().unwrap()
529 }
530
531 #[test]
532 fn test_command_queue_integration() {
533 let mut peer = create_virtual_connection();
534
535 assert!(!peer.has_queued_commands());
537 assert_eq!(peer.queued_commands_count(), 0);
538
539 peer.enqueue_command(ProtocolCommand::Ping { timestamp: 1000 });
540 assert!(peer.has_queued_commands());
541 assert_eq!(peer.queued_commands_count(), 1);
542
543 peer.enqueue_command(ProtocolCommand::SendReliable {
544 channel_id: 0,
545 sequence: 0,
546 ordered: true,
547 data: vec![1, 2, 3].into(),
548 });
549 assert_eq!(peer.queued_commands_count(), 2);
550
551 let commands: Vec<_> = peer.drain_commands().collect();
553 assert_eq!(commands.len(), 2);
554 assert!(!peer.has_queued_commands());
555 }
556
557 #[test]
558 fn test_process_command_reliable_data() {
559 let mut peer = create_virtual_connection();
560 let time = Instant::now();
561
562 let command = ProtocolCommand::SendReliable {
563 channel_id: 0,
564 sequence: 0,
565 ordered: true,
566 data: vec![1, 2, 3, 4].into(),
567 };
568
569 let result = peer.process_command(&command, time).unwrap();
570 let packets: Vec<_> = result.into_iter().collect();
571
572 assert_eq!(packets.len(), 1);
573 let (packet, _) = &packets[0];
574 assert_eq!(packet.payload(), &[1, 2, 3, 4]);
575 }
576
577 #[test]
578 fn test_process_command_unreliable_data() {
579 let mut peer = create_virtual_connection();
580 let time = Instant::now();
581
582 let command = ProtocolCommand::SendUnreliable { channel_id: 0, data: vec![5, 6, 7].into() };
583
584 let result = peer.process_command(&command, time).unwrap();
585 let packets: Vec<_> = result.into_iter().collect();
586
587 assert_eq!(packets.len(), 1);
588 let (packet, _) = &packets[0];
589 assert_eq!(packet.payload(), &[5, 6, 7]);
590 }
591
592 #[test]
593 fn test_automatic_pong_response() {
594 let mut peer = create_virtual_connection();
595 let time = Instant::now();
596
597 assert!(!peer.has_queued_commands());
599
600 let ping = ProtocolCommand::Ping { timestamp: 12345 };
602 peer.process_command(&ping, time).unwrap();
603
604 assert!(peer.has_queued_commands());
606 assert_eq!(peer.queued_commands_count(), 1);
607
608 let commands: Vec<_> = peer.drain_commands().collect();
609 assert_eq!(commands.len(), 1);
610 match &commands[0] {
611 ProtocolCommand::Pong { timestamp } => {
612 assert_eq!(*timestamp, 12345);
613 }
614 _ => panic!("Expected Pong command"),
615 }
616 }
617
618 #[test]
619 fn test_automatic_ack_response() {
620 let mut peer = create_virtual_connection();
621 let time = Instant::now();
622
623 assert!(!peer.has_queued_commands());
625
626 let reliable = ProtocolCommand::SendReliable {
628 channel_id: 0,
629 sequence: 0,
630 ordered: true,
631 data: vec![1, 2, 3, 4].into(),
632 };
633 let result = peer.process_command(&reliable, time).unwrap();
634
635 assert_eq!(result.into_iter().count(), 1);
637
638 assert!(peer.has_queued_commands());
640 let commands: Vec<_> = peer.drain_commands().collect();
641 assert_eq!(commands.len(), 1);
642 match &commands[0] {
643 ProtocolCommand::Acknowledge { .. } => {
644 }
646 _ => panic!("Expected Acknowledge command"),
647 }
648 }
649
650 #[test]
651 fn test_round_trip_ping_pong() {
652 let mut peer1 = create_virtual_connection();
653 let mut peer2 = create_virtual_connection();
654 let time = Instant::now();
655
656 peer1.enqueue_ping_command(1000);
658 let bytes = peer1.encode_queued_commands().unwrap();
659
660 peer2.process_command_packet(&bytes, time).unwrap();
662 assert!(peer2.has_queued_commands());
663
664 let pong_bytes = peer2.encode_queued_commands().unwrap();
665
666 peer1.process_command_packet(&pong_bytes, time).unwrap();
668 assert!(!peer1.has_queued_commands()); }
670
671 #[test]
672 fn test_round_trip_reliable_with_ack() {
673 let mut peer1 = create_virtual_connection();
674 let mut peer2 = create_virtual_connection();
675 let time = Instant::now();
676
677 peer1.enqueue_command(ProtocolCommand::SendReliable {
679 channel_id: 0,
680 sequence: 0,
681 ordered: true,
682 data: vec![1, 2, 3, 4, 5].into(),
683 });
684 let bytes = peer1.encode_queued_commands().unwrap();
685
686 let result = peer2.process_command_packet(&bytes, time).unwrap();
688 let packets: Vec<_> = result.into_iter().collect();
689 assert_eq!(packets.len(), 1);
690 assert_eq!(packets[0].0.payload(), &[1, 2, 3, 4, 5]);
691
692 assert!(peer2.has_queued_commands());
694 let ack_bytes = peer2.encode_queued_commands().unwrap();
695
696 let result = peer1.process_command_packet(&ack_bytes, time).unwrap();
698 assert_eq!(result.into_iter().count(), 0);
699 }
700
701 #[test]
702 fn test_bandwidth_limit_command_updates_config() {
703 let start = Instant::now();
704 let cfg = Config::default();
705 let mut peer = Peer::new(get_fake_addr(), &cfg, start);
706
707 assert_eq!(peer.config().incoming_bandwidth_limit, 2_097_152);
709 assert_eq!(peer.config().outgoing_bandwidth_limit, 2_097_152);
710
711 let _ = peer
713 .process_command(
714 &ProtocolCommand::BandwidthLimit { incoming: 1234, outgoing: 5678 },
715 start,
716 )
717 .unwrap();
718
719 assert_eq!(peer.config().incoming_bandwidth_limit, 1234);
720 assert_eq!(peer.config().outgoing_bandwidth_limit, 5678);
721 }
722
723 #[test]
724 fn test_multi_channel_packets() {
725 let mut peer = create_virtual_connection();
726 let time = Instant::now();
727
728 let cmd_ch0 = ProtocolCommand::SendReliable {
730 channel_id: 0,
731 sequence: 0,
732 ordered: true,
733 data: vec![0, 1, 2].into(),
734 };
735 let cmd_ch1 = ProtocolCommand::SendReliable {
736 channel_id: 1,
737 sequence: 0,
738 ordered: true,
739 data: vec![10, 11, 12].into(),
740 };
741 let cmd_ch5 =
742 ProtocolCommand::SendUnreliable { channel_id: 5, data: vec![50, 51, 52].into() };
743
744 let result0 = peer.process_command(&cmd_ch0, time).unwrap();
746 let result1 = peer.process_command(&cmd_ch1, time).unwrap();
747 let result5 = peer.process_command(&cmd_ch5, time).unwrap();
748
749 let packets0: Vec<_> = result0.into_iter().collect();
751 assert_eq!(packets0.len(), 1);
752 assert_eq!(packets0[0].0.channel_id(), 0);
753 assert_eq!(packets0[0].0.payload(), &[0, 1, 2]);
754
755 let packets1: Vec<_> = result1.into_iter().collect();
756 assert_eq!(packets1.len(), 1);
757 assert_eq!(packets1[0].0.channel_id(), 1);
758 assert_eq!(packets1[0].0.payload(), &[10, 11, 12]);
759
760 let packets5: Vec<_> = result5.into_iter().collect();
761 assert_eq!(packets5.len(), 1);
762 assert_eq!(packets5[0].0.channel_id(), 5);
763 assert_eq!(packets5[0].0.payload(), &[50, 51, 52]);
764 }
765
766 #[test]
767 fn test_per_channel_ordering() {
768 let mut peer = create_virtual_connection();
769 let time = Instant::now();
770
771 let cmd2 = ProtocolCommand::SendReliable {
773 channel_id: 0,
774 sequence: 2,
775 ordered: true,
776 data: vec![20, 21, 22].into(),
777 };
778 let cmd0 = ProtocolCommand::SendReliable {
779 channel_id: 0,
780 sequence: 0,
781 ordered: true,
782 data: vec![0, 1, 2].into(),
783 };
784 let cmd1 = ProtocolCommand::SendReliable {
785 channel_id: 0,
786 sequence: 1,
787 ordered: true,
788 data: vec![10, 11, 12].into(),
789 };
790
791 let result2 = peer.process_command(&cmd2, time).unwrap();
793 assert_eq!(result2.into_iter().count(), 0); let result0 = peer.process_command(&cmd0, time).unwrap();
796 assert_eq!(result0.into_iter().count(), 1); let result1 = peer.process_command(&cmd1, time).unwrap();
799 let packets: Vec<_> = result1.into_iter().collect();
800 assert_eq!(packets.len(), 2); assert_eq!(packets[0].0.payload(), &[10, 11, 12]); assert_eq!(packets[1].0.payload(), &[20, 21, 22]); }
806
807 #[test]
808 fn test_reliable_unordered_delivery() {
809 let mut peer = create_virtual_connection();
810 let time = Instant::now();
811
812 let cmd2 = ProtocolCommand::SendReliable {
814 channel_id: 0,
815 sequence: 2,
816 ordered: false,
817 data: vec![20, 21, 22].into(),
818 };
819 let cmd0 = ProtocolCommand::SendReliable {
820 channel_id: 0,
821 sequence: 0,
822 ordered: false,
823 data: vec![0, 1, 2].into(),
824 };
825 let cmd1 = ProtocolCommand::SendReliable {
826 channel_id: 0,
827 sequence: 1,
828 ordered: false,
829 data: vec![10, 11, 12].into(),
830 };
831
832 let r2 = peer.process_command(&cmd2, time).unwrap();
834 let v2: Vec<_> = r2.into_iter().collect();
835 assert_eq!(v2.len(), 1);
836 assert_eq!(v2[0].0.payload(), &[20, 21, 22]);
837
838 let r0 = peer.process_command(&cmd0, time).unwrap();
839 let v0: Vec<_> = r0.into_iter().collect();
840 assert_eq!(v0.len(), 1);
841 assert_eq!(v0[0].0.payload(), &[0, 1, 2]);
842
843 let r1 = peer.process_command(&cmd1, time).unwrap();
844 let v1: Vec<_> = r1.into_iter().collect();
845 assert_eq!(v1.len(), 1);
846 assert_eq!(v1[0].0.payload(), &[10, 11, 12]);
847 }
848
849 #[test]
850 fn test_per_channel_sequencing() {
851 let mut peer = create_virtual_connection();
852 let time = Instant::now();
853
854 let cmd0 = ProtocolCommand::SendUnreliableSequenced {
856 channel_id: 0,
857 sequence: 0,
858 data: vec![0, 1, 2].into(),
859 };
860 let cmd2 = ProtocolCommand::SendUnreliableSequenced {
861 channel_id: 0,
862 sequence: 2,
863 data: vec![20, 21, 22].into(),
864 };
865 let cmd1 = ProtocolCommand::SendUnreliableSequenced {
866 channel_id: 0,
867 sequence: 1,
868 data: vec![10, 11, 12].into(),
869 };
870
871 let result0 = peer.process_command(&cmd0, time).unwrap();
873 assert_eq!(result0.into_iter().count(), 1); let result2 = peer.process_command(&cmd2, time).unwrap();
876 assert_eq!(result2.into_iter().count(), 1); let result1 = peer.process_command(&cmd1, time).unwrap();
879 assert_eq!(result1.into_iter().count(), 0); }
881
882 #[test]
883 fn test_independent_channel_ordering() {
884 let mut peer = create_virtual_connection();
885 let time = Instant::now();
886
887 let ch0_cmd1 = ProtocolCommand::SendReliable {
889 channel_id: 0,
890 sequence: 1,
891 ordered: true,
892 data: vec![0, 1].into(),
893 };
894 let ch1_cmd1 = ProtocolCommand::SendReliable {
895 channel_id: 1,
896 sequence: 1,
897 ordered: true,
898 data: vec![1, 1].into(),
899 };
900 let ch0_cmd0 = ProtocolCommand::SendReliable {
901 channel_id: 0,
902 sequence: 0,
903 ordered: true,
904 data: vec![0, 0].into(),
905 };
906 let ch1_cmd0 = ProtocolCommand::SendReliable {
907 channel_id: 1,
908 sequence: 0,
909 ordered: true,
910 data: vec![1, 0].into(),
911 };
912
913 let result = peer.process_command(&ch0_cmd1, time).unwrap();
915 assert_eq!(result.into_iter().count(), 0);
916
917 let result = peer.process_command(&ch1_cmd1, time).unwrap();
919 assert_eq!(result.into_iter().count(), 0);
920
921 let result = peer.process_command(&ch0_cmd0, time).unwrap();
923 let packets: Vec<_> = result.into_iter().collect();
924 assert_eq!(packets.len(), 2);
925 assert_eq!(packets[0].0.channel_id(), 0);
926
927 let result = peer.process_command(&ch1_cmd0, time).unwrap();
929 let packets: Vec<_> = result.into_iter().collect();
930 assert_eq!(packets.len(), 2);
931 assert_eq!(packets[0].0.channel_id(), 1);
932 }
933
934 #[test]
935 fn test_unsequenced_packets_basic() {
936 let mut peer = create_virtual_connection();
937 let time = Instant::now();
938
939 let cmd1 = ProtocolCommand::SendUnsequenced {
941 channel_id: 0,
942 unsequenced_group: 0,
943 data: vec![1, 2, 3].into(),
944 };
945 let cmd2 = ProtocolCommand::SendUnsequenced {
946 channel_id: 0,
947 unsequenced_group: 1,
948 data: vec![4, 5, 6].into(),
949 };
950
951 let result1 = peer.process_command(&cmd1, time).unwrap();
953 let result2 = peer.process_command(&cmd2, time).unwrap();
954
955 assert_eq!(result1.into_iter().count(), 1);
957 assert_eq!(result2.into_iter().count(), 1);
958 }
959
960 #[test]
961 fn test_unsequenced_packets_prevent_duplicates() {
962 let mut peer = create_virtual_connection();
963 let time = Instant::now();
964
965 let cmd = ProtocolCommand::SendUnsequenced {
967 channel_id: 0,
968 unsequenced_group: 5,
969 data: vec![1, 2, 3].into(),
970 };
971
972 let result1 = peer.process_command(&cmd, time).unwrap();
974 assert_eq!(result1.into_iter().count(), 1);
975
976 let result2 = peer.process_command(&cmd, time).unwrap();
978 assert_eq!(result2.into_iter().count(), 0); }
980
981 #[test]
982 fn test_unsequenced_packets_allow_out_of_order() {
983 let mut peer = create_virtual_connection();
984 let time = Instant::now();
985
986 let cmd10 = ProtocolCommand::SendUnsequenced {
988 channel_id: 0,
989 unsequenced_group: 10,
990 data: vec![10].into(),
991 };
992 let cmd5 = ProtocolCommand::SendUnsequenced {
993 channel_id: 0,
994 unsequenced_group: 5,
995 data: vec![5].into(),
996 };
997 let cmd15 = ProtocolCommand::SendUnsequenced {
998 channel_id: 0,
999 unsequenced_group: 15,
1000 data: vec![15].into(),
1001 };
1002
1003 let result10 = peer.process_command(&cmd10, time).unwrap();
1005 let result5 = peer.process_command(&cmd5, time).unwrap();
1006 let result15 = peer.process_command(&cmd15, time).unwrap();
1007
1008 assert_eq!(result10.into_iter().count(), 1);
1009 assert_eq!(result5.into_iter().count(), 1);
1010 assert_eq!(result15.into_iter().count(), 1);
1011 }
1012
1013 #[test]
1014 fn test_unsequenced_window_sliding() {
1015 let mut peer = create_virtual_connection();
1016 let time = Instant::now();
1017
1018 let cmd0 = ProtocolCommand::SendUnsequenced {
1020 channel_id: 0,
1021 unsequenced_group: 0,
1022 data: vec![0].into(),
1023 };
1024 let result0 = peer.process_command(&cmd0, time).unwrap();
1025 assert_eq!(result0.into_iter().count(), 1);
1026
1027 let cmd1500 = ProtocolCommand::SendUnsequenced {
1029 channel_id: 0,
1030 unsequenced_group: 1500,
1031 data: vec![1].into(),
1032 };
1033 let result1500 = peer.process_command(&cmd1500, time).unwrap();
1034 assert_eq!(result1500.into_iter().count(), 1); let result0_again = peer.process_command(&cmd0, time).unwrap();
1038 assert_eq!(result0_again.into_iter().count(), 0); }
1040}