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