xref: /webrtc/sctp/src/stream/mod.rs (revision e32feda5)
1 #[cfg(test)]
2 mod stream_test;
3 
4 use crate::association::AssociationState;
5 use crate::chunk::chunk_payload_data::{ChunkPayloadData, PayloadProtocolIdentifier};
6 use crate::error::{Error, Result};
7 use crate::queue::pending_queue::PendingQueue;
8 use crate::queue::reassembly_queue::ReassemblyQueue;
9 
10 use arc_swap::ArcSwapOption;
11 use bytes::Bytes;
12 use std::{
13     fmt,
14     future::Future,
15     io,
16     net::Shutdown,
17     pin::Pin,
18     sync::atomic::{AtomicBool, AtomicU16, AtomicU32, AtomicU8, AtomicUsize, Ordering},
19     sync::Arc,
20     task::{Context, Poll},
21 };
22 use tokio::{
23     io::{AsyncRead, AsyncWrite, ReadBuf},
24     sync::{mpsc, Mutex, Notify},
25 };
26 
27 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
28 #[repr(C)]
29 pub enum ReliabilityType {
30     /// ReliabilityTypeReliable is used for reliable transmission
31     Reliable = 0,
32     /// ReliabilityTypeRexmit is used for partial reliability by retransmission count
33     Rexmit = 1,
34     /// ReliabilityTypeTimed is used for partial reliability by retransmission duration
35     Timed = 2,
36 }
37 
38 impl Default for ReliabilityType {
39     fn default() -> Self {
40         ReliabilityType::Reliable
41     }
42 }
43 
44 impl fmt::Display for ReliabilityType {
45     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46         let s = match *self {
47             ReliabilityType::Reliable => "Reliable",
48             ReliabilityType::Rexmit => "Rexmit",
49             ReliabilityType::Timed => "Timed",
50         };
51         write!(f, "{}", s)
52     }
53 }
54 
55 impl From<u8> for ReliabilityType {
56     fn from(v: u8) -> ReliabilityType {
57         match v {
58             1 => ReliabilityType::Rexmit,
59             2 => ReliabilityType::Timed,
60             _ => ReliabilityType::Reliable,
61         }
62     }
63 }
64 
65 pub type OnBufferedAmountLowFn =
66     Box<dyn (FnMut() -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>) + Send + Sync>;
67 
68 // TODO: benchmark performance between multiple Atomic+Mutex vs one Mutex<StreamInternal>
69 
70 /// Stream represents an SCTP stream
71 #[derive(Default)]
72 pub struct Stream {
73     pub(crate) max_payload_size: u32,
74     pub(crate) max_message_size: Arc<AtomicU32>, // clone from association
75     pub(crate) state: Arc<AtomicU8>,             // clone from association
76     pub(crate) awake_write_loop_ch: Option<Arc<mpsc::Sender<()>>>,
77     pub(crate) pending_queue: Arc<PendingQueue>,
78 
79     pub(crate) stream_identifier: u16,
80     pub(crate) default_payload_type: AtomicU32, //PayloadProtocolIdentifier,
81     pub(crate) reassembly_queue: Mutex<ReassemblyQueue>,
82     pub(crate) sequence_number: AtomicU16,
83     pub(crate) read_notifier: Notify,
84     pub(crate) read_shutdown: AtomicBool,
85     pub(crate) write_shutdown: AtomicBool,
86     pub(crate) unordered: AtomicBool,
87     pub(crate) reliability_type: AtomicU8, //ReliabilityType,
88     pub(crate) reliability_value: AtomicU32,
89     pub(crate) buffered_amount: AtomicUsize,
90     pub(crate) buffered_amount_low: AtomicUsize,
91     pub(crate) on_buffered_amount_low: ArcSwapOption<Mutex<OnBufferedAmountLowFn>>,
92     pub(crate) name: String,
93 }
94 
95 impl fmt::Debug for Stream {
96     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97         f.debug_struct("Stream")
98             .field("max_payload_size", &self.max_payload_size)
99             .field("max_message_size", &self.max_message_size)
100             .field("state", &self.state)
101             .field("awake_write_loop_ch", &self.awake_write_loop_ch)
102             .field("stream_identifier", &self.stream_identifier)
103             .field("default_payload_type", &self.default_payload_type)
104             .field("reassembly_queue", &self.reassembly_queue)
105             .field("sequence_number", &self.sequence_number)
106             .field("read_shutdown", &self.read_shutdown)
107             .field("write_shutdown", &self.write_shutdown)
108             .field("unordered", &self.unordered)
109             .field("reliability_type", &self.reliability_type)
110             .field("reliability_value", &self.reliability_value)
111             .field("buffered_amount", &self.buffered_amount)
112             .field("buffered_amount_low", &self.buffered_amount_low)
113             .field("name", &self.name)
114             .finish()
115     }
116 }
117 
118 impl Stream {
119     pub(crate) fn new(
120         name: String,
121         stream_identifier: u16,
122         max_payload_size: u32,
123         max_message_size: Arc<AtomicU32>,
124         state: Arc<AtomicU8>,
125         awake_write_loop_ch: Option<Arc<mpsc::Sender<()>>>,
126         pending_queue: Arc<PendingQueue>,
127     ) -> Self {
128         Stream {
129             max_payload_size,
130             max_message_size,
131             state,
132             awake_write_loop_ch,
133             pending_queue,
134 
135             stream_identifier,
136             default_payload_type: AtomicU32::new(0), //PayloadProtocolIdentifier::Unknown,
137             reassembly_queue: Mutex::new(ReassemblyQueue::new(stream_identifier)),
138             sequence_number: AtomicU16::new(0),
139             read_notifier: Notify::new(),
140             read_shutdown: AtomicBool::new(false),
141             write_shutdown: AtomicBool::new(false),
142             unordered: AtomicBool::new(false),
143             reliability_type: AtomicU8::new(0), //ReliabilityType::Reliable,
144             reliability_value: AtomicU32::new(0),
145             buffered_amount: AtomicUsize::new(0),
146             buffered_amount_low: AtomicUsize::new(0),
147             on_buffered_amount_low: ArcSwapOption::empty(),
148             name,
149         }
150     }
151 
152     /// stream_identifier returns the Stream identifier associated to the stream.
153     pub fn stream_identifier(&self) -> u16 {
154         self.stream_identifier
155     }
156 
157     /// set_default_payload_type sets the default payload type used by write.
158     pub fn set_default_payload_type(&self, default_payload_type: PayloadProtocolIdentifier) {
159         self.default_payload_type
160             .store(default_payload_type as u32, Ordering::SeqCst);
161     }
162 
163     /// set_reliability_params sets reliability parameters for this stream.
164     pub fn set_reliability_params(&self, unordered: bool, rel_type: ReliabilityType, rel_val: u32) {
165         log::debug!(
166             "[{}] reliability params: ordered={} type={} value={}",
167             self.name,
168             !unordered,
169             rel_type,
170             rel_val
171         );
172         self.unordered.store(unordered, Ordering::SeqCst);
173         self.reliability_type
174             .store(rel_type as u8, Ordering::SeqCst);
175         self.reliability_value.store(rel_val, Ordering::SeqCst);
176     }
177 
178     /// Reads a packet of len(p) bytes, dropping the Payload Protocol Identifier.
179     ///
180     /// Returns `Error::ErrShortBuffer` if `p` is too short.
181     /// Returns `0` if the reading half of this stream is shutdown or it (the stream) was reset.
182     pub async fn read(&self, p: &mut [u8]) -> Result<usize> {
183         let (n, _) = self.read_sctp(p).await?;
184         Ok(n)
185     }
186 
187     /// Reads a packet of len(p) bytes and returns the associated Payload Protocol Identifier.
188     ///
189     /// Returns `Error::ErrShortBuffer` if `p` is too short.
190     /// Returns `(0, PayloadProtocolIdentifier::Unknown)` if the reading half of this stream is shutdown or it (the stream) was reset.
191     pub async fn read_sctp(&self, p: &mut [u8]) -> Result<(usize, PayloadProtocolIdentifier)> {
192         loop {
193             if self.read_shutdown.load(Ordering::SeqCst) {
194                 return Ok((0, PayloadProtocolIdentifier::Unknown));
195             }
196 
197             let result = {
198                 let mut reassembly_queue = self.reassembly_queue.lock().await;
199                 reassembly_queue.read(p)
200             };
201 
202             match result {
203                 Ok(_) | Err(Error::ErrShortBuffer) => return result,
204                 Err(_) => {
205                     // wait for the next chunk to become available
206                     self.read_notifier.notified().await;
207                 }
208             }
209         }
210     }
211 
212     pub(crate) async fn handle_data(&self, pd: ChunkPayloadData) {
213         let readable = {
214             let mut reassembly_queue = self.reassembly_queue.lock().await;
215             if reassembly_queue.push(pd) {
216                 let readable = reassembly_queue.is_readable();
217                 log::debug!("[{}] reassemblyQueue readable={}", self.name, readable);
218                 readable
219             } else {
220                 false
221             }
222         };
223 
224         if readable {
225             log::debug!("[{}] readNotifier.signal()", self.name);
226             self.read_notifier.notify_one();
227             log::debug!("[{}] readNotifier.signal() done", self.name);
228         }
229     }
230 
231     pub(crate) async fn handle_forward_tsn_for_ordered(&self, ssn: u16) {
232         if self.unordered.load(Ordering::SeqCst) {
233             return; // unordered chunks are handled by handleForwardUnordered method
234         }
235 
236         // Remove all chunks older than or equal to the new TSN from
237         // the reassembly_queue.
238         let readable = {
239             let mut reassembly_queue = self.reassembly_queue.lock().await;
240             reassembly_queue.forward_tsn_for_ordered(ssn);
241             reassembly_queue.is_readable()
242         };
243 
244         // Notify the reader asynchronously if there's a data chunk to read.
245         if readable {
246             self.read_notifier.notify_one();
247         }
248     }
249 
250     pub(crate) async fn handle_forward_tsn_for_unordered(&self, new_cumulative_tsn: u32) {
251         if !self.unordered.load(Ordering::SeqCst) {
252             return; // ordered chunks are handled by handleForwardTSNOrdered method
253         }
254 
255         // Remove all chunks older than or equal to the new TSN from
256         // the reassembly_queue.
257         let readable = {
258             let mut reassembly_queue = self.reassembly_queue.lock().await;
259             reassembly_queue.forward_tsn_for_unordered(new_cumulative_tsn);
260             reassembly_queue.is_readable()
261         };
262 
263         // Notify the reader asynchronously if there's a data chunk to read.
264         if readable {
265             self.read_notifier.notify_one();
266         }
267     }
268 
269     /// Writes `p` to the DTLS connection with the default Payload Protocol Identifier.
270     ///
271     /// Returns an error if the write half of this stream is shutdown or `p` is too large.
272     pub fn write(&self, p: &Bytes) -> Result<usize> {
273         self.write_sctp(p, self.default_payload_type.load(Ordering::SeqCst).into())
274     }
275 
276     /// Writes `p` to the DTLS connection with the given Payload Protocol Identifier.
277     ///
278     /// Returns an error if the write half of this stream is shutdown or `p` is too large.
279     pub fn write_sctp(&self, p: &Bytes, ppi: PayloadProtocolIdentifier) -> Result<usize> {
280         if self.write_shutdown.load(Ordering::SeqCst) {
281             return Err(Error::ErrStreamClosed);
282         }
283 
284         if p.len() > self.max_message_size.load(Ordering::SeqCst) as usize {
285             return Err(Error::ErrOutboundPacketTooLarge);
286         }
287 
288         let state: AssociationState = self.state.load(Ordering::SeqCst).into();
289         match state {
290             AssociationState::ShutdownSent
291             | AssociationState::ShutdownAckSent
292             | AssociationState::ShutdownPending
293             | AssociationState::ShutdownReceived => return Err(Error::ErrStreamClosed),
294             _ => {}
295         };
296 
297         let chunks = self.packetize(p, ppi);
298         self.send_payload_data(chunks)?;
299 
300         Ok(p.len())
301     }
302 
303     fn packetize(&self, raw: &Bytes, ppi: PayloadProtocolIdentifier) -> Vec<ChunkPayloadData> {
304         let mut i = 0;
305         let mut remaining = raw.len();
306 
307         // From draft-ietf-rtcweb-data-protocol-09, section 6:
308         //   All Data Channel Establishment Protocol messages MUST be sent using
309         //   ordered delivery and reliable transmission.
310         let unordered =
311             ppi != PayloadProtocolIdentifier::Dcep && self.unordered.load(Ordering::SeqCst);
312 
313         let mut chunks = vec![];
314 
315         let head_abandoned = Arc::new(AtomicBool::new(false));
316         let head_all_inflight = Arc::new(AtomicBool::new(false));
317         while remaining != 0 {
318             let fragment_size = std::cmp::min(self.max_payload_size as usize, remaining); //self.association.max_payload_size
319 
320             // Copy the userdata since we'll have to store it until acked
321             // and the caller may re-use the buffer in the mean time
322             let user_data = raw.slice(i..i + fragment_size);
323 
324             let chunk = ChunkPayloadData {
325                 stream_identifier: self.stream_identifier,
326                 user_data,
327                 unordered,
328                 beginning_fragment: i == 0,
329                 ending_fragment: remaining - fragment_size == 0,
330                 immediate_sack: false,
331                 payload_type: ppi,
332                 stream_sequence_number: self.sequence_number.load(Ordering::SeqCst),
333                 abandoned: head_abandoned.clone(), // all fragmented chunks use the same abandoned
334                 all_inflight: head_all_inflight.clone(), // all fragmented chunks use the same all_inflight
335                 ..Default::default()
336             };
337 
338             chunks.push(chunk);
339 
340             remaining -= fragment_size;
341             i += fragment_size;
342         }
343 
344         // RFC 4960 Sec 6.6
345         // Note: When transmitting ordered and unordered data, an endpoint does
346         // not increment its Stream Sequence Number when transmitting a DATA
347         // chunk with U flag set to 1.
348         if !unordered {
349             self.sequence_number.fetch_add(1, Ordering::SeqCst);
350         }
351 
352         let old_value = self.buffered_amount.fetch_add(raw.len(), Ordering::SeqCst);
353         log::trace!("[{}] bufferedAmount = {}", self.name, old_value + raw.len());
354 
355         chunks
356     }
357 
358     /// Closes both read and write halves of this stream.
359     ///
360     /// Use [`Stream::shutdown`] instead.
361     #[deprecated]
362     pub async fn close(&self) -> Result<()> {
363         self.shutdown(Shutdown::Both).await
364     }
365 
366     /// Shuts down the read, write, or both halves of this stream.
367     ///
368     /// This function will cause all pending and future I/O on the specified portions to return
369     /// immediately with an appropriate value (see the documentation of [`Shutdown`]).
370     ///
371     /// Resets the stream when both halves of this stream are shutdown.
372     pub async fn shutdown(&self, how: Shutdown) -> Result<()> {
373         if self.read_shutdown.load(Ordering::SeqCst) && self.write_shutdown.load(Ordering::SeqCst) {
374             return Ok(());
375         }
376 
377         if how == Shutdown::Write || how == Shutdown::Both {
378             self.write_shutdown.store(true, Ordering::SeqCst);
379         }
380 
381         if (how == Shutdown::Read || how == Shutdown::Both)
382             && !self.read_shutdown.swap(true, Ordering::SeqCst)
383         {
384             self.read_notifier.notify_waiters();
385         }
386 
387         if how == Shutdown::Both
388             || (self.read_shutdown.load(Ordering::SeqCst)
389                 && self.write_shutdown.load(Ordering::SeqCst))
390         {
391             // Reset the stream
392             // https://tools.ietf.org/html/rfc6525
393             self.send_reset_request(self.stream_identifier)?;
394         }
395 
396         Ok(())
397     }
398 
399     /// buffered_amount returns the number of bytes of data currently queued to be sent over this stream.
400     pub fn buffered_amount(&self) -> usize {
401         self.buffered_amount.load(Ordering::SeqCst)
402     }
403 
404     /// buffered_amount_low_threshold returns the number of bytes of buffered outgoing data that is
405     /// considered "low." Defaults to 0.
406     pub fn buffered_amount_low_threshold(&self) -> usize {
407         self.buffered_amount_low.load(Ordering::SeqCst)
408     }
409 
410     /// set_buffered_amount_low_threshold is used to update the threshold.
411     /// See buffered_amount_low_threshold().
412     pub fn set_buffered_amount_low_threshold(&self, th: usize) {
413         self.buffered_amount_low.store(th, Ordering::SeqCst);
414     }
415 
416     /// on_buffered_amount_low sets the callback handler which would be called when the number of
417     /// bytes of outgoing data buffered is lower than the threshold.
418     pub fn on_buffered_amount_low(&self, f: OnBufferedAmountLowFn) {
419         self.on_buffered_amount_low
420             .store(Some(Arc::new(Mutex::new(f))));
421     }
422 
423     /// This method is called by association's read_loop (go-)routine to notify this stream
424     /// of the specified amount of outgoing data has been delivered to the peer.
425     pub(crate) async fn on_buffer_released(&self, n_bytes_released: i64) {
426         if n_bytes_released <= 0 {
427             return;
428         }
429 
430         let from_amount = self.buffered_amount.load(Ordering::SeqCst);
431         let new_amount = if from_amount < n_bytes_released as usize {
432             self.buffered_amount.store(0, Ordering::SeqCst);
433             log::error!(
434                 "[{}] released buffer size {} should be <= {}",
435                 self.name,
436                 n_bytes_released,
437                 0,
438             );
439             0
440         } else {
441             self.buffered_amount
442                 .fetch_sub(n_bytes_released as usize, Ordering::SeqCst);
443 
444             from_amount - n_bytes_released as usize
445         };
446 
447         let buffered_amount_low = self.buffered_amount_low.load(Ordering::SeqCst);
448 
449         log::trace!(
450             "[{}] bufferedAmount = {}, from_amount = {}, buffered_amount_low = {}",
451             self.name,
452             new_amount,
453             from_amount,
454             buffered_amount_low,
455         );
456 
457         if from_amount > buffered_amount_low && new_amount <= buffered_amount_low {
458             if let Some(handler) = &*self.on_buffered_amount_low.load() {
459                 let mut f = handler.lock().await;
460                 f().await;
461             }
462         }
463     }
464 
465     /// get_num_bytes_in_reassembly_queue returns the number of bytes of data currently queued to
466     /// be read (once chunk is complete).
467     pub(crate) async fn get_num_bytes_in_reassembly_queue(&self) -> usize {
468         // No lock is required as it reads the size with atomic load function.
469         let reassembly_queue = self.reassembly_queue.lock().await;
470         reassembly_queue.get_num_bytes()
471     }
472 
473     /// get_state atomically returns the state of the Association.
474     fn get_state(&self) -> AssociationState {
475         self.state.load(Ordering::SeqCst).into()
476     }
477 
478     fn awake_write_loop(&self) {
479         //log::debug!("[{}] awake_write_loop_ch.notify_one", self.name);
480         if let Some(awake_write_loop_ch) = &self.awake_write_loop_ch {
481             let _ = awake_write_loop_ch.try_send(());
482         }
483     }
484 
485     fn send_payload_data(&self, chunks: Vec<ChunkPayloadData>) -> Result<()> {
486         let state = self.get_state();
487         if state != AssociationState::Established {
488             return Err(Error::ErrPayloadDataStateNotExist);
489         }
490 
491         // NOTE: append is used here instead of push in order to prevent chunks interlacing.
492         self.pending_queue.append(chunks);
493 
494         self.awake_write_loop();
495         Ok(())
496     }
497 
498     fn send_reset_request(&self, stream_identifier: u16) -> Result<()> {
499         let state = self.get_state();
500         if state != AssociationState::Established {
501             return Err(Error::ErrResetPacketInStateNotExist);
502         }
503 
504         // Create DATA chunk which only contains valid stream identifier with
505         // nil userData and use it as a EOS from the stream.
506         let c = ChunkPayloadData {
507             stream_identifier,
508             beginning_fragment: true,
509             ending_fragment: true,
510             user_data: Bytes::new(),
511             ..Default::default()
512         };
513 
514         self.pending_queue.push(c);
515 
516         self.awake_write_loop();
517         Ok(())
518     }
519 }
520 
521 /// Default capacity of the temporary read buffer used by [`PollStream`].
522 const DEFAULT_READ_BUF_SIZE: usize = 8192;
523 
524 /// State of the read `Future` in [`PollStream`].
525 enum ReadFut {
526     /// Nothing in progress.
527     Idle,
528     /// Reading data from the underlying stream.
529     Reading(Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send>>),
530     /// Finished reading, but there's unread data in the temporary buffer.
531     RemainingData(Vec<u8>),
532 }
533 
534 impl ReadFut {
535     /// Gets a mutable reference to the future stored inside `Reading(future)`.
536     ///
537     /// # Panics
538     ///
539     /// Panics if `ReadFut` variant is not `Reading`.
540     fn get_reading_mut(&mut self) -> &mut Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send>> {
541         match self {
542             ReadFut::Reading(ref mut fut) => fut,
543             _ => panic!("expected ReadFut to be Reading"),
544         }
545     }
546 }
547 
548 /// A wrapper around around [`Stream`], which implements [`AsyncRead`] and
549 /// [`AsyncWrite`].
550 ///
551 /// Both `poll_read` and `poll_write` calls allocate temporary buffers, which results in an
552 /// additional overhead.
553 pub struct PollStream {
554     stream: Arc<Stream>,
555 
556     read_fut: ReadFut,
557     write_fut: Option<Pin<Box<dyn Future<Output = Result<usize>> + Send>>>,
558     shutdown_fut: Option<Pin<Box<dyn Future<Output = Result<()>> + Send>>>,
559 
560     read_buf_cap: usize,
561 }
562 
563 impl PollStream {
564     /// Constructs a new `PollStream`.
565     ///
566     /// # Examples
567     ///
568     /// ```
569     /// use webrtc_sctp::stream::{Stream, PollStream};
570     /// use std::sync::Arc;
571     ///
572     /// let stream = Arc::new(Stream::default());
573     /// let poll_stream = PollStream::new(stream);
574     /// ```
575     pub fn new(stream: Arc<Stream>) -> Self {
576         Self {
577             stream,
578             read_fut: ReadFut::Idle,
579             write_fut: None,
580             shutdown_fut: None,
581             read_buf_cap: DEFAULT_READ_BUF_SIZE,
582         }
583     }
584 
585     /// Get back the inner stream.
586     #[must_use]
587     pub fn into_inner(self) -> Arc<Stream> {
588         self.stream
589     }
590 
591     /// Obtain a clone of the inner stream.
592     #[must_use]
593     pub fn clone_inner(&self) -> Arc<Stream> {
594         self.stream.clone()
595     }
596 
597     /// stream_identifier returns the Stream identifier associated to the stream.
598     pub fn stream_identifier(&self) -> u16 {
599         self.stream.stream_identifier
600     }
601 
602     /// buffered_amount returns the number of bytes of data currently queued to be sent over this stream.
603     pub fn buffered_amount(&self) -> usize {
604         self.stream.buffered_amount.load(Ordering::SeqCst)
605     }
606 
607     /// buffered_amount_low_threshold returns the number of bytes of buffered outgoing data that is
608     /// considered "low." Defaults to 0.
609     pub fn buffered_amount_low_threshold(&self) -> usize {
610         self.stream.buffered_amount_low.load(Ordering::SeqCst)
611     }
612 
613     /// get_num_bytes_in_reassembly_queue returns the number of bytes of data currently queued to
614     /// be read (once chunk is complete).
615     pub(crate) async fn get_num_bytes_in_reassembly_queue(&self) -> usize {
616         // No lock is required as it reads the size with atomic load function.
617         let reassembly_queue = self.stream.reassembly_queue.lock().await;
618         reassembly_queue.get_num_bytes()
619     }
620 
621     /// Set the capacity of the temporary read buffer (default: 8192).
622     pub fn set_read_buf_capacity(&mut self, capacity: usize) {
623         self.read_buf_cap = capacity
624     }
625 }
626 
627 impl AsyncRead for PollStream {
628     fn poll_read(
629         mut self: Pin<&mut Self>,
630         cx: &mut Context<'_>,
631         buf: &mut ReadBuf<'_>,
632     ) -> Poll<io::Result<()>> {
633         if buf.remaining() == 0 {
634             return Poll::Ready(Ok(()));
635         }
636 
637         let fut = match self.read_fut {
638             ReadFut::Idle => {
639                 // read into a temporary buffer because `buf` has an unonymous lifetime, which can
640                 // be shorter than the lifetime of `read_fut`.
641                 let stream = self.stream.clone();
642                 let mut temp_buf = vec![0; self.read_buf_cap];
643                 self.read_fut = ReadFut::Reading(Box::pin(async move {
644                     stream.read(temp_buf.as_mut_slice()).await.map(|n| {
645                         temp_buf.truncate(n);
646                         temp_buf
647                     })
648                 }));
649                 self.read_fut.get_reading_mut()
650             }
651             ReadFut::Reading(ref mut fut) => fut,
652             ReadFut::RemainingData(ref mut data) => {
653                 let remaining = buf.remaining();
654                 let len = std::cmp::min(data.len(), remaining);
655                 buf.put_slice(&data[..len]);
656                 if data.len() > remaining {
657                     // ReadFut remains to be RemainingData
658                     data.drain(0..len);
659                 } else {
660                     self.read_fut = ReadFut::Idle;
661                 }
662                 return Poll::Ready(Ok(()));
663             }
664         };
665 
666         loop {
667             match fut.as_mut().poll(cx) {
668                 Poll::Pending => return Poll::Pending,
669                 // retry immediately upon empty data or incomplete chunks
670                 // since there's no way to setup a waker.
671                 Poll::Ready(Err(Error::ErrTryAgain)) => {}
672                 // EOF has been reached => don't touch buf and just return Ok
673                 Poll::Ready(Err(Error::ErrEof)) => {
674                     self.read_fut = ReadFut::Idle;
675                     return Poll::Ready(Ok(()));
676                 }
677                 Poll::Ready(Err(e)) => {
678                     self.read_fut = ReadFut::Idle;
679                     return Poll::Ready(Err(e.into()));
680                 }
681                 Poll::Ready(Ok(mut temp_buf)) => {
682                     let remaining = buf.remaining();
683                     let len = std::cmp::min(temp_buf.len(), remaining);
684                     buf.put_slice(&temp_buf[..len]);
685                     if temp_buf.len() > remaining {
686                         temp_buf.drain(0..len);
687                         self.read_fut = ReadFut::RemainingData(temp_buf);
688                     } else {
689                         self.read_fut = ReadFut::Idle;
690                     }
691                     return Poll::Ready(Ok(()));
692                 }
693             }
694         }
695     }
696 }
697 
698 impl AsyncWrite for PollStream {
699     fn poll_write(
700         self: Pin<&mut Self>,
701         _cx: &mut Context<'_>,
702         buf: &[u8],
703     ) -> Poll<io::Result<usize>> {
704         let bytes = Bytes::copy_from_slice(buf);
705         match self.stream.write(&bytes) {
706             Ok(n) => Poll::Ready(Ok(n)),
707             Err(e) => Poll::Ready(Err(e.into())),
708         }
709     }
710 
711     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
712         match self.write_fut.as_mut() {
713             Some(fut) => match fut.as_mut().poll(cx) {
714                 Poll::Pending => Poll::Pending,
715                 Poll::Ready(Err(e)) => {
716                     self.write_fut = None;
717                     Poll::Ready(Err(e.into()))
718                 }
719                 Poll::Ready(Ok(_)) => {
720                     self.write_fut = None;
721                     Poll::Ready(Ok(()))
722                 }
723             },
724             None => Poll::Ready(Ok(())),
725         }
726     }
727 
728     fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
729         match self.as_mut().poll_flush(cx) {
730             Poll::Pending => return Poll::Pending,
731             Poll::Ready(_) => {}
732         }
733 
734         let fut = match self.shutdown_fut.as_mut() {
735             Some(fut) => fut,
736             None => {
737                 let stream = self.stream.clone();
738                 self.shutdown_fut.get_or_insert(Box::pin(async move {
739                     stream.shutdown(Shutdown::Write).await
740                 }))
741             }
742         };
743 
744         match fut.as_mut().poll(cx) {
745             Poll::Pending => Poll::Pending,
746             Poll::Ready(Err(e)) => {
747                 self.shutdown_fut = None;
748                 Poll::Ready(Err(e.into()))
749             }
750             Poll::Ready(Ok(_)) => {
751                 self.shutdown_fut = None;
752                 Poll::Ready(Ok(()))
753             }
754         }
755     }
756 }
757 
758 impl Clone for PollStream {
759     fn clone(&self) -> PollStream {
760         PollStream::new(self.clone_inner())
761     }
762 }
763 
764 impl fmt::Debug for PollStream {
765     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
766         f.debug_struct("PollStream")
767             .field("stream", &self.stream)
768             .field("read_buf_cap", &self.read_buf_cap)
769             .finish()
770     }
771 }
772 
773 impl AsRef<Stream> for PollStream {
774     fn as_ref(&self) -> &Stream {
775         &self.stream
776     }
777 }
778