1use async_trait::async_trait;
18use futures::FutureExt;
19use log::{debug, error};
20
21use pingora_error::{ErrorType::*, OrErr, Result};
22#[cfg(target_os = "linux")]
23use std::io::IoSliceMut;
24#[cfg(unix)]
25use std::os::unix::io::AsRawFd;
26#[cfg(windows)]
27use std::os::windows::io::AsRawSocket;
28use std::pin::Pin;
29use std::sync::Arc;
30use std::task::{Context, Poll};
31use std::time::{Duration, Instant, SystemTime};
32#[cfg(target_os = "linux")]
33use tokio::io::Interest;
34use tokio::io::{self, AsyncRead, AsyncWrite, AsyncWriteExt, BufReader, BufWriter, ReadBuf};
35use tokio::net::TcpStream;
36#[cfg(unix)]
37use tokio::net::UnixStream;
38
39use crate::protocols::l4::ext::{set_tcp_keepalive, TcpKeepalive};
40use crate::protocols::l4::virt;
41use crate::protocols::raw_connect::ProxyDigest;
42use crate::protocols::{
43 GetProxyDigest, GetSocketDigest, GetTimingDigest, Peek, Shutdown, SocketDigest, Ssl,
44 TimingDigest, UniqueID, UniqueIDType,
45};
46use crate::upstreams::peer::Tracer;
47
48#[derive(Debug)]
49enum RawStream {
50 Tcp(TcpStream),
51 #[cfg(unix)]
52 Unix(UnixStream),
53 Virtual(virt::VirtualSocketStream),
54}
55
56impl AsyncRead for RawStream {
57 fn poll_read(
58 self: Pin<&mut Self>,
59 cx: &mut Context<'_>,
60 buf: &mut ReadBuf<'_>,
61 ) -> Poll<io::Result<()>> {
62 unsafe {
64 match &mut Pin::get_unchecked_mut(self) {
65 RawStream::Tcp(s) => Pin::new_unchecked(s).poll_read(cx, buf),
66 #[cfg(unix)]
67 RawStream::Unix(s) => Pin::new_unchecked(s).poll_read(cx, buf),
68 RawStream::Virtual(s) => Pin::new_unchecked(s).poll_read(cx, buf),
69 }
70 }
71 }
72}
73
74impl AsyncWrite for RawStream {
75 fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<io::Result<usize>> {
76 unsafe {
78 match &mut Pin::get_unchecked_mut(self) {
79 RawStream::Tcp(s) => Pin::new_unchecked(s).poll_write(cx, buf),
80 #[cfg(unix)]
81 RawStream::Unix(s) => Pin::new_unchecked(s).poll_write(cx, buf),
82 RawStream::Virtual(s) => Pin::new_unchecked(s).poll_write(cx, buf),
83 }
84 }
85 }
86
87 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
88 unsafe {
90 match &mut Pin::get_unchecked_mut(self) {
91 RawStream::Tcp(s) => Pin::new_unchecked(s).poll_flush(cx),
92 #[cfg(unix)]
93 RawStream::Unix(s) => Pin::new_unchecked(s).poll_flush(cx),
94 RawStream::Virtual(s) => Pin::new_unchecked(s).poll_flush(cx),
95 }
96 }
97 }
98
99 fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
100 unsafe {
102 match &mut Pin::get_unchecked_mut(self) {
103 RawStream::Tcp(s) => Pin::new_unchecked(s).poll_shutdown(cx),
104 #[cfg(unix)]
105 RawStream::Unix(s) => Pin::new_unchecked(s).poll_shutdown(cx),
106 RawStream::Virtual(s) => Pin::new_unchecked(s).poll_shutdown(cx),
107 }
108 }
109 }
110
111 fn poll_write_vectored(
112 self: Pin<&mut Self>,
113 cx: &mut Context<'_>,
114 bufs: &[std::io::IoSlice<'_>],
115 ) -> Poll<io::Result<usize>> {
116 unsafe {
118 match &mut Pin::get_unchecked_mut(self) {
119 RawStream::Tcp(s) => Pin::new_unchecked(s).poll_write_vectored(cx, bufs),
120 #[cfg(unix)]
121 RawStream::Unix(s) => Pin::new_unchecked(s).poll_write_vectored(cx, bufs),
122 RawStream::Virtual(s) => Pin::new_unchecked(s).poll_write_vectored(cx, bufs),
123 }
124 }
125 }
126
127 fn is_write_vectored(&self) -> bool {
128 match self {
129 RawStream::Tcp(s) => s.is_write_vectored(),
130 #[cfg(unix)]
131 RawStream::Unix(s) => s.is_write_vectored(),
132 RawStream::Virtual(s) => s.is_write_vectored(),
133 }
134 }
135}
136
137#[cfg(unix)]
138impl AsRawFd for RawStream {
139 fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
140 match self {
141 RawStream::Tcp(s) => s.as_raw_fd(),
142 RawStream::Unix(s) => s.as_raw_fd(),
143 RawStream::Virtual(_) => -1, }
145 }
146}
147
148#[cfg(windows)]
149impl AsRawSocket for RawStream {
150 fn as_raw_socket(&self) -> std::os::windows::io::RawSocket {
151 match self {
152 RawStream::Tcp(s) => s.as_raw_socket(),
153 RawStream::Virtual(_) => !0,
155 }
156 }
157}
158
159#[derive(Debug)]
160struct RawStreamWrapper {
161 pub(crate) stream: RawStream,
162 pub(crate) rx_ts: Option<SystemTime>,
164 #[cfg(target_os = "linux")]
166 pub(crate) enable_rx_ts: bool,
167 #[cfg(target_os = "linux")]
168 reusable_cmsg_space: Vec<u8>,
172}
173
174impl RawStreamWrapper {
175 pub fn new(stream: RawStream) -> Self {
176 RawStreamWrapper {
177 stream,
178 rx_ts: None,
179 #[cfg(target_os = "linux")]
180 enable_rx_ts: false,
181 #[cfg(target_os = "linux")]
182 reusable_cmsg_space: nix::cmsg_space!(nix::sys::socket::Timestamps),
183 }
184 }
185
186 #[cfg(target_os = "linux")]
187 pub fn enable_rx_ts(&mut self, enable_rx_ts: bool) {
188 self.enable_rx_ts = enable_rx_ts;
189 }
190}
191
192impl AsyncRead for RawStreamWrapper {
193 #[cfg(not(target_os = "linux"))]
194 fn poll_read(
195 self: Pin<&mut Self>,
196 cx: &mut Context<'_>,
197 buf: &mut ReadBuf<'_>,
198 ) -> Poll<io::Result<()>> {
199 unsafe {
201 let rs_wrapper = Pin::get_unchecked_mut(self);
202 match &mut rs_wrapper.stream {
203 RawStream::Tcp(s) => Pin::new_unchecked(s).poll_read(cx, buf),
204 #[cfg(unix)]
205 RawStream::Unix(s) => Pin::new_unchecked(s).poll_read(cx, buf),
206 RawStream::Virtual(s) => Pin::new_unchecked(s).poll_read(cx, buf),
207 }
208 }
209 }
210
211 #[cfg(target_os = "linux")]
212 fn poll_read(
213 self: Pin<&mut Self>,
214 cx: &mut Context<'_>,
215 buf: &mut ReadBuf<'_>,
216 ) -> Poll<io::Result<()>> {
217 use futures::ready;
218 use nix::sys::socket::{recvmsg, ControlMessageOwned, MsgFlags, SockaddrStorage};
219
220 if !self.enable_rx_ts {
222 unsafe {
224 let rs_wrapper = Pin::get_unchecked_mut(self);
225 match &mut rs_wrapper.stream {
226 RawStream::Tcp(s) => return Pin::new_unchecked(s).poll_read(cx, buf),
227 RawStream::Unix(s) => return Pin::new_unchecked(s).poll_read(cx, buf),
228 RawStream::Virtual(s) => return Pin::new_unchecked(s).poll_read(cx, buf),
229 }
230 }
231 }
232
233 let rs_wrapper = unsafe { Pin::get_unchecked_mut(self) };
235 match &mut rs_wrapper.stream {
236 RawStream::Tcp(s) => {
237 loop {
238 ready!(s.poll_read_ready(cx))?;
239 let b = unsafe {
241 &mut *(buf.unfilled_mut() as *mut [std::mem::MaybeUninit<u8>]
242 as *mut [u8])
243 };
244 let mut iov = [IoSliceMut::new(b)];
245
246 rs_wrapper.reusable_cmsg_space.fill(0);
247
248 match s.try_io(Interest::READABLE, || {
249 recvmsg::<SockaddrStorage>(
250 s.as_raw_fd(),
251 &mut iov,
252 Some(&mut rs_wrapper.reusable_cmsg_space),
253 MsgFlags::empty(),
254 )
255 .map_err(|errno| errno.into())
256 }) {
257 Ok(r) => {
258 if let Some(ControlMessageOwned::ScmTimestampsns(rtime)) = r
259 .cmsgs()?
260 .find(|i| matches!(i, ControlMessageOwned::ScmTimestampsns(_)))
261 {
262 rs_wrapper.rx_ts =
265 SystemTime::UNIX_EPOCH.checked_add(rtime.system.into());
266 }
267 unsafe {
269 buf.assume_init(r.bytes);
270 }
271 buf.advance(r.bytes);
272 return Poll::Ready(Ok(()));
273 }
274 Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
275 Err(e) => return Poll::Ready(Err(e)),
276 }
277 }
278 }
279 RawStream::Unix(s) => unsafe { Pin::new_unchecked(s).poll_read(cx, buf) },
281 RawStream::Virtual(s) => unsafe { Pin::new_unchecked(s).poll_read(cx, buf) },
282 }
283 }
284}
285
286impl AsyncWrite for RawStreamWrapper {
287 fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<io::Result<usize>> {
288 unsafe {
290 match &mut Pin::get_unchecked_mut(self).stream {
291 RawStream::Tcp(s) => Pin::new_unchecked(s).poll_write(cx, buf),
292 #[cfg(unix)]
293 RawStream::Unix(s) => Pin::new_unchecked(s).poll_write(cx, buf),
294 RawStream::Virtual(s) => Pin::new_unchecked(s).poll_write(cx, buf),
295 }
296 }
297 }
298
299 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
300 unsafe {
302 match &mut Pin::get_unchecked_mut(self).stream {
303 RawStream::Tcp(s) => Pin::new_unchecked(s).poll_flush(cx),
304 #[cfg(unix)]
305 RawStream::Unix(s) => Pin::new_unchecked(s).poll_flush(cx),
306 RawStream::Virtual(s) => Pin::new_unchecked(s).poll_flush(cx),
307 }
308 }
309 }
310
311 fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
312 unsafe {
314 match &mut Pin::get_unchecked_mut(self).stream {
315 RawStream::Tcp(s) => Pin::new_unchecked(s).poll_shutdown(cx),
316 #[cfg(unix)]
317 RawStream::Unix(s) => Pin::new_unchecked(s).poll_shutdown(cx),
318 RawStream::Virtual(s) => Pin::new_unchecked(s).poll_shutdown(cx),
319 }
320 }
321 }
322
323 fn poll_write_vectored(
324 self: Pin<&mut Self>,
325 cx: &mut Context<'_>,
326 bufs: &[std::io::IoSlice<'_>],
327 ) -> Poll<io::Result<usize>> {
328 unsafe {
330 match &mut Pin::get_unchecked_mut(self).stream {
331 RawStream::Tcp(s) => Pin::new_unchecked(s).poll_write_vectored(cx, bufs),
332 #[cfg(unix)]
333 RawStream::Unix(s) => Pin::new_unchecked(s).poll_write_vectored(cx, bufs),
334 RawStream::Virtual(s) => Pin::new_unchecked(s).poll_write_vectored(cx, bufs),
335 }
336 }
337 }
338
339 fn is_write_vectored(&self) -> bool {
340 self.stream.is_write_vectored()
341 }
342}
343
344#[cfg(unix)]
345impl AsRawFd for RawStreamWrapper {
346 fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
347 self.stream.as_raw_fd()
348 }
349}
350
351#[cfg(windows)]
352impl AsRawSocket for RawStreamWrapper {
353 fn as_raw_socket(&self) -> std::os::windows::io::RawSocket {
354 self.stream.as_raw_socket()
355 }
356}
357
358pub const DEFAULT_L4_READ_BUFFER_SIZE: usize = 64 * 1024;
364
365pub const DEFAULT_L4_WRITE_BUFFER_SIZE: usize = 1460;
371
372#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
377pub struct L4BufferSettings {
378 pub read: Option<usize>,
380 pub write: Option<usize>,
382}
383
384impl L4BufferSettings {
385 pub fn new(read: usize, write: usize) -> Self {
387 Self {
388 read: Some(read),
389 write: Some(write),
390 }
391 }
392
393 pub fn unbuffered() -> Self {
395 Self::new(0, 0)
396 }
397
398 pub fn read(mut self, read: usize) -> Self {
400 self.read = Some(read);
401 self
402 }
403
404 pub fn write(mut self, write: usize) -> Self {
406 self.write = Some(write);
407 self
408 }
409
410 pub fn read_capacity(&self) -> usize {
412 self.read.unwrap_or(DEFAULT_L4_READ_BUFFER_SIZE)
413 }
414
415 pub fn write_capacity(&self) -> usize {
417 self.write.unwrap_or(DEFAULT_L4_WRITE_BUFFER_SIZE)
418 }
419}
420
421#[derive(Debug)]
429enum BufferedStream {
430 UnbufferedRead(BufWriter<RawStreamWrapper>),
431 BufferedRead(BufReader<BufWriter<RawStreamWrapper>>),
432}
433
434impl BufferedStream {
435 fn with_capacity(read: usize, write: usize, stream: RawStreamWrapper) -> Self {
436 let writer = BufWriter::with_capacity(write, stream);
437 if read == 0 {
438 BufferedStream::UnbufferedRead(writer)
439 } else {
440 BufferedStream::BufferedRead(BufReader::with_capacity(read, writer))
441 }
442 }
443
444 fn writer(&self) -> &BufWriter<RawStreamWrapper> {
445 match self {
446 BufferedStream::UnbufferedRead(writer) => writer,
447 BufferedStream::BufferedRead(reader) => reader.get_ref(),
448 }
449 }
450
451 fn writer_mut(&mut self) -> &mut BufWriter<RawStreamWrapper> {
452 match self {
453 BufferedStream::UnbufferedRead(writer) => writer,
454 BufferedStream::BufferedRead(reader) => reader.get_mut(),
455 }
456 }
457
458 fn get_ref(&self) -> &RawStreamWrapper {
459 self.writer().get_ref()
460 }
461
462 fn get_mut(&mut self) -> &mut RawStreamWrapper {
463 self.writer_mut().get_mut()
464 }
465
466 fn into_inner(self) -> RawStreamWrapper {
468 match self {
469 BufferedStream::UnbufferedRead(writer) => writer.into_inner(),
470 BufferedStream::BufferedRead(reader) => reader.into_inner().into_inner(),
471 }
472 }
473}
474
475impl AsyncRead for BufferedStream {
476 fn poll_read(
477 mut self: Pin<&mut Self>,
478 cx: &mut Context<'_>,
479 buf: &mut ReadBuf<'_>,
480 ) -> Poll<io::Result<()>> {
481 match &mut *self {
482 BufferedStream::UnbufferedRead(writer) => Pin::new(writer).poll_read(cx, buf),
483 BufferedStream::BufferedRead(reader) => Pin::new(reader).poll_read(cx, buf),
484 }
485 }
486}
487
488impl AsyncWrite for BufferedStream {
491 fn poll_write(
492 mut self: Pin<&mut Self>,
493 cx: &mut Context,
494 buf: &[u8],
495 ) -> Poll<io::Result<usize>> {
496 Pin::new(self.writer_mut()).poll_write(cx, buf)
497 }
498
499 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
500 Pin::new(self.writer_mut()).poll_flush(cx)
501 }
502
503 fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
504 Pin::new(self.writer_mut()).poll_shutdown(cx)
505 }
506
507 fn poll_write_vectored(
508 mut self: Pin<&mut Self>,
509 cx: &mut Context<'_>,
510 bufs: &[std::io::IoSlice<'_>],
511 ) -> Poll<io::Result<usize>> {
512 Pin::new(self.writer_mut()).poll_write_vectored(cx, bufs)
513 }
514
515 fn is_write_vectored(&self) -> bool {
516 self.writer().is_write_vectored()
517 }
518}
519
520#[derive(Debug)]
525pub struct Stream {
526 stream: Option<BufferedStream>,
528 rewind_read_buf: Vec<Vec<u8>>,
530 buffer_write: bool,
531 proxy_digest: Option<Arc<ProxyDigest>>,
532 socket_digest: Option<Arc<SocketDigest>>,
533 pub established_ts: SystemTime,
535 establishment_duration: Option<Duration>,
536 offload_wait_duration: Option<Duration>,
537 pub tracer: Option<Tracer>,
539 read_pending_time: AccumulatedDuration,
540 write_pending_time: AccumulatedDuration,
541 pub rx_ts: Option<SystemTime>,
543}
544
545impl Stream {
546 fn stream(&self) -> &BufferedStream {
547 self.stream.as_ref().expect("stream should always be set")
548 }
549
550 fn stream_mut(&mut self) -> &mut BufferedStream {
551 self.stream.as_mut().expect("stream should always be set")
552 }
553
554 pub(crate) fn set_establishment_timing(
556 &mut self,
557 establishment_duration: Duration,
558 offload_wait_duration: Option<Duration>,
559 ) {
560 self.establishment_duration = Some(establishment_duration);
561 self.offload_wait_duration = offload_wait_duration;
562 }
563
564 pub fn set_nodelay(&mut self) -> Result<()> {
566 match &self.stream_mut().get_mut().stream {
567 RawStream::Tcp(s) => {
568 s.set_nodelay(true)
569 .or_err(ConnectError, "failed to set_nodelay")?;
570 }
571 RawStream::Virtual(s) => {
572 s.set_socket_option(virt::VirtualSockOpt::NoDelay)
573 .or_err(ConnectError, "failed to set_nodelay on virtual socket")?;
574 }
575 _ => (),
576 }
577 Ok(())
578 }
579
580 pub fn set_keepalive(&mut self, ka: &TcpKeepalive) -> Result<()> {
582 match &self.stream_mut().get_mut().stream {
583 RawStream::Tcp(s) => {
584 debug!("Setting tcp keepalive");
585 set_tcp_keepalive(s, ka)?;
586 }
587 RawStream::Virtual(s) => {
588 s.set_socket_option(virt::VirtualSockOpt::KeepAlive(ka.clone()))
589 .or_err(ConnectError, "failed to set_keepalive on virtual socket")?;
590 }
591 _ => (),
592 }
593 Ok(())
594 }
595
596 #[cfg(target_os = "linux")]
597 pub fn set_rx_timestamp(&mut self) -> Result<()> {
598 use nix::sys::socket::{setsockopt, sockopt, TimestampingFlag};
599
600 if let RawStream::Tcp(s) = &self.stream_mut().get_mut().stream {
601 let timestamp_options = TimestampingFlag::SOF_TIMESTAMPING_RX_SOFTWARE
602 | TimestampingFlag::SOF_TIMESTAMPING_SOFTWARE;
603 setsockopt(&s, sockopt::Timestamping, ×tamp_options)
604 .or_err(InternalError, "failed to set SOF_TIMESTAMPING_RX_SOFTWARE")?;
605 self.stream_mut().get_mut().enable_rx_ts(true);
606 }
607
608 Ok(())
609 }
610
611 #[cfg(not(target_os = "linux"))]
612 pub fn set_rx_timestamp(&mut self) -> io::Result<()> {
613 Ok(())
614 }
615
616 pub fn rewind(&mut self, data: &[u8]) {
621 if !data.is_empty() {
622 self.rewind_read_buf.push(data.to_vec());
623 }
624 }
625
626 pub(crate) fn set_buffer(&mut self, buffer: L4BufferSettings) {
629 use std::mem;
630 let stream = mem::take(&mut self.stream);
633 let stream = stream.map(|s| {
634 BufferedStream::with_capacity(
635 buffer.read_capacity(),
636 buffer.write_capacity(),
637 s.into_inner(),
638 )
639 });
640 let _ = mem::replace(&mut self.stream, stream);
641 }
642}
643
644impl From<TcpStream> for Stream {
645 fn from(s: TcpStream) -> Self {
646 Stream {
647 stream: Some(BufferedStream::with_capacity(
648 0,
649 0,
650 RawStreamWrapper::new(RawStream::Tcp(s)),
651 )),
652 rewind_read_buf: Vec::new(),
653 buffer_write: true,
654 established_ts: SystemTime::now(),
655 establishment_duration: None,
656 offload_wait_duration: None,
657 proxy_digest: None,
658 socket_digest: None,
659 tracer: None,
660 read_pending_time: AccumulatedDuration::new(),
661 write_pending_time: AccumulatedDuration::new(),
662 rx_ts: None,
663 }
664 }
665}
666
667impl From<virt::VirtualSocketStream> for Stream {
668 fn from(s: virt::VirtualSocketStream) -> Self {
669 Stream {
670 stream: Some(BufferedStream::with_capacity(
671 0,
672 0,
673 RawStreamWrapper::new(RawStream::Virtual(s)),
674 )),
675 rewind_read_buf: Vec::new(),
676 buffer_write: true,
677 established_ts: SystemTime::now(),
678 establishment_duration: None,
679 offload_wait_duration: None,
680 proxy_digest: None,
681 socket_digest: None,
682 tracer: None,
683 read_pending_time: AccumulatedDuration::new(),
684 write_pending_time: AccumulatedDuration::new(),
685 rx_ts: None,
686 }
687 }
688}
689
690#[cfg(unix)]
691impl From<UnixStream> for Stream {
692 fn from(s: UnixStream) -> Self {
693 Stream {
694 stream: Some(BufferedStream::with_capacity(
695 0,
696 0,
697 RawStreamWrapper::new(RawStream::Unix(s)),
698 )),
699 rewind_read_buf: Vec::new(),
700 buffer_write: true,
701 established_ts: SystemTime::now(),
702 establishment_duration: None,
703 offload_wait_duration: None,
704 proxy_digest: None,
705 socket_digest: None,
706 tracer: None,
707 read_pending_time: AccumulatedDuration::new(),
708 write_pending_time: AccumulatedDuration::new(),
709 rx_ts: None,
710 }
711 }
712}
713
714#[cfg(unix)]
715impl AsRawFd for Stream {
716 fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
717 self.stream().get_ref().as_raw_fd()
718 }
719}
720
721#[cfg(windows)]
722impl AsRawSocket for Stream {
723 fn as_raw_socket(&self) -> std::os::windows::io::RawSocket {
724 self.stream().get_ref().as_raw_socket()
725 }
726}
727
728#[cfg(unix)]
729impl UniqueID for Stream {
730 fn id(&self) -> UniqueIDType {
731 self.as_raw_fd()
732 }
733}
734
735#[cfg(windows)]
736impl UniqueID for Stream {
737 fn id(&self) -> usize {
738 self.as_raw_socket() as usize
739 }
740}
741
742impl Ssl for Stream {}
743
744#[async_trait]
745impl Peek for Stream {
746 async fn try_peek(&mut self, buf: &mut [u8]) -> std::io::Result<bool> {
747 use tokio::io::AsyncReadExt;
748 self.read_exact(buf).await?;
749 self.rewind(buf);
751 Ok(true)
752 }
753}
754
755#[async_trait]
756impl Shutdown for Stream {
757 async fn shutdown(&mut self) {
758 AsyncWriteExt::shutdown(self).await.unwrap_or_else(|e| {
759 debug!("Failed to shutdown connection: {:?}", e);
760 });
761 }
762}
763
764impl GetTimingDigest for Stream {
765 fn get_timing_digest(&self) -> Vec<Option<TimingDigest>> {
766 let mut digest = Vec::with_capacity(2); digest.push(Some(TimingDigest {
768 established_ts: self.established_ts,
769 establishment_duration: self.establishment_duration,
770 offload_wait_duration: self.offload_wait_duration,
771 }));
772 digest
773 }
774
775 fn get_read_pending_time(&self) -> Duration {
776 self.read_pending_time.total
777 }
778
779 fn get_write_pending_time(&self) -> Duration {
780 self.write_pending_time.total
781 }
782}
783
784impl GetProxyDigest for Stream {
785 fn get_proxy_digest(&self) -> Option<Arc<ProxyDigest>> {
786 self.proxy_digest.clone()
787 }
788
789 fn set_proxy_digest(&mut self, digest: ProxyDigest) {
790 self.proxy_digest = Some(Arc::new(digest));
791 }
792}
793
794impl GetSocketDigest for Stream {
795 fn get_socket_digest(&self) -> Option<Arc<SocketDigest>> {
796 self.socket_digest.clone()
797 }
798
799 fn set_socket_digest(&mut self, socket_digest: SocketDigest) {
800 self.socket_digest = Some(Arc::new(socket_digest))
801 }
802}
803
804impl Drop for Stream {
805 fn drop(&mut self) {
806 if let Some(t) = self.tracer.as_ref() {
807 t.0.on_disconnected();
808 }
809 let ret = match &self.stream().get_ref().stream {
811 RawStream::Tcp(s) => s.nodelay().err(),
812 #[cfg(unix)]
813 RawStream::Unix(s) => s.local_addr().err(),
814 RawStream::Virtual(_) => {
815 None
817 }
818 };
819 if let Some(e) = ret {
820 match e.kind() {
821 tokio::io::ErrorKind::Other => {
822 if let Some(ecode) = e.raw_os_error() {
823 if ecode == 9 {
824 error!("Crit: socket {:?} is being double closed", self.stream);
826 }
827 }
828 }
829 _ => {
830 debug!("Socket is already broken {:?}", e);
831 }
832 }
833 } else {
834 let _ = self.flush().now_or_never();
838 }
839 debug!("Dropping socket {:?}", self.stream);
840 }
841}
842
843impl AsyncRead for Stream {
844 fn poll_read(
845 mut self: Pin<&mut Self>,
846 cx: &mut Context<'_>,
847 buf: &mut ReadBuf<'_>,
848 ) -> Poll<io::Result<()>> {
849 let result = if !self.rewind_read_buf.is_empty() {
850 let data_to_read = self.rewind_read_buf.pop().unwrap(); let mut data_to_read = data_to_read.as_slice();
852 let result = Pin::new(&mut data_to_read).poll_read(cx, buf);
853 if !data_to_read.is_empty() {
855 let remaining_buf = Vec::from(data_to_read);
856 self.rewind_read_buf.push(remaining_buf);
857 }
858 result
859 } else {
860 Pin::new(&mut self.stream_mut()).poll_read(cx, buf)
861 };
862 self.read_pending_time.poll_time(&result);
863 self.rx_ts = self.stream().get_ref().rx_ts;
864 result
865 }
866}
867
868impl AsyncWrite for Stream {
869 fn poll_write(
870 mut self: Pin<&mut Self>,
871 cx: &mut Context,
872 buf: &[u8],
873 ) -> Poll<io::Result<usize>> {
874 let result = if self.buffer_write {
875 Pin::new(&mut self.stream_mut()).poll_write(cx, buf)
876 } else {
877 Pin::new(&mut self.stream_mut().get_mut()).poll_write(cx, buf)
878 };
879 self.write_pending_time.poll_write_time(&result, buf.len());
880 result
881 }
882
883 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
884 let result = Pin::new(&mut self.stream_mut()).poll_flush(cx);
885 self.write_pending_time.poll_time(&result);
886 result
887 }
888
889 fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
890 Pin::new(&mut self.stream_mut()).poll_shutdown(cx)
891 }
892
893 fn poll_write_vectored(
894 mut self: Pin<&mut Self>,
895 cx: &mut Context<'_>,
896 bufs: &[std::io::IoSlice<'_>],
897 ) -> Poll<io::Result<usize>> {
898 let total_size = bufs.iter().fold(0, |acc, s| acc + s.len());
899
900 let result = if self.buffer_write {
901 Pin::new(&mut self.stream_mut()).poll_write_vectored(cx, bufs)
902 } else {
903 Pin::new(&mut self.stream_mut().get_mut()).poll_write_vectored(cx, bufs)
904 };
905
906 self.write_pending_time.poll_write_time(&result, total_size);
907 result
908 }
909
910 fn is_write_vectored(&self) -> bool {
911 if self.buffer_write {
912 self.stream().is_write_vectored() } else {
914 self.stream().get_ref().is_write_vectored()
915 }
916 }
917}
918
919#[derive(Debug)]
920struct AccumulatedDuration {
921 total: Duration,
922 last_start: Option<Instant>,
923}
924
925impl AccumulatedDuration {
926 fn new() -> Self {
927 AccumulatedDuration {
928 total: Duration::ZERO,
929 last_start: None,
930 }
931 }
932
933 fn start(&mut self) {
934 if self.last_start.is_none() {
935 self.last_start = Some(Instant::now());
936 }
937 }
938
939 fn stop(&mut self) {
940 if let Some(start) = self.last_start.take() {
941 self.total += start.elapsed();
942 }
943 }
944
945 fn poll_write_time(&mut self, result: &Poll<io::Result<usize>>, buf_size: usize) {
946 match result {
947 Poll::Ready(Ok(n)) => {
948 if *n == buf_size {
949 self.stop();
950 } else {
951 self.start();
953 }
954 }
955 Poll::Ready(Err(_)) => {
956 self.stop();
957 }
958 _ => self.start(),
959 }
960 }
961
962 fn poll_time(&mut self, result: &Poll<io::Result<()>>) {
963 match result {
964 Poll::Ready(_) => {
965 self.stop();
966 }
967 _ => self.start(),
968 }
969 }
970}
971
972#[cfg(test)]
973#[cfg(target_os = "linux")]
974mod tests {
975 use super::*;
976 use std::sync::Arc;
977 use tokio::io::AsyncReadExt;
978 use tokio::io::AsyncWriteExt;
979 use tokio::net::TcpListener;
980 use tokio::sync::Notify;
981
982 #[cfg(target_os = "linux")]
983 #[tokio::test]
984 async fn test_rx_timestamp() {
985 let message = "hello world".as_bytes();
986 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
987 let addr = listener.local_addr().unwrap();
988 let notify = Arc::new(Notify::new());
989 let notify2 = notify.clone();
990
991 tokio::spawn(async move {
992 let (mut stream, _) = listener.accept().await.unwrap();
993 notify2.notified().await;
994 stream.write_all(message).await.unwrap();
995 });
996
997 let mut stream: Stream = TcpStream::connect(addr).await.unwrap().into();
998 stream.set_rx_timestamp().unwrap();
999 std::thread::sleep(Duration::from_micros(100));
1003 notify.notify_one();
1004
1005 let mut buffer = vec![0u8; message.len()];
1006 let n = stream.read(buffer.as_mut_slice()).await.unwrap();
1007 assert_eq!(n, message.len());
1008 assert!(stream.rx_ts.is_some());
1009 }
1010
1011 #[cfg(target_os = "linux")]
1012 #[tokio::test]
1013 async fn test_rx_timestamp_standard_path() {
1014 let message = "hello world".as_bytes();
1015 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
1016 let addr = listener.local_addr().unwrap();
1017 let notify = Arc::new(Notify::new());
1018 let notify2 = notify.clone();
1019
1020 tokio::spawn(async move {
1021 let (mut stream, _) = listener.accept().await.unwrap();
1022 notify2.notified().await;
1023 stream.write_all(message).await.unwrap();
1024 });
1025
1026 let mut stream: Stream = TcpStream::connect(addr).await.unwrap().into();
1027 std::thread::sleep(Duration::from_micros(100));
1028 notify.notify_one();
1029
1030 let mut buffer = vec![0u8; message.len()];
1031 let n = stream.read(buffer.as_mut_slice()).await.unwrap();
1032 assert_eq!(n, message.len());
1033 assert!(stream.rx_ts.is_none());
1034 }
1035
1036 #[tokio::test]
1037 async fn test_stream_rewind() {
1038 let message = b"hello world";
1039 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
1040 let addr = listener.local_addr().unwrap();
1041 let notify = Arc::new(Notify::new());
1042 let notify2 = notify.clone();
1043
1044 tokio::spawn(async move {
1045 let (mut stream, _) = listener.accept().await.unwrap();
1046 notify2.notified().await;
1047 stream.write_all(message).await.unwrap();
1048 });
1049
1050 let mut stream: Stream = TcpStream::connect(addr).await.unwrap().into();
1051
1052 let rewind_test = b"this is Sparta!";
1053 stream.rewind(rewind_test);
1054
1055 let mut buffer = vec![0u8; message.len()];
1057 let n = stream.read(buffer.as_mut_slice()).await.unwrap();
1058 assert_eq!(n, message.len());
1059 assert_eq!(buffer, rewind_test[..message.len()]);
1060
1061 let n = stream.read(buffer.as_mut_slice()).await.unwrap();
1063 assert_eq!(n, rewind_test.len() - message.len());
1064 assert_eq!(buffer[..n], rewind_test[message.len()..]);
1065
1066 notify.notify_one();
1068 let n = stream.read(buffer.as_mut_slice()).await.unwrap();
1069 assert_eq!(n, message.len());
1070 assert_eq!(buffer, message);
1071 }
1072
1073 #[tokio::test]
1074 async fn test_stream_peek() {
1075 let message = b"hello world";
1076 dbg!("try peek");
1077 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
1078 let addr = listener.local_addr().unwrap();
1079 let notify = Arc::new(Notify::new());
1080 let notify2 = notify.clone();
1081
1082 tokio::spawn(async move {
1083 let (mut stream, _) = listener.accept().await.unwrap();
1084 notify2.notified().await;
1085 stream.write_all(message).await.unwrap();
1086 drop(stream);
1087 });
1088
1089 notify.notify_one();
1090
1091 let mut stream: Stream = TcpStream::connect(addr).await.unwrap().into();
1092 let mut buffer = vec![0u8; 5];
1093 assert!(stream.try_peek(&mut buffer).await.unwrap());
1094 assert_eq!(buffer, message[0..5]);
1095 let mut buffer = vec![];
1096 stream.read_to_end(&mut buffer).await.unwrap();
1097 assert_eq!(buffer, message);
1098 }
1099
1100 #[tokio::test]
1101 async fn test_stream_two_subsequent_peek_calls_before_read() {
1102 let message = b"abcdefghijklmn";
1103
1104 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
1105 let addr = listener.local_addr().unwrap();
1106 let notify = Arc::new(Notify::new());
1107 let notify2 = notify.clone();
1108
1109 tokio::spawn(async move {
1110 let (mut stream, _) = listener.accept().await.unwrap();
1111 notify2.notified().await;
1112 stream.write_all(message).await.unwrap();
1113 drop(stream);
1114 });
1115
1116 notify.notify_one();
1117
1118 let mut stream: Stream = TcpStream::connect(addr).await.unwrap().into();
1119
1120 let mut buffer = vec![0u8; 4];
1122 assert!(stream.try_peek(&mut buffer).await.unwrap());
1123 assert_eq!(buffer, message[0..4]);
1124
1125 let mut buffer = vec![0u8; 2];
1127 assert!(stream.try_peek(&mut buffer).await.unwrap());
1128 assert_eq!(buffer, message[0..2]);
1129
1130 let mut buffer = vec![0u8; 1];
1132 stream.read_exact(&mut buffer).await.unwrap();
1133 assert_eq!(buffer, message[0..1]);
1134
1135 let mut buffer = vec![0u8; 100];
1138 let n = stream.read(&mut buffer).await.unwrap();
1139 assert_eq!(n, 1);
1140 assert_eq!(buffer[..n], message[1..2]);
1141
1142 let mut buffer = vec![];
1144 stream.read_to_end(&mut buffer).await.unwrap();
1145 assert_eq!(buffer, message[2..]);
1146 }
1147}