1 #[cfg(test)]
2 mod association_internal_test;
3 
4 use super::*;
5 
6 use crate::param::param_type::ParamType;
7 use crate::param::param_unrecognized::ParamUnrecognized;
8 use async_trait::async_trait;
9 use std::sync::atomic::AtomicBool;
10 
11 #[derive(Default)]
12 pub struct AssociationInternal {
13     pub(crate) name: String,
14     pub(crate) state: Arc<AtomicU8>,
15     pub(crate) max_message_size: Arc<AtomicU32>,
16     pub(crate) inflight_queue_length: Arc<AtomicUsize>,
17     pub(crate) will_send_shutdown: Arc<AtomicBool>,
18     awake_write_loop_ch: Option<Arc<mpsc::Sender<()>>>,
19 
20     peer_verification_tag: u32,
21     pub(crate) my_verification_tag: u32,
22 
23     pub(crate) my_next_tsn: u32, // nextTSN
24     peer_last_tsn: u32,          // lastRcvdTSN
25     min_tsn2measure_rtt: u32,    // for RTT measurement
26     will_send_forward_tsn: bool,
27     will_retransmit_fast: bool,
28     will_retransmit_reconfig: bool,
29 
30     will_send_shutdown_ack: bool,
31     will_send_shutdown_complete: bool,
32 
33     // Reconfig
34     my_next_rsn: u32,
35     reconfigs: HashMap<u32, ChunkReconfig>,
36     reconfig_requests: HashMap<u32, ParamOutgoingResetRequest>,
37 
38     // Non-RFC internal data
39     source_port: u16,
40     destination_port: u16,
41     pub(crate) my_max_num_inbound_streams: u16,
42     pub(crate) my_max_num_outbound_streams: u16,
43     my_cookie: Option<ParamStateCookie>,
44     payload_queue: PayloadQueue,
45     inflight_queue: PayloadQueue,
46     pending_queue: Arc<PendingQueue>,
47     control_queue: ControlQueue,
48     pub(crate) mtu: u32,
49     max_payload_size: u32, // max DATA chunk payload size
50     cumulative_tsn_ack_point: u32,
51     advanced_peer_tsn_ack_point: u32,
52     use_forward_tsn: bool,
53 
54     // Congestion control parameters
55     pub(crate) max_receive_buffer_size: u32,
56     pub(crate) cwnd: u32,     // my congestion window size
57     rwnd: u32,                // calculated peer's receiver windows size
58     pub(crate) ssthresh: u32, // slow start threshold
59     partial_bytes_acked: u32,
60     pub(crate) in_fast_recovery: bool,
61     fast_recover_exit_point: u32,
62 
63     // RTX & Ack timer
64     pub(crate) rto_mgr: RtoManager,
65     pub(crate) t1init: Option<RtxTimer<AssociationInternal>>,
66     pub(crate) t1cookie: Option<RtxTimer<AssociationInternal>>,
67     pub(crate) t2shutdown: Option<RtxTimer<AssociationInternal>>,
68     pub(crate) t3rtx: Option<RtxTimer<AssociationInternal>>,
69     pub(crate) treconfig: Option<RtxTimer<AssociationInternal>>,
70     pub(crate) ack_timer: Option<AckTimer<AssociationInternal>>,
71 
72     // Chunks stored for retransmission
73     pub(crate) stored_init: Option<ChunkInit>,
74     stored_cookie_echo: Option<ChunkCookieEcho>,
75 
76     streams: HashMap<u16, Arc<Stream>>,
77 
78     close_loop_ch_tx: Option<broadcast::Sender<()>>,
79     accept_ch_tx: Option<mpsc::Sender<Arc<Stream>>>,
80     handshake_completed_ch_tx: Option<mpsc::Sender<Option<Error>>>,
81 
82     // local error
83     silent_error: Option<Error>,
84 
85     // per inbound packet context
86     delayed_ack_triggered: bool,
87     immediate_ack_triggered: bool,
88 
89     pub(crate) stats: Arc<AssociationStats>,
90     ack_state: AckState,
91     pub(crate) ack_mode: AckMode, // for testing
92 }
93 
94 impl AssociationInternal {
new( config: Config, close_loop_ch_tx: broadcast::Sender<()>, accept_ch_tx: mpsc::Sender<Arc<Stream>>, handshake_completed_ch_tx: mpsc::Sender<Option<Error>>, awake_write_loop_ch: Arc<mpsc::Sender<()>>, ) -> Self95     pub(crate) fn new(
96         config: Config,
97         close_loop_ch_tx: broadcast::Sender<()>,
98         accept_ch_tx: mpsc::Sender<Arc<Stream>>,
99         handshake_completed_ch_tx: mpsc::Sender<Option<Error>>,
100         awake_write_loop_ch: Arc<mpsc::Sender<()>>,
101     ) -> Self {
102         let max_receive_buffer_size = if config.max_receive_buffer_size == 0 {
103             INITIAL_RECV_BUF_SIZE
104         } else {
105             config.max_receive_buffer_size
106         };
107 
108         let max_message_size = if config.max_message_size == 0 {
109             DEFAULT_MAX_MESSAGE_SIZE
110         } else {
111             config.max_message_size
112         };
113 
114         let inflight_queue_length = Arc::new(AtomicUsize::new(0));
115 
116         let mut tsn = random::<u32>();
117         if tsn == 0 {
118             tsn += 1;
119         }
120         let mut a = AssociationInternal {
121             name: config.name,
122             max_receive_buffer_size,
123             max_message_size: Arc::new(AtomicU32::new(max_message_size)),
124 
125             my_max_num_outbound_streams: u16::MAX,
126             my_max_num_inbound_streams: u16::MAX,
127             payload_queue: PayloadQueue::new(Arc::new(AtomicUsize::new(0))),
128             inflight_queue: PayloadQueue::new(Arc::clone(&inflight_queue_length)),
129             inflight_queue_length,
130             pending_queue: Arc::new(PendingQueue::new()),
131             control_queue: ControlQueue::new(),
132             mtu: INITIAL_MTU,
133             max_payload_size: INITIAL_MTU - (COMMON_HEADER_SIZE + DATA_CHUNK_HEADER_SIZE),
134             my_verification_tag: random::<u32>(),
135             my_next_tsn: tsn,
136             my_next_rsn: tsn,
137             min_tsn2measure_rtt: tsn,
138             state: Arc::new(AtomicU8::new(AssociationState::Closed as u8)),
139             rto_mgr: RtoManager::new(),
140             streams: HashMap::new(),
141             reconfigs: HashMap::new(),
142             reconfig_requests: HashMap::new(),
143             accept_ch_tx: Some(accept_ch_tx),
144             close_loop_ch_tx: Some(close_loop_ch_tx),
145             handshake_completed_ch_tx: Some(handshake_completed_ch_tx),
146             cumulative_tsn_ack_point: tsn - 1,
147             advanced_peer_tsn_ack_point: tsn - 1,
148             silent_error: Some(Error::ErrSilentlyDiscard),
149             stats: Arc::new(AssociationStats::default()),
150             awake_write_loop_ch: Some(awake_write_loop_ch),
151             ..Default::default()
152         };
153 
154         // RFC 4690 Sec 7.2.1
155         //  o  The initial cwnd before DATA transmission or after a sufficiently
156         //     long idle period MUST be set to min(4*MTU, max (2*MTU, 4380
157         //     bytes)).
158         //     TODO: Consider whether this should use `clamp`
159         #[allow(clippy::manual_clamp)]
160         {
161             a.cwnd = std::cmp::min(4 * a.mtu, std::cmp::max(2 * a.mtu, 4380));
162         }
163         log::trace!(
164             "[{}] updated cwnd={} ssthresh={} inflight={} (INI)",
165             a.name,
166             a.cwnd,
167             a.ssthresh,
168             a.inflight_queue.get_num_bytes()
169         );
170 
171         a
172     }
173 
174     /// caller must hold self.lock
send_init(&mut self) -> Result<()>175     pub(crate) fn send_init(&mut self) -> Result<()> {
176         if let Some(stored_init) = self.stored_init.clone() {
177             log::debug!("[{}] sending INIT", self.name);
178 
179             self.source_port = 5000; // Spec??
180             self.destination_port = 5000; // Spec??
181 
182             let outbound = Packet {
183                 source_port: self.source_port,
184                 destination_port: self.destination_port,
185                 verification_tag: 0,
186                 chunks: vec![Box::new(stored_init)],
187             };
188 
189             self.control_queue.push_back(outbound);
190             self.awake_write_loop();
191 
192             Ok(())
193         } else {
194             Err(Error::ErrInitNotStoredToSend)
195         }
196     }
197 
198     /// caller must hold self.lock
send_cookie_echo(&mut self) -> Result<()>199     fn send_cookie_echo(&mut self) -> Result<()> {
200         if let Some(stored_cookie_echo) = &self.stored_cookie_echo {
201             log::debug!("[{}] sending COOKIE-ECHO", self.name);
202 
203             let outbound = Packet {
204                 source_port: self.source_port,
205                 destination_port: self.destination_port,
206                 verification_tag: self.peer_verification_tag,
207                 chunks: vec![Box::new(stored_cookie_echo.clone())],
208             };
209 
210             self.control_queue.push_back(outbound);
211             self.awake_write_loop();
212             Ok(())
213         } else {
214             Err(Error::ErrCookieEchoNotStoredToSend)
215         }
216     }
217 
close(&mut self) -> Result<()>218     pub(crate) async fn close(&mut self) -> Result<()> {
219         if self.get_state() != AssociationState::Closed {
220             self.set_state(AssociationState::Closed);
221 
222             log::debug!("[{}] closing association..", self.name);
223 
224             self.close_all_timers().await;
225 
226             // awake read/write_loop to exit
227             self.close_loop_ch_tx.take();
228 
229             for si in self.streams.keys().cloned().collect::<Vec<u16>>() {
230                 self.unregister_stream(si);
231             }
232 
233             // Wait for read_loop to end
234             //if let Some(read_loop_close_ch) = &mut self.read_loop_close_ch {
235             //    let _ = read_loop_close_ch.recv().await;
236             //}
237 
238             log::debug!("[{}] association closed", self.name);
239             log::debug!(
240                 "[{}] stats nDATAs (in) : {}",
241                 self.name,
242                 self.stats.get_num_datas()
243             );
244             log::debug!(
245                 "[{}] stats nSACKs (in) : {}",
246                 self.name,
247                 self.stats.get_num_sacks()
248             );
249             log::debug!(
250                 "[{}] stats nT3Timeouts : {}",
251                 self.name,
252                 self.stats.get_num_t3timeouts()
253             );
254             log::debug!(
255                 "[{}] stats nAckTimeouts: {}",
256                 self.name,
257                 self.stats.get_num_ack_timeouts()
258             );
259             log::debug!(
260                 "[{}] stats nFastRetrans: {}",
261                 self.name,
262                 self.stats.get_num_fast_retrans()
263             );
264         }
265 
266         Ok(())
267     }
268 
close_all_timers(&mut self)269     async fn close_all_timers(&mut self) {
270         // Close all retransmission & ack timers
271         if let Some(t1init) = &self.t1init {
272             t1init.stop().await;
273         }
274         if let Some(t1cookie) = &self.t1cookie {
275             t1cookie.stop().await;
276         }
277         if let Some(t2shutdown) = &self.t2shutdown {
278             t2shutdown.stop().await;
279         }
280         if let Some(t3rtx) = &self.t3rtx {
281             t3rtx.stop().await;
282         }
283         if let Some(treconfig) = &self.treconfig {
284             treconfig.stop().await;
285         }
286         if let Some(ack_timer) = &mut self.ack_timer {
287             ack_timer.stop();
288         }
289     }
290 
awake_write_loop(&self)291     fn awake_write_loop(&self) {
292         //log::debug!("[{}] awake_write_loop_ch.notify_one", self.name);
293         if let Some(awake_write_loop_ch) = &self.awake_write_loop_ch {
294             let _ = awake_write_loop_ch.try_send(());
295         }
296     }
297 
298     /// unregister_stream un-registers a stream from the association
299     /// The caller should hold the association write lock.
unregister_stream(&mut self, stream_identifier: u16)300     fn unregister_stream(&mut self, stream_identifier: u16) {
301         let s = self.streams.remove(&stream_identifier);
302         if let Some(s) = s {
303             // NOTE: shutdown is not used here because it resets the stream.
304             if !s.read_shutdown.swap(true, Ordering::SeqCst) {
305                 s.read_notifier.notify_waiters();
306             }
307             s.write_shutdown.store(true, Ordering::SeqCst);
308         }
309     }
310 
311     /// handle_inbound parses incoming raw packets
handle_inbound(&mut self, raw: &Bytes) -> Result<()>312     pub(crate) async fn handle_inbound(&mut self, raw: &Bytes) -> Result<()> {
313         let p = match Packet::unmarshal(raw) {
314             Ok(p) => p,
315             Err(err) => {
316                 log::warn!("[{}] unable to parse SCTP packet {}", self.name, err);
317                 return Ok(());
318             }
319         };
320 
321         if let Err(err) = p.check_packet() {
322             log::warn!("[{}] failed validating packet {}", self.name, err);
323             return Ok(());
324         }
325 
326         self.handle_chunk_start();
327 
328         for c in &p.chunks {
329             self.handle_chunk(&p, c).await?;
330         }
331 
332         self.handle_chunk_end();
333         Ok(())
334     }
335 
gather_data_packets_to_retransmit(&mut self, mut raw_packets: Vec<Packet>) -> Vec<Packet>336     fn gather_data_packets_to_retransmit(&mut self, mut raw_packets: Vec<Packet>) -> Vec<Packet> {
337         for p in self.get_data_packets_to_retransmit() {
338             raw_packets.push(p);
339         }
340 
341         raw_packets
342     }
343 
gather_outbound_data_and_reconfig_packets( &mut self, mut raw_packets: Vec<Packet>, ) -> Vec<Packet>344     async fn gather_outbound_data_and_reconfig_packets(
345         &mut self,
346         mut raw_packets: Vec<Packet>,
347     ) -> Vec<Packet> {
348         // Pop unsent data chunks from the pending queue to send as much as
349         // cwnd and rwnd allow.
350         let (chunks, sis_to_reset) = self.pop_pending_data_chunks_to_send().await;
351         if !chunks.is_empty() {
352             // Start timer. (noop if already started)
353             log::trace!("[{}] T3-rtx timer start (pt1)", self.name);
354             if let Some(t3rtx) = &self.t3rtx {
355                 t3rtx.start(self.rto_mgr.get_rto()).await;
356             }
357             for p in self.bundle_data_chunks_into_packets(chunks) {
358                 raw_packets.push(p);
359             }
360         }
361 
362         if !sis_to_reset.is_empty() || self.will_retransmit_reconfig {
363             if self.will_retransmit_reconfig {
364                 self.will_retransmit_reconfig = false;
365                 log::debug!(
366                     "[{}] retransmit {} RECONFIG chunk(s)",
367                     self.name,
368                     self.reconfigs.len()
369                 );
370                 for c in self.reconfigs.values() {
371                     let p = self.create_packet(vec![Box::new(c.clone())]);
372                     raw_packets.push(p);
373                 }
374             }
375 
376             if !sis_to_reset.is_empty() {
377                 let rsn = self.generate_next_rsn();
378                 let tsn = self.my_next_tsn - 1;
379                 log::debug!(
380                     "[{}] sending RECONFIG: rsn={} tsn={} streams={:?}",
381                     self.name,
382                     rsn,
383                     self.my_next_tsn - 1,
384                     sis_to_reset
385                 );
386 
387                 let c = ChunkReconfig {
388                     param_a: Some(Box::new(ParamOutgoingResetRequest {
389                         reconfig_request_sequence_number: rsn,
390                         sender_last_tsn: tsn,
391                         stream_identifiers: sis_to_reset,
392                         ..Default::default()
393                     })),
394                     ..Default::default()
395                 };
396                 self.reconfigs.insert(rsn, c.clone()); // store in the map for retransmission
397 
398                 let p = self.create_packet(vec![Box::new(c)]);
399                 raw_packets.push(p);
400             }
401 
402             if !self.reconfigs.is_empty() {
403                 if let Some(treconfig) = &self.treconfig {
404                     treconfig.start(self.rto_mgr.get_rto()).await;
405                 }
406             }
407         }
408 
409         raw_packets
410     }
411 
gather_outbound_fast_retransmission_packets( &mut self, mut raw_packets: Vec<Packet>, ) -> Vec<Packet>412     fn gather_outbound_fast_retransmission_packets(
413         &mut self,
414         mut raw_packets: Vec<Packet>,
415     ) -> Vec<Packet> {
416         if self.will_retransmit_fast {
417             self.will_retransmit_fast = false;
418 
419             let mut to_fast_retrans: Vec<Box<dyn Chunk + Send + Sync>> = vec![];
420             let mut fast_retrans_size = COMMON_HEADER_SIZE;
421 
422             let mut i = 0;
423             loop {
424                 let tsn = self.cumulative_tsn_ack_point + i + 1;
425                 if let Some(c) = self.inflight_queue.get_mut(tsn) {
426                     if c.acked || c.abandoned() || c.nsent > 1 || c.miss_indicator < 3 {
427                         i += 1;
428                         continue;
429                     }
430 
431                     // RFC 4960 Sec 7.2.4 Fast Retransmit on Gap Reports
432                     //  3)  Determine how many of the earliest (i.e., lowest TSN) DATA chunks
433                     //      marked for retransmission will fit into a single packet, subject
434                     //      to constraint of the path MTU of the destination transport
435                     //      address to which the packet is being sent.  Call this value K.
436                     //      Retransmit those K DATA chunks in a single packet.  When a Fast
437                     //      Retransmit is being performed, the sender SHOULD ignore the value
438                     //      of cwnd and SHOULD NOT delay retransmission for this single
439                     //		packet.
440 
441                     let data_chunk_size = DATA_CHUNK_HEADER_SIZE + c.user_data.len() as u32;
442                     if self.mtu < fast_retrans_size + data_chunk_size {
443                         break;
444                     }
445 
446                     fast_retrans_size += data_chunk_size;
447                     self.stats.inc_fast_retrans();
448                     c.nsent += 1;
449                 } else {
450                     break; // end of pending data
451                 }
452 
453                 if let Some(c) = self.inflight_queue.get(tsn) {
454                     self.check_partial_reliability_status(c);
455                     to_fast_retrans.push(Box::new(c.clone()));
456                     log::trace!(
457                         "[{}] fast-retransmit: tsn={} sent={} htna={}",
458                         self.name,
459                         c.tsn,
460                         c.nsent,
461                         self.fast_recover_exit_point
462                     );
463                 }
464                 i += 1;
465             }
466 
467             if !to_fast_retrans.is_empty() {
468                 let p = self.create_packet(to_fast_retrans);
469                 raw_packets.push(p);
470             }
471         }
472 
473         raw_packets
474     }
475 
gather_outbound_sack_packets(&mut self, mut raw_packets: Vec<Packet>) -> Vec<Packet>476     async fn gather_outbound_sack_packets(&mut self, mut raw_packets: Vec<Packet>) -> Vec<Packet> {
477         if self.ack_state == AckState::Immediate {
478             self.ack_state = AckState::Idle;
479             let sack = self.create_selective_ack_chunk().await;
480             log::debug!("[{}] sending SACK: {}", self.name, sack);
481             let p = self.create_packet(vec![Box::new(sack)]);
482             raw_packets.push(p);
483         }
484 
485         raw_packets
486     }
487 
gather_outbound_forward_tsn_packets(&mut self, mut raw_packets: Vec<Packet>) -> Vec<Packet>488     fn gather_outbound_forward_tsn_packets(&mut self, mut raw_packets: Vec<Packet>) -> Vec<Packet> {
489         /*log::debug!(
490             "[{}] gatherOutboundForwardTSNPackets {}",
491             self.name,
492             self.will_send_forward_tsn
493         );*/
494         if self.will_send_forward_tsn {
495             self.will_send_forward_tsn = false;
496             if sna32gt(
497                 self.advanced_peer_tsn_ack_point,
498                 self.cumulative_tsn_ack_point,
499             ) {
500                 let fwd_tsn = self.create_forward_tsn();
501                 let p = self.create_packet(vec![Box::new(fwd_tsn)]);
502                 raw_packets.push(p);
503             }
504         }
505 
506         raw_packets
507     }
508 
gather_outbound_shutdown_packets( &mut self, mut raw_packets: Vec<Packet>, ) -> (Vec<Packet>, bool)509     async fn gather_outbound_shutdown_packets(
510         &mut self,
511         mut raw_packets: Vec<Packet>,
512     ) -> (Vec<Packet>, bool) {
513         let mut ok = true;
514 
515         if self.will_send_shutdown.load(Ordering::SeqCst) {
516             self.will_send_shutdown.store(false, Ordering::SeqCst);
517 
518             let shutdown = ChunkShutdown {
519                 cumulative_tsn_ack: self.cumulative_tsn_ack_point,
520             };
521 
522             let p = self.create_packet(vec![Box::new(shutdown)]);
523             if let Some(t2shutdown) = &self.t2shutdown {
524                 t2shutdown.start(self.rto_mgr.get_rto()).await;
525             }
526             raw_packets.push(p);
527         } else if self.will_send_shutdown_ack {
528             self.will_send_shutdown_ack = false;
529 
530             let shutdown_ack = ChunkShutdownAck {};
531 
532             let p = self.create_packet(vec![Box::new(shutdown_ack)]);
533             if let Some(t2shutdown) = &self.t2shutdown {
534                 t2shutdown.start(self.rto_mgr.get_rto()).await;
535             }
536             raw_packets.push(p);
537         } else if self.will_send_shutdown_complete {
538             self.will_send_shutdown_complete = false;
539 
540             let shutdown_complete = ChunkShutdownComplete {};
541             ok = false;
542             let p = self.create_packet(vec![Box::new(shutdown_complete)]);
543 
544             raw_packets.push(p);
545         }
546 
547         (raw_packets, ok)
548     }
549 
550     /// gather_outbound gathers outgoing packets. The returned bool value set to
551     /// false means the association should be closed down after the final send.
gather_outbound(&mut self) -> (Vec<Packet>, bool)552     pub(crate) async fn gather_outbound(&mut self) -> (Vec<Packet>, bool) {
553         let mut raw_packets = Vec::with_capacity(16);
554 
555         if !self.control_queue.is_empty() {
556             for p in self.control_queue.drain(..) {
557                 raw_packets.push(p);
558             }
559         }
560 
561         let state = self.get_state();
562         match state {
563             AssociationState::Established => {
564                 raw_packets = self.gather_data_packets_to_retransmit(raw_packets);
565                 raw_packets = self
566                     .gather_outbound_data_and_reconfig_packets(raw_packets)
567                     .await;
568                 raw_packets = self.gather_outbound_fast_retransmission_packets(raw_packets);
569                 raw_packets = self.gather_outbound_sack_packets(raw_packets).await;
570                 raw_packets = self.gather_outbound_forward_tsn_packets(raw_packets);
571                 (raw_packets, true)
572             }
573             AssociationState::ShutdownPending
574             | AssociationState::ShutdownSent
575             | AssociationState::ShutdownReceived => {
576                 raw_packets = self.gather_data_packets_to_retransmit(raw_packets);
577                 raw_packets = self.gather_outbound_fast_retransmission_packets(raw_packets);
578                 raw_packets = self.gather_outbound_sack_packets(raw_packets).await;
579                 self.gather_outbound_shutdown_packets(raw_packets).await
580             }
581             AssociationState::ShutdownAckSent => {
582                 self.gather_outbound_shutdown_packets(raw_packets).await
583             }
584             _ => (raw_packets, true),
585         }
586     }
587 
588     /// set_state atomically sets the state of the Association.
set_state(&self, new_state: AssociationState)589     pub(crate) fn set_state(&self, new_state: AssociationState) {
590         let old_state = AssociationState::from(self.state.swap(new_state as u8, Ordering::SeqCst));
591         if new_state != old_state {
592             log::debug!(
593                 "[{}] state change: '{}' => '{}'",
594                 self.name,
595                 old_state,
596                 new_state,
597             );
598         }
599     }
600 
601     /// get_state atomically returns the state of the Association.
get_state(&self) -> AssociationState602     fn get_state(&self) -> AssociationState {
603         self.state.load(Ordering::SeqCst).into()
604     }
605 
handle_init(&mut self, p: &Packet, i: &ChunkInit) -> Result<Vec<Packet>>606     async fn handle_init(&mut self, p: &Packet, i: &ChunkInit) -> Result<Vec<Packet>> {
607         let state = self.get_state();
608         log::debug!("[{}] chunkInit received in state '{}'", self.name, state);
609 
610         // https://tools.ietf.org/html/rfc4960#section-5.2.1
611         // Upon receipt of an INIT in the COOKIE-WAIT state, an endpoint MUST
612         // respond with an INIT ACK using the same parameters it sent in its
613         // original INIT chunk (including its Initiate Tag, unchanged).  When
614         // responding, the endpoint MUST send the INIT ACK back to the same
615         // address that the original INIT (sent by this endpoint) was sent.
616 
617         if state != AssociationState::Closed
618             && state != AssociationState::CookieWait
619             && state != AssociationState::CookieEchoed
620         {
621             // 5.2.2.  Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
622             //        COOKIE-WAIT, and SHUTDOWN-ACK-SENT
623             return Err(Error::ErrHandleInitState);
624         }
625 
626         // Should we be setting any of these permanently until we've ACKed further?
627         self.my_max_num_inbound_streams =
628             std::cmp::min(i.num_inbound_streams, self.my_max_num_inbound_streams);
629         self.my_max_num_outbound_streams =
630             std::cmp::min(i.num_outbound_streams, self.my_max_num_outbound_streams);
631         self.peer_verification_tag = i.initiate_tag;
632         self.source_port = p.destination_port;
633         self.destination_port = p.source_port;
634 
635         // 13.2 This is the last TSN received in sequence.  This value
636         // is set initially by taking the peer's initial TSN,
637         // received in the INIT or INIT ACK chunk, and
638         // subtracting one from it.
639         self.peer_last_tsn = if i.initial_tsn == 0 {
640             u32::MAX
641         } else {
642             i.initial_tsn - 1
643         };
644 
645         for param in &i.params {
646             if let Some(v) = param.as_any().downcast_ref::<ParamSupportedExtensions>() {
647                 for t in &v.chunk_types {
648                     if *t == CT_FORWARD_TSN {
649                         log::debug!("[{}] use ForwardTSN (on init)", self.name);
650                         self.use_forward_tsn = true;
651                     }
652                 }
653             }
654         }
655         if !self.use_forward_tsn {
656             log::warn!("[{}] not using ForwardTSN (on init)", self.name);
657         }
658 
659         let mut outbound = Packet {
660             verification_tag: self.peer_verification_tag,
661             source_port: self.source_port,
662             destination_port: self.destination_port,
663             ..Default::default()
664         };
665 
666         // According to RFC https://datatracker.ietf.org/doc/html/rfc4960#section-3.2.2
667         // We report unknown parameters with a paramtype with bit 14 set as unrecognized
668         let unrecognized_params_from_init = i
669             .params
670             .iter()
671             .filter_map(|param| {
672                 if let ParamType::Unknown { param_type } = param.header().typ {
673                     let needs_to_be_reported = ((param_type >> 14) & 0x01) == 1;
674                     if needs_to_be_reported {
675                         let wrapped: Box<dyn Param + Send + Sync> =
676                             Box::new(ParamUnrecognized::wrap(param.clone()));
677                         Some(wrapped)
678                     } else {
679                         None
680                     }
681                 } else {
682                     None
683                 }
684             })
685             .collect();
686 
687         let mut init_ack = ChunkInit {
688             is_ack: true,
689             initial_tsn: self.my_next_tsn,
690             num_outbound_streams: self.my_max_num_outbound_streams,
691             num_inbound_streams: self.my_max_num_inbound_streams,
692             initiate_tag: self.my_verification_tag,
693             advertised_receiver_window_credit: self.max_receive_buffer_size,
694             params: unrecognized_params_from_init,
695         };
696 
697         if self.my_cookie.is_none() {
698             self.my_cookie = Some(ParamStateCookie::new());
699         }
700 
701         if let Some(my_cookie) = &self.my_cookie {
702             init_ack.params = vec![Box::new(my_cookie.clone())];
703         }
704 
705         init_ack.set_supported_extensions();
706 
707         outbound.chunks = vec![Box::new(init_ack)];
708 
709         Ok(vec![outbound])
710     }
711 
handle_init_ack(&mut self, p: &Packet, i: &ChunkInit) -> Result<Vec<Packet>>712     async fn handle_init_ack(&mut self, p: &Packet, i: &ChunkInit) -> Result<Vec<Packet>> {
713         let state = self.get_state();
714         log::debug!("[{}] chunkInitAck received in state '{}'", self.name, state);
715         if state != AssociationState::CookieWait {
716             // RFC 4960
717             // 5.2.3.  Unexpected INIT ACK
718             //   If an INIT ACK is received by an endpoint in any state other than the
719             //   COOKIE-WAIT state, the endpoint should discard the INIT ACK chunk.
720             //   An unexpected INIT ACK usually indicates the processing of an old or
721             //   duplicated INIT chunk.
722             return Ok(vec![]);
723         }
724 
725         self.my_max_num_inbound_streams =
726             std::cmp::min(i.num_inbound_streams, self.my_max_num_inbound_streams);
727         self.my_max_num_outbound_streams =
728             std::cmp::min(i.num_outbound_streams, self.my_max_num_outbound_streams);
729         self.peer_verification_tag = i.initiate_tag;
730         self.peer_last_tsn = if i.initial_tsn == 0 {
731             u32::MAX
732         } else {
733             i.initial_tsn - 1
734         };
735         if self.source_port != p.destination_port || self.destination_port != p.source_port {
736             log::warn!("[{}] handle_init_ack: port mismatch", self.name);
737             return Ok(vec![]);
738         }
739 
740         self.rwnd = i.advertised_receiver_window_credit;
741         log::debug!("[{}] initial rwnd={}", self.name, self.rwnd);
742 
743         // RFC 4690 Sec 7.2.1
744         //  o  The initial value of ssthresh MAY be arbitrarily high (for
745         //     example, implementations MAY use the size of the receiver
746         //     advertised window).
747         self.ssthresh = self.rwnd;
748         log::trace!(
749             "[{}] updated cwnd={} ssthresh={} inflight={} (INI)",
750             self.name,
751             self.cwnd,
752             self.ssthresh,
753             self.inflight_queue.get_num_bytes()
754         );
755 
756         if let Some(t1init) = &self.t1init {
757             t1init.stop().await;
758         }
759         self.stored_init = None;
760 
761         let mut cookie_param = None;
762         for param in &i.params {
763             if let Some(v) = param.as_any().downcast_ref::<ParamStateCookie>() {
764                 cookie_param = Some(v);
765             } else if let Some(v) = param.as_any().downcast_ref::<ParamSupportedExtensions>() {
766                 for t in &v.chunk_types {
767                     if *t == CT_FORWARD_TSN {
768                         log::debug!("[{}] use ForwardTSN (on initAck)", self.name);
769                         self.use_forward_tsn = true;
770                     }
771                 }
772             }
773         }
774         if !self.use_forward_tsn {
775             log::warn!("[{}] not using ForwardTSN (on initAck)", self.name);
776         }
777 
778         if let Some(v) = cookie_param {
779             self.stored_cookie_echo = Some(ChunkCookieEcho {
780                 cookie: v.cookie.clone(),
781             });
782 
783             self.send_cookie_echo()?;
784 
785             if let Some(t1cookie) = &self.t1cookie {
786                 t1cookie.start(self.rto_mgr.get_rto()).await;
787             }
788 
789             self.set_state(AssociationState::CookieEchoed);
790 
791             Ok(vec![])
792         } else {
793             Err(Error::ErrInitAckNoCookie)
794         }
795     }
796 
handle_heartbeat(&self, c: &ChunkHeartbeat) -> Result<Vec<Packet>>797     async fn handle_heartbeat(&self, c: &ChunkHeartbeat) -> Result<Vec<Packet>> {
798         log::trace!("[{}] chunkHeartbeat", self.name);
799         if let Some(p) = c.params.first() {
800             if let Some(hbi) = p.as_any().downcast_ref::<ParamHeartbeatInfo>() {
801                 return Ok(vec![Packet {
802                     verification_tag: self.peer_verification_tag,
803                     source_port: self.source_port,
804                     destination_port: self.destination_port,
805                     chunks: vec![Box::new(ChunkHeartbeatAck {
806                         params: vec![Box::new(ParamHeartbeatInfo {
807                             heartbeat_information: hbi.heartbeat_information.clone(),
808                         })],
809                     })],
810                 }]);
811             } else {
812                 log::warn!(
813                     "[{}] failed to handle Heartbeat, no ParamHeartbeatInfo",
814                     self.name,
815                 );
816             }
817         }
818 
819         Ok(vec![])
820     }
821 
handle_cookie_echo(&mut self, c: &ChunkCookieEcho) -> Result<Vec<Packet>>822     async fn handle_cookie_echo(&mut self, c: &ChunkCookieEcho) -> Result<Vec<Packet>> {
823         let state = self.get_state();
824         log::debug!("[{}] COOKIE-ECHO received in state '{}'", self.name, state);
825 
826         if let Some(my_cookie) = &self.my_cookie {
827             match state {
828                 AssociationState::Established => {
829                     if my_cookie.cookie != c.cookie {
830                         return Ok(vec![]);
831                     }
832                 }
833                 AssociationState::Closed
834                 | AssociationState::CookieWait
835                 | AssociationState::CookieEchoed => {
836                     if my_cookie.cookie != c.cookie {
837                         return Ok(vec![]);
838                     }
839 
840                     if let Some(t1init) = &self.t1init {
841                         t1init.stop().await;
842                     }
843                     self.stored_init = None;
844 
845                     if let Some(t1cookie) = &self.t1cookie {
846                         t1cookie.stop().await;
847                     }
848                     self.stored_cookie_echo = None;
849 
850                     self.set_state(AssociationState::Established);
851                     if let Some(handshake_completed_ch) = &self.handshake_completed_ch_tx {
852                         let _ = handshake_completed_ch.send(None).await;
853                     }
854                 }
855                 _ => return Ok(vec![]),
856             };
857         } else {
858             log::debug!("[{}] COOKIE-ECHO received before initialization", self.name);
859             return Ok(vec![]);
860         }
861 
862         Ok(vec![Packet {
863             verification_tag: self.peer_verification_tag,
864             source_port: self.source_port,
865             destination_port: self.destination_port,
866             chunks: vec![Box::new(ChunkCookieAck {})],
867         }])
868     }
869 
handle_cookie_ack(&mut self) -> Result<Vec<Packet>>870     async fn handle_cookie_ack(&mut self) -> Result<Vec<Packet>> {
871         let state = self.get_state();
872         log::debug!("[{}] COOKIE-ACK received in state '{}'", self.name, state);
873         if state != AssociationState::CookieEchoed {
874             // RFC 4960
875             // 5.2.5.  Handle Duplicate COOKIE-ACK.
876             //   At any state other than COOKIE-ECHOED, an endpoint should silently
877             //   discard a received COOKIE ACK chunk.
878             return Ok(vec![]);
879         }
880 
881         if let Some(t1cookie) = &self.t1cookie {
882             t1cookie.stop().await;
883         }
884         self.stored_cookie_echo = None;
885 
886         self.set_state(AssociationState::Established);
887         if let Some(handshake_completed_ch) = &self.handshake_completed_ch_tx {
888             let _ = handshake_completed_ch.send(None).await;
889         }
890 
891         Ok(vec![])
892     }
893 
handle_data(&mut self, d: &ChunkPayloadData) -> Result<Vec<Packet>>894     async fn handle_data(&mut self, d: &ChunkPayloadData) -> Result<Vec<Packet>> {
895         log::trace!(
896             "[{}] DATA: tsn={} immediateSack={} len={}",
897             self.name,
898             d.tsn,
899             d.immediate_sack,
900             d.user_data.len()
901         );
902         self.stats.inc_datas();
903 
904         let can_push = self.payload_queue.can_push(d, self.peer_last_tsn);
905         let mut stream_handle_data = false;
906         if can_push {
907             if let Some(_s) = self.get_or_create_stream(d.stream_identifier) {
908                 if self.get_my_receiver_window_credit().await > 0 {
909                     // Pass the new chunk to stream level as soon as it arrives
910                     self.payload_queue.push(d.clone(), self.peer_last_tsn);
911                     stream_handle_data = true;
912                 } else {
913                     // Receive buffer is full
914                     if let Some(last_tsn) = self.payload_queue.get_last_tsn_received() {
915                         if sna32lt(d.tsn, *last_tsn) {
916                             log::debug!("[{}] receive buffer full, but accepted as this is a missing chunk with tsn={} ssn={}", self.name, d.tsn, d.stream_sequence_number);
917                             self.payload_queue.push(d.clone(), self.peer_last_tsn);
918                             stream_handle_data = true; //s.handle_data(d.clone());
919                         }
920                     } else {
921                         log::debug!(
922                             "[{}] receive buffer full. dropping DATA with tsn={} ssn={}",
923                             self.name,
924                             d.tsn,
925                             d.stream_sequence_number
926                         );
927                     }
928                 }
929             } else {
930                 // silently discard the data. (sender will retry on T3-rtx timeout)
931                 // see pion/sctp#30
932                 log::debug!("discard {}", d.stream_sequence_number);
933                 return Ok(vec![]);
934             }
935         }
936 
937         let immediate_sack = d.immediate_sack;
938 
939         if stream_handle_data {
940             if let Some(s) = self.streams.get_mut(&d.stream_identifier) {
941                 s.handle_data(d.clone()).await;
942             }
943         }
944 
945         self.handle_peer_last_tsn_and_acknowledgement(immediate_sack)
946     }
947 
948     /// A common routine for handle_data and handle_forward_tsn routines
handle_peer_last_tsn_and_acknowledgement( &mut self, sack_immediately: bool, ) -> Result<Vec<Packet>>949     fn handle_peer_last_tsn_and_acknowledgement(
950         &mut self,
951         sack_immediately: bool,
952     ) -> Result<Vec<Packet>> {
953         let mut reply = vec![];
954 
955         // Try to advance peer_last_tsn
956 
957         // From RFC 3758 Sec 3.6:
958         //   .. and then MUST further advance its cumulative TSN point locally
959         //   if possible
960         // Meaning, if peer_last_tsn+1 points to a chunk that is received,
961         // advance peer_last_tsn until peer_last_tsn+1 points to unreceived chunk.
962         log::debug!("[{}] peer_last_tsn = {}", self.name, self.peer_last_tsn);
963         while self.payload_queue.pop(self.peer_last_tsn + 1).is_some() {
964             self.peer_last_tsn += 1;
965             log::debug!("[{}] peer_last_tsn = {}", self.name, self.peer_last_tsn);
966 
967             let rst_reqs: Vec<ParamOutgoingResetRequest> =
968                 self.reconfig_requests.values().cloned().collect();
969             for rst_req in rst_reqs {
970                 let resp = self.reset_streams_if_any(&rst_req);
971                 log::debug!("[{}] RESET RESPONSE: {}", self.name, resp);
972                 reply.push(resp);
973             }
974         }
975 
976         let has_packet_loss = !self.payload_queue.is_empty();
977         if has_packet_loss {
978             log::trace!(
979                 "[{}] packetloss: {}",
980                 self.name,
981                 self.payload_queue
982                     .get_gap_ack_blocks_string(self.peer_last_tsn)
983             );
984         }
985 
986         if (self.ack_state != AckState::Immediate
987             && !sack_immediately
988             && !has_packet_loss
989             && self.ack_mode == AckMode::Normal)
990             || self.ack_mode == AckMode::AlwaysDelay
991         {
992             if self.ack_state == AckState::Idle {
993                 self.delayed_ack_triggered = true;
994             } else {
995                 self.immediate_ack_triggered = true;
996             }
997         } else {
998             self.immediate_ack_triggered = true;
999         }
1000 
1001         Ok(reply)
1002     }
1003 
get_my_receiver_window_credit(&self) -> u321004     pub(crate) async fn get_my_receiver_window_credit(&self) -> u32 {
1005         let mut bytes_queued = 0;
1006         for s in self.streams.values() {
1007             bytes_queued += s.get_num_bytes_in_reassembly_queue().await as u32;
1008         }
1009 
1010         if bytes_queued >= self.max_receive_buffer_size {
1011             0
1012         } else {
1013             self.max_receive_buffer_size - bytes_queued
1014         }
1015     }
1016 
open_stream( &mut self, stream_identifier: u16, default_payload_type: PayloadProtocolIdentifier, ) -> Result<Arc<Stream>>1017     pub(crate) fn open_stream(
1018         &mut self,
1019         stream_identifier: u16,
1020         default_payload_type: PayloadProtocolIdentifier,
1021     ) -> Result<Arc<Stream>> {
1022         if self.streams.contains_key(&stream_identifier) {
1023             return Err(Error::ErrStreamAlreadyExist);
1024         }
1025 
1026         if let Some(s) = self.create_stream(stream_identifier, false) {
1027             s.set_default_payload_type(default_payload_type);
1028             Ok(Arc::clone(&s))
1029         } else {
1030             Err(Error::ErrStreamCreateFailed)
1031         }
1032     }
1033 
1034     /// create_stream creates a stream. The caller should hold the lock and check no stream exists for this id.
create_stream(&mut self, stream_identifier: u16, accept: bool) -> Option<Arc<Stream>>1035     fn create_stream(&mut self, stream_identifier: u16, accept: bool) -> Option<Arc<Stream>> {
1036         let s = Arc::new(Stream::new(
1037             format!("{}:{}", stream_identifier, self.name),
1038             stream_identifier,
1039             self.max_payload_size,
1040             Arc::clone(&self.max_message_size),
1041             Arc::clone(&self.state),
1042             self.awake_write_loop_ch.clone(),
1043             Arc::clone(&self.pending_queue),
1044         ));
1045 
1046         if accept {
1047             if let Some(accept_ch) = &self.accept_ch_tx {
1048                 if accept_ch.try_send(Arc::clone(&s)).is_ok() {
1049                     log::debug!(
1050                         "[{}] accepted a new stream (streamIdentifier: {})",
1051                         self.name,
1052                         stream_identifier
1053                     );
1054                 } else {
1055                     log::debug!("[{}] dropped a new stream due to accept_ch full", self.name);
1056                     return None;
1057                 }
1058             } else {
1059                 log::debug!(
1060                     "[{}] dropped a new stream due to accept_ch_tx is None",
1061                     self.name
1062                 );
1063                 return None;
1064             }
1065         }
1066         self.streams.insert(stream_identifier, Arc::clone(&s));
1067         Some(s)
1068     }
1069 
1070     /// get_or_create_stream gets or creates a stream. The caller should hold the lock.
get_or_create_stream(&mut self, stream_identifier: u16) -> Option<Arc<Stream>>1071     fn get_or_create_stream(&mut self, stream_identifier: u16) -> Option<Arc<Stream>> {
1072         if self.streams.contains_key(&stream_identifier) {
1073             self.streams.get(&stream_identifier).cloned()
1074         } else {
1075             self.create_stream(stream_identifier, true)
1076         }
1077     }
1078 
process_selective_ack( &mut self, d: &ChunkSelectiveAck, ) -> Result<(HashMap<u16, i64>, u32)>1079     async fn process_selective_ack(
1080         &mut self,
1081         d: &ChunkSelectiveAck,
1082     ) -> Result<(HashMap<u16, i64>, u32)> {
1083         let mut bytes_acked_per_stream = HashMap::new();
1084 
1085         // New ack point, so pop all ACKed packets from inflight_queue
1086         // We add 1 because the "currentAckPoint" has already been popped from the inflight queue
1087         // For the first SACK we take care of this by setting the ackpoint to cumAck - 1
1088         let mut i = self.cumulative_tsn_ack_point + 1;
1089         //log::debug!("[{}] i={} d={}", self.name, i, d.cumulative_tsn_ack);
1090         while sna32lte(i, d.cumulative_tsn_ack) {
1091             if let Some(c) = self.inflight_queue.pop(i) {
1092                 if !c.acked {
1093                     // RFC 4096 sec 6.3.2.  Retransmission Timer Rules
1094                     //   R3)  Whenever a SACK is received that acknowledges the DATA chunk
1095                     //        with the earliest outstanding TSN for that address, restart the
1096                     //        T3-rtx timer for that address with its current RTO (if there is
1097                     //        still outstanding data on that address).
1098                     if i == self.cumulative_tsn_ack_point + 1 {
1099                         // T3 timer needs to be reset. Stop it for now.
1100                         if let Some(t3rtx) = &self.t3rtx {
1101                             t3rtx.stop().await;
1102                         }
1103                     }
1104 
1105                     let n_bytes_acked = c.user_data.len() as i64;
1106 
1107                     // Sum the number of bytes acknowledged per stream
1108                     if let Some(amount) = bytes_acked_per_stream.get_mut(&c.stream_identifier) {
1109                         *amount += n_bytes_acked;
1110                     } else {
1111                         bytes_acked_per_stream.insert(c.stream_identifier, n_bytes_acked);
1112                     }
1113 
1114                     // RFC 4960 sec 6.3.1.  RTO Calculation
1115                     //   C4)  When data is in flight and when allowed by rule C5 below, a new
1116                     //        RTT measurement MUST be made each round trip.  Furthermore, new
1117                     //        RTT measurements SHOULD be made no more than once per round trip
1118                     //        for a given destination transport address.
1119                     //   C5)  Karn's algorithm: RTT measurements MUST NOT be made using
1120                     //        packets that were retransmitted (and thus for which it is
1121                     //        ambiguous whether the reply was for the first instance of the
1122                     //        chunk or for a later instance)
1123                     if c.nsent == 1 && sna32gte(c.tsn, self.min_tsn2measure_rtt) {
1124                         self.min_tsn2measure_rtt = self.my_next_tsn;
1125                         let rtt = match SystemTime::now().duration_since(c.since) {
1126                             Ok(rtt) => rtt,
1127                             Err(_) => return Err(Error::ErrInvalidSystemTime),
1128                         };
1129                         let srtt = self.rto_mgr.set_new_rtt(rtt.as_millis() as u64);
1130                         log::trace!(
1131                             "[{}] SACK: measured-rtt={} srtt={} new-rto={}",
1132                             self.name,
1133                             rtt.as_millis(),
1134                             srtt,
1135                             self.rto_mgr.get_rto()
1136                         );
1137                     }
1138                 }
1139 
1140                 if self.in_fast_recovery && c.tsn == self.fast_recover_exit_point {
1141                     log::debug!("[{}] exit fast-recovery", self.name);
1142                     self.in_fast_recovery = false;
1143                 }
1144             } else {
1145                 return Err(Error::ErrInflightQueueTsnPop);
1146             }
1147 
1148             i += 1;
1149         }
1150 
1151         let mut htna = d.cumulative_tsn_ack;
1152 
1153         // Mark selectively acknowledged chunks as "acked"
1154         for g in &d.gap_ack_blocks {
1155             for i in g.start..=g.end {
1156                 let tsn = d.cumulative_tsn_ack + i as u32;
1157 
1158                 let (is_existed, is_acked) = if let Some(c) = self.inflight_queue.get(tsn) {
1159                     (true, c.acked)
1160                 } else {
1161                     (false, false)
1162                 };
1163                 let n_bytes_acked = if is_existed && !is_acked {
1164                     self.inflight_queue.mark_as_acked(tsn) as i64
1165                 } else {
1166                     0
1167                 };
1168 
1169                 if let Some(c) = self.inflight_queue.get(tsn) {
1170                     if !is_acked {
1171                         // Sum the number of bytes acknowledged per stream
1172                         if let Some(amount) = bytes_acked_per_stream.get_mut(&c.stream_identifier) {
1173                             *amount += n_bytes_acked;
1174                         } else {
1175                             bytes_acked_per_stream.insert(c.stream_identifier, n_bytes_acked);
1176                         }
1177 
1178                         log::trace!("[{}] tsn={} has been sacked", self.name, c.tsn);
1179 
1180                         if c.nsent == 1 {
1181                             self.min_tsn2measure_rtt = self.my_next_tsn;
1182                             let rtt = match SystemTime::now().duration_since(c.since) {
1183                                 Ok(rtt) => rtt,
1184                                 Err(_) => return Err(Error::ErrInvalidSystemTime),
1185                             };
1186                             let srtt = self.rto_mgr.set_new_rtt(rtt.as_millis() as u64);
1187                             log::trace!(
1188                                 "[{}] SACK: measured-rtt={} srtt={} new-rto={}",
1189                                 self.name,
1190                                 rtt.as_millis(),
1191                                 srtt,
1192                                 self.rto_mgr.get_rto()
1193                             );
1194                         }
1195 
1196                         if sna32lt(htna, tsn) {
1197                             htna = tsn;
1198                         }
1199                     }
1200                 } else {
1201                     return Err(Error::ErrTsnRequestNotExist);
1202                 }
1203             }
1204         }
1205 
1206         Ok((bytes_acked_per_stream, htna))
1207     }
1208 
on_cumulative_tsn_ack_point_advanced(&mut self, total_bytes_acked: i64)1209     async fn on_cumulative_tsn_ack_point_advanced(&mut self, total_bytes_acked: i64) {
1210         // RFC 4096, sec 6.3.2.  Retransmission Timer Rules
1211         //   R2)  Whenever all outstanding data sent to an address have been
1212         //        acknowledged, turn off the T3-rtx timer of that address.
1213         if self.inflight_queue.is_empty() {
1214             log::trace!(
1215                 "[{}] SACK: no more packet in-flight (pending={})",
1216                 self.name,
1217                 self.pending_queue.len()
1218             );
1219             if let Some(t3rtx) = &self.t3rtx {
1220                 t3rtx.stop().await;
1221             }
1222         } else {
1223             log::trace!("[{}] T3-rtx timer start (pt2)", self.name);
1224             if let Some(t3rtx) = &self.t3rtx {
1225                 t3rtx.start(self.rto_mgr.get_rto()).await;
1226             }
1227         }
1228 
1229         // Update congestion control parameters
1230         if self.cwnd <= self.ssthresh {
1231             // RFC 4096, sec 7.2.1.  Slow-Start
1232             //   o  When cwnd is less than or equal to ssthresh, an SCTP endpoint MUST
1233             //		use the slow-start algorithm to increase cwnd only if the current
1234             //      congestion window is being fully utilized, an incoming SACK
1235             //      advances the Cumulative TSN Ack Point, and the data sender is not
1236             //      in Fast Recovery.  Only when these three conditions are met can
1237             //      the cwnd be increased; otherwise, the cwnd MUST not be increased.
1238             //		If these conditions are met, then cwnd MUST be increased by, at
1239             //      most, the lesser of 1) the total size of the previously
1240             //      outstanding DATA chunk(s) acknowledged, and 2) the destination's
1241             //      path MTU.
1242             if !self.in_fast_recovery && self.pending_queue.len() > 0 {
1243                 self.cwnd += std::cmp::min(total_bytes_acked as u32, self.cwnd); // TCP way
1244                                                                                  // self.cwnd += min32(uint32(total_bytes_acked), self.mtu) // SCTP way (slow)
1245                 log::trace!(
1246                     "[{}] updated cwnd={} ssthresh={} acked={} (SS)",
1247                     self.name,
1248                     self.cwnd,
1249                     self.ssthresh,
1250                     total_bytes_acked
1251                 );
1252             } else {
1253                 log::trace!(
1254                     "[{}] cwnd did not grow: cwnd={} ssthresh={} acked={} FR={} pending={}",
1255                     self.name,
1256                     self.cwnd,
1257                     self.ssthresh,
1258                     total_bytes_acked,
1259                     self.in_fast_recovery,
1260                     self.pending_queue.len()
1261                 );
1262             }
1263         } else {
1264             // RFC 4096, sec 7.2.2.  Congestion Avoidance
1265             //   o  Whenever cwnd is greater than ssthresh, upon each SACK arrival
1266             //      that advances the Cumulative TSN Ack Point, increase
1267             //      partial_bytes_acked by the total number of bytes of all new chunks
1268             //      acknowledged in that SACK including chunks acknowledged by the new
1269             //      Cumulative TSN Ack and by Gap Ack Blocks.
1270             self.partial_bytes_acked += total_bytes_acked as u32;
1271 
1272             //   o  When partial_bytes_acked is equal to or greater than cwnd and
1273             //      before the arrival of the SACK the sender had cwnd or more bytes
1274             //      of data outstanding (i.e., before arrival of the SACK, flight size
1275             //      was greater than or equal to cwnd), increase cwnd by MTU, and
1276             //      reset partial_bytes_acked to (partial_bytes_acked - cwnd).
1277             if self.partial_bytes_acked >= self.cwnd && self.pending_queue.len() > 0 {
1278                 self.partial_bytes_acked -= self.cwnd;
1279                 self.cwnd += self.mtu;
1280                 log::trace!(
1281                     "[{}] updated cwnd={} ssthresh={} acked={} (CA)",
1282                     self.name,
1283                     self.cwnd,
1284                     self.ssthresh,
1285                     total_bytes_acked
1286                 );
1287             }
1288         }
1289     }
1290 
process_fast_retransmission( &mut self, cum_tsn_ack_point: u32, htna: u32, cum_tsn_ack_point_advanced: bool, ) -> Result<()>1291     fn process_fast_retransmission(
1292         &mut self,
1293         cum_tsn_ack_point: u32,
1294         htna: u32,
1295         cum_tsn_ack_point_advanced: bool,
1296     ) -> Result<()> {
1297         // HTNA algorithm - RFC 4960 Sec 7.2.4
1298         // Increment missIndicator of each chunks that the SACK reported missing
1299         // when either of the following is met:
1300         // a)  Not in fast-recovery
1301         //     miss indications are incremented only for missing TSNs prior to the
1302         //     highest TSN newly acknowledged in the SACK.
1303         // b)  In fast-recovery AND the Cumulative TSN Ack Point advanced
1304         //     the miss indications are incremented for all TSNs reported missing
1305         //     in the SACK.
1306         if !self.in_fast_recovery || cum_tsn_ack_point_advanced {
1307             let max_tsn = if !self.in_fast_recovery {
1308                 // a) increment only for missing TSNs prior to the HTNA
1309                 htna
1310             } else {
1311                 // b) increment for all TSNs reported missing
1312                 cum_tsn_ack_point + (self.inflight_queue.len() as u32) + 1
1313             };
1314 
1315             let mut tsn = cum_tsn_ack_point + 1;
1316             while sna32lt(tsn, max_tsn) {
1317                 if let Some(c) = self.inflight_queue.get_mut(tsn) {
1318                     if !c.acked && !c.abandoned() && c.miss_indicator < 3 {
1319                         c.miss_indicator += 1;
1320                         if c.miss_indicator == 3 && !self.in_fast_recovery {
1321                             // 2)  If not in Fast Recovery, adjust the ssthresh and cwnd of the
1322                             //     destination address(es) to which the missing DATA chunks were
1323                             //     last sent, according to the formula described in Section 7.2.3.
1324                             self.in_fast_recovery = true;
1325                             self.fast_recover_exit_point = htna;
1326                             self.ssthresh = std::cmp::max(self.cwnd / 2, 4 * self.mtu);
1327                             self.cwnd = self.ssthresh;
1328                             self.partial_bytes_acked = 0;
1329                             self.will_retransmit_fast = true;
1330 
1331                             log::trace!(
1332                                 "[{}] updated cwnd={} ssthresh={} inflight={} (FR)",
1333                                 self.name,
1334                                 self.cwnd,
1335                                 self.ssthresh,
1336                                 self.inflight_queue.get_num_bytes()
1337                             );
1338                         }
1339                     }
1340                 } else {
1341                     return Err(Error::ErrTsnRequestNotExist);
1342                 }
1343 
1344                 tsn += 1;
1345             }
1346         }
1347 
1348         if self.in_fast_recovery && cum_tsn_ack_point_advanced {
1349             self.will_retransmit_fast = true;
1350         }
1351 
1352         Ok(())
1353     }
1354 
handle_sack(&mut self, d: &ChunkSelectiveAck) -> Result<Vec<Packet>>1355     async fn handle_sack(&mut self, d: &ChunkSelectiveAck) -> Result<Vec<Packet>> {
1356         log::trace!(
1357             "[{}] {}, SACK: cumTSN={} a_rwnd={}",
1358             self.name,
1359             self.cumulative_tsn_ack_point,
1360             d.cumulative_tsn_ack,
1361             d.advertised_receiver_window_credit
1362         );
1363         let state = self.get_state();
1364         if state != AssociationState::Established
1365             && state != AssociationState::ShutdownPending
1366             && state != AssociationState::ShutdownReceived
1367         {
1368             return Ok(vec![]);
1369         }
1370 
1371         self.stats.inc_sacks();
1372 
1373         if sna32gt(self.cumulative_tsn_ack_point, d.cumulative_tsn_ack) {
1374             // RFC 4960 sec 6.2.1.  Processing a Received SACK
1375             // D)
1376             //   i) If Cumulative TSN Ack is less than the Cumulative TSN Ack
1377             //      Point, then drop the SACK.  Since Cumulative TSN Ack is
1378             //      monotonically increasing, a SACK whose Cumulative TSN Ack is
1379             //      less than the Cumulative TSN Ack Point indicates an out-of-
1380             //      order SACK.
1381 
1382             log::debug!(
1383                 "[{}] SACK Cumulative ACK {} is older than ACK point {}",
1384                 self.name,
1385                 d.cumulative_tsn_ack,
1386                 self.cumulative_tsn_ack_point
1387             );
1388 
1389             return Ok(vec![]);
1390         }
1391 
1392         // Process selective ack
1393         let (bytes_acked_per_stream, htna) = self.process_selective_ack(d).await?;
1394 
1395         let mut total_bytes_acked = 0;
1396         for n_bytes_acked in bytes_acked_per_stream.values() {
1397             total_bytes_acked += *n_bytes_acked;
1398         }
1399 
1400         let mut cum_tsn_ack_point_advanced = false;
1401         if sna32lt(self.cumulative_tsn_ack_point, d.cumulative_tsn_ack) {
1402             log::trace!(
1403                 "[{}] SACK: cumTSN advanced: {} -> {}",
1404                 self.name,
1405                 self.cumulative_tsn_ack_point,
1406                 d.cumulative_tsn_ack
1407             );
1408 
1409             self.cumulative_tsn_ack_point = d.cumulative_tsn_ack;
1410             cum_tsn_ack_point_advanced = true;
1411             self.on_cumulative_tsn_ack_point_advanced(total_bytes_acked)
1412                 .await;
1413         }
1414 
1415         for (si, n_bytes_acked) in &bytes_acked_per_stream {
1416             if let Some(s) = self.streams.get_mut(si) {
1417                 s.on_buffer_released(*n_bytes_acked).await;
1418             }
1419         }
1420 
1421         // New rwnd value
1422         // RFC 4960 sec 6.2.1.  Processing a Received SACK
1423         // D)
1424         //   ii) Set rwnd equal to the newly received a_rwnd minus the number
1425         //       of bytes still outstanding after processing the Cumulative
1426         //       TSN Ack and the Gap Ack Blocks.
1427 
1428         // bytes acked were already subtracted by markAsAcked() method
1429         let bytes_outstanding = self.inflight_queue.get_num_bytes() as u32;
1430         if bytes_outstanding >= d.advertised_receiver_window_credit {
1431             self.rwnd = 0;
1432         } else {
1433             self.rwnd = d.advertised_receiver_window_credit - bytes_outstanding;
1434         }
1435 
1436         self.process_fast_retransmission(d.cumulative_tsn_ack, htna, cum_tsn_ack_point_advanced)?;
1437 
1438         if self.use_forward_tsn {
1439             // RFC 3758 Sec 3.5 C1
1440             if sna32lt(
1441                 self.advanced_peer_tsn_ack_point,
1442                 self.cumulative_tsn_ack_point,
1443             ) {
1444                 self.advanced_peer_tsn_ack_point = self.cumulative_tsn_ack_point
1445             }
1446 
1447             // RFC 3758 Sec 3.5 C2
1448             let mut i = self.advanced_peer_tsn_ack_point + 1;
1449             while let Some(c) = self.inflight_queue.get(i) {
1450                 if !c.abandoned() {
1451                     break;
1452                 }
1453                 self.advanced_peer_tsn_ack_point = i;
1454                 i += 1;
1455             }
1456 
1457             // RFC 3758 Sec 3.5 C3
1458             if sna32gt(
1459                 self.advanced_peer_tsn_ack_point,
1460                 self.cumulative_tsn_ack_point,
1461             ) {
1462                 self.will_send_forward_tsn = true;
1463                 log::debug!(
1464                     "[{}] handleSack {}: sna32GT({}, {})",
1465                     self.name,
1466                     self.will_send_forward_tsn,
1467                     self.advanced_peer_tsn_ack_point,
1468                     self.cumulative_tsn_ack_point
1469                 );
1470             }
1471             self.awake_write_loop();
1472         }
1473 
1474         self.postprocess_sack(state, cum_tsn_ack_point_advanced)
1475             .await;
1476 
1477         Ok(vec![])
1478     }
1479 
1480     /// The caller must hold the lock. This method was only added because the
1481     /// linter was complaining about the "cognitive complexity" of handle_sack.
postprocess_sack( &mut self, state: AssociationState, mut should_awake_write_loop: bool, )1482     async fn postprocess_sack(
1483         &mut self,
1484         state: AssociationState,
1485         mut should_awake_write_loop: bool,
1486     ) {
1487         if !self.inflight_queue.is_empty() {
1488             // Start timer. (noop if already started)
1489             log::trace!("[{}] T3-rtx timer start (pt3)", self.name);
1490             if let Some(t3rtx) = &self.t3rtx {
1491                 t3rtx.start(self.rto_mgr.get_rto()).await;
1492             }
1493         } else if state == AssociationState::ShutdownPending {
1494             // No more outstanding, send shutdown.
1495             should_awake_write_loop = true;
1496             self.will_send_shutdown.store(true, Ordering::SeqCst);
1497             self.set_state(AssociationState::ShutdownSent);
1498         } else if state == AssociationState::ShutdownReceived {
1499             // No more outstanding, send shutdown ack.
1500             should_awake_write_loop = true;
1501             self.will_send_shutdown_ack = true;
1502             self.set_state(AssociationState::ShutdownAckSent);
1503         }
1504 
1505         if should_awake_write_loop {
1506             self.awake_write_loop();
1507         }
1508     }
1509 
handle_shutdown(&mut self, _: &ChunkShutdown) -> Result<Vec<Packet>>1510     async fn handle_shutdown(&mut self, _: &ChunkShutdown) -> Result<Vec<Packet>> {
1511         let state = self.get_state();
1512 
1513         if state == AssociationState::Established {
1514             if !self.inflight_queue.is_empty() {
1515                 self.set_state(AssociationState::ShutdownReceived);
1516             } else {
1517                 // No more outstanding, send shutdown ack.
1518                 self.will_send_shutdown_ack = true;
1519                 self.set_state(AssociationState::ShutdownAckSent);
1520 
1521                 self.awake_write_loop();
1522             }
1523         } else if state == AssociationState::ShutdownSent {
1524             // self.cumulative_tsn_ack_point = c.cumulative_tsn_ack
1525 
1526             self.will_send_shutdown_ack = true;
1527             self.set_state(AssociationState::ShutdownAckSent);
1528 
1529             self.awake_write_loop();
1530         }
1531 
1532         Ok(vec![])
1533     }
1534 
handle_shutdown_ack(&mut self, _: &ChunkShutdownAck) -> Result<Vec<Packet>>1535     async fn handle_shutdown_ack(&mut self, _: &ChunkShutdownAck) -> Result<Vec<Packet>> {
1536         let state = self.get_state();
1537         if state == AssociationState::ShutdownSent || state == AssociationState::ShutdownAckSent {
1538             if let Some(t2shutdown) = &self.t2shutdown {
1539                 t2shutdown.stop().await;
1540             }
1541             self.will_send_shutdown_complete = true;
1542 
1543             self.awake_write_loop();
1544         }
1545 
1546         Ok(vec![])
1547     }
1548 
handle_shutdown_complete(&mut self, _: &ChunkShutdownComplete) -> Result<Vec<Packet>>1549     async fn handle_shutdown_complete(&mut self, _: &ChunkShutdownComplete) -> Result<Vec<Packet>> {
1550         let state = self.get_state();
1551         if state == AssociationState::ShutdownAckSent {
1552             if let Some(t2shutdown) = &self.t2shutdown {
1553                 t2shutdown.stop().await;
1554             }
1555             self.close().await?;
1556         }
1557 
1558         Ok(vec![])
1559     }
1560 
1561     /// create_forward_tsn generates ForwardTSN chunk.
1562     /// This method will be be called if use_forward_tsn is set to false.
create_forward_tsn(&self) -> ChunkForwardTsn1563     fn create_forward_tsn(&self) -> ChunkForwardTsn {
1564         // RFC 3758 Sec 3.5 C4
1565         let mut stream_map: HashMap<u16, u16> = HashMap::new(); // to report only once per SI
1566         let mut i = self.cumulative_tsn_ack_point + 1;
1567         while sna32lte(i, self.advanced_peer_tsn_ack_point) {
1568             if let Some(c) = self.inflight_queue.get(i) {
1569                 if let Some(ssn) = stream_map.get(&c.stream_identifier) {
1570                     if sna16lt(*ssn, c.stream_sequence_number) {
1571                         // to report only once with greatest SSN
1572                         stream_map.insert(c.stream_identifier, c.stream_sequence_number);
1573                     }
1574                 } else {
1575                     stream_map.insert(c.stream_identifier, c.stream_sequence_number);
1576                 }
1577             } else {
1578                 break;
1579             }
1580 
1581             i += 1;
1582         }
1583 
1584         let mut fwd_tsn = ChunkForwardTsn {
1585             new_cumulative_tsn: self.advanced_peer_tsn_ack_point,
1586             streams: vec![],
1587         };
1588 
1589         let mut stream_str = String::new();
1590         for (si, ssn) in &stream_map {
1591             stream_str += format!("(si={si} ssn={ssn})").as_str();
1592             fwd_tsn.streams.push(ChunkForwardTsnStream {
1593                 identifier: *si,
1594                 sequence: *ssn,
1595             });
1596         }
1597         log::trace!(
1598             "[{}] building fwd_tsn: newCumulativeTSN={} cumTSN={} - {}",
1599             self.name,
1600             fwd_tsn.new_cumulative_tsn,
1601             self.cumulative_tsn_ack_point,
1602             stream_str
1603         );
1604 
1605         fwd_tsn
1606     }
1607 
1608     /// create_packet wraps chunks in a packet.
1609     /// The caller should hold the read lock.
create_packet(&self, chunks: Vec<Box<dyn Chunk + Send + Sync>>) -> Packet1610     pub(crate) fn create_packet(&self, chunks: Vec<Box<dyn Chunk + Send + Sync>>) -> Packet {
1611         Packet {
1612             verification_tag: self.peer_verification_tag,
1613             source_port: self.source_port,
1614             destination_port: self.destination_port,
1615             chunks,
1616         }
1617     }
1618 
handle_reconfig(&mut self, c: &ChunkReconfig) -> Result<Vec<Packet>>1619     async fn handle_reconfig(&mut self, c: &ChunkReconfig) -> Result<Vec<Packet>> {
1620         log::trace!("[{}] handle_reconfig", self.name);
1621 
1622         let mut pp = vec![];
1623 
1624         if let Some(param_a) = &c.param_a {
1625             if let Some(p) = self.handle_reconfig_param(param_a).await? {
1626                 pp.push(p);
1627             }
1628         }
1629 
1630         if let Some(param_b) = &c.param_b {
1631             if let Some(p) = self.handle_reconfig_param(param_b).await? {
1632                 pp.push(p);
1633             }
1634         }
1635 
1636         Ok(pp)
1637     }
1638 
handle_forward_tsn(&mut self, c: &ChunkForwardTsn) -> Result<Vec<Packet>>1639     async fn handle_forward_tsn(&mut self, c: &ChunkForwardTsn) -> Result<Vec<Packet>> {
1640         log::trace!("[{}] FwdTSN: {}", self.name, c.to_string());
1641 
1642         if !self.use_forward_tsn {
1643             log::warn!("[{}] received FwdTSN but not enabled", self.name);
1644             // Return an error chunk
1645             let cerr = ChunkError {
1646                 error_causes: vec![ErrorCauseUnrecognizedChunkType::default()],
1647             };
1648 
1649             let outbound = Packet {
1650                 verification_tag: self.peer_verification_tag,
1651                 source_port: self.source_port,
1652                 destination_port: self.destination_port,
1653                 chunks: vec![Box::new(cerr)],
1654             };
1655             return Ok(vec![outbound]);
1656         }
1657 
1658         // From RFC 3758 Sec 3.6:
1659         //   Note, if the "New Cumulative TSN" value carried in the arrived
1660         //   FORWARD TSN chunk is found to be behind or at the current cumulative
1661         //   TSN point, the data receiver MUST treat this FORWARD TSN as out-of-
1662         //   date and MUST NOT update its Cumulative TSN.  The receiver SHOULD
1663         //   send a SACK to its peer (the sender of the FORWARD TSN) since such a
1664         //   duplicate may indicate the previous SACK was lost in the network.
1665 
1666         log::trace!(
1667             "[{}] should send ack? newCumTSN={} peer_last_tsn={}",
1668             self.name,
1669             c.new_cumulative_tsn,
1670             self.peer_last_tsn
1671         );
1672         if sna32lte(c.new_cumulative_tsn, self.peer_last_tsn) {
1673             log::trace!("[{}] sending ack on Forward TSN", self.name);
1674             self.ack_state = AckState::Immediate;
1675             if let Some(ack_timer) = &mut self.ack_timer {
1676                 ack_timer.stop();
1677             }
1678             self.awake_write_loop();
1679             return Ok(vec![]);
1680         }
1681 
1682         // From RFC 3758 Sec 3.6:
1683         //   the receiver MUST perform the same TSN handling, including duplicate
1684         //   detection, gap detection, SACK generation, cumulative TSN
1685         //   advancement, etc. as defined in RFC 2960 [2]---with the following
1686         //   exceptions and additions.
1687 
1688         //   When a FORWARD TSN chunk arrives, the data receiver MUST first update
1689         //   its cumulative TSN point to the value carried in the FORWARD TSN
1690         //   chunk,
1691 
1692         // Advance peer_last_tsn
1693         while sna32lt(self.peer_last_tsn, c.new_cumulative_tsn) {
1694             self.payload_queue.pop(self.peer_last_tsn + 1); // may not exist
1695             self.peer_last_tsn += 1;
1696         }
1697 
1698         // Report new peer_last_tsn value and abandoned largest SSN value to
1699         // corresponding streams so that the abandoned chunks can be removed
1700         // from the reassemblyQueue.
1701         for forwarded in &c.streams {
1702             if let Some(s) = self.streams.get_mut(&forwarded.identifier) {
1703                 s.handle_forward_tsn_for_ordered(forwarded.sequence).await;
1704             }
1705         }
1706 
1707         // TSN may be forewared for unordered chunks. ForwardTSN chunk does not
1708         // report which stream identifier it skipped for unordered chunks.
1709         // Therefore, we need to broadcast this event to all existing streams for
1710         // unordered chunks.
1711         // See https://github.com/pion/sctp/issues/106
1712         for s in self.streams.values_mut() {
1713             s.handle_forward_tsn_for_unordered(c.new_cumulative_tsn)
1714                 .await;
1715         }
1716 
1717         self.handle_peer_last_tsn_and_acknowledgement(false)
1718     }
1719 
send_reset_request(&mut self, stream_identifier: u16) -> Result<()>1720     async fn send_reset_request(&mut self, stream_identifier: u16) -> Result<()> {
1721         let state = self.get_state();
1722         if state != AssociationState::Established {
1723             return Err(Error::ErrResetPacketInStateNotExist);
1724         }
1725 
1726         // Create DATA chunk which only contains valid stream identifier with
1727         // nil userData and use it as a EOS from the stream.
1728         let c = ChunkPayloadData {
1729             stream_identifier,
1730             beginning_fragment: true,
1731             ending_fragment: true,
1732             user_data: Bytes::new(),
1733             ..Default::default()
1734         };
1735 
1736         self.pending_queue.push(c).await;
1737         self.awake_write_loop();
1738 
1739         Ok(())
1740     }
1741 
1742     #[allow(clippy::borrowed_box)]
handle_reconfig_param( &mut self, raw: &Box<dyn Param + Send + Sync>, ) -> Result<Option<Packet>>1743     async fn handle_reconfig_param(
1744         &mut self,
1745         raw: &Box<dyn Param + Send + Sync>,
1746     ) -> Result<Option<Packet>> {
1747         if let Some(p) = raw.as_any().downcast_ref::<ParamOutgoingResetRequest>() {
1748             self.reconfig_requests
1749                 .insert(p.reconfig_request_sequence_number, p.clone());
1750             Ok(Some(self.reset_streams_if_any(p)))
1751         } else if let Some(p) = raw.as_any().downcast_ref::<ParamReconfigResponse>() {
1752             self.reconfigs.remove(&p.reconfig_response_sequence_number);
1753             if self.reconfigs.is_empty() {
1754                 if let Some(treconfig) = &self.treconfig {
1755                     treconfig.stop().await;
1756                 }
1757             }
1758             Ok(None)
1759         } else {
1760             Err(Error::ErrParamterType)
1761         }
1762     }
1763 
reset_streams_if_any(&mut self, p: &ParamOutgoingResetRequest) -> Packet1764     fn reset_streams_if_any(&mut self, p: &ParamOutgoingResetRequest) -> Packet {
1765         let mut result = ReconfigResult::SuccessPerformed;
1766         if sna32lte(p.sender_last_tsn, self.peer_last_tsn) {
1767             log::debug!(
1768                 "[{}] resetStream(): senderLastTSN={} <= peer_last_tsn={}",
1769                 self.name,
1770                 p.sender_last_tsn,
1771                 self.peer_last_tsn
1772             );
1773             for id in &p.stream_identifiers {
1774                 if let Some(s) = self.streams.get(id) {
1775                     let stream_identifier = s.stream_identifier;
1776                     self.unregister_stream(stream_identifier);
1777                 }
1778             }
1779             self.reconfig_requests
1780                 .remove(&p.reconfig_request_sequence_number);
1781         } else {
1782             log::debug!(
1783                 "[{}] resetStream(): senderLastTSN={} > peer_last_tsn={}",
1784                 self.name,
1785                 p.sender_last_tsn,
1786                 self.peer_last_tsn
1787             );
1788             result = ReconfigResult::InProgress;
1789         }
1790 
1791         self.create_packet(vec![Box::new(ChunkReconfig {
1792             param_a: Some(Box::new(ParamReconfigResponse {
1793                 reconfig_response_sequence_number: p.reconfig_request_sequence_number,
1794                 result,
1795             })),
1796             param_b: None,
1797         })])
1798     }
1799 
1800     /// Move the chunk peeked with self.pending_queue.peek() to the inflight_queue.
move_pending_data_chunk_to_inflight_queue( &mut self, beginning_fragment: bool, unordered: bool, ) -> Option<ChunkPayloadData>1801     async fn move_pending_data_chunk_to_inflight_queue(
1802         &mut self,
1803         beginning_fragment: bool,
1804         unordered: bool,
1805     ) -> Option<ChunkPayloadData> {
1806         if let Some(mut c) = self.pending_queue.pop(beginning_fragment, unordered) {
1807             // Mark all fragements are in-flight now
1808             if c.ending_fragment {
1809                 c.set_all_inflight();
1810             }
1811 
1812             // Assign TSN
1813             c.tsn = self.generate_next_tsn();
1814 
1815             c.since = SystemTime::now(); // use to calculate RTT and also for maxPacketLifeTime
1816             c.nsent = 1; // being sent for the first time
1817 
1818             self.check_partial_reliability_status(&c);
1819 
1820             log::trace!(
1821                 "[{}] sending ppi={} tsn={} ssn={} sent={} len={} ({},{})",
1822                 self.name,
1823                 c.payload_type as u32,
1824                 c.tsn,
1825                 c.stream_sequence_number,
1826                 c.nsent,
1827                 c.user_data.len(),
1828                 c.beginning_fragment,
1829                 c.ending_fragment
1830             );
1831 
1832             self.inflight_queue.push_no_check(c.clone());
1833 
1834             Some(c)
1835         } else {
1836             log::error!("[{}] failed to pop from pending queue", self.name);
1837             None
1838         }
1839     }
1840 
1841     /// pop_pending_data_chunks_to_send pops chunks from the pending queues as many as
1842     /// the cwnd and rwnd allows to send.
pop_pending_data_chunks_to_send(&mut self) -> (Vec<ChunkPayloadData>, Vec<u16>)1843     async fn pop_pending_data_chunks_to_send(&mut self) -> (Vec<ChunkPayloadData>, Vec<u16>) {
1844         let mut chunks = vec![];
1845         let mut sis_to_reset = vec![]; // stream identifiers to reset
1846 
1847         if self.pending_queue.len() == 0 {
1848             return (chunks, sis_to_reset);
1849         }
1850 
1851         // RFC 4960 sec 6.1.  Transmission of DATA Chunks
1852         //   A) At any given time, the data sender MUST NOT transmit new data to
1853         //      any destination transport address if its peer's rwnd indicates
1854         //      that the peer has no buffer space (i.e., rwnd is 0; see Section
1855         //      6.2.1).  However, regardless of the value of rwnd (including if it
1856         //      is 0), the data sender can always have one DATA chunk in flight to
1857         //      the receiver if allowed by cwnd (see rule B, below).
1858         while let Some(c) = self.pending_queue.peek() {
1859             let (beginning_fragment, unordered, data_len, stream_identifier) = (
1860                 c.beginning_fragment,
1861                 c.unordered,
1862                 c.user_data.len(),
1863                 c.stream_identifier,
1864             );
1865 
1866             if data_len == 0 {
1867                 sis_to_reset.push(stream_identifier);
1868                 if self
1869                     .pending_queue
1870                     .pop(beginning_fragment, unordered)
1871                     .is_none()
1872                 {
1873                     log::error!("failed to pop from pending queue");
1874                 }
1875                 continue;
1876             }
1877 
1878             if self.inflight_queue.get_num_bytes() + data_len > self.cwnd as usize {
1879                 break; // would exceed cwnd
1880             }
1881 
1882             if data_len > self.rwnd as usize {
1883                 break; // no more rwnd
1884             }
1885 
1886             self.rwnd -= data_len as u32;
1887 
1888             if let Some(chunk) = self
1889                 .move_pending_data_chunk_to_inflight_queue(beginning_fragment, unordered)
1890                 .await
1891             {
1892                 chunks.push(chunk);
1893             }
1894         }
1895 
1896         // the data sender can always have one DATA chunk in flight to the receiver
1897         if chunks.is_empty() && self.inflight_queue.is_empty() {
1898             // Send zero window probe
1899             if let Some(c) = self.pending_queue.peek() {
1900                 let (beginning_fragment, unordered) = (c.beginning_fragment, c.unordered);
1901 
1902                 if let Some(chunk) = self
1903                     .move_pending_data_chunk_to_inflight_queue(beginning_fragment, unordered)
1904                     .await
1905                 {
1906                     chunks.push(chunk);
1907                 }
1908             }
1909         }
1910 
1911         (chunks, sis_to_reset)
1912     }
1913 
1914     /// bundle_data_chunks_into_packets packs DATA chunks into packets. It tries to bundle
1915     /// DATA chunks into a packet so long as the resulting packet size does not exceed
1916     /// the path MTU.
bundle_data_chunks_into_packets(&self, chunks: Vec<ChunkPayloadData>) -> Vec<Packet>1917     fn bundle_data_chunks_into_packets(&self, chunks: Vec<ChunkPayloadData>) -> Vec<Packet> {
1918         let mut packets = vec![];
1919         let mut chunks_to_send = vec![];
1920         let mut bytes_in_packet = COMMON_HEADER_SIZE;
1921 
1922         for c in chunks {
1923             // RFC 4960 sec 6.1.  Transmission of DATA Chunks
1924             //   Multiple DATA chunks committed for transmission MAY be bundled in a
1925             //   single packet.  Furthermore, DATA chunks being retransmitted MAY be
1926             //   bundled with new DATA chunks, as long as the resulting packet size
1927             //   does not exceed the path MTU.
1928             if bytes_in_packet + c.user_data.len() as u32 > self.mtu {
1929                 packets.push(self.create_packet(chunks_to_send));
1930                 chunks_to_send = vec![];
1931                 bytes_in_packet = COMMON_HEADER_SIZE;
1932             }
1933 
1934             bytes_in_packet += DATA_CHUNK_HEADER_SIZE + c.user_data.len() as u32;
1935             chunks_to_send.push(Box::new(c));
1936         }
1937 
1938         if !chunks_to_send.is_empty() {
1939             packets.push(self.create_packet(chunks_to_send));
1940         }
1941 
1942         packets
1943     }
1944 
check_partial_reliability_status(&self, c: &ChunkPayloadData)1945     fn check_partial_reliability_status(&self, c: &ChunkPayloadData) {
1946         if !self.use_forward_tsn {
1947             return;
1948         }
1949 
1950         // draft-ietf-rtcweb-data-protocol-09.txt section 6
1951         //	6.  Procedures
1952         //		All Data Channel Establishment Protocol messages MUST be sent using
1953         //		ordered delivery and reliable transmission.
1954         //
1955         if c.payload_type == PayloadProtocolIdentifier::Dcep {
1956             return;
1957         }
1958 
1959         // PR-SCTP
1960         if let Some(s) = self.streams.get(&c.stream_identifier) {
1961             let reliability_type: ReliabilityType =
1962                 s.reliability_type.load(Ordering::SeqCst).into();
1963             let reliability_value = s.reliability_value.load(Ordering::SeqCst);
1964 
1965             if reliability_type == ReliabilityType::Rexmit {
1966                 if c.nsent >= reliability_value {
1967                     c.set_abandoned(true);
1968                     log::trace!(
1969                         "[{}] marked as abandoned: tsn={} ppi={} (remix: {})",
1970                         self.name,
1971                         c.tsn,
1972                         c.payload_type,
1973                         c.nsent
1974                     );
1975                 }
1976             } else if reliability_type == ReliabilityType::Timed {
1977                 if let Ok(elapsed) = SystemTime::now().duration_since(c.since) {
1978                     if elapsed.as_millis() as u32 >= reliability_value {
1979                         c.set_abandoned(true);
1980                         log::trace!(
1981                             "[{}] marked as abandoned: tsn={} ppi={} (timed: {:?})",
1982                             self.name,
1983                             c.tsn,
1984                             c.payload_type,
1985                             elapsed
1986                         );
1987                     }
1988                 }
1989             }
1990         } else {
1991             log::error!("[{}] stream {} not found)", self.name, c.stream_identifier);
1992         }
1993     }
1994 
1995     /// get_data_packets_to_retransmit is called when T3-rtx is timed out and retransmit outstanding data chunks
1996     /// that are not acked or abandoned yet.
get_data_packets_to_retransmit(&mut self) -> Vec<Packet>1997     fn get_data_packets_to_retransmit(&mut self) -> Vec<Packet> {
1998         let awnd = std::cmp::min(self.cwnd, self.rwnd);
1999         let mut chunks = vec![];
2000         let mut bytes_to_send = 0;
2001         let mut done = false;
2002         let mut i = 0;
2003         while !done {
2004             let tsn = self.cumulative_tsn_ack_point + i + 1;
2005             if let Some(c) = self.inflight_queue.get_mut(tsn) {
2006                 if !c.retransmit {
2007                     i += 1;
2008                     continue;
2009                 }
2010 
2011                 if i == 0 && self.rwnd < c.user_data.len() as u32 {
2012                     // Send it as a zero window probe
2013                     done = true;
2014                 } else if bytes_to_send + c.user_data.len() > awnd as usize {
2015                     break;
2016                 }
2017 
2018                 // reset the retransmit flag not to retransmit again before the next
2019                 // t3-rtx timer fires
2020                 c.retransmit = false;
2021                 bytes_to_send += c.user_data.len();
2022 
2023                 c.nsent += 1;
2024             } else {
2025                 break; // end of pending data
2026             }
2027 
2028             if let Some(c) = self.inflight_queue.get(tsn) {
2029                 self.check_partial_reliability_status(c);
2030 
2031                 log::trace!(
2032                     "[{}] retransmitting tsn={} ssn={} sent={}",
2033                     self.name,
2034                     c.tsn,
2035                     c.stream_sequence_number,
2036                     c.nsent
2037                 );
2038 
2039                 chunks.push(c.clone());
2040             }
2041             i += 1;
2042         }
2043 
2044         self.bundle_data_chunks_into_packets(chunks)
2045     }
2046 
2047     /// generate_next_tsn returns the my_next_tsn and increases it. The caller should hold the lock.
generate_next_tsn(&mut self) -> u322048     fn generate_next_tsn(&mut self) -> u32 {
2049         let tsn = self.my_next_tsn;
2050         self.my_next_tsn += 1;
2051         tsn
2052     }
2053 
2054     /// generate_next_rsn returns the my_next_rsn and increases it. The caller should hold the lock.
generate_next_rsn(&mut self) -> u322055     fn generate_next_rsn(&mut self) -> u32 {
2056         let rsn = self.my_next_rsn;
2057         self.my_next_rsn += 1;
2058         rsn
2059     }
2060 
create_selective_ack_chunk(&mut self) -> ChunkSelectiveAck2061     async fn create_selective_ack_chunk(&mut self) -> ChunkSelectiveAck {
2062         ChunkSelectiveAck {
2063             cumulative_tsn_ack: self.peer_last_tsn,
2064             advertised_receiver_window_credit: self.get_my_receiver_window_credit().await,
2065             gap_ack_blocks: self.payload_queue.get_gap_ack_blocks(self.peer_last_tsn),
2066             duplicate_tsn: self.payload_queue.pop_duplicates(),
2067         }
2068     }
2069 
pack(p: Packet) -> Vec<Packet>2070     fn pack(p: Packet) -> Vec<Packet> {
2071         vec![p]
2072     }
2073 
handle_chunk_start(&mut self)2074     fn handle_chunk_start(&mut self) {
2075         self.delayed_ack_triggered = false;
2076         self.immediate_ack_triggered = false;
2077     }
2078 
handle_chunk_end(&mut self)2079     fn handle_chunk_end(&mut self) {
2080         if self.immediate_ack_triggered {
2081             self.ack_state = AckState::Immediate;
2082             if let Some(ack_timer) = &mut self.ack_timer {
2083                 ack_timer.stop();
2084             }
2085             self.awake_write_loop();
2086         } else if self.delayed_ack_triggered {
2087             // Will send delayed ack in the next ack timeout
2088             self.ack_state = AckState::Delay;
2089             if let Some(ack_timer) = &mut self.ack_timer {
2090                 ack_timer.start();
2091             }
2092         }
2093     }
2094 
2095     #[allow(clippy::borrowed_box)]
handle_chunk( &mut self, p: &Packet, chunk: &Box<dyn Chunk + Send + Sync>, ) -> Result<()>2096     async fn handle_chunk(
2097         &mut self,
2098         p: &Packet,
2099         chunk: &Box<dyn Chunk + Send + Sync>,
2100     ) -> Result<()> {
2101         chunk.check()?;
2102         let chunk_any = chunk.as_any();
2103         let packets = if let Some(c) = chunk_any.downcast_ref::<ChunkInit>() {
2104             if c.is_ack {
2105                 self.handle_init_ack(p, c).await?
2106             } else {
2107                 self.handle_init(p, c).await?
2108             }
2109         } else if chunk_any.downcast_ref::<ChunkAbort>().is_some()
2110             || chunk_any.downcast_ref::<ChunkError>().is_some()
2111         {
2112             return Err(Error::ErrChunk);
2113         } else if let Some(c) = chunk_any.downcast_ref::<ChunkHeartbeat>() {
2114             self.handle_heartbeat(c).await?
2115         } else if let Some(c) = chunk_any.downcast_ref::<ChunkCookieEcho>() {
2116             self.handle_cookie_echo(c).await?
2117         } else if chunk_any.downcast_ref::<ChunkCookieAck>().is_some() {
2118             self.handle_cookie_ack().await?
2119         } else if let Some(c) = chunk_any.downcast_ref::<ChunkPayloadData>() {
2120             self.handle_data(c).await?
2121         } else if let Some(c) = chunk_any.downcast_ref::<ChunkSelectiveAck>() {
2122             self.handle_sack(c).await?
2123         } else if let Some(c) = chunk_any.downcast_ref::<ChunkReconfig>() {
2124             self.handle_reconfig(c).await?
2125         } else if let Some(c) = chunk_any.downcast_ref::<ChunkForwardTsn>() {
2126             self.handle_forward_tsn(c).await?
2127         } else if let Some(c) = chunk_any.downcast_ref::<ChunkShutdown>() {
2128             self.handle_shutdown(c).await?
2129         } else if let Some(c) = chunk_any.downcast_ref::<ChunkShutdownAck>() {
2130             self.handle_shutdown_ack(c).await?
2131         } else if let Some(c) = chunk_any.downcast_ref::<ChunkShutdownComplete>() {
2132             self.handle_shutdown_complete(c).await?
2133         } else {
2134             /*
2135             https://datatracker.ietf.org/doc/html/rfc4960#section-3
2136 
2137             00 -  Stop processing this SCTP packet and discard it, do not
2138                   process any further chunks within it.
2139 
2140             01 -  Stop processing this SCTP packet and discard it, do not
2141                   process any further chunks within it, and report the
2142                   unrecognized chunk in an 'Unrecognized Chunk Type'.
2143 
2144             10 -  Skip this chunk and continue processing.
2145 
2146             11 -  Skip this chunk and continue processing, but report in an
2147                   ERROR chunk using the 'Unrecognized Chunk Type' cause of
2148                   error.
2149             */
2150             let handle_code = chunk.header().typ.0 >> 6;
2151             match handle_code {
2152                 0b00 => {
2153                     // Stop processing this packet
2154                     return Err(Error::ErrChunkTypeUnhandled);
2155                 }
2156                 0b01 => {
2157                     // stop processing but report the chunk as unrecognized
2158                     let err_chunk = ChunkError {
2159                         error_causes: vec![ErrorCause {
2160                             code: UNRECOGNIZED_CHUNK_TYPE,
2161                             raw: chunk.marshal()?,
2162                         }],
2163                     };
2164                     let packet = Packet {
2165                         verification_tag: self.peer_verification_tag,
2166                         source_port: self.source_port,
2167                         destination_port: self.destination_port,
2168                         chunks: vec![Box::new(err_chunk)],
2169                     };
2170                     self.control_queue.push_back(packet);
2171                     self.awake_write_loop();
2172                     return Err(Error::ErrChunkTypeUnhandled);
2173                 }
2174                 0b10 => {
2175                     // just ignore
2176                     vec![]
2177                 }
2178                 0b11 => {
2179                     // keep processing but report the chunk as unrecognized
2180                     let err_chunk = ChunkError {
2181                         error_causes: vec![ErrorCause {
2182                             code: UNRECOGNIZED_CHUNK_TYPE,
2183                             raw: chunk.marshal()?,
2184                         }],
2185                     };
2186                     let packet = Packet {
2187                         verification_tag: self.peer_verification_tag,
2188                         source_port: self.source_port,
2189                         destination_port: self.destination_port,
2190                         chunks: vec![Box::new(err_chunk)],
2191                     };
2192                     vec![packet]
2193                 }
2194                 _ => unreachable!("This can only have 4 values."),
2195             }
2196         };
2197 
2198         if !packets.is_empty() {
2199             let mut buf: VecDeque<_> = packets.into_iter().collect();
2200             self.control_queue.append(&mut buf);
2201             self.awake_write_loop();
2202         }
2203 
2204         Ok(())
2205     }
2206 
2207     /// buffered_amount returns total amount (in bytes) of currently buffered user data.
2208     /// This is used only by testing.
buffered_amount(&self) -> usize2209     pub(crate) fn buffered_amount(&self) -> usize {
2210         self.pending_queue.get_num_bytes() + self.inflight_queue.get_num_bytes()
2211     }
2212 }
2213 
2214 #[async_trait]
2215 impl AckTimerObserver for AssociationInternal {
on_ack_timeout(&mut self)2216     async fn on_ack_timeout(&mut self) {
2217         log::trace!(
2218             "[{}] ack timed out (ack_state: {})",
2219             self.name,
2220             self.ack_state
2221         );
2222         self.stats.inc_ack_timeouts();
2223         self.ack_state = AckState::Immediate;
2224         self.awake_write_loop();
2225     }
2226 }
2227 
2228 #[async_trait]
2229 impl RtxTimerObserver for AssociationInternal {
on_retransmission_timeout(&mut self, id: RtxTimerId, n_rtos: usize)2230     async fn on_retransmission_timeout(&mut self, id: RtxTimerId, n_rtos: usize) {
2231         match id {
2232             RtxTimerId::T1Init => {
2233                 if let Err(err) = self.send_init() {
2234                     log::debug!(
2235                         "[{}] failed to retransmit init (n_rtos={}): {:?}",
2236                         self.name,
2237                         n_rtos,
2238                         err
2239                     );
2240                 }
2241             }
2242 
2243             RtxTimerId::T1Cookie => {
2244                 if let Err(err) = self.send_cookie_echo() {
2245                     log::debug!(
2246                         "[{}] failed to retransmit cookie-echo (n_rtos={}): {:?}",
2247                         self.name,
2248                         n_rtos,
2249                         err
2250                     );
2251                 }
2252             }
2253 
2254             RtxTimerId::T2Shutdown => {
2255                 log::debug!(
2256                     "[{}] retransmission of shutdown timeout (n_rtos={})",
2257                     self.name,
2258                     n_rtos
2259                 );
2260                 let state = self.get_state();
2261                 match state {
2262                     AssociationState::ShutdownSent => {
2263                         self.will_send_shutdown.store(true, Ordering::SeqCst);
2264                         self.awake_write_loop();
2265                     }
2266                     AssociationState::ShutdownAckSent => {
2267                         self.will_send_shutdown_ack = true;
2268                         self.awake_write_loop();
2269                     }
2270                     _ => {}
2271                 }
2272             }
2273 
2274             RtxTimerId::T3RTX => {
2275                 self.stats.inc_t3timeouts();
2276 
2277                 // RFC 4960 sec 6.3.3
2278                 //  E1)  For the destination address for which the timer expires, adjust
2279                 //       its ssthresh with rules defined in Section 7.2.3 and set the
2280                 //       cwnd <- MTU.
2281                 // RFC 4960 sec 7.2.3
2282                 //   When the T3-rtx timer expires on an address, SCTP should perform slow
2283                 //   start by:
2284                 //      ssthresh = max(cwnd/2, 4*MTU)
2285                 //      cwnd = 1*MTU
2286 
2287                 self.ssthresh = std::cmp::max(self.cwnd / 2, 4 * self.mtu);
2288                 self.cwnd = self.mtu;
2289                 log::trace!(
2290                     "[{}] updated cwnd={} ssthresh={} inflight={} (RTO)",
2291                     self.name,
2292                     self.cwnd,
2293                     self.ssthresh,
2294                     self.inflight_queue.get_num_bytes()
2295                 );
2296 
2297                 // RFC 3758 sec 3.5
2298                 //  A5) Any time the T3-rtx timer expires, on any destination, the sender
2299                 //  SHOULD try to advance the "Advanced.Peer.Ack.Point" by following
2300                 //  the procedures outlined in C2 - C5.
2301                 if self.use_forward_tsn {
2302                     // RFC 3758 Sec 3.5 C2
2303                     let mut i = self.advanced_peer_tsn_ack_point + 1;
2304                     while let Some(c) = self.inflight_queue.get(i) {
2305                         if !c.abandoned() {
2306                             break;
2307                         }
2308                         self.advanced_peer_tsn_ack_point = i;
2309                         i += 1;
2310                     }
2311 
2312                     // RFC 3758 Sec 3.5 C3
2313                     if sna32gt(
2314                         self.advanced_peer_tsn_ack_point,
2315                         self.cumulative_tsn_ack_point,
2316                     ) {
2317                         self.will_send_forward_tsn = true;
2318                         log::debug!(
2319                             "[{}] on_retransmission_timeout {}: sna32GT({}, {})",
2320                             self.name,
2321                             self.will_send_forward_tsn,
2322                             self.advanced_peer_tsn_ack_point,
2323                             self.cumulative_tsn_ack_point
2324                         );
2325                     }
2326                 }
2327 
2328                 log::debug!(
2329                     "[{}] T3-rtx timed out: n_rtos={} cwnd={} ssthresh={}",
2330                     self.name,
2331                     n_rtos,
2332                     self.cwnd,
2333                     self.ssthresh
2334                 );
2335 
2336                 self.inflight_queue.mark_all_to_retrasmit();
2337                 self.awake_write_loop();
2338             }
2339 
2340             RtxTimerId::Reconfig => {
2341                 self.will_retransmit_reconfig = true;
2342                 self.awake_write_loop();
2343             }
2344         }
2345     }
2346 
on_retransmission_failure(&mut self, id: RtxTimerId)2347     async fn on_retransmission_failure(&mut self, id: RtxTimerId) {
2348         match id {
2349             RtxTimerId::T1Init => {
2350                 log::error!("[{}] retransmission failure: T1-init", self.name);
2351                 if let Some(handshake_completed_ch) = &self.handshake_completed_ch_tx {
2352                     let _ = handshake_completed_ch
2353                         .send(Some(Error::ErrHandshakeInitAck))
2354                         .await;
2355                 }
2356             }
2357             RtxTimerId::T1Cookie => {
2358                 log::error!("[{}] retransmission failure: T1-cookie", self.name);
2359                 if let Some(handshake_completed_ch) = &self.handshake_completed_ch_tx {
2360                     let _ = handshake_completed_ch
2361                         .send(Some(Error::ErrHandshakeCookieEcho))
2362                         .await;
2363                 }
2364             }
2365 
2366             RtxTimerId::T2Shutdown => {
2367                 log::error!("[{}] retransmission failure: T2-shutdown", self.name);
2368             }
2369 
2370             RtxTimerId::T3RTX => {
2371                 // T3-rtx timer will not fail by design
2372                 // Justifications:
2373                 //  * ICE would fail if the connectivity is lost
2374                 //  * WebRTC spec is not clear how this incident should be reported to ULP
2375                 log::error!("[{}] retransmission failure: T3-rtx (DATA)", self.name);
2376             }
2377             _ => {}
2378         }
2379     }
2380 }
2381