1 #[cfg(test)] 2 mod data_channel_test; 3 4 pub mod data_channel_init; 5 pub mod data_channel_message; 6 pub mod data_channel_parameters; 7 pub mod data_channel_state; 8 9 use data_channel_message::*; 10 use data_channel_parameters::*; 11 12 use arc_swap::ArcSwapOption; 13 use bytes::Bytes; 14 use std::{ 15 future::Future, 16 pin::Pin, 17 sync::{ 18 atomic::{AtomicBool, AtomicU16, AtomicU8, AtomicUsize, Ordering}, 19 Arc, Weak, 20 }, 21 time::SystemTime, 22 }; 23 24 use data::message::message_channel_open::ChannelType; 25 use sctp::stream::OnBufferedAmountLowFn; 26 use tokio::sync::{Mutex, Notify}; 27 use util::sync::Mutex as SyncMutex; 28 29 use data_channel_state::RTCDataChannelState; 30 31 use crate::api::setting_engine::SettingEngine; 32 use crate::error::{Error, OnErrorHdlrFn, Result}; 33 use crate::sctp_transport::RTCSctpTransport; 34 use crate::stats::stats_collector::StatsCollector; 35 use crate::stats::{DataChannelStats, StatsReportType}; 36 37 /// message size limit for Chromium 38 const DATA_CHANNEL_BUFFER_SIZE: u16 = u16::MAX; 39 40 pub type OnMessageHdlrFn = Box< 41 dyn (FnMut(DataChannelMessage) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>) 42 + Send 43 + Sync, 44 >; 45 46 pub type OnOpenHdlrFn = 47 Box<dyn (FnOnce() -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>) + Send + Sync>; 48 49 pub type OnCloseHdlrFn = 50 Box<dyn (FnMut() -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>) + Send + Sync>; 51 52 /// DataChannel represents a WebRTC DataChannel 53 /// The DataChannel interface represents a network channel 54 /// which can be used for bidirectional peer-to-peer transfers of arbitrary data 55 #[derive(Default)] 56 pub struct RTCDataChannel { 57 pub(crate) stats_id: String, 58 pub(crate) label: String, 59 pub(crate) ordered: bool, 60 pub(crate) max_packet_lifetime: u16, 61 pub(crate) max_retransmits: u16, 62 pub(crate) protocol: String, 63 pub(crate) negotiated: bool, 64 pub(crate) id: AtomicU16, 65 pub(crate) ready_state: Arc<AtomicU8>, // DataChannelState 66 pub(crate) buffered_amount_low_threshold: AtomicUsize, 67 pub(crate) detach_called: Arc<AtomicBool>, 68 69 // The binaryType represents attribute MUST, on getting, return the value to 70 // which it was last set. On setting, if the new value is either the string 71 // "blob" or the string "arraybuffer", then set the IDL attribute to this 72 // new value. Otherwise, throw a SyntaxError. When an DataChannel object 73 // is created, the binaryType attribute MUST be initialized to the string 74 // "blob". This attribute controls how binary data is exposed to scripts. 75 // binaryType string 76 pub(crate) on_message_handler: Arc<ArcSwapOption<Mutex<OnMessageHdlrFn>>>, 77 pub(crate) on_open_handler: SyncMutex<Option<OnOpenHdlrFn>>, 78 pub(crate) on_close_handler: Arc<ArcSwapOption<Mutex<OnCloseHdlrFn>>>, 79 pub(crate) on_error_handler: Arc<ArcSwapOption<Mutex<OnErrorHdlrFn>>>, 80 81 pub(crate) on_buffered_amount_low: Mutex<Option<OnBufferedAmountLowFn>>, 82 83 pub(crate) sctp_transport: Mutex<Option<Weak<RTCSctpTransport>>>, 84 pub(crate) data_channel: Mutex<Option<Arc<data::data_channel::DataChannel>>>, 85 86 pub(crate) notify_tx: Arc<Notify>, 87 88 // A reference to the associated api object used by this datachannel 89 pub(crate) setting_engine: Arc<SettingEngine>, 90 } 91 92 impl RTCDataChannel { 93 // create the DataChannel object before the networking is set up. new(params: DataChannelParameters, setting_engine: Arc<SettingEngine>) -> Self94 pub(crate) fn new(params: DataChannelParameters, setting_engine: Arc<SettingEngine>) -> Self { 95 // the id value if non-negotiated doesn't matter, since it will be overwritten 96 // on opening 97 let id = params.negotiated.unwrap_or(0); 98 RTCDataChannel { 99 stats_id: format!( 100 "DataChannel-{}", 101 SystemTime::now() 102 .duration_since(SystemTime::UNIX_EPOCH) 103 .map_or(0, |d| d.as_nanos()) 104 ), 105 label: params.label, 106 protocol: params.protocol, 107 negotiated: params.negotiated.is_some(), 108 id: AtomicU16::new(id), 109 ordered: params.ordered, 110 max_packet_lifetime: params.max_packet_life_time, 111 max_retransmits: params.max_retransmits, 112 ready_state: Arc::new(AtomicU8::new(RTCDataChannelState::Connecting as u8)), 113 detach_called: Arc::new(AtomicBool::new(false)), 114 115 notify_tx: Arc::new(Notify::new()), 116 117 setting_engine, 118 ..Default::default() 119 } 120 } 121 122 /// open opens the datachannel over the sctp transport open(&self, sctp_transport: Arc<RTCSctpTransport>) -> Result<()>123 pub(crate) async fn open(&self, sctp_transport: Arc<RTCSctpTransport>) -> Result<()> { 124 if let Some(association) = sctp_transport.association().await { 125 { 126 let mut st = self.sctp_transport.lock().await; 127 if st.is_none() { 128 *st = Some(Arc::downgrade(&sctp_transport)); 129 } else { 130 return Ok(()); 131 } 132 } 133 134 let channel_type; 135 let reliability_parameter; 136 137 if self.max_packet_lifetime == 0 && self.max_retransmits == 0 { 138 reliability_parameter = 0u32; 139 if self.ordered { 140 channel_type = ChannelType::Reliable; 141 } else { 142 channel_type = ChannelType::ReliableUnordered; 143 } 144 } else if self.max_retransmits != 0 { 145 reliability_parameter = self.max_retransmits as u32; 146 if self.ordered { 147 channel_type = ChannelType::PartialReliableRexmit; 148 } else { 149 channel_type = ChannelType::PartialReliableRexmitUnordered; 150 } 151 } else { 152 reliability_parameter = self.max_packet_lifetime as u32; 153 if self.ordered { 154 channel_type = ChannelType::PartialReliableTimed; 155 } else { 156 channel_type = ChannelType::PartialReliableTimedUnordered; 157 } 158 } 159 160 let cfg = data::data_channel::Config { 161 channel_type, 162 priority: data::message::message_channel_open::CHANNEL_PRIORITY_NORMAL, 163 reliability_parameter, 164 label: self.label.clone(), 165 protocol: self.protocol.clone(), 166 negotiated: self.negotiated, 167 }; 168 169 if !self.negotiated { 170 self.id.store( 171 sctp_transport 172 .generate_and_set_data_channel_id( 173 sctp_transport.dtls_transport.role().await, 174 ) 175 .await?, 176 Ordering::SeqCst, 177 ); 178 } 179 180 let dc = data::data_channel::DataChannel::dial(&association, self.id(), cfg).await?; 181 182 // buffered_amount_low_threshold and on_buffered_amount_low might be set earlier 183 dc.set_buffered_amount_low_threshold( 184 self.buffered_amount_low_threshold.load(Ordering::SeqCst), 185 ); 186 { 187 let mut on_buffered_amount_low = self.on_buffered_amount_low.lock().await; 188 if let Some(f) = on_buffered_amount_low.take() { 189 dc.on_buffered_amount_low(f); 190 } 191 } 192 193 self.handle_open(Arc::new(dc)).await; 194 195 Ok(()) 196 } else { 197 Err(Error::ErrSCTPNotEstablished) 198 } 199 } 200 201 /// transport returns the SCTPTransport instance the DataChannel is sending over. transport(&self) -> Option<Weak<RTCSctpTransport>>202 pub async fn transport(&self) -> Option<Weak<RTCSctpTransport>> { 203 let sctp_transport = self.sctp_transport.lock().await; 204 sctp_transport.clone() 205 } 206 207 /// on_open sets an event handler which is invoked when 208 /// the underlying data transport has been established (or re-established). on_open(&self, f: OnOpenHdlrFn)209 pub fn on_open(&self, f: OnOpenHdlrFn) { 210 let _ = self.on_open_handler.lock().replace(f); 211 212 if self.ready_state() == RTCDataChannelState::Open { 213 self.do_open(); 214 } 215 } 216 do_open(&self)217 fn do_open(&self) { 218 let on_open_handler = self.on_open_handler.lock().take(); 219 if on_open_handler.is_none() { 220 return; 221 } 222 223 let detach_data_channels = self.setting_engine.detach.data_channels; 224 let detach_called = Arc::clone(&self.detach_called); 225 tokio::spawn(async move { 226 if let Some(f) = on_open_handler { 227 f().await; 228 229 // self.check_detach_after_open(); 230 // After onOpen is complete check that the user called detach 231 // and provide an error message if the call was missed 232 if detach_data_channels && !detach_called.load(Ordering::SeqCst) { 233 log::warn!( 234 "webrtc.DetachDataChannels() enabled but didn't Detach, call Detach from OnOpen" 235 ); 236 } 237 } 238 }); 239 } 240 241 /// on_close sets an event handler which is invoked when 242 /// the underlying data transport has been closed. on_close(&self, f: OnCloseHdlrFn)243 pub fn on_close(&self, f: OnCloseHdlrFn) { 244 self.on_close_handler.store(Some(Arc::new(Mutex::new(f)))); 245 } 246 247 /// on_message sets an event handler which is invoked on a binary 248 /// message arrival over the sctp transport from a remote peer. 249 /// OnMessage can currently receive messages up to 16384 bytes 250 /// in size. Check out the detach API if you want to use larger 251 /// message sizes. Note that browser support for larger messages 252 /// is also limited. on_message(&self, f: OnMessageHdlrFn)253 pub fn on_message(&self, f: OnMessageHdlrFn) { 254 self.on_message_handler.store(Some(Arc::new(Mutex::new(f)))); 255 } 256 do_message(&self, msg: DataChannelMessage)257 async fn do_message(&self, msg: DataChannelMessage) { 258 if let Some(handler) = &*self.on_message_handler.load() { 259 let mut f = handler.lock().await; 260 f(msg).await; 261 } 262 } 263 handle_open(&self, dc: Arc<data::data_channel::DataChannel>)264 pub(crate) async fn handle_open(&self, dc: Arc<data::data_channel::DataChannel>) { 265 { 266 let mut data_channel = self.data_channel.lock().await; 267 *data_channel = Some(Arc::clone(&dc)); 268 } 269 self.set_ready_state(RTCDataChannelState::Open); 270 271 self.do_open(); 272 273 if !self.setting_engine.detach.data_channels { 274 let ready_state = Arc::clone(&self.ready_state); 275 let on_message_handler = Arc::clone(&self.on_message_handler); 276 let on_close_handler = Arc::clone(&self.on_close_handler); 277 let on_error_handler = Arc::clone(&self.on_error_handler); 278 let notify_rx = self.notify_tx.clone(); 279 tokio::spawn(async move { 280 RTCDataChannel::read_loop( 281 notify_rx, 282 dc, 283 ready_state, 284 on_message_handler, 285 on_close_handler, 286 on_error_handler, 287 ) 288 .await; 289 }); 290 } 291 } 292 293 /// on_error sets an event handler which is invoked when 294 /// the underlying data transport cannot be read. on_error(&self, f: OnErrorHdlrFn)295 pub fn on_error(&self, f: OnErrorHdlrFn) { 296 self.on_error_handler.store(Some(Arc::new(Mutex::new(f)))); 297 } 298 read_loop( notify_rx: Arc<Notify>, data_channel: Arc<data::data_channel::DataChannel>, ready_state: Arc<AtomicU8>, on_message_handler: Arc<ArcSwapOption<Mutex<OnMessageHdlrFn>>>, on_close_handler: Arc<ArcSwapOption<Mutex<OnCloseHdlrFn>>>, on_error_handler: Arc<ArcSwapOption<Mutex<OnErrorHdlrFn>>>, )299 async fn read_loop( 300 notify_rx: Arc<Notify>, 301 data_channel: Arc<data::data_channel::DataChannel>, 302 ready_state: Arc<AtomicU8>, 303 on_message_handler: Arc<ArcSwapOption<Mutex<OnMessageHdlrFn>>>, 304 on_close_handler: Arc<ArcSwapOption<Mutex<OnCloseHdlrFn>>>, 305 on_error_handler: Arc<ArcSwapOption<Mutex<OnErrorHdlrFn>>>, 306 ) { 307 let mut buffer = vec![0u8; DATA_CHANNEL_BUFFER_SIZE as usize]; 308 loop { 309 let (n, is_string) = tokio::select! { 310 _ = notify_rx.notified() => break, 311 result = data_channel.read_data_channel(&mut buffer) => { 312 match result{ 313 // EOF (`data_channel` was either closed or the underlying stream got 314 // reset by the remote) => close and run `on_close` handler. 315 Ok((0, _)) => 316 { 317 ready_state.store(RTCDataChannelState::Closed as u8, Ordering::SeqCst); 318 319 let on_close_handler2 = Arc::clone(&on_close_handler); 320 tokio::spawn(async move { 321 if let Some(handler) = &*on_close_handler2.load() { 322 let mut f = handler.lock().await; 323 f().await; 324 } 325 }); 326 327 break; 328 } 329 Ok((n, is_string)) => (n, is_string), 330 Err(err) => { 331 ready_state.store(RTCDataChannelState::Closed as u8, Ordering::SeqCst); 332 333 let on_error_handler2 = Arc::clone(&on_error_handler); 334 tokio::spawn(async move { 335 if let Some(handler) = &*on_error_handler2.load() { 336 let mut f = handler.lock().await; 337 f(err.into()).await; 338 } 339 }); 340 341 let on_close_handler2 = Arc::clone(&on_close_handler); 342 tokio::spawn(async move { 343 if let Some(handler) = &*on_close_handler2.load() { 344 let mut f = handler.lock().await; 345 f().await; 346 } 347 }); 348 349 break; 350 } 351 } 352 } 353 }; 354 355 if let Some(handler) = &*on_message_handler.load() { 356 let mut f = handler.lock().await; 357 f(DataChannelMessage { 358 is_string, 359 data: Bytes::from(buffer[..n].to_vec()), 360 }) 361 .await; 362 } 363 } 364 } 365 366 /// send sends the binary message to the DataChannel peer send(&self, data: &Bytes) -> Result<usize>367 pub async fn send(&self, data: &Bytes) -> Result<usize> { 368 self.ensure_open()?; 369 370 let data_channel = self.data_channel.lock().await; 371 if let Some(dc) = &*data_channel { 372 Ok(dc.write_data_channel(data, false).await?) 373 } else { 374 Err(Error::ErrClosedPipe) 375 } 376 } 377 378 /// send_text sends the text message to the DataChannel peer send_text(&self, s: impl Into<String>) -> Result<usize>379 pub async fn send_text(&self, s: impl Into<String>) -> Result<usize> { 380 self.ensure_open()?; 381 382 let data_channel = self.data_channel.lock().await; 383 if let Some(dc) = &*data_channel { 384 Ok(dc.write_data_channel(&Bytes::from(s.into()), true).await?) 385 } else { 386 Err(Error::ErrClosedPipe) 387 } 388 } 389 ensure_open(&self) -> Result<()>390 fn ensure_open(&self) -> Result<()> { 391 if self.ready_state() != RTCDataChannelState::Open { 392 Err(Error::ErrClosedPipe) 393 } else { 394 Ok(()) 395 } 396 } 397 398 /// detach allows you to detach the underlying datachannel. This provides 399 /// an idiomatic API to work with, however it disables the OnMessage callback. 400 /// Before calling Detach you have to enable this behavior by calling 401 /// webrtc.DetachDataChannels(). Combining detached and normal data channels 402 /// is not supported. 403 /// Please refer to the data-channels-detach example and the 404 /// pion/datachannel documentation for the correct way to handle the 405 /// resulting DataChannel object. detach(&self) -> Result<Arc<data::data_channel::DataChannel>>406 pub async fn detach(&self) -> Result<Arc<data::data_channel::DataChannel>> { 407 if !self.setting_engine.detach.data_channels { 408 return Err(Error::ErrDetachNotEnabled); 409 } 410 411 let data_channel = self.data_channel.lock().await; 412 if let Some(dc) = &*data_channel { 413 self.detach_called.store(true, Ordering::SeqCst); 414 415 Ok(Arc::clone(dc)) 416 } else { 417 Err(Error::ErrDetachBeforeOpened) 418 } 419 } 420 421 /// Close Closes the DataChannel. It may be called regardless of whether 422 /// the DataChannel object was created by this peer or the remote peer. close(&self) -> Result<()>423 pub async fn close(&self) -> Result<()> { 424 if self.ready_state() == RTCDataChannelState::Closed { 425 return Ok(()); 426 } 427 428 self.set_ready_state(RTCDataChannelState::Closing); 429 self.notify_tx.notify_waiters(); 430 431 let data_channel = self.data_channel.lock().await; 432 if let Some(dc) = &*data_channel { 433 Ok(dc.close().await?) 434 } else { 435 Ok(()) 436 } 437 } 438 439 /// label represents a label that can be used to distinguish this 440 /// DataChannel object from other DataChannel objects. Scripts are 441 /// allowed to create multiple DataChannel objects with the same label. label(&self) -> &str442 pub fn label(&self) -> &str { 443 self.label.as_str() 444 } 445 446 /// Ordered returns true if the DataChannel is ordered, and false if 447 /// out-of-order delivery is allowed. ordered(&self) -> bool448 pub fn ordered(&self) -> bool { 449 self.ordered 450 } 451 452 /// max_packet_lifetime represents the length of the time window (msec) during 453 /// which transmissions and retransmissions may occur in unreliable mode. max_packet_lifetime(&self) -> u16454 pub fn max_packet_lifetime(&self) -> u16 { 455 self.max_packet_lifetime 456 } 457 458 /// max_retransmits represents the maximum number of retransmissions that are 459 /// attempted in unreliable mode. max_retransmits(&self) -> u16460 pub fn max_retransmits(&self) -> u16 { 461 self.max_retransmits 462 } 463 464 /// protocol represents the name of the sub-protocol used with this 465 /// DataChannel. protocol(&self) -> &str466 pub fn protocol(&self) -> &str { 467 self.protocol.as_str() 468 } 469 470 /// negotiated represents whether this DataChannel was negotiated by the 471 /// application (true), or not (false). negotiated(&self) -> bool472 pub fn negotiated(&self) -> bool { 473 self.negotiated 474 } 475 476 /// ID represents the ID for this DataChannel. The value is initially 477 /// null, which is what will be returned if the ID was not provided at 478 /// channel creation time, and the DTLS role of the SCTP transport has not 479 /// yet been negotiated. Otherwise, it will return the ID that was either 480 /// selected by the script or generated. After the ID is set to a non-null 481 /// value, it will not change. id(&self) -> u16482 pub fn id(&self) -> u16 { 483 self.id.load(Ordering::SeqCst) 484 } 485 486 /// ready_state represents the state of the DataChannel object. ready_state(&self) -> RTCDataChannelState487 pub fn ready_state(&self) -> RTCDataChannelState { 488 self.ready_state.load(Ordering::SeqCst).into() 489 } 490 491 /// buffered_amount represents the number of bytes of application data 492 /// (UTF-8 text and binary data) that have been queued using send(). Even 493 /// though the data transmission can occur in parallel, the returned value 494 /// MUST NOT be decreased before the current task yielded back to the event 495 /// loop to prevent race conditions. The value does not include framing 496 /// overhead incurred by the protocol, or buffering done by the operating 497 /// system or network hardware. The value of buffered_amount slot will only 498 /// increase with each call to the send() method as long as the ready_state is 499 /// open; however, buffered_amount does not reset to zero once the channel 500 /// closes. buffered_amount(&self) -> usize501 pub async fn buffered_amount(&self) -> usize { 502 let data_channel = self.data_channel.lock().await; 503 if let Some(dc) = &*data_channel { 504 dc.buffered_amount() 505 } else { 506 0 507 } 508 } 509 510 /// buffered_amount_low_threshold represents the threshold at which the 511 /// bufferedAmount is considered to be low. When the bufferedAmount decreases 512 /// from above this threshold to equal or below it, the bufferedamountlow 513 /// event fires. buffered_amount_low_threshold is initially zero on each new 514 /// DataChannel, but the application may change its value at any time. 515 /// The threshold is set to 0 by default. buffered_amount_low_threshold(&self) -> usize516 pub async fn buffered_amount_low_threshold(&self) -> usize { 517 let data_channel = self.data_channel.lock().await; 518 if let Some(dc) = &*data_channel { 519 dc.buffered_amount_low_threshold() 520 } else { 521 self.buffered_amount_low_threshold.load(Ordering::SeqCst) 522 } 523 } 524 525 /// set_buffered_amount_low_threshold is used to update the threshold. 526 /// See buffered_amount_low_threshold(). set_buffered_amount_low_threshold(&self, th: usize)527 pub async fn set_buffered_amount_low_threshold(&self, th: usize) { 528 self.buffered_amount_low_threshold 529 .store(th, Ordering::SeqCst); 530 let data_channel = self.data_channel.lock().await; 531 if let Some(dc) = &*data_channel { 532 dc.set_buffered_amount_low_threshold(th); 533 } 534 } 535 536 /// on_buffered_amount_low sets an event handler which is invoked when 537 /// the number of bytes of outgoing data becomes lower than the 538 /// buffered_amount_low_threshold. on_buffered_amount_low(&self, f: OnBufferedAmountLowFn)539 pub async fn on_buffered_amount_low(&self, f: OnBufferedAmountLowFn) { 540 let data_channel = self.data_channel.lock().await; 541 if let Some(dc) = &*data_channel { 542 dc.on_buffered_amount_low(f); 543 } else { 544 let mut on_buffered_amount_low = self.on_buffered_amount_low.lock().await; 545 *on_buffered_amount_low = Some(f); 546 } 547 } 548 get_stats_id(&self) -> &str549 pub(crate) fn get_stats_id(&self) -> &str { 550 self.stats_id.as_str() 551 } 552 collect_stats(&self, collector: &StatsCollector)553 pub(crate) async fn collect_stats(&self, collector: &StatsCollector) { 554 let stats = DataChannelStats::from(self).await; 555 collector.insert(self.stats_id.clone(), StatsReportType::DataChannel(stats)); 556 } 557 set_ready_state(&self, r: RTCDataChannelState)558 pub(crate) fn set_ready_state(&self, r: RTCDataChannelState) { 559 self.ready_state.store(r as u8, Ordering::SeqCst); 560 } 561 } 562