1use crate::association::{
2 state::{AckMode, AckState, AssociationState},
3 stats::AssociationStats,
4};
5use crate::chunk::chunk_header::CHUNK_HEADER_SIZE;
6use crate::chunk::{
7 Chunk, ErrorCauseUnrecognizedChunkType, USER_INITIATED_ABORT, chunk_abort::ChunkAbort,
8 chunk_cookie_ack::ChunkCookieAck, chunk_cookie_echo::ChunkCookieEcho, chunk_error::ChunkError,
9 chunk_forward_tsn::ChunkForwardTsn, chunk_forward_tsn::ChunkForwardTsnStream,
10 chunk_heartbeat::ChunkHeartbeat, chunk_heartbeat_ack::ChunkHeartbeatAck, chunk_init::ChunkInit,
11 chunk_init::ChunkInitAck, chunk_payload_data::ChunkPayloadData,
12 chunk_payload_data::PayloadProtocolIdentifier, chunk_reconfig::ChunkReconfig,
13 chunk_selective_ack::ChunkSelectiveAck, chunk_shutdown::ChunkShutdown,
14 chunk_shutdown_ack::ChunkShutdownAck, chunk_shutdown_complete::ChunkShutdownComplete,
15 chunk_type::CT_FORWARD_TSN,
16};
17use crate::config::{COMMON_HEADER_SIZE, DATA_CHUNK_HEADER_SIZE, ServerConfig, TransportConfig};
18use crate::packet::{CommonHeader, Packet};
19use crate::param::{
20 Param,
21 param_heartbeat_info::ParamHeartbeatInfo,
22 param_outgoing_reset_request::ParamOutgoingResetRequest,
23 param_reconfig_response::{ParamReconfigResponse, ReconfigResult},
24 param_state_cookie::ParamStateCookie,
25 param_supported_extensions::ParamSupportedExtensions,
26};
27use crate::queue::{payload_queue::PayloadQueue, pending_queue::PendingQueue};
28use crate::shared::{AssociationEventInner, AssociationId, EndpointEvent, EndpointEventInner};
29use crate::util::{sna16lt, sna32gt, sna32gte, sna32lt, sna32lte};
30use crate::{AssociationEvent, Payload, Side};
31use shared::error::{Error, Result};
32use shared::{TransportContext, TransportMessage, TransportProtocol};
33use stream::{ReliabilityType, Stream, StreamEvent, StreamId, StreamState};
34use timer::{ACK_INTERVAL, RtoManager, Timer, TimerTable};
35
36use crate::association::stream::RecvSendState;
37use bytes::{Bytes, BytesMut};
38use log::{debug, error, trace, warn};
39use rand::random;
40use rustc_hash::FxHashMap;
41use std::collections::{HashMap, VecDeque};
42use std::net::SocketAddr;
43use std::str::FromStr;
44use std::sync::Arc;
45use std::time::{Duration, Instant};
46use thiserror::Error;
47
48pub(crate) mod state;
49pub(crate) mod stats;
50pub(crate) mod stream;
51pub(crate) mod timer;
52
53#[cfg(test)]
54mod association_test;
55
56#[derive(Debug, Error, Clone, PartialEq)]
58pub enum AssociationError {
59 #[error("handshake failed due to {0}")]
61 HandshakeFailed(String),
62 #[error("transport error")]
64 TransportError,
65 #[error("aborted by peer")]
67 AssociationClosed,
68 #[error("closed by peer")]
70 ApplicationClosed,
71 #[error("reset by peer")]
73 Reset,
74 #[error("timed out")]
79 TimedOut,
80 #[error("closed")]
82 LocallyClosed,
83}
84
85#[derive(Debug)]
87#[non_exhaustive]
88pub enum Event {
89 HandshakeFailed {
91 reason: AssociationError,
93 },
94
95 Connected,
97 AssociationLost {
101 reason: AssociationError,
103 id: StreamId,
105 },
106 Stream(StreamEvent),
108 DatagramReceived,
110}
111
112pub struct Association {
130 side: Side,
131 state: AssociationState,
132 handshake_completed: bool,
133 max_message_size: u32,
134 inflight_queue_length: usize,
135 will_send_shutdown: bool,
136 bytes_received: usize,
137 bytes_sent: usize,
138
139 peer_verification_tag: u32,
140 my_verification_tag: u32,
141 my_next_tsn: u32,
142 peer_last_tsn: u32,
143 min_tsn2measure_rtt: u32,
145 will_send_forward_tsn: bool,
146 will_retransmit_fast: bool,
147 will_retransmit_reconfig: bool,
148 t3_retransmit_pending: bool,
154
155 will_send_shutdown_ack: bool,
156 will_send_shutdown_complete: bool,
157
158 my_next_rsn: u32,
160 reconfigs: HashMap<u32, ChunkReconfig>,
161 reconfig_requests: HashMap<u32, ParamOutgoingResetRequest>,
162
163 remote_addr: SocketAddr,
165 local_addr: SocketAddr,
166 transport_protocol: TransportProtocol,
167
168 source_port: u16,
169 destination_port: u16,
170 my_max_num_inbound_streams: u16,
171 my_max_num_outbound_streams: u16,
172 my_cookie: Option<ParamStateCookie>,
173
174 payload_queue: PayloadQueue,
175 inflight_queue: PayloadQueue,
176 pending_queue: PendingQueue,
177 control_queue: VecDeque<Packet>,
178 stream_queue: VecDeque<u16>,
179
180 pub(crate) mtu: u32,
181 max_payload_size: u32,
183 cumulative_tsn_ack_point: u32,
184 advanced_peer_tsn_ack_point: u32,
185 use_forward_tsn: bool,
186 fwd_tsn_stream_map: FxHashMap<u16, u16>,
196
197 pub(crate) rto_mgr: RtoManager,
198 timers: TimerTable,
199
200 max_receive_buffer_size: u32,
202 pub(crate) cwnd: u32,
204 rwnd: u32,
206 pub(crate) ssthresh: u32,
208 partial_bytes_acked: u32,
209 pub(crate) in_fast_recovery: bool,
210 fast_recover_exit_point: u32,
211
212 stored_init: Option<ChunkInit>,
214 stored_cookie_echo: Option<ChunkCookieEcho>,
215 pub(crate) streams: FxHashMap<StreamId, StreamState>,
218
219 events: VecDeque<Event>,
220 endpoint_events: VecDeque<EndpointEventInner>,
221 error: Option<AssociationError>,
222
223 delayed_ack_triggered: bool,
225 immediate_ack_triggered: bool,
226
227 pub(crate) stats: AssociationStats,
228 ack_state: AckState,
229
230 pub(crate) ack_mode: AckMode,
232}
233
234impl Default for Association {
235 fn default() -> Self {
236 Association {
237 side: Side::default(),
238 state: AssociationState::default(),
239 handshake_completed: false,
240 max_message_size: 0,
241 inflight_queue_length: 0,
242 will_send_shutdown: false,
243 bytes_received: 0,
244 bytes_sent: 0,
245
246 peer_verification_tag: 0,
247 my_verification_tag: 0,
248 my_next_tsn: 0,
249 peer_last_tsn: 0,
250 min_tsn2measure_rtt: 0,
252 will_send_forward_tsn: false,
253 will_retransmit_fast: false,
254 will_retransmit_reconfig: false,
255 t3_retransmit_pending: false,
256
257 will_send_shutdown_ack: false,
258 will_send_shutdown_complete: false,
259
260 my_next_rsn: 0,
262 reconfigs: HashMap::default(),
263 reconfig_requests: HashMap::default(),
264
265 remote_addr: SocketAddr::from_str("0.0.0.0:0").unwrap(),
267 local_addr: SocketAddr::from_str("0.0.0.0:0").unwrap(),
268 transport_protocol: TransportProtocol::UDP,
269
270 source_port: 0,
271 destination_port: 0,
272 my_max_num_inbound_streams: 0,
273 my_max_num_outbound_streams: 0,
274 my_cookie: None,
275
276 payload_queue: PayloadQueue::default(),
277 inflight_queue: PayloadQueue::default(),
278 pending_queue: PendingQueue::default(),
279 control_queue: VecDeque::default(),
280 stream_queue: VecDeque::default(),
281
282 mtu: 0,
283 max_payload_size: 0,
285 cumulative_tsn_ack_point: 0,
286 advanced_peer_tsn_ack_point: 0,
287 use_forward_tsn: false,
288 fwd_tsn_stream_map: FxHashMap::default(),
289
290 rto_mgr: RtoManager::default(),
291 timers: TimerTable::default(),
292
293 max_receive_buffer_size: 0,
295 cwnd: 0,
297 rwnd: 0,
299 ssthresh: 0,
301 partial_bytes_acked: 0,
302 in_fast_recovery: false,
303 fast_recover_exit_point: 0,
304
305 stored_init: None,
307 stored_cookie_echo: None,
308 streams: FxHashMap::default(),
309
310 events: VecDeque::default(),
311 endpoint_events: VecDeque::default(),
312 error: None,
313
314 delayed_ack_triggered: false,
316 immediate_ack_triggered: false,
317
318 stats: AssociationStats::default(),
319 ack_state: AckState::default(),
320
321 ack_mode: AckMode::default(),
323 }
324 }
325}
326
327impl Association {
328 #[allow(clippy::too_many_arguments)]
329 pub(crate) fn new(
330 server_config: Option<Arc<ServerConfig>>,
331 config: Arc<TransportConfig>,
332 max_payload_size: u32,
333 local_aid: AssociationId,
334 remote_addr: SocketAddr,
335 local_addr: SocketAddr,
336 protocol: TransportProtocol,
337 now: Instant,
338 ) -> Self {
339 let side = if server_config.is_some() {
340 Side::Server
341 } else {
342 Side::Client
343 };
344
345 let mtu = max_payload_size + COMMON_HEADER_SIZE + DATA_CHUNK_HEADER_SIZE;
348
349 let cwnd = (2 * mtu).clamp(4380, 4 * mtu);
353 let mut tsn = random::<u32>();
354 if tsn == 0 {
355 tsn += 1;
356 }
357
358 let mut this = Association {
359 side,
360 handshake_completed: false,
361 max_receive_buffer_size: config.max_receive_buffer_size(),
362 max_message_size: config.max_message_size(),
363 my_max_num_outbound_streams: config.max_num_outbound_streams(),
364 my_max_num_inbound_streams: config.max_num_inbound_streams(),
365 max_payload_size,
366
367 rto_mgr: RtoManager::new(),
368 timers: TimerTable::new(config.timer_config()),
369
370 mtu,
371 cwnd,
372 remote_addr,
373 local_addr,
374 transport_protocol: protocol,
375
376 my_verification_tag: local_aid,
377 my_next_tsn: tsn,
378 my_next_rsn: tsn,
379 min_tsn2measure_rtt: tsn,
380 cumulative_tsn_ack_point: tsn - 1,
381 advanced_peer_tsn_ack_point: tsn - 1,
382 error: None,
383
384 ..Default::default()
385 };
386
387 if side.is_client() {
388 let mut init = ChunkInit {
389 initial_tsn: this.my_next_tsn,
390 num_outbound_streams: this.my_max_num_outbound_streams,
391 num_inbound_streams: this.my_max_num_inbound_streams,
392 initiate_tag: this.my_verification_tag,
393 advertised_receiver_window_credit: this.max_receive_buffer_size,
394 ..Default::default()
395 };
396 init.set_supported_extensions();
397
398 this.set_state(AssociationState::CookieWait);
399 this.stored_init = Some(init);
400 let _ = this.send_init();
401 this.timers
402 .start(Timer::T1Init, now, this.rto_mgr.get_rto());
403 }
404
405 this
406 }
407
408 #[must_use]
414 pub fn poll(&mut self) -> Option<Event> {
415 if let Some(x) = self.events.pop_front() {
416 return Some(x);
417 }
418
419 if let Some(err) = self.error.take() {
424 return Some(Event::HandshakeFailed { reason: err });
425 }
426
427 None
428 }
429
430 #[must_use]
432 pub fn poll_endpoint_event(&mut self) -> Option<EndpointEvent> {
433 self.endpoint_events.pop_front().map(EndpointEvent)
434 }
435
436 #[must_use]
444 pub fn poll_timeout(&self) -> Option<Instant> {
445 self.timers.next_timeout()
446 }
447
448 #[must_use]
455 pub fn poll_transmit(&mut self, now: Instant) -> Option<TransportMessage<Payload>> {
456 let (contents, _) = self.gather_outbound(now);
457 if contents.is_empty() {
458 None
459 } else {
460 trace!(
461 "[{}] sending {} bytes (total {} datagrams)",
462 self.side,
463 contents.iter().fold(0, |l, c| l + c.len()),
464 contents.len()
465 );
466 Some(TransportMessage {
467 now,
468 transport: TransportContext {
469 local_addr: self.local_addr,
470 peer_addr: self.remote_addr,
471 ecn: None,
472 transport_protocol: Default::default(),
473 },
474 message: Payload::RawEncode(contents),
475 })
476 }
477 }
478
479 pub fn handle_timeout(&mut self, now: Instant) {
489 for &timer in &Timer::VALUES {
490 let (expired, failure, n_rtos) = self.timers.is_expired(timer, now);
491 if !expired {
492 continue;
493 }
494 self.timers.set(timer, None);
495 if timer == Timer::Ack {
498 self.on_ack_timeout();
499 } else if failure {
500 self.on_retransmission_failure(timer);
501 } else {
502 self.on_retransmission_timeout(timer, n_rtos);
503 self.timers.start(timer, now, self.rto_mgr.get_rto());
504 }
505 }
506 }
507
508 pub fn handle_event(&mut self, event: AssociationEvent) {
514 match event.0 {
515 AssociationEventInner::Datagram(transmit) => {
516 if let Payload::PartialDecode(partial_decode) = transmit.message {
526 debug!(
527 "[{}] recving {} bytes",
528 self.side,
529 COMMON_HEADER_SIZE as usize + partial_decode.remaining.len()
530 );
531
532 let pkt = match partial_decode.finish() {
533 Ok(p) => p,
534 Err(err) => {
535 warn!("[{}] unable to parse SCTP packet {}", self.side, err);
536 return;
537 }
538 };
539
540 if let Err(err) = self.handle_inbound(pkt, transmit.now) {
541 error!("handle_inbound got err: {}", err);
542 let _ = self.close(AssociationError::TransportError);
543 }
544 } else {
545 trace!("discarding invalid partial_decode");
546 }
547 } }
549 }
550
551 pub fn stats(&self) -> AssociationStats {
553 self.stats
554 }
555
556 pub fn is_handshaking(&self) -> bool {
561 !self.handshake_completed
562 }
563
564 pub fn is_closed(&self) -> bool {
572 self.state == AssociationState::Closed
573 }
574
575 pub fn is_drained(&self) -> bool {
580 self.state.is_drained()
581 }
582
583 pub fn side(&self) -> Side {
585 self.side
586 }
587
588 pub fn remote_addr(&self) -> SocketAddr {
590 self.remote_addr
591 }
592
593 pub fn rtt(&self) -> Duration {
595 Duration::from_millis(self.rto_mgr.get_rto())
596 }
597
598 pub fn local_addr(&self) -> SocketAddr {
613 self.local_addr
614 }
615
616 pub fn shutdown(&mut self) -> Result<()> {
620 debug!("[{}] closing association..", self.side);
621
622 let state = self.state();
623 if state != AssociationState::Established {
624 return Err(Error::ErrShutdownNonEstablished);
625 }
626
627 self.set_state(AssociationState::ShutdownPending);
629
630 if self.inflight_queue_length == 0 {
631 self.will_send_shutdown = true;
633 self.awake_write_loop();
634 self.set_state(AssociationState::ShutdownSent);
635 }
636
637 self.endpoint_events.push_back(EndpointEventInner::Drained);
638
639 Ok(())
640 }
641
642 pub fn close(&mut self, reason: AssociationError) -> Result<()> {
644 if self.state() != AssociationState::Closed {
645 self.set_state(AssociationState::Closed);
646
647 debug!("[{}] closing association..", self.side);
648
649 self.close_all_timers();
650
651 for si in self.streams.keys().cloned().collect::<Vec<u16>>() {
652 self.unregister_stream(si, reason.clone());
653 }
654
655 debug!("[{}] association closed", self.side);
656 debug!(
657 "[{}] stats nDATAs (in) : {}",
658 self.side,
659 self.stats.get_num_datas()
660 );
661 debug!(
662 "[{}] stats nSACKs (in) : {}",
663 self.side,
664 self.stats.get_num_sacks()
665 );
666 debug!(
667 "[{}] stats nT3Timeouts : {}",
668 self.side,
669 self.stats.get_num_t3timeouts()
670 );
671 debug!(
672 "[{}] stats nAckTimeouts: {}",
673 self.side,
674 self.stats.get_num_ack_timeouts()
675 );
676 debug!(
677 "[{}] stats nFastRetrans: {}",
678 self.side,
679 self.stats.get_num_fast_retrans()
680 );
681 }
682
683 Ok(())
684 }
685
686 pub fn open_stream(
688 &mut self,
689 stream_identifier: StreamId,
690 default_payload_type: PayloadProtocolIdentifier,
691 ) -> Result<Stream<'_>> {
692 if self.streams.contains_key(&stream_identifier) {
693 return Err(Error::ErrStreamAlreadyExist);
694 }
695
696 if let Some(s) = self.create_stream(stream_identifier, false, default_payload_type) {
697 Ok(s)
698 } else {
699 Err(Error::ErrStreamCreateFailed)
700 }
701 }
702
703 pub fn accept_stream(&mut self) -> Option<Stream<'_>> {
705 self.stream_queue
706 .pop_front()
707 .map(move |stream_identifier| Stream {
708 stream_identifier,
709 association: self,
710 })
711 }
712
713 pub fn stream(&mut self, stream_identifier: StreamId) -> Result<Stream<'_>> {
715 if !self.streams.contains_key(&stream_identifier) {
716 Err(Error::ErrStreamNotExisted)
717 } else {
718 Ok(Stream {
719 stream_identifier,
720 association: self,
721 })
722 }
723 }
724
725 pub fn stream_ids(&self) -> Vec<StreamId> {
727 self.streams.keys().cloned().collect()
728 }
729
730 pub(crate) fn bytes_sent(&self) -> usize {
732 self.bytes_sent
733 }
734
735 pub(crate) fn bytes_received(&self) -> usize {
737 self.bytes_received
738 }
739
740 pub(crate) fn max_message_size(&self) -> u32 {
742 self.max_message_size
743 }
744
745 pub(crate) fn set_max_message_size(&mut self, max_message_size: u32) {
747 self.max_message_size = max_message_size;
748 }
749
750 fn unregister_stream(&mut self, stream_identifier: StreamId, reason: AssociationError) {
753 if let Some(mut s) = self.streams.remove(&stream_identifier) {
754 debug!("[{}] unregister_stream {}", self.side, stream_identifier);
755 self.events.push_back(Event::AssociationLost {
756 reason,
757 id: stream_identifier,
758 });
759 s.state = RecvSendState::Closed;
760 }
761 }
762
763 fn set_state(&mut self, new_state: AssociationState) {
765 if new_state != self.state {
766 debug!(
767 "[{}] state change: '{}' => '{}'",
768 self.side, self.state, new_state,
769 );
770 }
771 self.state = new_state;
772 }
773
774 pub(crate) fn state(&self) -> AssociationState {
776 self.state
777 }
778
779 fn send_init(&mut self) -> Result<()> {
781 if let Some(stored_init) = &self.stored_init {
782 debug!("[{}] sending INIT", self.side);
783
784 self.source_port = 5000; self.destination_port = 5000; let outbound = Packet {
788 common_header: CommonHeader {
789 source_port: self.source_port,
790 destination_port: self.destination_port,
791 verification_tag: self.peer_verification_tag,
792 },
793 chunks: vec![Box::new(stored_init.clone())],
794 };
795
796 self.control_queue.push_back(outbound);
797 self.awake_write_loop();
798
799 Ok(())
800 } else {
801 Err(Error::ErrInitNotStoredToSend)
802 }
803 }
804
805 fn send_cookie_echo(&mut self) -> Result<()> {
807 if let Some(stored_cookie_echo) = &self.stored_cookie_echo {
808 debug!("[{}] sending COOKIE-ECHO", self.side);
809
810 let outbound = Packet {
811 common_header: CommonHeader {
812 source_port: self.source_port,
813 destination_port: self.destination_port,
814 verification_tag: self.peer_verification_tag,
815 },
816 chunks: vec![Box::new(stored_cookie_echo.clone())],
817 };
818
819 self.control_queue.push_back(outbound);
820 self.awake_write_loop();
821
822 Ok(())
823 } else {
824 Err(Error::ErrCookieEchoNotStoredToSend)
825 }
826 }
827
828 fn handle_inbound(&mut self, p: Packet, now: Instant) -> Result<()> {
830 if let Err(err) = p.check_packet() {
831 warn!("[{}] failed validating packet {}", self.side, err);
832 return Ok(());
833 }
834
835 self.handle_chunk_start();
836
837 for c in &p.chunks {
838 self.handle_chunk(&p, c, now)?;
839 }
840
841 self.handle_chunk_end(now);
842
843 Ok(())
844 }
845
846 fn handle_chunk_start(&mut self) {
847 self.delayed_ack_triggered = false;
848 self.immediate_ack_triggered = false;
849 }
850
851 fn handle_chunk_end(&mut self, now: Instant) {
852 if self.immediate_ack_triggered {
853 self.ack_state = AckState::Immediate;
854 self.timers.stop(Timer::Ack);
855 self.awake_write_loop();
856 } else if self.delayed_ack_triggered {
857 self.ack_state = AckState::Delay;
859 self.timers.start(Timer::Ack, now, ACK_INTERVAL);
860 }
861 }
862
863 #[allow(clippy::borrowed_box)]
864 fn handle_chunk(&mut self, p: &Packet, chunk: &Box<dyn Chunk>, now: Instant) -> Result<()> {
865 chunk.check()?;
866 let chunk_any = chunk.as_any();
867 let packets = if let Some(c) = chunk_any.downcast_ref::<ChunkInit>() {
868 if c.is_ack {
869 self.handle_init_ack(p, c, now)?
870 } else {
871 self.handle_init(p, c)?
872 }
873 } else if let Some(c) = chunk_any.downcast_ref::<ChunkAbort>() {
874 let mut err_str = String::new();
875 for e in &c.error_causes {
876 if matches!(e.code, USER_INITIATED_ABORT) {
877 debug!("User initiated abort received");
878 let _ = self.close(AssociationError::Reset);
879 return Ok(());
880 }
881 err_str += &format!("({})", e);
882 }
883 return Err(Error::ErrAbortChunk(err_str));
884 } else if let Some(c) = chunk_any.downcast_ref::<ChunkError>() {
885 let mut err_str = String::new();
886 for e in &c.error_causes {
887 err_str += &format!("({})", e);
888 }
889 return Err(Error::ErrAbortChunk(err_str));
890 } else if let Some(c) = chunk_any.downcast_ref::<ChunkHeartbeat>() {
891 self.handle_heartbeat(c)?
892 } else if let Some(c) = chunk_any.downcast_ref::<ChunkCookieEcho>() {
893 self.handle_cookie_echo(c)?
894 } else if chunk_any.downcast_ref::<ChunkCookieAck>().is_some() {
895 self.handle_cookie_ack()?
896 } else if let Some(c) = chunk_any.downcast_ref::<ChunkPayloadData>() {
897 self.handle_data(c)?
898 } else if let Some(c) = chunk_any.downcast_ref::<ChunkSelectiveAck>() {
899 self.handle_sack(c, now)?
900 } else if let Some(c) = chunk_any.downcast_ref::<ChunkReconfig>() {
901 self.handle_reconfig(c)?
902 } else if let Some(c) = chunk_any.downcast_ref::<ChunkForwardTsn>() {
903 self.handle_forward_tsn(c)?
904 } else if let Some(c) = chunk_any.downcast_ref::<ChunkShutdown>() {
905 self.handle_shutdown(c)?
906 } else if let Some(c) = chunk_any.downcast_ref::<ChunkShutdownAck>() {
907 self.handle_shutdown_ack(c)?
908 } else if let Some(c) = chunk_any.downcast_ref::<ChunkShutdownComplete>() {
909 self.handle_shutdown_complete(c)?
910 } else {
911 return Err(Error::ErrChunkTypeUnhandled);
912 };
913
914 if !packets.is_empty() {
915 let mut buf: VecDeque<_> = packets.into_iter().collect();
916 self.control_queue.append(&mut buf);
917 self.awake_write_loop();
918 }
919
920 Ok(())
921 }
922
923 fn handle_init(&mut self, p: &Packet, i: &ChunkInit) -> Result<Vec<Packet>> {
924 let state = self.state();
925 debug!("[{}] chunkInit received in state '{}'", self.side, state);
926
927 if state != AssociationState::Closed
935 && state != AssociationState::CookieWait
936 && state != AssociationState::CookieEchoed
937 {
938 return Err(Error::ErrHandleInitState);
941 }
942
943 self.my_max_num_inbound_streams =
945 std::cmp::min(i.num_inbound_streams, self.my_max_num_inbound_streams);
946 self.my_max_num_outbound_streams =
947 std::cmp::min(i.num_outbound_streams, self.my_max_num_outbound_streams);
948 self.peer_verification_tag = i.initiate_tag;
949 self.source_port = p.common_header.destination_port;
950 self.destination_port = p.common_header.source_port;
951
952 self.peer_last_tsn = if i.initial_tsn == 0 {
957 u32::MAX
958 } else {
959 i.initial_tsn - 1
960 };
961
962 self.rwnd = i.advertised_receiver_window_credit;
969 debug!("[{}] initial rwnd={}", self.side, self.rwnd);
970 self.ssthresh = self.rwnd;
971
972 for param in &i.params {
973 if let Some(v) = param.as_any().downcast_ref::<ParamSupportedExtensions>() {
974 for t in &v.chunk_types {
975 if *t == CT_FORWARD_TSN {
976 debug!("[{}] use ForwardTSN (on init)", self.side);
977 self.use_forward_tsn = true;
978 }
979 }
980 }
981 }
982 if !self.use_forward_tsn {
983 warn!("[{}] not using ForwardTSN (on init)", self.side);
984 }
985
986 let mut outbound = Packet {
987 common_header: CommonHeader {
988 verification_tag: self.peer_verification_tag,
989 source_port: self.source_port,
990 destination_port: self.destination_port,
991 },
992 chunks: vec![],
993 };
994
995 let mut init_ack = ChunkInit {
996 is_ack: true,
997 initial_tsn: self.my_next_tsn,
998 num_outbound_streams: self.my_max_num_outbound_streams,
999 num_inbound_streams: self.my_max_num_inbound_streams,
1000 initiate_tag: self.my_verification_tag,
1001 advertised_receiver_window_credit: self.max_receive_buffer_size,
1002 ..Default::default()
1003 };
1004
1005 if self.my_cookie.is_none() {
1006 self.my_cookie = Some(ParamStateCookie::new());
1007 }
1008
1009 if let Some(my_cookie) = &self.my_cookie {
1010 init_ack.params = vec![Box::new(my_cookie.clone())];
1011 }
1012
1013 init_ack.set_supported_extensions();
1014
1015 outbound.chunks = vec![Box::new(init_ack)];
1016
1017 Ok(vec![outbound])
1018 }
1019
1020 fn handle_init_ack(
1021 &mut self,
1022 p: &Packet,
1023 i: &ChunkInitAck,
1024 now: Instant,
1025 ) -> Result<Vec<Packet>> {
1026 let state = self.state();
1027 debug!("[{}] chunkInitAck received in state '{}'", self.side, state);
1028 if state != AssociationState::CookieWait {
1029 return Ok(vec![]);
1036 }
1037
1038 self.my_max_num_inbound_streams =
1039 std::cmp::min(i.num_inbound_streams, self.my_max_num_inbound_streams);
1040 self.my_max_num_outbound_streams =
1041 std::cmp::min(i.num_outbound_streams, self.my_max_num_outbound_streams);
1042 self.peer_verification_tag = i.initiate_tag;
1043 self.peer_last_tsn = if i.initial_tsn == 0 {
1044 u32::MAX
1045 } else {
1046 i.initial_tsn - 1
1047 };
1048 if self.source_port != p.common_header.destination_port
1049 || self.destination_port != p.common_header.source_port
1050 {
1051 warn!("[{}] handle_init_ack: port mismatch", self.side);
1052 return Ok(vec![]);
1053 }
1054
1055 self.rwnd = i.advertised_receiver_window_credit;
1056 debug!("[{}] initial rwnd={}", self.side, self.rwnd);
1057
1058 self.ssthresh = self.rwnd;
1063 trace!(
1064 "[{}] updated cwnd={} ssthresh={} inflight={} (INI)",
1065 self.side,
1066 self.cwnd,
1067 self.ssthresh,
1068 self.inflight_queue.get_num_bytes()
1069 );
1070
1071 self.timers.stop(Timer::T1Init);
1072 self.stored_init = None;
1073
1074 let mut cookie_param = None;
1075 for param in &i.params {
1076 if let Some(v) = param.as_any().downcast_ref::<ParamStateCookie>() {
1077 cookie_param = Some(v);
1078 } else if let Some(v) = param.as_any().downcast_ref::<ParamSupportedExtensions>() {
1079 for t in &v.chunk_types {
1080 if *t == CT_FORWARD_TSN {
1081 debug!("[{}] use ForwardTSN (on initAck)", self.side);
1082 self.use_forward_tsn = true;
1083 }
1084 }
1085 }
1086 }
1087 if !self.use_forward_tsn {
1088 warn!("[{}] not using ForwardTSN (on initAck)", self.side);
1089 }
1090
1091 if let Some(v) = cookie_param {
1092 self.stored_cookie_echo = Some(ChunkCookieEcho {
1093 cookie: v.cookie.clone(),
1094 });
1095
1096 self.send_cookie_echo()?;
1097
1098 self.timers
1099 .start(Timer::T1Cookie, now, self.rto_mgr.get_rto());
1100
1101 self.set_state(AssociationState::CookieEchoed);
1102
1103 Ok(vec![])
1104 } else {
1105 Err(Error::ErrInitAckNoCookie)
1106 }
1107 }
1108
1109 fn handle_heartbeat(&self, c: &ChunkHeartbeat) -> Result<Vec<Packet>> {
1110 trace!("[{}] chunkHeartbeat", self.side);
1111 if let Some(p) = c.params.first() {
1112 if let Some(hbi) = p.as_any().downcast_ref::<ParamHeartbeatInfo>() {
1113 return Ok(vec![Packet {
1114 common_header: CommonHeader {
1115 verification_tag: self.peer_verification_tag,
1116 source_port: self.source_port,
1117 destination_port: self.destination_port,
1118 },
1119 chunks: vec![Box::new(ChunkHeartbeatAck {
1120 params: vec![Box::new(ParamHeartbeatInfo {
1121 heartbeat_information: hbi.heartbeat_information.clone(),
1122 })],
1123 })],
1124 }]);
1125 } else {
1126 warn!(
1127 "[{}] failed to handle Heartbeat, no ParamHeartbeatInfo",
1128 self.side,
1129 );
1130 }
1131 }
1132
1133 Ok(vec![])
1134 }
1135
1136 fn handle_cookie_echo(&mut self, c: &ChunkCookieEcho) -> Result<Vec<Packet>> {
1137 let state = self.state();
1138 debug!("[{}] COOKIE-ECHO received in state '{}'", self.side, state);
1139
1140 if let Some(my_cookie) = &self.my_cookie {
1141 match state {
1142 AssociationState::Established => {
1143 if my_cookie.cookie != c.cookie {
1144 return Ok(vec![]);
1145 }
1146 }
1147 AssociationState::Closed
1148 | AssociationState::CookieWait
1149 | AssociationState::CookieEchoed => {
1150 if my_cookie.cookie != c.cookie {
1151 return Ok(vec![]);
1152 }
1153
1154 self.timers.stop(Timer::T1Init);
1155 self.stored_init = None;
1156
1157 self.timers.stop(Timer::T1Cookie);
1158 self.stored_cookie_echo = None;
1159
1160 self.events.push_back(Event::Connected);
1161 self.set_state(AssociationState::Established);
1162 self.handshake_completed = true;
1163 }
1164 _ => return Ok(vec![]),
1165 };
1166 } else {
1167 debug!("[{}] COOKIE-ECHO received before initialization", self.side);
1168 return Ok(vec![]);
1169 }
1170
1171 Ok(vec![Packet {
1172 common_header: CommonHeader {
1173 verification_tag: self.peer_verification_tag,
1174 source_port: self.source_port,
1175 destination_port: self.destination_port,
1176 },
1177 chunks: vec![Box::new(ChunkCookieAck {})],
1178 }])
1179 }
1180
1181 fn handle_cookie_ack(&mut self) -> Result<Vec<Packet>> {
1182 let state = self.state();
1183 debug!("[{}] COOKIE-ACK received in state '{}'", self.side, state);
1184 if state != AssociationState::CookieEchoed {
1185 return Ok(vec![]);
1190 }
1191
1192 self.timers.stop(Timer::T1Cookie);
1193 self.stored_cookie_echo = None;
1194
1195 self.events.push_back(Event::Connected);
1196 self.set_state(AssociationState::Established);
1197 self.handshake_completed = true;
1198
1199 Ok(vec![])
1200 }
1201
1202 fn handle_data(&mut self, d: &ChunkPayloadData) -> Result<Vec<Packet>> {
1203 debug!(
1204 "[{}] DATA: tsn={} peer_last_tsn={} immediateSack={} len={}, unordered={}",
1205 self.side,
1206 d.tsn,
1207 self.peer_last_tsn,
1208 d.immediate_sack,
1209 d.user_data.len(),
1210 d.unordered,
1211 );
1212 self.stats.inc_datas();
1213
1214 let can_push = self.payload_queue.can_push(d, self.peer_last_tsn);
1215 let mut stream_handle_data = false;
1216 if can_push {
1217 if self.get_or_create_stream(d.stream_identifier).is_some() {
1218 if self.get_my_receiver_window_credit() > 0 {
1219 self.payload_queue.push(d.clone(), self.peer_last_tsn);
1221 stream_handle_data = true;
1222 } else {
1223 let fills_gap = self
1229 .payload_queue
1230 .get_last_tsn_received()
1231 .is_some_and(|last_tsn| sna32lt(d.tsn, *last_tsn));
1232
1233 let unblocks_reassembly =
1249 d.tsn == self.peer_last_tsn.wrapping_add(1) && !self.has_readable_data();
1250
1251 if fills_gap || unblocks_reassembly {
1252 debug!(
1253 "[{}] receive buffer full, but accepted {} with tsn={} ssn={}",
1254 self.side,
1255 if fills_gap {
1256 "as this is a missing chunk"
1257 } else {
1258 "as the in-sequence chunk that unblocks reassembly"
1259 },
1260 d.tsn,
1261 d.stream_sequence_number
1262 );
1263 self.payload_queue.push(d.clone(), self.peer_last_tsn);
1264 stream_handle_data = true;
1265 } else {
1266 debug!(
1267 "[{}] receive buffer full. dropping DATA with tsn={} ssn={}",
1268 self.side, d.tsn, d.stream_sequence_number
1269 );
1270 }
1271 }
1272 } else {
1273 debug!("[{}] discard {}", self.side, d.stream_sequence_number);
1275 return Ok(vec![]);
1276 }
1277 }
1278
1279 let immediate_sack = d.immediate_sack;
1280
1281 if stream_handle_data && let Some(s) = self.streams.get_mut(&d.stream_identifier) {
1282 self.events.push_back(Event::DatagramReceived);
1283 if s.handle_data(d) && s.reassembly_queue.is_readable() {
1284 self.events.push_back(Event::Stream(StreamEvent::Readable {
1285 id: s.stream_identifier,
1286 }));
1287 }
1288 }
1289
1290 self.handle_peer_last_tsn_and_acknowledgement(immediate_sack)
1291 }
1292
1293 fn handle_sack(&mut self, d: &ChunkSelectiveAck, now: Instant) -> Result<Vec<Packet>> {
1294 trace!(
1295 "[{}] {}, SACK: cumTSN={} a_rwnd={}",
1296 self.side,
1297 self.cumulative_tsn_ack_point,
1298 d.cumulative_tsn_ack,
1299 d.advertised_receiver_window_credit
1300 );
1301 let state = self.state();
1302 if state != AssociationState::Established
1303 && state != AssociationState::ShutdownPending
1304 && state != AssociationState::ShutdownReceived
1305 {
1306 return Ok(vec![]);
1307 }
1308
1309 self.stats.inc_sacks();
1310
1311 if sna32gt(self.cumulative_tsn_ack_point, d.cumulative_tsn_ack) {
1312 debug!(
1321 "[{}] SACK Cumulative ACK {} is older than ACK point {}",
1322 self.side, d.cumulative_tsn_ack, self.cumulative_tsn_ack_point
1323 );
1324
1325 return Ok(vec![]);
1326 }
1327
1328 let (bytes_acked_per_stream, htna) = self.process_selective_ack(d, now)?;
1330
1331 let mut total_bytes_acked = 0;
1332 for n_bytes_acked in bytes_acked_per_stream.values() {
1333 total_bytes_acked += *n_bytes_acked;
1334 }
1335
1336 let mut cum_tsn_ack_point_advanced = false;
1337 if sna32lt(self.cumulative_tsn_ack_point, d.cumulative_tsn_ack) {
1338 trace!(
1339 "[{}] SACK: cumTSN advanced: {} -> {}",
1340 self.side, self.cumulative_tsn_ack_point, d.cumulative_tsn_ack
1341 );
1342
1343 self.cumulative_tsn_ack_point = d.cumulative_tsn_ack;
1344 cum_tsn_ack_point_advanced = true;
1345 self.on_cumulative_tsn_ack_point_advanced(total_bytes_acked, now);
1346 }
1347
1348 for (si, n_bytes_acked) in &bytes_acked_per_stream {
1349 if *n_bytes_acked > 0 {
1350 self.events
1356 .push_back(Event::Stream(StreamEvent::BufferedAmountReleased {
1357 id: *si,
1358 n_bytes: *n_bytes_acked as usize,
1359 }));
1360 }
1361 if let Some(s) = self.streams.get_mut(si)
1362 && s.on_buffer_released(*n_bytes_acked)
1363 {
1364 trace!("StreamEvent::BufferedAmountLow");
1365 self.events
1366 .push_back(Event::Stream(StreamEvent::BufferedAmountLow { id: *si }))
1367 }
1368 }
1369
1370 let bytes_outstanding = self.inflight_queue.get_num_bytes() as u32;
1379 if bytes_outstanding >= d.advertised_receiver_window_credit {
1380 self.rwnd = 0;
1381 } else {
1382 self.rwnd = d.advertised_receiver_window_credit - bytes_outstanding;
1383 }
1384
1385 self.process_fast_retransmission(d.cumulative_tsn_ack, htna, cum_tsn_ack_point_advanced)?;
1386
1387 if self.use_forward_tsn {
1388 if sna32lt(
1390 self.advanced_peer_tsn_ack_point,
1391 self.cumulative_tsn_ack_point,
1392 ) {
1393 self.advanced_peer_tsn_ack_point = self.cumulative_tsn_ack_point;
1394 self.fwd_tsn_stream_map.clear();
1397 }
1398
1399 let mut i = self.advanced_peer_tsn_ack_point + 1;
1403 while let Some((abandoned, unordered, si, ssn)) = self.inflight_queue.get(i).map(|c| {
1404 (
1405 c.abandoned(),
1406 c.unordered,
1407 c.stream_identifier,
1408 c.stream_sequence_number,
1409 )
1410 }) {
1411 if !abandoned {
1412 break;
1413 }
1414 self.advanced_peer_tsn_ack_point = i;
1415 self.note_abandoned_for_forward_tsn(unordered, si, ssn);
1416 i += 1;
1417 }
1418
1419 if sna32gt(
1421 self.advanced_peer_tsn_ack_point,
1422 self.cumulative_tsn_ack_point,
1423 ) {
1424 self.will_send_forward_tsn = true;
1425 debug!(
1426 "[{}] handleSack {}: sna32GT({}, {})",
1427 self.side,
1428 self.will_send_forward_tsn,
1429 self.advanced_peer_tsn_ack_point,
1430 self.cumulative_tsn_ack_point
1431 );
1432 } else {
1433 self.fwd_tsn_stream_map.clear();
1436 }
1437 self.awake_write_loop();
1438 }
1439
1440 self.postprocess_sack(state, cum_tsn_ack_point_advanced, now);
1441
1442 Ok(vec![])
1443 }
1444
1445 fn handle_reconfig(&mut self, c: &ChunkReconfig) -> Result<Vec<Packet>> {
1446 trace!("[{}] handle_reconfig", self.side);
1447
1448 let mut pp = vec![];
1449
1450 if let Some(param_a) = &c.param_a {
1451 self.handle_reconfig_param(param_a, &mut pp)?;
1452 }
1453
1454 if let Some(param_b) = &c.param_b {
1455 self.handle_reconfig_param(param_b, &mut pp)?;
1456 }
1457
1458 Ok(pp)
1459 }
1460
1461 fn handle_forward_tsn(&mut self, c: &ChunkForwardTsn) -> Result<Vec<Packet>> {
1462 trace!("[{}] FwdTSN: {}", self.side, c);
1463
1464 if !self.use_forward_tsn {
1465 warn!("[{}] received FwdTSN but not enabled", self.side);
1466 let cerr = ChunkError {
1468 error_causes: vec![ErrorCauseUnrecognizedChunkType::default()],
1469 };
1470
1471 let outbound = Packet {
1472 common_header: CommonHeader {
1473 verification_tag: self.peer_verification_tag,
1474 source_port: self.source_port,
1475 destination_port: self.destination_port,
1476 },
1477 chunks: vec![Box::new(cerr)],
1478 };
1479 return Ok(vec![outbound]);
1480 }
1481
1482 trace!(
1491 "[{}] should send ack? newCumTSN={} peer_last_tsn={}",
1492 self.side, c.new_cumulative_tsn, self.peer_last_tsn
1493 );
1494 if sna32lte(c.new_cumulative_tsn, self.peer_last_tsn) {
1495 trace!("[{}] sending ack on Forward TSN", self.side);
1496 self.ack_state = AckState::Immediate;
1497 self.timers.stop(Timer::Ack);
1498 self.awake_write_loop();
1499 return Ok(vec![]);
1500 }
1501
1502 while sna32lt(self.peer_last_tsn, c.new_cumulative_tsn) {
1514 self.payload_queue.pop(self.peer_last_tsn + 1); self.peer_last_tsn += 1;
1516 }
1517
1518 for forwarded in &c.streams {
1522 if let Some(s) = self.streams.get_mut(&forwarded.identifier) {
1523 s.handle_forward_tsn_for_ordered(forwarded.sequence);
1524 if s.reassembly_queue.is_readable() {
1525 self.events.push_back(Event::Stream(StreamEvent::Readable {
1526 id: s.stream_identifier,
1527 }));
1528 }
1529 }
1530 }
1531
1532 for s in self.streams.values_mut() {
1537 s.handle_forward_tsn_for_unordered(c.new_cumulative_tsn);
1538 if s.reassembly_queue.is_readable() {
1539 self.events.push_back(Event::Stream(StreamEvent::Readable {
1540 id: s.stream_identifier,
1541 }));
1542 }
1543 }
1544
1545 self.handle_peer_last_tsn_and_acknowledgement(false)
1546 }
1547
1548 fn handle_shutdown(&mut self, _: &ChunkShutdown) -> Result<Vec<Packet>> {
1549 let state = self.state();
1550
1551 if state == AssociationState::Established {
1552 if !self.inflight_queue.is_empty() {
1553 self.set_state(AssociationState::ShutdownReceived);
1554 } else {
1555 self.will_send_shutdown_ack = true;
1557 self.set_state(AssociationState::ShutdownAckSent);
1558
1559 self.awake_write_loop();
1560 }
1561 } else if state == AssociationState::ShutdownSent {
1562 self.will_send_shutdown_ack = true;
1565 self.set_state(AssociationState::ShutdownAckSent);
1566
1567 self.awake_write_loop();
1568 }
1569
1570 Ok(vec![])
1571 }
1572
1573 fn handle_shutdown_ack(&mut self, _: &ChunkShutdownAck) -> Result<Vec<Packet>> {
1574 let state = self.state();
1575 if state == AssociationState::ShutdownSent || state == AssociationState::ShutdownAckSent {
1576 self.timers.stop(Timer::T2Shutdown);
1577 self.will_send_shutdown_complete = true;
1578
1579 self.awake_write_loop();
1580 }
1581
1582 Ok(vec![])
1583 }
1584
1585 fn handle_shutdown_complete(&mut self, _: &ChunkShutdownComplete) -> Result<Vec<Packet>> {
1586 let state = self.state();
1587 if state == AssociationState::ShutdownAckSent {
1588 self.timers.stop(Timer::T2Shutdown);
1589 self.close(AssociationError::AssociationClosed)?;
1590 }
1591
1592 Ok(vec![])
1593 }
1594
1595 fn handle_peer_last_tsn_and_acknowledgement(
1597 &mut self,
1598 sack_immediately: bool,
1599 ) -> Result<Vec<Packet>> {
1600 let mut reply = vec![];
1601
1602 while self.payload_queue.pop(self.peer_last_tsn + 1).is_some() {
1611 self.peer_last_tsn += 1;
1612 let rst_reqs: Vec<ParamOutgoingResetRequest> =
1615 self.reconfig_requests.values().cloned().collect();
1616 for rst_req in rst_reqs {
1617 self.reset_streams_if_any(&rst_req, false, &mut reply)?;
1618 }
1619 }
1620
1621 let has_packet_loss = !self.payload_queue.is_empty();
1622 if has_packet_loss {
1623 trace!(
1624 "[{}] packetloss: {}",
1625 self.side,
1626 self.payload_queue
1627 .get_gap_ack_blocks_string(self.peer_last_tsn)
1628 );
1629 }
1630
1631 if (self.ack_state != AckState::Immediate
1632 && !sack_immediately
1633 && !has_packet_loss
1634 && self.ack_mode == AckMode::Normal)
1635 || self.ack_mode == AckMode::AlwaysDelay
1636 {
1637 if self.ack_state == AckState::Idle {
1638 self.delayed_ack_triggered = true;
1639 } else {
1640 self.immediate_ack_triggered = true;
1641 }
1642 } else {
1643 self.immediate_ack_triggered = true;
1644 }
1645
1646 Ok(reply)
1647 }
1648
1649 #[allow(clippy::borrowed_box)]
1650 fn handle_reconfig_param(
1651 &mut self,
1652 raw: &Box<dyn Param>,
1653 reply: &mut Vec<Packet>,
1654 ) -> Result<()> {
1655 if let Some(p) = raw.as_any().downcast_ref::<ParamOutgoingResetRequest>() {
1656 self.reconfig_requests
1657 .insert(p.reconfig_request_sequence_number, p.clone());
1658 self.reset_streams_if_any(p, true, reply)?;
1659 Ok(())
1660 } else if let Some(p) = raw.as_any().downcast_ref::<ParamReconfigResponse>() {
1661 self.reconfigs.remove(&p.reconfig_response_sequence_number);
1662 if self.reconfigs.is_empty() {
1663 self.timers.stop(Timer::Reconfig);
1664 }
1665 Ok(())
1666 } else {
1667 Err(Error::ErrParameterType)
1668 }
1669 }
1670
1671 fn process_selective_ack(
1672 &mut self,
1673 d: &ChunkSelectiveAck,
1674 now: Instant,
1675 ) -> Result<(FxHashMap<u16, i64>, u32)> {
1676 let mut bytes_acked_per_stream = FxHashMap::default();
1677
1678 let mut i = self.cumulative_tsn_ack_point + 1;
1682 while sna32lte(i, d.cumulative_tsn_ack) {
1684 if let Some(c) = self.inflight_queue.pop(i) {
1685 if !c.acked {
1686 if i == self.cumulative_tsn_ack_point + 1 {
1692 self.timers.stop(Timer::T3RTX);
1694 }
1695
1696 let n_bytes_acked = c.user_data.len() as i64;
1697
1698 if let Some(amount) = bytes_acked_per_stream.get_mut(&c.stream_identifier) {
1700 *amount += n_bytes_acked;
1701 } else {
1702 bytes_acked_per_stream.insert(c.stream_identifier, n_bytes_acked);
1703 }
1704
1705 if c.nsent == 1 && sna32gte(c.tsn, self.min_tsn2measure_rtt) {
1715 self.min_tsn2measure_rtt = self.my_next_tsn;
1716 if let Some(since) = &c.since {
1717 let rtt = now.duration_since(*since);
1718 let srtt = self.rto_mgr.set_new_rtt(rtt.as_millis() as u64);
1719 trace!(
1720 "[{}] SACK: measured-rtt={} srtt={} new-rto={}",
1721 self.side,
1722 rtt.as_millis(),
1723 srtt,
1724 self.rto_mgr.get_rto()
1725 );
1726 } else {
1727 error!("[{}] invalid c.since", self.side);
1728 }
1729 }
1730 }
1731
1732 if self.in_fast_recovery && c.tsn == self.fast_recover_exit_point {
1733 debug!("[{}] exit fast-recovery", self.side);
1734 self.in_fast_recovery = false;
1735 }
1736 } else {
1737 return Err(Error::ErrInflightQueueTsnPop);
1738 }
1739
1740 i += 1;
1741 }
1742
1743 let mut htna = d.cumulative_tsn_ack;
1744
1745 for g in &d.gap_ack_blocks {
1747 for i in g.start..=g.end {
1748 let tsn = d.cumulative_tsn_ack + i as u32;
1749
1750 let (is_existed, is_acked) = if let Some(c) = self.inflight_queue.get(tsn) {
1751 (true, c.acked)
1752 } else {
1753 (false, false)
1754 };
1755 let n_bytes_acked = if is_existed && !is_acked {
1756 self.inflight_queue.mark_as_acked(tsn) as i64
1757 } else {
1758 0
1759 };
1760
1761 if let Some(c) = self.inflight_queue.get(tsn) {
1762 if !is_acked {
1763 if let Some(amount) = bytes_acked_per_stream.get_mut(&c.stream_identifier) {
1765 *amount += n_bytes_acked;
1766 } else {
1767 bytes_acked_per_stream.insert(c.stream_identifier, n_bytes_acked);
1768 }
1769
1770 trace!("[{}] tsn={} has been sacked", self.side, c.tsn);
1771
1772 if c.nsent == 1 {
1773 self.min_tsn2measure_rtt = self.my_next_tsn;
1774 if let Some(since) = &c.since {
1775 let rtt = now.duration_since(*since);
1776 let srtt = self.rto_mgr.set_new_rtt(rtt.as_millis() as u64);
1777 trace!(
1778 "[{}] SACK: measured-rtt={} srtt={} new-rto={}",
1779 self.side,
1780 rtt.as_millis(),
1781 srtt,
1782 self.rto_mgr.get_rto()
1783 );
1784 } else {
1785 error!("[{}] invalid c.since", self.side);
1786 }
1787 }
1788
1789 if sna32lt(htna, tsn) {
1790 htna = tsn;
1791 }
1792 }
1793 } else {
1794 return Err(Error::ErrTsnRequestNotExist);
1795 }
1796 }
1797 }
1798
1799 Ok((bytes_acked_per_stream, htna))
1800 }
1801
1802 fn on_cumulative_tsn_ack_point_advanced(&mut self, total_bytes_acked: i64, now: Instant) {
1803 if self.inflight_queue.is_empty() {
1807 trace!(
1808 "[{}] SACK: no more packet in-flight (pending={})",
1809 self.side,
1810 self.pending_queue.len()
1811 );
1812 self.timers.stop(Timer::T3RTX);
1813 } else {
1814 trace!("[{}] T3-rtx timer start (pt2)", self.side);
1815 self.timers
1816 .restart_if_stale(Timer::T3RTX, now, self.rto_mgr.get_rto());
1817 }
1818
1819 if self.cwnd <= self.ssthresh {
1821 if !self.in_fast_recovery && !self.pending_queue.is_empty() {
1833 self.cwnd += std::cmp::min(total_bytes_acked as u32, self.cwnd); trace!(
1836 "[{}] updated cwnd={} ssthresh={} acked={} (SS)",
1837 self.side, self.cwnd, self.ssthresh, total_bytes_acked
1838 );
1839 } else {
1840 trace!(
1841 "[{}] cwnd did not grow: cwnd={} ssthresh={} acked={} FR={} pending={}",
1842 self.side,
1843 self.cwnd,
1844 self.ssthresh,
1845 total_bytes_acked,
1846 self.in_fast_recovery,
1847 self.pending_queue.len()
1848 );
1849 }
1850 } else {
1851 self.partial_bytes_acked += total_bytes_acked as u32;
1858
1859 if self.partial_bytes_acked >= self.cwnd && !self.pending_queue.is_empty() {
1865 self.partial_bytes_acked -= self.cwnd;
1866 self.cwnd += self.mtu;
1867 trace!(
1868 "[{}] updated cwnd={} ssthresh={} acked={} (CA)",
1869 self.side, self.cwnd, self.ssthresh, total_bytes_acked
1870 );
1871 }
1872 }
1873 }
1874
1875 fn process_fast_retransmission(
1876 &mut self,
1877 cum_tsn_ack_point: u32,
1878 htna: u32,
1879 cum_tsn_ack_point_advanced: bool,
1880 ) -> Result<()> {
1881 if !self.in_fast_recovery || cum_tsn_ack_point_advanced {
1891 let max_tsn = if !self.in_fast_recovery {
1892 htna
1894 } else {
1895 cum_tsn_ack_point + (self.inflight_queue.len() as u32) + 1
1897 };
1898
1899 let mut tsn = cum_tsn_ack_point + 1;
1900 while sna32lt(tsn, max_tsn) {
1901 if let Some(c) = self.inflight_queue.get_mut(tsn) {
1902 if !c.acked && !c.abandoned() && c.miss_indicator < 3 {
1903 c.miss_indicator += 1;
1904 if c.miss_indicator == 3 && !self.in_fast_recovery {
1905 self.in_fast_recovery = true;
1909 self.fast_recover_exit_point = htna;
1910 self.ssthresh = std::cmp::max(self.cwnd / 2, 4 * self.mtu);
1911 self.cwnd = self.ssthresh;
1912 self.partial_bytes_acked = 0;
1913 self.will_retransmit_fast = true;
1914
1915 trace!(
1916 "[{}] updated cwnd={} ssthresh={} inflight={} (FR)",
1917 self.side,
1918 self.cwnd,
1919 self.ssthresh,
1920 self.inflight_queue.get_num_bytes()
1921 );
1922 }
1923 }
1924 } else {
1925 return Err(Error::ErrTsnRequestNotExist);
1926 }
1927
1928 tsn += 1;
1929 }
1930 }
1931
1932 if self.in_fast_recovery && cum_tsn_ack_point_advanced {
1933 self.will_retransmit_fast = true;
1934 }
1935
1936 Ok(())
1937 }
1938
1939 fn postprocess_sack(
1942 &mut self,
1943 state: AssociationState,
1944 mut should_awake_write_loop: bool,
1945 now: Instant,
1946 ) {
1947 if !self.inflight_queue.is_empty() {
1948 trace!("[{}] T3-rtx timer start (pt3)", self.side);
1950 self.timers
1951 .restart_if_stale(Timer::T3RTX, now, self.rto_mgr.get_rto());
1952 } else if state == AssociationState::ShutdownPending {
1953 should_awake_write_loop = true;
1955 self.will_send_shutdown = true;
1956 self.set_state(AssociationState::ShutdownSent);
1957 } else if state == AssociationState::ShutdownReceived {
1958 should_awake_write_loop = true;
1960 self.will_send_shutdown_ack = true;
1961 self.set_state(AssociationState::ShutdownAckSent);
1962 }
1963
1964 if should_awake_write_loop {
1965 self.awake_write_loop();
1966 }
1967 }
1968
1969 fn reset_streams_if_any(
1970 &mut self,
1971 p: &ParamOutgoingResetRequest,
1972 respond: bool,
1973 reply: &mut Vec<Packet>,
1974 ) -> Result<()> {
1975 let mut result = ReconfigResult::SuccessPerformed;
1976 let mut sis_to_reset = vec![];
1977
1978 if sna32lte(p.sender_last_tsn, self.peer_last_tsn) {
1979 debug!(
1980 "[{}] resetStream(): senderLastTSN={} <= peer_last_tsn={}",
1981 self.side, p.sender_last_tsn, self.peer_last_tsn
1982 );
1983 for id in &p.stream_identifiers {
1984 if self.streams.contains_key(id) {
1985 if respond {
1986 sis_to_reset.push(*id);
1987 }
1988 self.unregister_stream(*id, AssociationError::Reset);
1989 }
1990 }
1991 self.reconfig_requests
1992 .remove(&p.reconfig_request_sequence_number);
1993 } else {
1994 debug!(
1995 "[{}] resetStream(): senderLastTSN={} > peer_last_tsn={}",
1996 self.side, p.sender_last_tsn, self.peer_last_tsn
1997 );
1998 result = ReconfigResult::InProgress;
1999 }
2000
2001 if !sis_to_reset.is_empty() {
2004 let rsn = self.generate_next_rsn();
2005 let tsn = self.my_next_tsn - 1;
2006
2007 let c = ChunkReconfig {
2008 param_a: Some(Box::new(ParamOutgoingResetRequest {
2009 reconfig_request_sequence_number: rsn,
2010 reconfig_response_sequence_number: p.reconfig_request_sequence_number,
2011 sender_last_tsn: tsn,
2012 stream_identifiers: sis_to_reset,
2013 })),
2014 ..Default::default()
2015 };
2016
2017 self.reconfigs.insert(rsn, c.clone()); let p = self.create_packet(vec![Box::new(c)]);
2020 reply.push(p);
2021 }
2022
2023 let packet = self.create_packet(vec![Box::new(ChunkReconfig {
2024 param_a: Some(Box::new(ParamReconfigResponse {
2025 reconfig_response_sequence_number: p.reconfig_request_sequence_number,
2026 result,
2027 })),
2028 param_b: None,
2029 })]);
2030
2031 debug!("[{}] RESET RESPONSE: {}", self.side, packet);
2032
2033 reply.push(packet);
2034
2035 Ok(())
2036 }
2037
2038 pub(crate) fn create_packet(&self, chunks: Vec<Box<dyn Chunk>>) -> Packet {
2041 Packet {
2042 common_header: CommonHeader {
2043 verification_tag: self.peer_verification_tag,
2044 source_port: self.source_port,
2045 destination_port: self.destination_port,
2046 },
2047 chunks,
2048 }
2049 }
2050
2051 fn marshal_control_chunk(&self, chunk: &dyn Chunk) -> Result<Bytes> {
2058 let common_header = CommonHeader {
2059 verification_tag: self.peer_verification_tag,
2060 source_port: self.source_port,
2061 destination_port: self.destination_port,
2062 };
2063 let mut buf = BytesMut::with_capacity(
2065 COMMON_HEADER_SIZE as usize + CHUNK_HEADER_SIZE + chunk.value_length() + 3,
2066 );
2067 Packet::write_framed(&common_header, std::iter::once(chunk), &mut buf)?;
2068 Ok(buf.freeze())
2069 }
2070
2071 fn create_stream(
2073 &mut self,
2074 stream_identifier: StreamId,
2075 accept: bool,
2076 default_payload_type: PayloadProtocolIdentifier,
2077 ) -> Option<Stream<'_>> {
2078 let s = StreamState::new(
2079 self.side,
2080 stream_identifier,
2081 self.max_payload_size,
2082 default_payload_type,
2083 );
2084
2085 if accept {
2086 self.stream_queue.push_back(stream_identifier);
2087 self.events.push_back(Event::Stream(StreamEvent::Opened {
2088 id: stream_identifier,
2089 }));
2090 }
2091
2092 self.streams.insert(stream_identifier, s);
2093
2094 Some(Stream {
2095 stream_identifier,
2096 association: self,
2097 })
2098 }
2099
2100 fn get_or_create_stream(&mut self, stream_identifier: StreamId) -> Option<Stream<'_>> {
2102 if self.streams.contains_key(&stream_identifier) {
2103 Some(Stream {
2104 stream_identifier,
2105 association: self,
2106 })
2107 } else {
2108 self.create_stream(
2109 stream_identifier,
2110 true,
2111 PayloadProtocolIdentifier::default(),
2112 )
2113 }
2114 }
2115
2116 fn has_readable_data(&self) -> bool {
2123 self.streams
2124 .values()
2125 .any(|s| s.reassembly_queue.is_readable())
2126 }
2127
2128 pub(crate) fn get_my_receiver_window_credit(&self) -> u32 {
2129 let mut bytes_queued = 0;
2130 for s in self.streams.values() {
2131 bytes_queued += s.get_num_bytes_in_reassembly_queue() as u32;
2132 }
2133
2134 self.max_receive_buffer_size.saturating_sub(bytes_queued)
2135 }
2136
2137 fn gather_outbound(&mut self, now: Instant) -> (Vec<Bytes>, bool) {
2140 let mut raw_packets = vec![];
2141
2142 if !self.control_queue.is_empty() {
2143 for p in self.control_queue.drain(..) {
2144 if let Ok(raw) = p.marshal() {
2145 raw_packets.push(raw);
2146 } else {
2147 warn!("[{}] failed to serialize a control packet", self.side);
2148 continue;
2149 }
2150 }
2151 }
2152
2153 let state = self.state();
2154 match state {
2155 AssociationState::Established => {
2156 raw_packets = self.gather_data_packets_to_retransmit(raw_packets, now);
2157 raw_packets = self.gather_outbound_data_and_reconfig_packets(raw_packets, now);
2158 raw_packets = self.gather_outbound_fast_retransmission_packets(raw_packets, now);
2159 raw_packets = self.gather_outbound_sack_packets(raw_packets);
2160 raw_packets = self.gather_outbound_forward_tsn_packets(raw_packets);
2161 (raw_packets, true)
2162 }
2163 AssociationState::ShutdownPending
2164 | AssociationState::ShutdownSent
2165 | AssociationState::ShutdownReceived => {
2166 raw_packets = self.gather_data_packets_to_retransmit(raw_packets, now);
2167 raw_packets = self.gather_outbound_fast_retransmission_packets(raw_packets, now);
2168 raw_packets = self.gather_outbound_sack_packets(raw_packets);
2169 self.gather_outbound_shutdown_packets(raw_packets, now)
2170 }
2171 AssociationState::ShutdownAckSent => {
2172 self.gather_outbound_shutdown_packets(raw_packets, now)
2173 }
2174 _ => (raw_packets, true),
2175 }
2176 }
2177
2178 fn gather_data_packets_to_retransmit(
2179 &mut self,
2180 mut raw_packets: Vec<Bytes>,
2181 now: Instant,
2182 ) -> Vec<Bytes> {
2183 if self.t3_retransmit_pending {
2186 self.get_data_packets_to_retransmit(now, &mut raw_packets);
2187 }
2188 raw_packets
2189 }
2190
2191 fn gather_outbound_data_and_reconfig_packets(
2192 &mut self,
2193 mut raw_packets: Vec<Bytes>,
2194 now: Instant,
2195 ) -> Vec<Bytes> {
2196 let (chunks, sis_to_reset) = self.pop_pending_data_chunks_to_send(now);
2199 if !chunks.is_empty() {
2200 trace!("[{}] T3-rtx timer start (pt1)", self.side);
2202 self.timers
2203 .restart_if_stale(Timer::T3RTX, now, self.rto_mgr.get_rto());
2204
2205 self.bundle_data_chunks_into_packets(chunks, &mut raw_packets);
2206 }
2207
2208 if !sis_to_reset.is_empty() || self.will_retransmit_reconfig {
2209 if self.will_retransmit_reconfig {
2210 self.will_retransmit_reconfig = false;
2211 debug!(
2212 "[{}] retransmit {} RECONFIG chunk(s)",
2213 self.side,
2214 self.reconfigs.len()
2215 );
2216 for c in self.reconfigs.values() {
2217 let p = self.create_packet(vec![Box::new(c.clone())]);
2218 if let Ok(raw) = p.marshal() {
2219 raw_packets.push(raw);
2220 } else {
2221 warn!(
2222 "[{}] failed to serialize a RECONFIG packet to be retransmitted",
2223 self.side,
2224 );
2225 }
2226 }
2227 }
2228
2229 if !sis_to_reset.is_empty() {
2230 let rsn = self.generate_next_rsn();
2231 let tsn = self.my_next_tsn - 1;
2232 debug!(
2233 "[{}] sending RECONFIG: rsn={} tsn={} streams={:?}",
2234 self.side,
2235 rsn,
2236 self.my_next_tsn - 1,
2237 sis_to_reset
2238 );
2239
2240 let c = ChunkReconfig {
2241 param_a: Some(Box::new(ParamOutgoingResetRequest {
2242 reconfig_request_sequence_number: rsn,
2243 sender_last_tsn: tsn,
2244 stream_identifiers: sis_to_reset,
2245 ..Default::default()
2246 })),
2247 ..Default::default()
2248 };
2249 self.reconfigs.insert(rsn, c.clone()); let p = self.create_packet(vec![Box::new(c)]);
2252 if let Ok(raw) = p.marshal() {
2253 raw_packets.push(raw);
2254 } else {
2255 warn!(
2256 "[{}] failed to serialize a RECONFIG packet to be transmitted",
2257 self.side
2258 );
2259 }
2260 }
2261
2262 if !self.reconfigs.is_empty() {
2263 self.timers
2264 .start(Timer::Reconfig, now, self.rto_mgr.get_rto());
2265 }
2266 }
2267
2268 raw_packets
2269 }
2270
2271 fn gather_outbound_fast_retransmission_packets(
2272 &mut self,
2273 mut raw_packets: Vec<Bytes>,
2274 now: Instant,
2275 ) -> Vec<Bytes> {
2276 if self.will_retransmit_fast {
2277 self.will_retransmit_fast = false;
2278
2279 let mut to_fast_retrans: Vec<Box<dyn Chunk>> = vec![];
2280 let mut fast_retrans_size = COMMON_HEADER_SIZE;
2281
2282 let mut i = 0;
2283 loop {
2284 let tsn = self.cumulative_tsn_ack_point + i + 1;
2285 if let Some(c) = self.inflight_queue.get_mut(tsn) {
2286 if c.acked || c.abandoned() || c.nsent > 1 || c.miss_indicator < 3 {
2287 i += 1;
2288 continue;
2289 }
2290
2291 let data_chunk_size = DATA_CHUNK_HEADER_SIZE + c.user_data.len() as u32;
2302 if self.mtu < fast_retrans_size + data_chunk_size {
2303 break;
2304 }
2305
2306 fast_retrans_size += data_chunk_size;
2307 self.stats.inc_fast_retrans();
2308 c.nsent += 1;
2309 } else {
2310 break; }
2312
2313 if let Some(c) = self.inflight_queue.get_mut(tsn) {
2314 Association::check_partial_reliability_status(
2315 c,
2316 now,
2317 self.use_forward_tsn,
2318 self.side,
2319 &self.streams,
2320 );
2321 to_fast_retrans.push(Box::new(c.clone()));
2322 trace!(
2323 "[{}] fast-retransmit: tsn={} sent={} htna={}",
2324 self.side, c.tsn, c.nsent, self.fast_recover_exit_point
2325 );
2326 }
2327 i += 1;
2328 }
2329
2330 if !to_fast_retrans.is_empty() {
2331 if let Ok(raw) = self.create_packet(to_fast_retrans).marshal() {
2332 raw_packets.push(raw);
2333 } else {
2334 warn!(
2335 "[{}] failed to serialize a DATA packet to be fast-retransmitted",
2336 self.side
2337 );
2338 }
2339 }
2340 }
2341
2342 raw_packets
2343 }
2344
2345 fn gather_outbound_sack_packets(&mut self, mut raw_packets: Vec<Bytes>) -> Vec<Bytes> {
2346 if self.ack_state == AckState::Immediate {
2347 self.ack_state = AckState::Idle;
2348 let sack = self.create_selective_ack_chunk();
2349 debug!("[{}] sending SACK: {}", self.side, sack);
2350 if let Ok(raw) = self.marshal_control_chunk(&sack) {
2351 raw_packets.push(raw);
2352 } else {
2353 warn!("[{}] failed to serialize a SACK packet", self.side);
2354 }
2355 }
2356
2357 raw_packets
2358 }
2359
2360 fn gather_outbound_forward_tsn_packets(&mut self, mut raw_packets: Vec<Bytes>) -> Vec<Bytes> {
2361 if self.will_send_forward_tsn {
2367 self.will_send_forward_tsn = false;
2368 if sna32gt(
2369 self.advanced_peer_tsn_ack_point,
2370 self.cumulative_tsn_ack_point,
2371 ) {
2372 let fwd_tsn = self.create_forward_tsn();
2373 if let Ok(raw) = self.marshal_control_chunk(&fwd_tsn) {
2374 raw_packets.push(raw);
2375 } else {
2376 warn!("[{}] failed to serialize a Forward TSN packet", self.side);
2377 }
2378 }
2379 }
2380
2381 raw_packets
2382 }
2383
2384 fn gather_outbound_shutdown_packets(
2385 &mut self,
2386 mut raw_packets: Vec<Bytes>,
2387 now: Instant,
2388 ) -> (Vec<Bytes>, bool) {
2389 let mut ok = true;
2390
2391 if self.will_send_shutdown {
2392 self.will_send_shutdown = false;
2393
2394 let shutdown = ChunkShutdown {
2395 cumulative_tsn_ack: self.cumulative_tsn_ack_point,
2396 };
2397
2398 if let Ok(raw) = self.create_packet(vec![Box::new(shutdown)]).marshal() {
2399 self.timers
2400 .start(Timer::T2Shutdown, now, self.rto_mgr.get_rto());
2401 raw_packets.push(raw);
2402 } else {
2403 warn!("[{}] failed to serialize a Shutdown packet", self.side);
2404 }
2405 } else if self.will_send_shutdown_ack {
2406 self.will_send_shutdown_ack = false;
2407
2408 let shutdown_ack = ChunkShutdownAck {};
2409
2410 if let Ok(raw) = self.create_packet(vec![Box::new(shutdown_ack)]).marshal() {
2411 self.timers
2412 .start(Timer::T2Shutdown, now, self.rto_mgr.get_rto());
2413 raw_packets.push(raw);
2414 } else {
2415 warn!("[{}] failed to serialize a ShutdownAck packet", self.side);
2416 }
2417 } else if self.will_send_shutdown_complete {
2418 self.will_send_shutdown_complete = false;
2419
2420 let shutdown_complete = ChunkShutdownComplete {};
2421
2422 if let Ok(raw) = self
2423 .create_packet(vec![Box::new(shutdown_complete)])
2424 .marshal()
2425 {
2426 raw_packets.push(raw);
2427 ok = false;
2428 } else {
2429 warn!(
2430 "[{}] failed to serialize a ShutdownComplete packet",
2431 self.side
2432 );
2433 }
2434 }
2435
2436 (raw_packets, ok)
2437 }
2438
2439 fn get_data_packets_to_retransmit(&mut self, now: Instant, raw_packets: &mut Vec<Bytes>) {
2442 let awnd = std::cmp::min(self.cwnd, self.rwnd);
2443 let mut chunks = vec![];
2444 let mut bytes_to_send = 0;
2445 let mut done = false;
2446 let mut i = 0;
2447 let mut chunks_remaining = false;
2451 while !done {
2452 let tsn = self.cumulative_tsn_ack_point + i + 1;
2453 if let Some(c) = self.inflight_queue.get_mut(tsn) {
2454 if !c.retransmit {
2455 i += 1;
2456 continue;
2457 }
2458
2459 if i == 0 && self.rwnd < c.user_data.len() as u32 {
2460 done = true;
2462 chunks_remaining = true;
2463 } else if bytes_to_send + c.user_data.len() > awnd as usize {
2464 chunks_remaining = true;
2465 break;
2466 }
2467
2468 c.retransmit = false;
2471 bytes_to_send += c.user_data.len();
2472
2473 c.nsent += 1;
2474 } else {
2475 break; }
2477
2478 if let Some(c) = self.inflight_queue.get_mut(tsn) {
2479 Association::check_partial_reliability_status(
2480 c,
2481 now,
2482 self.use_forward_tsn,
2483 self.side,
2484 &self.streams,
2485 );
2486
2487 trace!(
2488 "[{}] retransmitting tsn={} ssn={} sent={}",
2489 self.side, c.tsn, c.stream_sequence_number, c.nsent
2490 );
2491
2492 chunks.push(c.clone());
2493 }
2494 i += 1;
2495 }
2496
2497 self.t3_retransmit_pending = chunks_remaining;
2500
2501 self.bundle_data_chunks_into_packets(chunks, raw_packets);
2502 }
2503
2504 fn pop_pending_data_chunks_to_send(
2507 &mut self,
2508 now: Instant,
2509 ) -> (Vec<ChunkPayloadData>, Vec<u16>) {
2510 let mut chunks = vec![];
2511 let mut sis_to_reset = vec![]; if !self.pending_queue.is_empty() {
2513 while let Some(c) = self.pending_queue.peek() {
2522 let (beginning_fragment, unordered, data_len, stream_identifier) = (
2523 c.beginning_fragment,
2524 c.unordered,
2525 c.user_data.len(),
2526 c.stream_identifier,
2527 );
2528
2529 if data_len == 0 {
2530 sis_to_reset.push(stream_identifier);
2531 if self
2532 .pending_queue
2533 .pop(beginning_fragment, unordered)
2534 .is_none()
2535 {
2536 error!("[{}] failed to pop from pending queue", self.side);
2537 }
2538 continue;
2539 }
2540
2541 if self.inflight_queue.get_num_bytes() + data_len > self.cwnd as usize {
2542 break; }
2544
2545 if data_len > self.rwnd as usize {
2546 break; }
2548
2549 self.rwnd -= data_len as u32;
2550
2551 if let Some(chunk) = self.move_pending_data_chunk_to_inflight_queue(
2552 beginning_fragment,
2553 unordered,
2554 now,
2555 ) {
2556 chunks.push(chunk);
2557 }
2558 }
2559
2560 if chunks.is_empty() && self.inflight_queue.is_empty() {
2562 if let Some(c) = self.pending_queue.peek() {
2564 let (beginning_fragment, unordered) = (c.beginning_fragment, c.unordered);
2565
2566 if let Some(chunk) = self.move_pending_data_chunk_to_inflight_queue(
2567 beginning_fragment,
2568 unordered,
2569 now,
2570 ) {
2571 chunks.push(chunk);
2572 }
2573 }
2574 }
2575 }
2576
2577 (chunks, sis_to_reset)
2578 }
2579
2580 fn bundle_data_chunks_into_packets(
2584 &self,
2585 chunks: Vec<ChunkPayloadData>,
2586 raw_packets: &mut Vec<Bytes>,
2587 ) {
2588 if chunks.is_empty() {
2599 return;
2600 }
2601 let common_header = CommonHeader {
2602 verification_tag: self.peer_verification_tag,
2603 source_port: self.source_port,
2604 destination_port: self.destination_port,
2605 };
2606
2607 let hdr = COMMON_HEADER_SIZE as usize;
2615 let mut bundles: Vec<(usize, usize)> = Vec::new();
2616 let mut total_len = 0usize;
2617 let mut bundle_start = 0;
2618 let mut bytes_in_packet = COMMON_HEADER_SIZE;
2619 let mut bundle_len = hdr;
2620 for (i, chunk) in chunks.iter().enumerate() {
2621 let data_len = chunk.user_data.len() as u32;
2622 if bytes_in_packet + data_len > self.mtu && i > bundle_start {
2624 bundles.push((bundle_start, i));
2625 total_len += bundle_len;
2626 bundle_start = i;
2627 bytes_in_packet = COMMON_HEADER_SIZE;
2628 bundle_len = hdr;
2629 }
2630 bytes_in_packet += DATA_CHUNK_HEADER_SIZE + data_len;
2631 let wire = (DATA_CHUNK_HEADER_SIZE + data_len) as usize;
2633 bundle_len += (wire + 3) & !3;
2634 }
2635 bundles.push((bundle_start, chunks.len()));
2636 total_len += bundle_len;
2637
2638 let mut buf = BytesMut::with_capacity(total_len);
2640 for (start, end) in bundles {
2641 match Packet::write_framed(
2642 &common_header,
2643 chunks[start..end].iter().map(|c| c as &dyn Chunk),
2644 &mut buf,
2645 ) {
2646 Ok(_) => {
2647 let plen = buf.len();
2648 raw_packets.push(buf.split_to(plen).freeze());
2649 }
2650 Err(_) => {
2651 warn!("[{}] failed to serialize a DATA packet", self.side);
2652 buf.clear();
2653 }
2654 }
2655 }
2656 }
2657
2658 fn generate_next_tsn(&mut self) -> u32 {
2660 let tsn = self.my_next_tsn;
2661 self.my_next_tsn += 1;
2662 tsn
2663 }
2664
2665 fn generate_next_rsn(&mut self) -> u32 {
2667 let rsn = self.my_next_rsn;
2668 self.my_next_rsn += 1;
2669 rsn
2670 }
2671
2672 fn check_partial_reliability_status(
2673 c: &mut ChunkPayloadData,
2674 now: Instant,
2675 use_forward_tsn: bool,
2676 side: Side,
2677 streams: &FxHashMap<u16, StreamState>,
2678 ) {
2679 if !use_forward_tsn {
2680 return;
2681 }
2682
2683 if c.payload_type == PayloadProtocolIdentifier::Dcep {
2689 return;
2690 }
2691
2692 if let Some(s) = streams.get(&c.stream_identifier) {
2694 let reliability_type: ReliabilityType = s.reliability_type;
2695 let reliability_value = s.reliability_value;
2696
2697 if reliability_type == ReliabilityType::Rexmit {
2698 if c.nsent >= reliability_value {
2699 c.set_abandoned(true);
2700 trace!(
2701 "[{}] marked as abandoned: tsn={} ppi={} (remix: {})",
2702 side, c.tsn, c.payload_type, c.nsent
2703 );
2704 }
2705 } else if reliability_type == ReliabilityType::Timed {
2706 if let Some(since) = &c.since {
2707 let elapsed = now.duration_since(*since);
2708 if elapsed.as_millis() as u32 >= reliability_value {
2709 c.set_abandoned(true);
2710 trace!(
2711 "[{}] marked as abandoned: tsn={} ppi={} (timed: {:?})",
2712 side, c.tsn, c.payload_type, elapsed
2713 );
2714 }
2715 } else {
2716 error!("[{}] invalid c.since", side);
2717 }
2718 }
2719 } else {
2720 error!("[{}] stream {} not found)", side, c.stream_identifier);
2721 }
2722 }
2723
2724 fn create_selective_ack_chunk(&mut self) -> ChunkSelectiveAck {
2725 ChunkSelectiveAck {
2726 cumulative_tsn_ack: self.peer_last_tsn,
2727 advertised_receiver_window_credit: self.get_my_receiver_window_credit(),
2728 gap_ack_blocks: self.payload_queue.get_gap_ack_blocks(self.peer_last_tsn),
2729 duplicate_tsn: self.payload_queue.pop_duplicates(),
2730 }
2731 }
2732
2733 fn note_abandoned_for_forward_tsn(&mut self, unordered: bool, si: u16, ssn: u16) {
2747 if unordered {
2748 return;
2749 }
2750 self.fwd_tsn_stream_map
2751 .entry(si)
2752 .and_modify(|cur| {
2753 if sna16lt(*cur, ssn) {
2754 *cur = ssn;
2755 }
2756 })
2757 .or_insert(ssn);
2758 }
2759
2760 #[cfg(test)]
2764 pub(crate) fn fwd_tsn_stream_map_is_empty(&self) -> bool {
2765 self.fwd_tsn_stream_map.is_empty()
2766 }
2767
2768 fn create_forward_tsn(&self) -> ChunkForwardTsn {
2771 let mut fwd_tsn = ChunkForwardTsn {
2779 new_cumulative_tsn: self.advanced_peer_tsn_ack_point,
2780 streams: Vec::with_capacity(self.fwd_tsn_stream_map.len()),
2781 };
2782 for (si, ssn) in &self.fwd_tsn_stream_map {
2783 fwd_tsn.streams.push(ChunkForwardTsnStream {
2784 identifier: *si,
2785 sequence: *ssn,
2786 });
2787 }
2788 trace!(
2793 "[{}] building fwd_tsn: newCumulativeTSN={} cumTSN={} streams={:?}",
2794 self.side, fwd_tsn.new_cumulative_tsn, self.cumulative_tsn_ack_point, fwd_tsn.streams
2795 );
2796
2797 fwd_tsn
2798 }
2799
2800 fn move_pending_data_chunk_to_inflight_queue(
2802 &mut self,
2803 beginning_fragment: bool,
2804 unordered: bool,
2805 now: Instant,
2806 ) -> Option<ChunkPayloadData> {
2807 if let Some(mut c) = self.pending_queue.pop(beginning_fragment, unordered) {
2808 if c.ending_fragment {
2810 c.set_all_inflight();
2811 }
2812
2813 c.tsn = self.generate_next_tsn();
2815
2816 c.since = Some(now); c.nsent = 1; Association::check_partial_reliability_status(
2820 &mut c,
2821 now,
2822 self.use_forward_tsn,
2823 self.side,
2824 &self.streams,
2825 );
2826
2827 trace!(
2828 "[{}] sending ppi={} tsn={} ssn={} sent={} len={} ({},{})",
2829 self.side,
2830 c.payload_type as u32,
2831 c.tsn,
2832 c.stream_sequence_number,
2833 c.nsent,
2834 c.user_data.len(),
2835 c.beginning_fragment,
2836 c.ending_fragment
2837 );
2838
2839 self.inflight_queue.push_no_check(c.clone());
2840
2841 Some(c)
2842 } else {
2843 error!("[{}] failed to pop from pending queue", self.side);
2844 None
2845 }
2846 }
2847
2848 pub(crate) fn send_reset_request(&mut self, stream_identifier: StreamId) -> Result<()> {
2849 let state = self.state();
2850 if state != AssociationState::Established {
2851 return Err(Error::ErrResetPacketInStateNotExist);
2852 }
2853
2854 let c = ChunkPayloadData {
2857 stream_identifier,
2858 beginning_fragment: true,
2859 ending_fragment: true,
2860 user_data: Bytes::new(),
2861 ..Default::default()
2862 };
2863
2864 self.pending_queue.push(c);
2865 self.awake_write_loop();
2866
2867 Ok(())
2868 }
2869
2870 pub(crate) fn send_payload_data(&mut self, chunks: Vec<ChunkPayloadData>) -> Result<()> {
2872 let state = self.state();
2873 if state != AssociationState::Established {
2874 return Err(Error::ErrPayloadDataStateNotExist);
2875 }
2876
2877 for c in chunks {
2879 self.pending_queue.push(c);
2880 }
2881
2882 self.awake_write_loop();
2883 Ok(())
2884 }
2885
2886 pub(crate) fn buffered_amount(&self) -> usize {
2889 self.pending_queue.get_num_bytes() + self.inflight_queue.get_num_bytes()
2890 }
2891
2892 fn awake_write_loop(&self) {
2893 }
2895
2896 fn close_all_timers(&mut self) {
2897 for timer in Timer::VALUES {
2899 self.timers.stop(timer);
2900 }
2901 }
2902
2903 fn on_ack_timeout(&mut self) {
2904 trace!(
2905 "[{}] ack timed out (ack_state: {})",
2906 self.side, self.ack_state
2907 );
2908 self.stats.inc_ack_timeouts();
2909 self.ack_state = AckState::Immediate;
2910 self.awake_write_loop();
2911 }
2912
2913 fn on_retransmission_timeout(&mut self, timer_id: Timer, n_rtos: usize) {
2914 match timer_id {
2915 Timer::T1Init => {
2916 if let Err(err) = self.send_init() {
2917 debug!(
2918 "[{}] failed to retransmit init (n_rtos={}): {:?}",
2919 self.side, n_rtos, err
2920 );
2921 }
2922 }
2923
2924 Timer::T1Cookie => {
2925 if let Err(err) = self.send_cookie_echo() {
2926 debug!(
2927 "[{}] failed to retransmit cookie-echo (n_rtos={}): {:?}",
2928 self.side, n_rtos, err
2929 );
2930 }
2931 }
2932
2933 Timer::T2Shutdown => {
2934 debug!(
2935 "[{}] retransmission of shutdown timeout (n_rtos={})",
2936 self.side, n_rtos
2937 );
2938 let state = self.state();
2939 match state {
2940 AssociationState::ShutdownSent => {
2941 self.will_send_shutdown = true;
2942 self.awake_write_loop();
2943 }
2944 AssociationState::ShutdownAckSent => {
2945 self.will_send_shutdown_ack = true;
2946 self.awake_write_loop();
2947 }
2948 _ => {}
2949 }
2950 }
2951
2952 Timer::T3RTX => {
2953 self.stats.inc_t3timeouts();
2954
2955 self.ssthresh = std::cmp::max(self.cwnd / 2, 4 * self.mtu);
2966 self.cwnd = self.mtu;
2967 trace!(
2968 "[{}] updated cwnd={} ssthresh={} inflight={} (RTO)",
2969 self.side,
2970 self.cwnd,
2971 self.ssthresh,
2972 self.inflight_queue.get_num_bytes()
2973 );
2974
2975 if self.use_forward_tsn {
2980 let mut i = self.advanced_peer_tsn_ack_point + 1;
2982 while let Some((abandoned, unordered, si, ssn)) =
2983 self.inflight_queue.get(i).map(|c| {
2984 (
2985 c.abandoned(),
2986 c.unordered,
2987 c.stream_identifier,
2988 c.stream_sequence_number,
2989 )
2990 })
2991 {
2992 if !abandoned {
2993 break;
2994 }
2995 self.advanced_peer_tsn_ack_point = i;
2996 self.note_abandoned_for_forward_tsn(unordered, si, ssn);
2997 i += 1;
2998 }
2999
3000 if sna32gt(
3002 self.advanced_peer_tsn_ack_point,
3003 self.cumulative_tsn_ack_point,
3004 ) {
3005 self.will_send_forward_tsn = true;
3006 debug!(
3007 "[{}] on_retransmission_timeout {}: sna32GT({}, {})",
3008 self.side,
3009 self.will_send_forward_tsn,
3010 self.advanced_peer_tsn_ack_point,
3011 self.cumulative_tsn_ack_point
3012 );
3013 }
3014 }
3015
3016 debug!(
3017 "[{}] T3-rtx timed out: n_rtos={} cwnd={} ssthresh={}",
3018 self.side, n_rtos, self.cwnd, self.ssthresh
3019 );
3020
3021 self.inflight_queue.mark_all_to_retrasmit();
3022 self.t3_retransmit_pending = true;
3023 self.awake_write_loop();
3024 }
3025
3026 Timer::Reconfig => {
3027 self.will_retransmit_reconfig = true;
3028 self.awake_write_loop();
3029 }
3030
3031 _ => {}
3032 }
3033 }
3034
3035 fn on_retransmission_failure(&mut self, id: Timer) {
3036 match id {
3037 Timer::T1Init => {
3038 error!("[{}] retransmission failure: T1-init", self.side);
3039 self.error = Some(AssociationError::HandshakeFailed(
3040 Error::ErrHandshakeInitAck.to_string(),
3041 ));
3042 }
3043
3044 Timer::T1Cookie => {
3045 error!("[{}] retransmission failure: T1-cookie", self.side);
3046 self.error = Some(AssociationError::HandshakeFailed(
3047 Error::ErrHandshakeCookieEcho.to_string(),
3048 ));
3049 }
3050
3051 Timer::T2Shutdown => {
3052 error!("[{}] retransmission failure: T2-shutdown", self.side);
3053 }
3054
3055 Timer::T3RTX => {
3056 error!("[{}] retransmission failure: T3-rtx (DATA)", self.side);
3061 }
3062
3063 _ => {}
3064 }
3065 }
3066
3067 #[cfg(test)]
3069 pub(crate) fn is_idle(&self) -> bool {
3070 Timer::VALUES
3071 .iter()
3072 .filter_map(|&t| Some((t, self.timers.get(t)?)))
3074 .min_by_key(|&(_, time)| time)
3075 .is_none()
3077 }
3078}