1 #[cfg(test)] 2 mod data_channel_test; 3 4 use crate::error::Result; 5 use crate::{ 6 error::Error, message::message_channel_ack::*, message::message_channel_open::*, message::*, 7 }; 8 9 use sctp::{ 10 association::Association, chunk::chunk_payload_data::PayloadProtocolIdentifier, stream::*, 11 }; 12 use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; 13 use util::marshal::*; 14 15 use bytes::{Buf, Bytes}; 16 use derive_builder::Builder; 17 use std::borrow::Borrow; 18 use std::fmt; 19 use std::future::Future; 20 use std::io; 21 use std::net::Shutdown; 22 use std::pin::Pin; 23 use std::sync::atomic::{AtomicUsize, Ordering}; 24 use std::sync::Arc; 25 use std::task::{Context, Poll}; 26 27 const RECEIVE_MTU: usize = 8192; 28 29 /// Config is used to configure the data channel. 30 #[derive(Eq, PartialEq, Default, Clone, Debug, Builder)] 31 pub struct Config { 32 #[builder(default)] 33 pub channel_type: ChannelType, 34 #[builder(default)] 35 pub negotiated: bool, 36 #[builder(default)] 37 pub priority: u16, 38 #[builder(default)] 39 pub reliability_parameter: u32, 40 #[builder(default)] 41 pub label: String, 42 #[builder(default)] 43 pub protocol: String, 44 } 45 46 /// DataChannel represents a data channel 47 #[derive(Debug, Default, Clone)] 48 pub struct DataChannel { 49 pub config: Config, 50 stream: Arc<Stream>, 51 52 // stats 53 messages_sent: Arc<AtomicUsize>, 54 messages_received: Arc<AtomicUsize>, 55 bytes_sent: Arc<AtomicUsize>, 56 bytes_received: Arc<AtomicUsize>, 57 } 58 59 impl DataChannel { 60 pub fn new(stream: Arc<Stream>, config: Config) -> Self { 61 Self { 62 config, 63 stream, 64 ..Default::default() 65 } 66 } 67 68 /// Dial opens a data channels over SCTP 69 pub async fn dial( 70 association: &Arc<Association>, 71 identifier: u16, 72 config: Config, 73 ) -> Result<Self> { 74 let stream = association 75 .open_stream(identifier, PayloadProtocolIdentifier::Binary) 76 .await?; 77 78 Self::client(stream, config).await 79 } 80 81 /// Accept is used to accept incoming data channels over SCTP 82 pub async fn accept<T>( 83 association: &Arc<Association>, 84 config: Config, 85 existing_channels: &[T], 86 ) -> Result<Self> 87 where 88 T: Borrow<Self>, 89 { 90 let stream = association 91 .accept_stream() 92 .await 93 .ok_or(Error::ErrStreamClosed)?; 94 95 for channel in existing_channels.iter().map(|ch| ch.borrow()) { 96 if channel.stream_identifier() == stream.stream_identifier() { 97 let ch = channel.to_owned(); 98 ch.stream 99 .set_default_payload_type(PayloadProtocolIdentifier::Binary); 100 return Ok(ch); 101 } 102 } 103 104 stream.set_default_payload_type(PayloadProtocolIdentifier::Binary); 105 106 Self::server(stream, config).await 107 } 108 109 /// Client opens a data channel over an SCTP stream 110 pub async fn client(stream: Arc<Stream>, config: Config) -> Result<Self> { 111 if !config.negotiated { 112 let msg = Message::DataChannelOpen(DataChannelOpen { 113 channel_type: config.channel_type, 114 priority: config.priority, 115 reliability_parameter: config.reliability_parameter, 116 label: config.label.bytes().collect(), 117 protocol: config.protocol.bytes().collect(), 118 }) 119 .marshal()?; 120 121 stream 122 .write_sctp(&msg, PayloadProtocolIdentifier::Dcep) 123 .await?; 124 } 125 Ok(DataChannel::new(stream, config)) 126 } 127 128 /// Server accepts a data channel over an SCTP stream 129 pub async fn server(stream: Arc<Stream>, mut config: Config) -> Result<Self> { 130 let mut buf = vec![0u8; RECEIVE_MTU]; 131 132 let (n, ppi) = stream.read_sctp(&mut buf).await?; 133 134 if ppi != PayloadProtocolIdentifier::Dcep { 135 return Err(Error::InvalidPayloadProtocolIdentifier(ppi as u8)); 136 } 137 138 let mut read_buf = &buf[..n]; 139 let msg = Message::unmarshal(&mut read_buf)?; 140 141 if let Message::DataChannelOpen(dco) = msg { 142 config.channel_type = dco.channel_type; 143 config.priority = dco.priority; 144 config.reliability_parameter = dco.reliability_parameter; 145 config.label = String::from_utf8(dco.label)?; 146 config.protocol = String::from_utf8(dco.protocol)?; 147 } else { 148 return Err(Error::InvalidMessageType(msg.message_type() as u8)); 149 }; 150 151 let data_channel = DataChannel::new(stream, config); 152 153 data_channel.write_data_channel_ack().await?; 154 data_channel.commit_reliability_params(); 155 156 Ok(data_channel) 157 } 158 159 /// Read reads a packet of len(p) bytes as binary data. 160 /// 161 /// See [`sctp::stream::Stream::read_sctp`]. 162 pub async fn read(&self, buf: &mut [u8]) -> Result<usize> { 163 self.read_data_channel(buf).await.map(|(n, _)| n) 164 } 165 166 /// ReadDataChannel reads a packet of len(p) bytes. It returns the number of bytes read and 167 /// `true` if the data read is a string. 168 /// 169 /// See [`sctp::stream::Stream::read_sctp`]. 170 pub async fn read_data_channel(&self, buf: &mut [u8]) -> Result<(usize, bool)> { 171 loop { 172 //TODO: add handling of cancel read_data_channel 173 let (mut n, ppi) = match self.stream.read_sctp(buf).await { 174 Ok((0, PayloadProtocolIdentifier::Unknown)) => { 175 // The incoming stream was reset or the reading half was shutdown 176 return Ok((0, false)); 177 } 178 Ok((n, ppi)) => (n, ppi), 179 Err(err) => { 180 // Shutdown the stream and send the reset request to the remote. 181 self.close().await?; 182 return Err(err.into()); 183 } 184 }; 185 186 let mut is_string = false; 187 match ppi { 188 PayloadProtocolIdentifier::Dcep => { 189 let mut data = &buf[..n]; 190 match self.handle_dcep(&mut data).await { 191 Ok(()) => {} 192 Err(err) => { 193 log::error!("Failed to handle DCEP: {:?}", err); 194 } 195 } 196 continue; 197 } 198 PayloadProtocolIdentifier::String | PayloadProtocolIdentifier::StringEmpty => { 199 is_string = true; 200 } 201 _ => {} 202 }; 203 204 match ppi { 205 PayloadProtocolIdentifier::StringEmpty | PayloadProtocolIdentifier::BinaryEmpty => { 206 n = 0; 207 } 208 _ => {} 209 }; 210 211 self.messages_received.fetch_add(1, Ordering::SeqCst); 212 self.bytes_received.fetch_add(n, Ordering::SeqCst); 213 214 return Ok((n, is_string)); 215 } 216 } 217 218 /// MessagesSent returns the number of messages sent 219 pub fn messages_sent(&self) -> usize { 220 self.messages_sent.load(Ordering::SeqCst) 221 } 222 223 /// MessagesReceived returns the number of messages received 224 pub fn messages_received(&self) -> usize { 225 self.messages_received.load(Ordering::SeqCst) 226 } 227 228 /// BytesSent returns the number of bytes sent 229 pub fn bytes_sent(&self) -> usize { 230 self.bytes_sent.load(Ordering::SeqCst) 231 } 232 233 /// BytesReceived returns the number of bytes received 234 pub fn bytes_received(&self) -> usize { 235 self.bytes_received.load(Ordering::SeqCst) 236 } 237 238 /// StreamIdentifier returns the Stream identifier associated to the stream. 239 pub fn stream_identifier(&self) -> u16 { 240 self.stream.stream_identifier() 241 } 242 243 async fn handle_dcep<B>(&self, data: &mut B) -> Result<()> 244 where 245 B: Buf, 246 { 247 let msg = Message::unmarshal(data)?; 248 249 match msg { 250 Message::DataChannelOpen(_) => { 251 // Note: DATA_CHANNEL_OPEN message is handled inside Server() method. 252 // Therefore, the message will not reach here. 253 log::debug!("Received DATA_CHANNEL_OPEN"); 254 let _ = self.write_data_channel_ack().await?; 255 } 256 Message::DataChannelAck(_) => { 257 log::debug!("Received DATA_CHANNEL_ACK"); 258 self.commit_reliability_params(); 259 } 260 }; 261 262 Ok(()) 263 } 264 265 /// Write writes len(p) bytes from p as binary data 266 pub async fn write(&self, data: &Bytes) -> Result<usize> { 267 self.write_data_channel(data, false).await 268 } 269 270 /// WriteDataChannel writes len(p) bytes from p 271 pub async fn write_data_channel(&self, data: &Bytes, is_string: bool) -> Result<usize> { 272 let data_len = data.len(); 273 274 // https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-12#section-6.6 275 // SCTP does not support the sending of empty user messages. Therefore, 276 // if an empty message has to be sent, the appropriate PPID (WebRTC 277 // String Empty or WebRTC Binary Empty) is used and the SCTP user 278 // message of one zero byte is sent. When receiving an SCTP user 279 // message with one of these PPIDs, the receiver MUST ignore the SCTP 280 // user message and process it as an empty message. 281 let ppi = match (is_string, data_len) { 282 (false, 0) => PayloadProtocolIdentifier::BinaryEmpty, 283 (false, _) => PayloadProtocolIdentifier::Binary, 284 (true, 0) => PayloadProtocolIdentifier::StringEmpty, 285 (true, _) => PayloadProtocolIdentifier::String, 286 }; 287 288 let n = if data_len == 0 { 289 let _ = self 290 .stream 291 .write_sctp(&Bytes::from_static(&[0]), ppi) 292 .await?; 293 0 294 } else { 295 let n = self.stream.write_sctp(data, ppi).await?; 296 self.bytes_sent.fetch_add(n, Ordering::SeqCst); 297 n 298 }; 299 300 self.messages_sent.fetch_add(1, Ordering::SeqCst); 301 Ok(n) 302 } 303 304 async fn write_data_channel_ack(&self) -> Result<usize> { 305 let ack = Message::DataChannelAck(DataChannelAck {}).marshal()?; 306 Ok(self 307 .stream 308 .write_sctp(&ack, PayloadProtocolIdentifier::Dcep) 309 .await?) 310 } 311 312 /// Close closes the DataChannel and the underlying SCTP stream. 313 pub async fn close(&self) -> Result<()> { 314 // https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-13#section-6.7 315 // Closing of a data channel MUST be signaled by resetting the 316 // corresponding outgoing streams [RFC6525]. This means that if one 317 // side decides to close the data channel, it resets the corresponding 318 // outgoing stream. When the peer sees that an incoming stream was 319 // reset, it also resets its corresponding outgoing stream. Once this 320 // is completed, the data channel is closed. Resetting a stream sets 321 // the Stream Sequence Numbers (SSNs) of the stream back to 'zero' with 322 // a corresponding notification to the application layer that the reset 323 // has been performed. Streams are available for reuse after a reset 324 // has been performed. 325 Ok(self.stream.shutdown(Shutdown::Both).await?) 326 } 327 328 /// BufferedAmount returns the number of bytes of data currently queued to be 329 /// sent over this stream. 330 pub fn buffered_amount(&self) -> usize { 331 self.stream.buffered_amount() 332 } 333 334 /// BufferedAmountLowThreshold returns the number of bytes of buffered outgoing 335 /// data that is considered "low." Defaults to 0. 336 pub fn buffered_amount_low_threshold(&self) -> usize { 337 self.stream.buffered_amount_low_threshold() 338 } 339 340 /// SetBufferedAmountLowThreshold is used to update the threshold. 341 /// See BufferedAmountLowThreshold(). 342 pub fn set_buffered_amount_low_threshold(&self, threshold: usize) { 343 self.stream.set_buffered_amount_low_threshold(threshold) 344 } 345 346 /// OnBufferedAmountLow sets the callback handler which would be called when the 347 /// number of bytes of outgoing data buffered is lower than the threshold. 348 pub async fn on_buffered_amount_low(&self, f: OnBufferedAmountLowFn) { 349 self.stream.on_buffered_amount_low(f).await 350 } 351 352 fn commit_reliability_params(&self) { 353 let (unordered, reliability_type) = match self.config.channel_type { 354 ChannelType::Reliable => (false, ReliabilityType::Reliable), 355 ChannelType::ReliableUnordered => (true, ReliabilityType::Reliable), 356 ChannelType::PartialReliableRexmit => (false, ReliabilityType::Rexmit), 357 ChannelType::PartialReliableRexmitUnordered => (true, ReliabilityType::Rexmit), 358 ChannelType::PartialReliableTimed => (false, ReliabilityType::Timed), 359 ChannelType::PartialReliableTimedUnordered => (true, ReliabilityType::Timed), 360 }; 361 362 self.stream.set_reliability_params( 363 unordered, 364 reliability_type, 365 self.config.reliability_parameter, 366 ); 367 } 368 } 369 370 /// Default capacity of the temporary read buffer used by [`PollStream`]. 371 const DEFAULT_READ_BUF_SIZE: usize = 8192; 372 373 /// State of the read `Future` in [`PollStream`]. 374 enum ReadFut { 375 /// Nothing in progress. 376 Idle, 377 /// Reading data from the underlying stream. 378 Reading(Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send>>), 379 /// Finished reading, but there's unread data in the temporary buffer. 380 RemainingData(Vec<u8>), 381 } 382 383 impl ReadFut { 384 /// Gets a mutable reference to the future stored inside `Reading(future)`. 385 /// 386 /// # Panics 387 /// 388 /// Panics if `ReadFut` variant is not `Reading`. 389 fn get_reading_mut(&mut self) -> &mut Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send>> { 390 match self { 391 ReadFut::Reading(ref mut fut) => fut, 392 _ => panic!("expected ReadFut to be Reading"), 393 } 394 } 395 } 396 397 /// A wrapper around around [`DataChannel`], which implements [`AsyncRead`] and 398 /// [`AsyncWrite`]. 399 /// 400 /// Both `poll_read` and `poll_write` calls allocate temporary buffers, which results in an 401 /// additional overhead. 402 pub struct PollDataChannel { 403 data_channel: Arc<DataChannel>, 404 405 read_fut: ReadFut, 406 write_fut: Option<Pin<Box<dyn Future<Output = Result<usize>> + Send>>>, 407 shutdown_fut: Option<Pin<Box<dyn Future<Output = Result<()>> + Send>>>, 408 409 read_buf_cap: usize, 410 } 411 412 impl PollDataChannel { 413 /// Constructs a new `PollDataChannel`. 414 /// 415 /// # Examples 416 /// 417 /// ``` 418 /// use webrtc_data::data_channel::{DataChannel, PollDataChannel, Config}; 419 /// use sctp::stream::Stream; 420 /// use std::sync::Arc; 421 /// 422 /// let dc = Arc::new(DataChannel::new(Arc::new(Stream::default()), Config::default())); 423 /// let poll_dc = PollDataChannel::new(dc); 424 /// ``` 425 pub fn new(data_channel: Arc<DataChannel>) -> Self { 426 Self { 427 data_channel, 428 read_fut: ReadFut::Idle, 429 write_fut: None, 430 shutdown_fut: None, 431 read_buf_cap: DEFAULT_READ_BUF_SIZE, 432 } 433 } 434 435 /// Get back the inner data_channel. 436 pub fn into_inner(self) -> Arc<DataChannel> { 437 self.data_channel 438 } 439 440 /// Obtain a clone of the inner data_channel. 441 pub fn clone_inner(&self) -> Arc<DataChannel> { 442 self.data_channel.clone() 443 } 444 445 /// MessagesSent returns the number of messages sent 446 pub fn messages_sent(&self) -> usize { 447 self.data_channel.messages_sent() 448 } 449 450 /// MessagesReceived returns the number of messages received 451 pub fn messages_received(&self) -> usize { 452 self.data_channel.messages_received() 453 } 454 455 /// BytesSent returns the number of bytes sent 456 pub fn bytes_sent(&self) -> usize { 457 self.data_channel.bytes_sent() 458 } 459 460 /// BytesReceived returns the number of bytes received 461 pub fn bytes_received(&self) -> usize { 462 self.data_channel.bytes_received() 463 } 464 465 /// StreamIdentifier returns the Stream identifier associated to the stream. 466 pub fn stream_identifier(&self) -> u16 { 467 self.data_channel.stream_identifier() 468 } 469 470 /// BufferedAmount returns the number of bytes of data currently queued to be 471 /// sent over this stream. 472 pub fn buffered_amount(&self) -> usize { 473 self.data_channel.buffered_amount() 474 } 475 476 /// BufferedAmountLowThreshold returns the number of bytes of buffered outgoing 477 /// data that is considered "low." Defaults to 0. 478 pub fn buffered_amount_low_threshold(&self) -> usize { 479 self.data_channel.buffered_amount_low_threshold() 480 } 481 482 /// Set the capacity of the temporary read buffer (default: 8192). 483 pub fn set_read_buf_capacity(&mut self, capacity: usize) { 484 self.read_buf_cap = capacity 485 } 486 } 487 488 impl AsyncRead for PollDataChannel { 489 fn poll_read( 490 mut self: Pin<&mut Self>, 491 cx: &mut Context<'_>, 492 buf: &mut ReadBuf<'_>, 493 ) -> Poll<io::Result<()>> { 494 if buf.remaining() == 0 { 495 return Poll::Ready(Ok(())); 496 } 497 498 let fut = match self.read_fut { 499 ReadFut::Idle => { 500 // read into a temporary buffer because `buf` has an unonymous lifetime, which can 501 // be shorter than the lifetime of `read_fut`. 502 let data_channel = self.data_channel.clone(); 503 let mut temp_buf = vec![0; self.read_buf_cap]; 504 self.read_fut = ReadFut::Reading(Box::pin(async move { 505 data_channel.read(temp_buf.as_mut_slice()).await.map(|n| { 506 temp_buf.truncate(n); 507 temp_buf 508 }) 509 })); 510 self.read_fut.get_reading_mut() 511 } 512 ReadFut::Reading(ref mut fut) => fut, 513 ReadFut::RemainingData(ref mut data) => { 514 let remaining = buf.remaining(); 515 let len = std::cmp::min(data.len(), remaining); 516 buf.put_slice(&data[..len]); 517 if data.len() > remaining { 518 // ReadFut remains to be RemainingData 519 data.drain(..len); 520 } else { 521 self.read_fut = ReadFut::Idle; 522 } 523 return Poll::Ready(Ok(())); 524 } 525 }; 526 527 loop { 528 match fut.as_mut().poll(cx) { 529 Poll::Pending => return Poll::Pending, 530 // retry immediately upon empty data or incomplete chunks 531 // since there's no way to setup a waker. 532 Poll::Ready(Err(Error::Sctp(sctp::Error::ErrTryAgain))) => {} 533 // EOF has been reached => don't touch buf and just return Ok 534 Poll::Ready(Err(Error::Sctp(sctp::Error::ErrEof))) => { 535 self.read_fut = ReadFut::Idle; 536 return Poll::Ready(Ok(())); 537 } 538 Poll::Ready(Err(e)) => { 539 self.read_fut = ReadFut::Idle; 540 return Poll::Ready(Err(e.into())); 541 } 542 Poll::Ready(Ok(mut temp_buf)) => { 543 let remaining = buf.remaining(); 544 let len = std::cmp::min(temp_buf.len(), remaining); 545 buf.put_slice(&temp_buf[..len]); 546 if temp_buf.len() > remaining { 547 temp_buf.drain(..len); 548 self.read_fut = ReadFut::RemainingData(temp_buf); 549 } else { 550 self.read_fut = ReadFut::Idle; 551 } 552 return Poll::Ready(Ok(())); 553 } 554 } 555 } 556 } 557 } 558 559 impl AsyncWrite for PollDataChannel { 560 fn poll_write( 561 mut self: Pin<&mut Self>, 562 cx: &mut Context<'_>, 563 buf: &[u8], 564 ) -> Poll<io::Result<usize>> { 565 if buf.is_empty() { 566 return Poll::Ready(Ok(0)); 567 } 568 569 let (fut, fut_is_new) = match self.write_fut.as_mut() { 570 Some(fut) => (fut, false), 571 None => { 572 let data_channel = self.data_channel.clone(); 573 let bytes = Bytes::copy_from_slice(buf); 574 ( 575 self.write_fut 576 .get_or_insert(Box::pin(async move { data_channel.write(&bytes).await })), 577 true, 578 ) 579 } 580 }; 581 582 match fut.as_mut().poll(cx) { 583 Poll::Pending => { 584 // If it's the first time we're polling the future, `Poll::Pending` can't be 585 // returned because that would mean the `PollStream` is not ready for writing. And 586 // this is not true since we've just created a future, which is going to write the 587 // buf to the underlying stream. 588 // 589 // It's okay to return `Poll::Ready` if the data is buffered (this is what the 590 // buffered writer and `File` do). 591 if fut_is_new { 592 Poll::Ready(Ok(buf.len())) 593 } else { 594 // If it's the subsequent poll, it's okay to return `Poll::Pending` as it 595 // indicates that the `PollStream` is not ready for writing. Only one future 596 // can be in progress at the time. 597 Poll::Pending 598 } 599 } 600 Poll::Ready(Err(e)) => { 601 self.write_fut = None; 602 Poll::Ready(Err(e.into())) 603 } 604 Poll::Ready(Ok(n)) => { 605 self.write_fut = None; 606 Poll::Ready(Ok(n)) 607 } 608 } 609 } 610 611 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> { 612 match self.write_fut.as_mut() { 613 Some(fut) => match fut.as_mut().poll(cx) { 614 Poll::Pending => Poll::Pending, 615 Poll::Ready(Err(e)) => { 616 self.write_fut = None; 617 Poll::Ready(Err(e.into())) 618 } 619 Poll::Ready(Ok(_)) => { 620 self.write_fut = None; 621 Poll::Ready(Ok(())) 622 } 623 }, 624 None => Poll::Ready(Ok(())), 625 } 626 } 627 628 fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> { 629 let fut = match self.shutdown_fut.as_mut() { 630 Some(fut) => fut, 631 None => { 632 let data_channel = self.data_channel.clone(); 633 self.shutdown_fut.get_or_insert(Box::pin(async move { 634 data_channel 635 .stream 636 .shutdown(Shutdown::Write) 637 .await 638 .map_err(Error::Sctp) 639 })) 640 } 641 }; 642 643 match fut.as_mut().poll(cx) { 644 Poll::Pending => Poll::Pending, 645 Poll::Ready(Err(e)) => { 646 self.shutdown_fut = None; 647 Poll::Ready(Err(e.into())) 648 } 649 Poll::Ready(Ok(_)) => { 650 self.shutdown_fut = None; 651 Poll::Ready(Ok(())) 652 } 653 } 654 } 655 } 656 657 impl Clone for PollDataChannel { 658 fn clone(&self) -> PollDataChannel { 659 PollDataChannel::new(self.clone_inner()) 660 } 661 } 662 663 impl fmt::Debug for PollDataChannel { 664 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 665 f.debug_struct("PollDataChannel") 666 .field("data_channel", &self.data_channel) 667 .field("read_buf_cap", &self.read_buf_cap) 668 .finish() 669 } 670 } 671 672 impl AsRef<DataChannel> for PollDataChannel { 673 fn as_ref(&self) -> &DataChannel { 674 &self.data_channel 675 } 676 } 677