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 if let Some(last_tsn) = self.payload_queue.get_last_tsn_received() {
1225 if sna32lt(d.tsn, *last_tsn) {
1226 debug!(
1227 "[{}] receive buffer full, but accepted as this is a missing chunk with tsn={} ssn={}",
1228 self.side, d.tsn, d.stream_sequence_number
1229 );
1230 self.payload_queue.push(d.clone(), self.peer_last_tsn);
1231 stream_handle_data = true; }
1233 } else {
1234 debug!(
1235 "[{}] receive buffer full. dropping DATA with tsn={} ssn={}",
1236 self.side, d.tsn, d.stream_sequence_number
1237 );
1238 }
1239 }
1240 } else {
1241 debug!("[{}] discard {}", self.side, d.stream_sequence_number);
1243 return Ok(vec![]);
1244 }
1245 }
1246
1247 let immediate_sack = d.immediate_sack;
1248
1249 if stream_handle_data && let Some(s) = self.streams.get_mut(&d.stream_identifier) {
1250 self.events.push_back(Event::DatagramReceived);
1251 if s.handle_data(d) && s.reassembly_queue.is_readable() {
1252 self.events.push_back(Event::Stream(StreamEvent::Readable {
1253 id: s.stream_identifier,
1254 }));
1255 }
1256 }
1257
1258 self.handle_peer_last_tsn_and_acknowledgement(immediate_sack)
1259 }
1260
1261 fn handle_sack(&mut self, d: &ChunkSelectiveAck, now: Instant) -> Result<Vec<Packet>> {
1262 trace!(
1263 "[{}] {}, SACK: cumTSN={} a_rwnd={}",
1264 self.side,
1265 self.cumulative_tsn_ack_point,
1266 d.cumulative_tsn_ack,
1267 d.advertised_receiver_window_credit
1268 );
1269 let state = self.state();
1270 if state != AssociationState::Established
1271 && state != AssociationState::ShutdownPending
1272 && state != AssociationState::ShutdownReceived
1273 {
1274 return Ok(vec![]);
1275 }
1276
1277 self.stats.inc_sacks();
1278
1279 if sna32gt(self.cumulative_tsn_ack_point, d.cumulative_tsn_ack) {
1280 debug!(
1289 "[{}] SACK Cumulative ACK {} is older than ACK point {}",
1290 self.side, d.cumulative_tsn_ack, self.cumulative_tsn_ack_point
1291 );
1292
1293 return Ok(vec![]);
1294 }
1295
1296 let (bytes_acked_per_stream, htna) = self.process_selective_ack(d, now)?;
1298
1299 let mut total_bytes_acked = 0;
1300 for n_bytes_acked in bytes_acked_per_stream.values() {
1301 total_bytes_acked += *n_bytes_acked;
1302 }
1303
1304 let mut cum_tsn_ack_point_advanced = false;
1305 if sna32lt(self.cumulative_tsn_ack_point, d.cumulative_tsn_ack) {
1306 trace!(
1307 "[{}] SACK: cumTSN advanced: {} -> {}",
1308 self.side, self.cumulative_tsn_ack_point, d.cumulative_tsn_ack
1309 );
1310
1311 self.cumulative_tsn_ack_point = d.cumulative_tsn_ack;
1312 cum_tsn_ack_point_advanced = true;
1313 self.on_cumulative_tsn_ack_point_advanced(total_bytes_acked, now);
1314 }
1315
1316 for (si, n_bytes_acked) in &bytes_acked_per_stream {
1317 if *n_bytes_acked > 0 {
1318 self.events
1324 .push_back(Event::Stream(StreamEvent::BufferedAmountReleased {
1325 id: *si,
1326 n_bytes: *n_bytes_acked as usize,
1327 }));
1328 }
1329 if let Some(s) = self.streams.get_mut(si)
1330 && s.on_buffer_released(*n_bytes_acked)
1331 {
1332 trace!("StreamEvent::BufferedAmountLow");
1333 self.events
1334 .push_back(Event::Stream(StreamEvent::BufferedAmountLow { id: *si }))
1335 }
1336 }
1337
1338 let bytes_outstanding = self.inflight_queue.get_num_bytes() as u32;
1347 if bytes_outstanding >= d.advertised_receiver_window_credit {
1348 self.rwnd = 0;
1349 } else {
1350 self.rwnd = d.advertised_receiver_window_credit - bytes_outstanding;
1351 }
1352
1353 self.process_fast_retransmission(d.cumulative_tsn_ack, htna, cum_tsn_ack_point_advanced)?;
1354
1355 if self.use_forward_tsn {
1356 if sna32lt(
1358 self.advanced_peer_tsn_ack_point,
1359 self.cumulative_tsn_ack_point,
1360 ) {
1361 self.advanced_peer_tsn_ack_point = self.cumulative_tsn_ack_point;
1362 self.fwd_tsn_stream_map.clear();
1365 }
1366
1367 let mut i = self.advanced_peer_tsn_ack_point + 1;
1371 while let Some((abandoned, unordered, si, ssn)) = self.inflight_queue.get(i).map(|c| {
1372 (
1373 c.abandoned(),
1374 c.unordered,
1375 c.stream_identifier,
1376 c.stream_sequence_number,
1377 )
1378 }) {
1379 if !abandoned {
1380 break;
1381 }
1382 self.advanced_peer_tsn_ack_point = i;
1383 self.note_abandoned_for_forward_tsn(unordered, si, ssn);
1384 i += 1;
1385 }
1386
1387 if sna32gt(
1389 self.advanced_peer_tsn_ack_point,
1390 self.cumulative_tsn_ack_point,
1391 ) {
1392 self.will_send_forward_tsn = true;
1393 debug!(
1394 "[{}] handleSack {}: sna32GT({}, {})",
1395 self.side,
1396 self.will_send_forward_tsn,
1397 self.advanced_peer_tsn_ack_point,
1398 self.cumulative_tsn_ack_point
1399 );
1400 } else {
1401 self.fwd_tsn_stream_map.clear();
1404 }
1405 self.awake_write_loop();
1406 }
1407
1408 self.postprocess_sack(state, cum_tsn_ack_point_advanced, now);
1409
1410 Ok(vec![])
1411 }
1412
1413 fn handle_reconfig(&mut self, c: &ChunkReconfig) -> Result<Vec<Packet>> {
1414 trace!("[{}] handle_reconfig", self.side);
1415
1416 let mut pp = vec![];
1417
1418 if let Some(param_a) = &c.param_a {
1419 self.handle_reconfig_param(param_a, &mut pp)?;
1420 }
1421
1422 if let Some(param_b) = &c.param_b {
1423 self.handle_reconfig_param(param_b, &mut pp)?;
1424 }
1425
1426 Ok(pp)
1427 }
1428
1429 fn handle_forward_tsn(&mut self, c: &ChunkForwardTsn) -> Result<Vec<Packet>> {
1430 trace!("[{}] FwdTSN: {}", self.side, c);
1431
1432 if !self.use_forward_tsn {
1433 warn!("[{}] received FwdTSN but not enabled", self.side);
1434 let cerr = ChunkError {
1436 error_causes: vec![ErrorCauseUnrecognizedChunkType::default()],
1437 };
1438
1439 let outbound = Packet {
1440 common_header: CommonHeader {
1441 verification_tag: self.peer_verification_tag,
1442 source_port: self.source_port,
1443 destination_port: self.destination_port,
1444 },
1445 chunks: vec![Box::new(cerr)],
1446 };
1447 return Ok(vec![outbound]);
1448 }
1449
1450 trace!(
1459 "[{}] should send ack? newCumTSN={} peer_last_tsn={}",
1460 self.side, c.new_cumulative_tsn, self.peer_last_tsn
1461 );
1462 if sna32lte(c.new_cumulative_tsn, self.peer_last_tsn) {
1463 trace!("[{}] sending ack on Forward TSN", self.side);
1464 self.ack_state = AckState::Immediate;
1465 self.timers.stop(Timer::Ack);
1466 self.awake_write_loop();
1467 return Ok(vec![]);
1468 }
1469
1470 while sna32lt(self.peer_last_tsn, c.new_cumulative_tsn) {
1482 self.payload_queue.pop(self.peer_last_tsn + 1); self.peer_last_tsn += 1;
1484 }
1485
1486 for forwarded in &c.streams {
1490 if let Some(s) = self.streams.get_mut(&forwarded.identifier) {
1491 s.handle_forward_tsn_for_ordered(forwarded.sequence);
1492 if s.reassembly_queue.is_readable() {
1493 self.events.push_back(Event::Stream(StreamEvent::Readable {
1494 id: s.stream_identifier,
1495 }));
1496 }
1497 }
1498 }
1499
1500 for s in self.streams.values_mut() {
1505 s.handle_forward_tsn_for_unordered(c.new_cumulative_tsn);
1506 if s.reassembly_queue.is_readable() {
1507 self.events.push_back(Event::Stream(StreamEvent::Readable {
1508 id: s.stream_identifier,
1509 }));
1510 }
1511 }
1512
1513 self.handle_peer_last_tsn_and_acknowledgement(false)
1514 }
1515
1516 fn handle_shutdown(&mut self, _: &ChunkShutdown) -> Result<Vec<Packet>> {
1517 let state = self.state();
1518
1519 if state == AssociationState::Established {
1520 if !self.inflight_queue.is_empty() {
1521 self.set_state(AssociationState::ShutdownReceived);
1522 } else {
1523 self.will_send_shutdown_ack = true;
1525 self.set_state(AssociationState::ShutdownAckSent);
1526
1527 self.awake_write_loop();
1528 }
1529 } else if state == AssociationState::ShutdownSent {
1530 self.will_send_shutdown_ack = true;
1533 self.set_state(AssociationState::ShutdownAckSent);
1534
1535 self.awake_write_loop();
1536 }
1537
1538 Ok(vec![])
1539 }
1540
1541 fn handle_shutdown_ack(&mut self, _: &ChunkShutdownAck) -> Result<Vec<Packet>> {
1542 let state = self.state();
1543 if state == AssociationState::ShutdownSent || state == AssociationState::ShutdownAckSent {
1544 self.timers.stop(Timer::T2Shutdown);
1545 self.will_send_shutdown_complete = true;
1546
1547 self.awake_write_loop();
1548 }
1549
1550 Ok(vec![])
1551 }
1552
1553 fn handle_shutdown_complete(&mut self, _: &ChunkShutdownComplete) -> Result<Vec<Packet>> {
1554 let state = self.state();
1555 if state == AssociationState::ShutdownAckSent {
1556 self.timers.stop(Timer::T2Shutdown);
1557 self.close(AssociationError::AssociationClosed)?;
1558 }
1559
1560 Ok(vec![])
1561 }
1562
1563 fn handle_peer_last_tsn_and_acknowledgement(
1565 &mut self,
1566 sack_immediately: bool,
1567 ) -> Result<Vec<Packet>> {
1568 let mut reply = vec![];
1569
1570 while self.payload_queue.pop(self.peer_last_tsn + 1).is_some() {
1579 self.peer_last_tsn += 1;
1580 let rst_reqs: Vec<ParamOutgoingResetRequest> =
1583 self.reconfig_requests.values().cloned().collect();
1584 for rst_req in rst_reqs {
1585 self.reset_streams_if_any(&rst_req, false, &mut reply)?;
1586 }
1587 }
1588
1589 let has_packet_loss = !self.payload_queue.is_empty();
1590 if has_packet_loss {
1591 trace!(
1592 "[{}] packetloss: {}",
1593 self.side,
1594 self.payload_queue
1595 .get_gap_ack_blocks_string(self.peer_last_tsn)
1596 );
1597 }
1598
1599 if (self.ack_state != AckState::Immediate
1600 && !sack_immediately
1601 && !has_packet_loss
1602 && self.ack_mode == AckMode::Normal)
1603 || self.ack_mode == AckMode::AlwaysDelay
1604 {
1605 if self.ack_state == AckState::Idle {
1606 self.delayed_ack_triggered = true;
1607 } else {
1608 self.immediate_ack_triggered = true;
1609 }
1610 } else {
1611 self.immediate_ack_triggered = true;
1612 }
1613
1614 Ok(reply)
1615 }
1616
1617 #[allow(clippy::borrowed_box)]
1618 fn handle_reconfig_param(
1619 &mut self,
1620 raw: &Box<dyn Param>,
1621 reply: &mut Vec<Packet>,
1622 ) -> Result<()> {
1623 if let Some(p) = raw.as_any().downcast_ref::<ParamOutgoingResetRequest>() {
1624 self.reconfig_requests
1625 .insert(p.reconfig_request_sequence_number, p.clone());
1626 self.reset_streams_if_any(p, true, reply)?;
1627 Ok(())
1628 } else if let Some(p) = raw.as_any().downcast_ref::<ParamReconfigResponse>() {
1629 self.reconfigs.remove(&p.reconfig_response_sequence_number);
1630 if self.reconfigs.is_empty() {
1631 self.timers.stop(Timer::Reconfig);
1632 }
1633 Ok(())
1634 } else {
1635 Err(Error::ErrParameterType)
1636 }
1637 }
1638
1639 fn process_selective_ack(
1640 &mut self,
1641 d: &ChunkSelectiveAck,
1642 now: Instant,
1643 ) -> Result<(FxHashMap<u16, i64>, u32)> {
1644 let mut bytes_acked_per_stream = FxHashMap::default();
1645
1646 let mut i = self.cumulative_tsn_ack_point + 1;
1650 while sna32lte(i, d.cumulative_tsn_ack) {
1652 if let Some(c) = self.inflight_queue.pop(i) {
1653 if !c.acked {
1654 if i == self.cumulative_tsn_ack_point + 1 {
1660 self.timers.stop(Timer::T3RTX);
1662 }
1663
1664 let n_bytes_acked = c.user_data.len() as i64;
1665
1666 if let Some(amount) = bytes_acked_per_stream.get_mut(&c.stream_identifier) {
1668 *amount += n_bytes_acked;
1669 } else {
1670 bytes_acked_per_stream.insert(c.stream_identifier, n_bytes_acked);
1671 }
1672
1673 if c.nsent == 1 && sna32gte(c.tsn, self.min_tsn2measure_rtt) {
1683 self.min_tsn2measure_rtt = self.my_next_tsn;
1684 if let Some(since) = &c.since {
1685 let rtt = now.duration_since(*since);
1686 let srtt = self.rto_mgr.set_new_rtt(rtt.as_millis() as u64);
1687 trace!(
1688 "[{}] SACK: measured-rtt={} srtt={} new-rto={}",
1689 self.side,
1690 rtt.as_millis(),
1691 srtt,
1692 self.rto_mgr.get_rto()
1693 );
1694 } else {
1695 error!("[{}] invalid c.since", self.side);
1696 }
1697 }
1698 }
1699
1700 if self.in_fast_recovery && c.tsn == self.fast_recover_exit_point {
1701 debug!("[{}] exit fast-recovery", self.side);
1702 self.in_fast_recovery = false;
1703 }
1704 } else {
1705 return Err(Error::ErrInflightQueueTsnPop);
1706 }
1707
1708 i += 1;
1709 }
1710
1711 let mut htna = d.cumulative_tsn_ack;
1712
1713 for g in &d.gap_ack_blocks {
1715 for i in g.start..=g.end {
1716 let tsn = d.cumulative_tsn_ack + i as u32;
1717
1718 let (is_existed, is_acked) = if let Some(c) = self.inflight_queue.get(tsn) {
1719 (true, c.acked)
1720 } else {
1721 (false, false)
1722 };
1723 let n_bytes_acked = if is_existed && !is_acked {
1724 self.inflight_queue.mark_as_acked(tsn) as i64
1725 } else {
1726 0
1727 };
1728
1729 if let Some(c) = self.inflight_queue.get(tsn) {
1730 if !is_acked {
1731 if let Some(amount) = bytes_acked_per_stream.get_mut(&c.stream_identifier) {
1733 *amount += n_bytes_acked;
1734 } else {
1735 bytes_acked_per_stream.insert(c.stream_identifier, n_bytes_acked);
1736 }
1737
1738 trace!("[{}] tsn={} has been sacked", self.side, c.tsn);
1739
1740 if c.nsent == 1 {
1741 self.min_tsn2measure_rtt = self.my_next_tsn;
1742 if let Some(since) = &c.since {
1743 let rtt = now.duration_since(*since);
1744 let srtt = self.rto_mgr.set_new_rtt(rtt.as_millis() as u64);
1745 trace!(
1746 "[{}] SACK: measured-rtt={} srtt={} new-rto={}",
1747 self.side,
1748 rtt.as_millis(),
1749 srtt,
1750 self.rto_mgr.get_rto()
1751 );
1752 } else {
1753 error!("[{}] invalid c.since", self.side);
1754 }
1755 }
1756
1757 if sna32lt(htna, tsn) {
1758 htna = tsn;
1759 }
1760 }
1761 } else {
1762 return Err(Error::ErrTsnRequestNotExist);
1763 }
1764 }
1765 }
1766
1767 Ok((bytes_acked_per_stream, htna))
1768 }
1769
1770 fn on_cumulative_tsn_ack_point_advanced(&mut self, total_bytes_acked: i64, now: Instant) {
1771 if self.inflight_queue.is_empty() {
1775 trace!(
1776 "[{}] SACK: no more packet in-flight (pending={})",
1777 self.side,
1778 self.pending_queue.len()
1779 );
1780 self.timers.stop(Timer::T3RTX);
1781 } else {
1782 trace!("[{}] T3-rtx timer start (pt2)", self.side);
1783 self.timers
1784 .restart_if_stale(Timer::T3RTX, now, self.rto_mgr.get_rto());
1785 }
1786
1787 if self.cwnd <= self.ssthresh {
1789 if !self.in_fast_recovery && !self.pending_queue.is_empty() {
1801 self.cwnd += std::cmp::min(total_bytes_acked as u32, self.cwnd); trace!(
1804 "[{}] updated cwnd={} ssthresh={} acked={} (SS)",
1805 self.side, self.cwnd, self.ssthresh, total_bytes_acked
1806 );
1807 } else {
1808 trace!(
1809 "[{}] cwnd did not grow: cwnd={} ssthresh={} acked={} FR={} pending={}",
1810 self.side,
1811 self.cwnd,
1812 self.ssthresh,
1813 total_bytes_acked,
1814 self.in_fast_recovery,
1815 self.pending_queue.len()
1816 );
1817 }
1818 } else {
1819 self.partial_bytes_acked += total_bytes_acked as u32;
1826
1827 if self.partial_bytes_acked >= self.cwnd && !self.pending_queue.is_empty() {
1833 self.partial_bytes_acked -= self.cwnd;
1834 self.cwnd += self.mtu;
1835 trace!(
1836 "[{}] updated cwnd={} ssthresh={} acked={} (CA)",
1837 self.side, self.cwnd, self.ssthresh, total_bytes_acked
1838 );
1839 }
1840 }
1841 }
1842
1843 fn process_fast_retransmission(
1844 &mut self,
1845 cum_tsn_ack_point: u32,
1846 htna: u32,
1847 cum_tsn_ack_point_advanced: bool,
1848 ) -> Result<()> {
1849 if !self.in_fast_recovery || cum_tsn_ack_point_advanced {
1859 let max_tsn = if !self.in_fast_recovery {
1860 htna
1862 } else {
1863 cum_tsn_ack_point + (self.inflight_queue.len() as u32) + 1
1865 };
1866
1867 let mut tsn = cum_tsn_ack_point + 1;
1868 while sna32lt(tsn, max_tsn) {
1869 if let Some(c) = self.inflight_queue.get_mut(tsn) {
1870 if !c.acked && !c.abandoned() && c.miss_indicator < 3 {
1871 c.miss_indicator += 1;
1872 if c.miss_indicator == 3 && !self.in_fast_recovery {
1873 self.in_fast_recovery = true;
1877 self.fast_recover_exit_point = htna;
1878 self.ssthresh = std::cmp::max(self.cwnd / 2, 4 * self.mtu);
1879 self.cwnd = self.ssthresh;
1880 self.partial_bytes_acked = 0;
1881 self.will_retransmit_fast = true;
1882
1883 trace!(
1884 "[{}] updated cwnd={} ssthresh={} inflight={} (FR)",
1885 self.side,
1886 self.cwnd,
1887 self.ssthresh,
1888 self.inflight_queue.get_num_bytes()
1889 );
1890 }
1891 }
1892 } else {
1893 return Err(Error::ErrTsnRequestNotExist);
1894 }
1895
1896 tsn += 1;
1897 }
1898 }
1899
1900 if self.in_fast_recovery && cum_tsn_ack_point_advanced {
1901 self.will_retransmit_fast = true;
1902 }
1903
1904 Ok(())
1905 }
1906
1907 fn postprocess_sack(
1910 &mut self,
1911 state: AssociationState,
1912 mut should_awake_write_loop: bool,
1913 now: Instant,
1914 ) {
1915 if !self.inflight_queue.is_empty() {
1916 trace!("[{}] T3-rtx timer start (pt3)", self.side);
1918 self.timers
1919 .restart_if_stale(Timer::T3RTX, now, self.rto_mgr.get_rto());
1920 } else if state == AssociationState::ShutdownPending {
1921 should_awake_write_loop = true;
1923 self.will_send_shutdown = true;
1924 self.set_state(AssociationState::ShutdownSent);
1925 } else if state == AssociationState::ShutdownReceived {
1926 should_awake_write_loop = true;
1928 self.will_send_shutdown_ack = true;
1929 self.set_state(AssociationState::ShutdownAckSent);
1930 }
1931
1932 if should_awake_write_loop {
1933 self.awake_write_loop();
1934 }
1935 }
1936
1937 fn reset_streams_if_any(
1938 &mut self,
1939 p: &ParamOutgoingResetRequest,
1940 respond: bool,
1941 reply: &mut Vec<Packet>,
1942 ) -> Result<()> {
1943 let mut result = ReconfigResult::SuccessPerformed;
1944 let mut sis_to_reset = vec![];
1945
1946 if sna32lte(p.sender_last_tsn, self.peer_last_tsn) {
1947 debug!(
1948 "[{}] resetStream(): senderLastTSN={} <= peer_last_tsn={}",
1949 self.side, p.sender_last_tsn, self.peer_last_tsn
1950 );
1951 for id in &p.stream_identifiers {
1952 if self.streams.contains_key(id) {
1953 if respond {
1954 sis_to_reset.push(*id);
1955 }
1956 self.unregister_stream(*id, AssociationError::Reset);
1957 }
1958 }
1959 self.reconfig_requests
1960 .remove(&p.reconfig_request_sequence_number);
1961 } else {
1962 debug!(
1963 "[{}] resetStream(): senderLastTSN={} > peer_last_tsn={}",
1964 self.side, p.sender_last_tsn, self.peer_last_tsn
1965 );
1966 result = ReconfigResult::InProgress;
1967 }
1968
1969 if !sis_to_reset.is_empty() {
1972 let rsn = self.generate_next_rsn();
1973 let tsn = self.my_next_tsn - 1;
1974
1975 let c = ChunkReconfig {
1976 param_a: Some(Box::new(ParamOutgoingResetRequest {
1977 reconfig_request_sequence_number: rsn,
1978 reconfig_response_sequence_number: p.reconfig_request_sequence_number,
1979 sender_last_tsn: tsn,
1980 stream_identifiers: sis_to_reset,
1981 })),
1982 ..Default::default()
1983 };
1984
1985 self.reconfigs.insert(rsn, c.clone()); let p = self.create_packet(vec![Box::new(c)]);
1988 reply.push(p);
1989 }
1990
1991 let packet = self.create_packet(vec![Box::new(ChunkReconfig {
1992 param_a: Some(Box::new(ParamReconfigResponse {
1993 reconfig_response_sequence_number: p.reconfig_request_sequence_number,
1994 result,
1995 })),
1996 param_b: None,
1997 })]);
1998
1999 debug!("[{}] RESET RESPONSE: {}", self.side, packet);
2000
2001 reply.push(packet);
2002
2003 Ok(())
2004 }
2005
2006 pub(crate) fn create_packet(&self, chunks: Vec<Box<dyn Chunk>>) -> Packet {
2009 Packet {
2010 common_header: CommonHeader {
2011 verification_tag: self.peer_verification_tag,
2012 source_port: self.source_port,
2013 destination_port: self.destination_port,
2014 },
2015 chunks,
2016 }
2017 }
2018
2019 fn marshal_control_chunk(&self, chunk: &dyn Chunk) -> Result<Bytes> {
2026 let common_header = CommonHeader {
2027 verification_tag: self.peer_verification_tag,
2028 source_port: self.source_port,
2029 destination_port: self.destination_port,
2030 };
2031 let mut buf = BytesMut::with_capacity(
2033 COMMON_HEADER_SIZE as usize + CHUNK_HEADER_SIZE + chunk.value_length() + 3,
2034 );
2035 Packet::write_framed(&common_header, std::iter::once(chunk), &mut buf)?;
2036 Ok(buf.freeze())
2037 }
2038
2039 fn create_stream(
2041 &mut self,
2042 stream_identifier: StreamId,
2043 accept: bool,
2044 default_payload_type: PayloadProtocolIdentifier,
2045 ) -> Option<Stream<'_>> {
2046 let s = StreamState::new(
2047 self.side,
2048 stream_identifier,
2049 self.max_payload_size,
2050 default_payload_type,
2051 );
2052
2053 if accept {
2054 self.stream_queue.push_back(stream_identifier);
2055 self.events.push_back(Event::Stream(StreamEvent::Opened {
2056 id: stream_identifier,
2057 }));
2058 }
2059
2060 self.streams.insert(stream_identifier, s);
2061
2062 Some(Stream {
2063 stream_identifier,
2064 association: self,
2065 })
2066 }
2067
2068 fn get_or_create_stream(&mut self, stream_identifier: StreamId) -> Option<Stream<'_>> {
2070 if self.streams.contains_key(&stream_identifier) {
2071 Some(Stream {
2072 stream_identifier,
2073 association: self,
2074 })
2075 } else {
2076 self.create_stream(
2077 stream_identifier,
2078 true,
2079 PayloadProtocolIdentifier::default(),
2080 )
2081 }
2082 }
2083
2084 pub(crate) fn get_my_receiver_window_credit(&self) -> u32 {
2085 let mut bytes_queued = 0;
2086 for s in self.streams.values() {
2087 bytes_queued += s.get_num_bytes_in_reassembly_queue() as u32;
2088 }
2089
2090 self.max_receive_buffer_size.saturating_sub(bytes_queued)
2091 }
2092
2093 fn gather_outbound(&mut self, now: Instant) -> (Vec<Bytes>, bool) {
2096 let mut raw_packets = vec![];
2097
2098 if !self.control_queue.is_empty() {
2099 for p in self.control_queue.drain(..) {
2100 if let Ok(raw) = p.marshal() {
2101 raw_packets.push(raw);
2102 } else {
2103 warn!("[{}] failed to serialize a control packet", self.side);
2104 continue;
2105 }
2106 }
2107 }
2108
2109 let state = self.state();
2110 match state {
2111 AssociationState::Established => {
2112 raw_packets = self.gather_data_packets_to_retransmit(raw_packets, now);
2113 raw_packets = self.gather_outbound_data_and_reconfig_packets(raw_packets, now);
2114 raw_packets = self.gather_outbound_fast_retransmission_packets(raw_packets, now);
2115 raw_packets = self.gather_outbound_sack_packets(raw_packets);
2116 raw_packets = self.gather_outbound_forward_tsn_packets(raw_packets);
2117 (raw_packets, true)
2118 }
2119 AssociationState::ShutdownPending
2120 | AssociationState::ShutdownSent
2121 | AssociationState::ShutdownReceived => {
2122 raw_packets = self.gather_data_packets_to_retransmit(raw_packets, now);
2123 raw_packets = self.gather_outbound_fast_retransmission_packets(raw_packets, now);
2124 raw_packets = self.gather_outbound_sack_packets(raw_packets);
2125 self.gather_outbound_shutdown_packets(raw_packets, now)
2126 }
2127 AssociationState::ShutdownAckSent => {
2128 self.gather_outbound_shutdown_packets(raw_packets, now)
2129 }
2130 _ => (raw_packets, true),
2131 }
2132 }
2133
2134 fn gather_data_packets_to_retransmit(
2135 &mut self,
2136 mut raw_packets: Vec<Bytes>,
2137 now: Instant,
2138 ) -> Vec<Bytes> {
2139 if self.t3_retransmit_pending {
2142 self.get_data_packets_to_retransmit(now, &mut raw_packets);
2143 }
2144 raw_packets
2145 }
2146
2147 fn gather_outbound_data_and_reconfig_packets(
2148 &mut self,
2149 mut raw_packets: Vec<Bytes>,
2150 now: Instant,
2151 ) -> Vec<Bytes> {
2152 let (chunks, sis_to_reset) = self.pop_pending_data_chunks_to_send(now);
2155 if !chunks.is_empty() {
2156 trace!("[{}] T3-rtx timer start (pt1)", self.side);
2158 self.timers
2159 .restart_if_stale(Timer::T3RTX, now, self.rto_mgr.get_rto());
2160
2161 self.bundle_data_chunks_into_packets(chunks, &mut raw_packets);
2162 }
2163
2164 if !sis_to_reset.is_empty() || self.will_retransmit_reconfig {
2165 if self.will_retransmit_reconfig {
2166 self.will_retransmit_reconfig = false;
2167 debug!(
2168 "[{}] retransmit {} RECONFIG chunk(s)",
2169 self.side,
2170 self.reconfigs.len()
2171 );
2172 for c in self.reconfigs.values() {
2173 let p = self.create_packet(vec![Box::new(c.clone())]);
2174 if let Ok(raw) = p.marshal() {
2175 raw_packets.push(raw);
2176 } else {
2177 warn!(
2178 "[{}] failed to serialize a RECONFIG packet to be retransmitted",
2179 self.side,
2180 );
2181 }
2182 }
2183 }
2184
2185 if !sis_to_reset.is_empty() {
2186 let rsn = self.generate_next_rsn();
2187 let tsn = self.my_next_tsn - 1;
2188 debug!(
2189 "[{}] sending RECONFIG: rsn={} tsn={} streams={:?}",
2190 self.side,
2191 rsn,
2192 self.my_next_tsn - 1,
2193 sis_to_reset
2194 );
2195
2196 let c = ChunkReconfig {
2197 param_a: Some(Box::new(ParamOutgoingResetRequest {
2198 reconfig_request_sequence_number: rsn,
2199 sender_last_tsn: tsn,
2200 stream_identifiers: sis_to_reset,
2201 ..Default::default()
2202 })),
2203 ..Default::default()
2204 };
2205 self.reconfigs.insert(rsn, c.clone()); let p = self.create_packet(vec![Box::new(c)]);
2208 if let Ok(raw) = p.marshal() {
2209 raw_packets.push(raw);
2210 } else {
2211 warn!(
2212 "[{}] failed to serialize a RECONFIG packet to be transmitted",
2213 self.side
2214 );
2215 }
2216 }
2217
2218 if !self.reconfigs.is_empty() {
2219 self.timers
2220 .start(Timer::Reconfig, now, self.rto_mgr.get_rto());
2221 }
2222 }
2223
2224 raw_packets
2225 }
2226
2227 fn gather_outbound_fast_retransmission_packets(
2228 &mut self,
2229 mut raw_packets: Vec<Bytes>,
2230 now: Instant,
2231 ) -> Vec<Bytes> {
2232 if self.will_retransmit_fast {
2233 self.will_retransmit_fast = false;
2234
2235 let mut to_fast_retrans: Vec<Box<dyn Chunk>> = vec![];
2236 let mut fast_retrans_size = COMMON_HEADER_SIZE;
2237
2238 let mut i = 0;
2239 loop {
2240 let tsn = self.cumulative_tsn_ack_point + i + 1;
2241 if let Some(c) = self.inflight_queue.get_mut(tsn) {
2242 if c.acked || c.abandoned() || c.nsent > 1 || c.miss_indicator < 3 {
2243 i += 1;
2244 continue;
2245 }
2246
2247 let data_chunk_size = DATA_CHUNK_HEADER_SIZE + c.user_data.len() as u32;
2258 if self.mtu < fast_retrans_size + data_chunk_size {
2259 break;
2260 }
2261
2262 fast_retrans_size += data_chunk_size;
2263 self.stats.inc_fast_retrans();
2264 c.nsent += 1;
2265 } else {
2266 break; }
2268
2269 if let Some(c) = self.inflight_queue.get_mut(tsn) {
2270 Association::check_partial_reliability_status(
2271 c,
2272 now,
2273 self.use_forward_tsn,
2274 self.side,
2275 &self.streams,
2276 );
2277 to_fast_retrans.push(Box::new(c.clone()));
2278 trace!(
2279 "[{}] fast-retransmit: tsn={} sent={} htna={}",
2280 self.side, c.tsn, c.nsent, self.fast_recover_exit_point
2281 );
2282 }
2283 i += 1;
2284 }
2285
2286 if !to_fast_retrans.is_empty() {
2287 if let Ok(raw) = self.create_packet(to_fast_retrans).marshal() {
2288 raw_packets.push(raw);
2289 } else {
2290 warn!(
2291 "[{}] failed to serialize a DATA packet to be fast-retransmitted",
2292 self.side
2293 );
2294 }
2295 }
2296 }
2297
2298 raw_packets
2299 }
2300
2301 fn gather_outbound_sack_packets(&mut self, mut raw_packets: Vec<Bytes>) -> Vec<Bytes> {
2302 if self.ack_state == AckState::Immediate {
2303 self.ack_state = AckState::Idle;
2304 let sack = self.create_selective_ack_chunk();
2305 debug!("[{}] sending SACK: {}", self.side, sack);
2306 if let Ok(raw) = self.marshal_control_chunk(&sack) {
2307 raw_packets.push(raw);
2308 } else {
2309 warn!("[{}] failed to serialize a SACK packet", self.side);
2310 }
2311 }
2312
2313 raw_packets
2314 }
2315
2316 fn gather_outbound_forward_tsn_packets(&mut self, mut raw_packets: Vec<Bytes>) -> Vec<Bytes> {
2317 if self.will_send_forward_tsn {
2323 self.will_send_forward_tsn = false;
2324 if sna32gt(
2325 self.advanced_peer_tsn_ack_point,
2326 self.cumulative_tsn_ack_point,
2327 ) {
2328 let fwd_tsn = self.create_forward_tsn();
2329 if let Ok(raw) = self.marshal_control_chunk(&fwd_tsn) {
2330 raw_packets.push(raw);
2331 } else {
2332 warn!("[{}] failed to serialize a Forward TSN packet", self.side);
2333 }
2334 }
2335 }
2336
2337 raw_packets
2338 }
2339
2340 fn gather_outbound_shutdown_packets(
2341 &mut self,
2342 mut raw_packets: Vec<Bytes>,
2343 now: Instant,
2344 ) -> (Vec<Bytes>, bool) {
2345 let mut ok = true;
2346
2347 if self.will_send_shutdown {
2348 self.will_send_shutdown = false;
2349
2350 let shutdown = ChunkShutdown {
2351 cumulative_tsn_ack: self.cumulative_tsn_ack_point,
2352 };
2353
2354 if let Ok(raw) = self.create_packet(vec![Box::new(shutdown)]).marshal() {
2355 self.timers
2356 .start(Timer::T2Shutdown, now, self.rto_mgr.get_rto());
2357 raw_packets.push(raw);
2358 } else {
2359 warn!("[{}] failed to serialize a Shutdown packet", self.side);
2360 }
2361 } else if self.will_send_shutdown_ack {
2362 self.will_send_shutdown_ack = false;
2363
2364 let shutdown_ack = ChunkShutdownAck {};
2365
2366 if let Ok(raw) = self.create_packet(vec![Box::new(shutdown_ack)]).marshal() {
2367 self.timers
2368 .start(Timer::T2Shutdown, now, self.rto_mgr.get_rto());
2369 raw_packets.push(raw);
2370 } else {
2371 warn!("[{}] failed to serialize a ShutdownAck packet", self.side);
2372 }
2373 } else if self.will_send_shutdown_complete {
2374 self.will_send_shutdown_complete = false;
2375
2376 let shutdown_complete = ChunkShutdownComplete {};
2377
2378 if let Ok(raw) = self
2379 .create_packet(vec![Box::new(shutdown_complete)])
2380 .marshal()
2381 {
2382 raw_packets.push(raw);
2383 ok = false;
2384 } else {
2385 warn!(
2386 "[{}] failed to serialize a ShutdownComplete packet",
2387 self.side
2388 );
2389 }
2390 }
2391
2392 (raw_packets, ok)
2393 }
2394
2395 fn get_data_packets_to_retransmit(&mut self, now: Instant, raw_packets: &mut Vec<Bytes>) {
2398 let awnd = std::cmp::min(self.cwnd, self.rwnd);
2399 let mut chunks = vec![];
2400 let mut bytes_to_send = 0;
2401 let mut done = false;
2402 let mut i = 0;
2403 let mut chunks_remaining = false;
2407 while !done {
2408 let tsn = self.cumulative_tsn_ack_point + i + 1;
2409 if let Some(c) = self.inflight_queue.get_mut(tsn) {
2410 if !c.retransmit {
2411 i += 1;
2412 continue;
2413 }
2414
2415 if i == 0 && self.rwnd < c.user_data.len() as u32 {
2416 done = true;
2418 chunks_remaining = true;
2419 } else if bytes_to_send + c.user_data.len() > awnd as usize {
2420 chunks_remaining = true;
2421 break;
2422 }
2423
2424 c.retransmit = false;
2427 bytes_to_send += c.user_data.len();
2428
2429 c.nsent += 1;
2430 } else {
2431 break; }
2433
2434 if let Some(c) = self.inflight_queue.get_mut(tsn) {
2435 Association::check_partial_reliability_status(
2436 c,
2437 now,
2438 self.use_forward_tsn,
2439 self.side,
2440 &self.streams,
2441 );
2442
2443 trace!(
2444 "[{}] retransmitting tsn={} ssn={} sent={}",
2445 self.side, c.tsn, c.stream_sequence_number, c.nsent
2446 );
2447
2448 chunks.push(c.clone());
2449 }
2450 i += 1;
2451 }
2452
2453 self.t3_retransmit_pending = chunks_remaining;
2456
2457 self.bundle_data_chunks_into_packets(chunks, raw_packets);
2458 }
2459
2460 fn pop_pending_data_chunks_to_send(
2463 &mut self,
2464 now: Instant,
2465 ) -> (Vec<ChunkPayloadData>, Vec<u16>) {
2466 let mut chunks = vec![];
2467 let mut sis_to_reset = vec![]; if !self.pending_queue.is_empty() {
2469 while let Some(c) = self.pending_queue.peek() {
2478 let (beginning_fragment, unordered, data_len, stream_identifier) = (
2479 c.beginning_fragment,
2480 c.unordered,
2481 c.user_data.len(),
2482 c.stream_identifier,
2483 );
2484
2485 if data_len == 0 {
2486 sis_to_reset.push(stream_identifier);
2487 if self
2488 .pending_queue
2489 .pop(beginning_fragment, unordered)
2490 .is_none()
2491 {
2492 error!("[{}] failed to pop from pending queue", self.side);
2493 }
2494 continue;
2495 }
2496
2497 if self.inflight_queue.get_num_bytes() + data_len > self.cwnd as usize {
2498 break; }
2500
2501 if data_len > self.rwnd as usize {
2502 break; }
2504
2505 self.rwnd -= data_len as u32;
2506
2507 if let Some(chunk) = self.move_pending_data_chunk_to_inflight_queue(
2508 beginning_fragment,
2509 unordered,
2510 now,
2511 ) {
2512 chunks.push(chunk);
2513 }
2514 }
2515
2516 if chunks.is_empty() && self.inflight_queue.is_empty() {
2518 if let Some(c) = self.pending_queue.peek() {
2520 let (beginning_fragment, unordered) = (c.beginning_fragment, c.unordered);
2521
2522 if let Some(chunk) = self.move_pending_data_chunk_to_inflight_queue(
2523 beginning_fragment,
2524 unordered,
2525 now,
2526 ) {
2527 chunks.push(chunk);
2528 }
2529 }
2530 }
2531 }
2532
2533 (chunks, sis_to_reset)
2534 }
2535
2536 fn bundle_data_chunks_into_packets(
2540 &self,
2541 chunks: Vec<ChunkPayloadData>,
2542 raw_packets: &mut Vec<Bytes>,
2543 ) {
2544 if chunks.is_empty() {
2555 return;
2556 }
2557 let common_header = CommonHeader {
2558 verification_tag: self.peer_verification_tag,
2559 source_port: self.source_port,
2560 destination_port: self.destination_port,
2561 };
2562
2563 let hdr = COMMON_HEADER_SIZE as usize;
2571 let mut bundles: Vec<(usize, usize)> = Vec::new();
2572 let mut total_len = 0usize;
2573 let mut bundle_start = 0;
2574 let mut bytes_in_packet = COMMON_HEADER_SIZE;
2575 let mut bundle_len = hdr;
2576 for (i, chunk) in chunks.iter().enumerate() {
2577 let data_len = chunk.user_data.len() as u32;
2578 if bytes_in_packet + data_len > self.mtu && i > bundle_start {
2580 bundles.push((bundle_start, i));
2581 total_len += bundle_len;
2582 bundle_start = i;
2583 bytes_in_packet = COMMON_HEADER_SIZE;
2584 bundle_len = hdr;
2585 }
2586 bytes_in_packet += DATA_CHUNK_HEADER_SIZE + data_len;
2587 let wire = (DATA_CHUNK_HEADER_SIZE + data_len) as usize;
2589 bundle_len += (wire + 3) & !3;
2590 }
2591 bundles.push((bundle_start, chunks.len()));
2592 total_len += bundle_len;
2593
2594 let mut buf = BytesMut::with_capacity(total_len);
2596 for (start, end) in bundles {
2597 match Packet::write_framed(
2598 &common_header,
2599 chunks[start..end].iter().map(|c| c as &dyn Chunk),
2600 &mut buf,
2601 ) {
2602 Ok(_) => {
2603 let plen = buf.len();
2604 raw_packets.push(buf.split_to(plen).freeze());
2605 }
2606 Err(_) => {
2607 warn!("[{}] failed to serialize a DATA packet", self.side);
2608 buf.clear();
2609 }
2610 }
2611 }
2612 }
2613
2614 fn generate_next_tsn(&mut self) -> u32 {
2616 let tsn = self.my_next_tsn;
2617 self.my_next_tsn += 1;
2618 tsn
2619 }
2620
2621 fn generate_next_rsn(&mut self) -> u32 {
2623 let rsn = self.my_next_rsn;
2624 self.my_next_rsn += 1;
2625 rsn
2626 }
2627
2628 fn check_partial_reliability_status(
2629 c: &mut ChunkPayloadData,
2630 now: Instant,
2631 use_forward_tsn: bool,
2632 side: Side,
2633 streams: &FxHashMap<u16, StreamState>,
2634 ) {
2635 if !use_forward_tsn {
2636 return;
2637 }
2638
2639 if c.payload_type == PayloadProtocolIdentifier::Dcep {
2645 return;
2646 }
2647
2648 if let Some(s) = streams.get(&c.stream_identifier) {
2650 let reliability_type: ReliabilityType = s.reliability_type;
2651 let reliability_value = s.reliability_value;
2652
2653 if reliability_type == ReliabilityType::Rexmit {
2654 if c.nsent >= reliability_value {
2655 c.set_abandoned(true);
2656 trace!(
2657 "[{}] marked as abandoned: tsn={} ppi={} (remix: {})",
2658 side, c.tsn, c.payload_type, c.nsent
2659 );
2660 }
2661 } else if reliability_type == ReliabilityType::Timed {
2662 if let Some(since) = &c.since {
2663 let elapsed = now.duration_since(*since);
2664 if elapsed.as_millis() as u32 >= reliability_value {
2665 c.set_abandoned(true);
2666 trace!(
2667 "[{}] marked as abandoned: tsn={} ppi={} (timed: {:?})",
2668 side, c.tsn, c.payload_type, elapsed
2669 );
2670 }
2671 } else {
2672 error!("[{}] invalid c.since", side);
2673 }
2674 }
2675 } else {
2676 error!("[{}] stream {} not found)", side, c.stream_identifier);
2677 }
2678 }
2679
2680 fn create_selective_ack_chunk(&mut self) -> ChunkSelectiveAck {
2681 ChunkSelectiveAck {
2682 cumulative_tsn_ack: self.peer_last_tsn,
2683 advertised_receiver_window_credit: self.get_my_receiver_window_credit(),
2684 gap_ack_blocks: self.payload_queue.get_gap_ack_blocks(self.peer_last_tsn),
2685 duplicate_tsn: self.payload_queue.pop_duplicates(),
2686 }
2687 }
2688
2689 fn note_abandoned_for_forward_tsn(&mut self, unordered: bool, si: u16, ssn: u16) {
2703 if unordered {
2704 return;
2705 }
2706 self.fwd_tsn_stream_map
2707 .entry(si)
2708 .and_modify(|cur| {
2709 if sna16lt(*cur, ssn) {
2710 *cur = ssn;
2711 }
2712 })
2713 .or_insert(ssn);
2714 }
2715
2716 #[cfg(test)]
2720 pub(crate) fn fwd_tsn_stream_map_is_empty(&self) -> bool {
2721 self.fwd_tsn_stream_map.is_empty()
2722 }
2723
2724 fn create_forward_tsn(&self) -> ChunkForwardTsn {
2727 let mut fwd_tsn = ChunkForwardTsn {
2735 new_cumulative_tsn: self.advanced_peer_tsn_ack_point,
2736 streams: Vec::with_capacity(self.fwd_tsn_stream_map.len()),
2737 };
2738 for (si, ssn) in &self.fwd_tsn_stream_map {
2739 fwd_tsn.streams.push(ChunkForwardTsnStream {
2740 identifier: *si,
2741 sequence: *ssn,
2742 });
2743 }
2744 trace!(
2749 "[{}] building fwd_tsn: newCumulativeTSN={} cumTSN={} streams={:?}",
2750 self.side, fwd_tsn.new_cumulative_tsn, self.cumulative_tsn_ack_point, fwd_tsn.streams
2751 );
2752
2753 fwd_tsn
2754 }
2755
2756 fn move_pending_data_chunk_to_inflight_queue(
2758 &mut self,
2759 beginning_fragment: bool,
2760 unordered: bool,
2761 now: Instant,
2762 ) -> Option<ChunkPayloadData> {
2763 if let Some(mut c) = self.pending_queue.pop(beginning_fragment, unordered) {
2764 if c.ending_fragment {
2766 c.set_all_inflight();
2767 }
2768
2769 c.tsn = self.generate_next_tsn();
2771
2772 c.since = Some(now); c.nsent = 1; Association::check_partial_reliability_status(
2776 &mut c,
2777 now,
2778 self.use_forward_tsn,
2779 self.side,
2780 &self.streams,
2781 );
2782
2783 trace!(
2784 "[{}] sending ppi={} tsn={} ssn={} sent={} len={} ({},{})",
2785 self.side,
2786 c.payload_type as u32,
2787 c.tsn,
2788 c.stream_sequence_number,
2789 c.nsent,
2790 c.user_data.len(),
2791 c.beginning_fragment,
2792 c.ending_fragment
2793 );
2794
2795 self.inflight_queue.push_no_check(c.clone());
2796
2797 Some(c)
2798 } else {
2799 error!("[{}] failed to pop from pending queue", self.side);
2800 None
2801 }
2802 }
2803
2804 pub(crate) fn send_reset_request(&mut self, stream_identifier: StreamId) -> Result<()> {
2805 let state = self.state();
2806 if state != AssociationState::Established {
2807 return Err(Error::ErrResetPacketInStateNotExist);
2808 }
2809
2810 let c = ChunkPayloadData {
2813 stream_identifier,
2814 beginning_fragment: true,
2815 ending_fragment: true,
2816 user_data: Bytes::new(),
2817 ..Default::default()
2818 };
2819
2820 self.pending_queue.push(c);
2821 self.awake_write_loop();
2822
2823 Ok(())
2824 }
2825
2826 pub(crate) fn send_payload_data(&mut self, chunks: Vec<ChunkPayloadData>) -> Result<()> {
2828 let state = self.state();
2829 if state != AssociationState::Established {
2830 return Err(Error::ErrPayloadDataStateNotExist);
2831 }
2832
2833 for c in chunks {
2835 self.pending_queue.push(c);
2836 }
2837
2838 self.awake_write_loop();
2839 Ok(())
2840 }
2841
2842 pub(crate) fn buffered_amount(&self) -> usize {
2845 self.pending_queue.get_num_bytes() + self.inflight_queue.get_num_bytes()
2846 }
2847
2848 fn awake_write_loop(&self) {
2849 }
2851
2852 fn close_all_timers(&mut self) {
2853 for timer in Timer::VALUES {
2855 self.timers.stop(timer);
2856 }
2857 }
2858
2859 fn on_ack_timeout(&mut self) {
2860 trace!(
2861 "[{}] ack timed out (ack_state: {})",
2862 self.side, self.ack_state
2863 );
2864 self.stats.inc_ack_timeouts();
2865 self.ack_state = AckState::Immediate;
2866 self.awake_write_loop();
2867 }
2868
2869 fn on_retransmission_timeout(&mut self, timer_id: Timer, n_rtos: usize) {
2870 match timer_id {
2871 Timer::T1Init => {
2872 if let Err(err) = self.send_init() {
2873 debug!(
2874 "[{}] failed to retransmit init (n_rtos={}): {:?}",
2875 self.side, n_rtos, err
2876 );
2877 }
2878 }
2879
2880 Timer::T1Cookie => {
2881 if let Err(err) = self.send_cookie_echo() {
2882 debug!(
2883 "[{}] failed to retransmit cookie-echo (n_rtos={}): {:?}",
2884 self.side, n_rtos, err
2885 );
2886 }
2887 }
2888
2889 Timer::T2Shutdown => {
2890 debug!(
2891 "[{}] retransmission of shutdown timeout (n_rtos={})",
2892 self.side, n_rtos
2893 );
2894 let state = self.state();
2895 match state {
2896 AssociationState::ShutdownSent => {
2897 self.will_send_shutdown = true;
2898 self.awake_write_loop();
2899 }
2900 AssociationState::ShutdownAckSent => {
2901 self.will_send_shutdown_ack = true;
2902 self.awake_write_loop();
2903 }
2904 _ => {}
2905 }
2906 }
2907
2908 Timer::T3RTX => {
2909 self.stats.inc_t3timeouts();
2910
2911 self.ssthresh = std::cmp::max(self.cwnd / 2, 4 * self.mtu);
2922 self.cwnd = self.mtu;
2923 trace!(
2924 "[{}] updated cwnd={} ssthresh={} inflight={} (RTO)",
2925 self.side,
2926 self.cwnd,
2927 self.ssthresh,
2928 self.inflight_queue.get_num_bytes()
2929 );
2930
2931 if self.use_forward_tsn {
2936 let mut i = self.advanced_peer_tsn_ack_point + 1;
2938 while let Some((abandoned, unordered, si, ssn)) =
2939 self.inflight_queue.get(i).map(|c| {
2940 (
2941 c.abandoned(),
2942 c.unordered,
2943 c.stream_identifier,
2944 c.stream_sequence_number,
2945 )
2946 })
2947 {
2948 if !abandoned {
2949 break;
2950 }
2951 self.advanced_peer_tsn_ack_point = i;
2952 self.note_abandoned_for_forward_tsn(unordered, si, ssn);
2953 i += 1;
2954 }
2955
2956 if sna32gt(
2958 self.advanced_peer_tsn_ack_point,
2959 self.cumulative_tsn_ack_point,
2960 ) {
2961 self.will_send_forward_tsn = true;
2962 debug!(
2963 "[{}] on_retransmission_timeout {}: sna32GT({}, {})",
2964 self.side,
2965 self.will_send_forward_tsn,
2966 self.advanced_peer_tsn_ack_point,
2967 self.cumulative_tsn_ack_point
2968 );
2969 }
2970 }
2971
2972 debug!(
2973 "[{}] T3-rtx timed out: n_rtos={} cwnd={} ssthresh={}",
2974 self.side, n_rtos, self.cwnd, self.ssthresh
2975 );
2976
2977 self.inflight_queue.mark_all_to_retrasmit();
2978 self.t3_retransmit_pending = true;
2979 self.awake_write_loop();
2980 }
2981
2982 Timer::Reconfig => {
2983 self.will_retransmit_reconfig = true;
2984 self.awake_write_loop();
2985 }
2986
2987 _ => {}
2988 }
2989 }
2990
2991 fn on_retransmission_failure(&mut self, id: Timer) {
2992 match id {
2993 Timer::T1Init => {
2994 error!("[{}] retransmission failure: T1-init", self.side);
2995 self.error = Some(AssociationError::HandshakeFailed(
2996 Error::ErrHandshakeInitAck.to_string(),
2997 ));
2998 }
2999
3000 Timer::T1Cookie => {
3001 error!("[{}] retransmission failure: T1-cookie", self.side);
3002 self.error = Some(AssociationError::HandshakeFailed(
3003 Error::ErrHandshakeCookieEcho.to_string(),
3004 ));
3005 }
3006
3007 Timer::T2Shutdown => {
3008 error!("[{}] retransmission failure: T2-shutdown", self.side);
3009 }
3010
3011 Timer::T3RTX => {
3012 error!("[{}] retransmission failure: T3-rtx (DATA)", self.side);
3017 }
3018
3019 _ => {}
3020 }
3021 }
3022
3023 #[cfg(test)]
3025 pub(crate) fn is_idle(&self) -> bool {
3026 Timer::VALUES
3027 .iter()
3028 .filter_map(|&t| Some((t, self.timers.get(t)?)))
3030 .min_by_key(|&(_, time)| time)
3031 .is_none()
3033 }
3034}