s2n_quic_dc/stream/socket/
handle.rs1use super::{Protocol, TransportFeatures};
5use crate::msg::{self, addr::Addr, cmsg};
6use core::task::{Context, Poll};
7use s2n_quic_core::inet::ExplicitCongestionNotification;
8use std::{
9 io::{self, IoSlice, IoSliceMut},
10 net::SocketAddr,
11 sync::Arc,
12};
13
14pub type Flags = libc::c_int;
15
16pub trait Socket: 'static + Send + Sync {
17 fn local_addr(&self) -> io::Result<SocketAddr>;
19
20 #[inline]
22 fn local_port(&self) -> io::Result<u16> {
23 Ok(self.local_addr()?.port())
24 }
25
26 fn protocol(&self) -> Protocol;
27
28 fn features(&self) -> TransportFeatures;
30
31 fn poll_peek_len(&self, cx: &mut Context) -> Poll<io::Result<usize>>;
33
34 #[inline]
35 fn poll_recv_buffer(
36 &self,
37 cx: &mut Context,
38 msg: &mut msg::recv::Message,
39 ) -> Poll<io::Result<usize>> {
40 #[cfg(debug_assertions)]
41 if !self.features().is_stream() {
42 assert!(
43 msg.is_empty(),
44 "receive buffer should be empty for datagram protocols"
45 );
46 }
47
48 msg.poll_recv_with(|addr, cmsg, buffer| self.poll_recv(cx, addr, cmsg, buffer))
49 }
50
51 fn poll_recv(
53 &self,
54 cx: &mut Context,
55 addr: &mut Addr,
56 cmsg: &mut cmsg::Receiver,
57 buffer: &mut [IoSliceMut],
58 ) -> Poll<io::Result<usize>>;
59
60 #[inline]
61 fn try_send_buffer(&self, msg: &mut msg::send::Message) -> io::Result<usize> {
62 msg.send_with(|addr, ecn, iov| self.try_send(addr, ecn, iov))
63 }
64
65 fn try_send(
67 &self,
68 addr: &Addr,
69 ecn: ExplicitCongestionNotification,
70 buffer: &[IoSlice],
71 ) -> io::Result<usize>;
72
73 #[inline]
74 fn poll_send_buffer(
75 &self,
76 cx: &mut Context,
77 msg: &mut msg::send::Message,
78 ) -> Poll<io::Result<usize>> {
79 msg.poll_send_with(|addr, ecn, iov| self.poll_send(cx, addr, ecn, iov))
80 }
81
82 fn poll_send(
84 &self,
85 cx: &mut Context,
86 addr: &Addr,
87 ecn: ExplicitCongestionNotification,
88 buffer: &[IoSlice],
89 ) -> Poll<io::Result<usize>>;
90
91 fn send_finish(&self) -> io::Result<()>;
93}
94
95pub trait Ext: Socket {
96 #[inline]
97 fn recv_buffer<'a>(&'a self, msg: &'a mut msg::recv::Message) -> ExtRecvBuffer<'a, Self> {
98 ExtRecvBuffer { socket: self, msg }
99 }
100}
101
102pub struct ExtRecvBuffer<'a, T: Socket + ?Sized> {
103 socket: &'a T,
104 msg: &'a mut msg::recv::Message,
105}
106
107impl<T: Socket> core::future::Future for ExtRecvBuffer<'_, T> {
108 type Output = io::Result<usize>;
109
110 fn poll(mut self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
111 self.socket.poll_recv_buffer(cx, self.msg)
112 }
113}
114
115impl<T: Socket> Ext for T {}
116
117macro_rules! impl_box {
118 ($b:ident) => {
119 impl<T: Socket> Socket for $b<T> {
120 #[inline(always)]
121 fn local_addr(&self) -> io::Result<SocketAddr> {
122 (**self).local_addr()
123 }
124
125 #[inline(always)]
126 fn protocol(&self) -> Protocol {
127 (**self).protocol()
128 }
129
130 #[inline(always)]
131 fn features(&self) -> TransportFeatures {
132 (**self).features()
133 }
134
135 #[inline(always)]
136 fn poll_peek_len(&self, cx: &mut Context) -> Poll<io::Result<usize>> {
137 (**self).poll_peek_len(cx)
138 }
139
140 #[inline(always)]
141 fn poll_recv(
142 &self,
143 cx: &mut Context,
144 addr: &mut Addr,
145 cmsg: &mut cmsg::Receiver,
146 buffer: &mut [IoSliceMut],
147 ) -> Poll<io::Result<usize>> {
148 (**self).poll_recv(cx, addr, cmsg, buffer)
149 }
150
151 #[inline(always)]
152 fn try_send(
153 &self,
154 addr: &Addr,
155 ecn: ExplicitCongestionNotification,
156 buffer: &[IoSlice],
157 ) -> io::Result<usize> {
158 (**self).try_send(addr, ecn, buffer)
159 }
160
161 #[inline(always)]
162 fn poll_send(
163 &self,
164 cx: &mut Context,
165 addr: &Addr,
166 ecn: ExplicitCongestionNotification,
167 buffer: &[IoSlice],
168 ) -> Poll<io::Result<usize>> {
169 (**self).poll_send(cx, addr, ecn, buffer)
170 }
171
172 #[inline(always)]
173 fn send_finish(&self) -> io::Result<()> {
174 (**self).send_finish()
175 }
176 }
177 };
178}
179
180impl_box!(Box);
181impl_box!(Arc);