1use crate::MAX_READ_SIZE_ALLOC;
2use crate::p2::bindings::sockets::network::ErrorCode;
3use crate::p2::{
4 DynInputStream, DynOutputStream, InputStream, OutputStream, Pollable, SocketResult, StreamError,
5};
6use crate::runtime::poll_now;
7use crate::sockets::{
8 MaybeSpawned, TcpListenStream, TcpReceiveStream, TcpSendStream, TcpSocket as P3Socket,
9};
10use std::future::poll_fn;
11use std::mem;
12use std::net::Shutdown;
13use std::sync::Arc;
14use std::sync::Mutex;
15use std::task::{Poll, ready};
16use wasmtime::Result;
17use wasmtime_wasi_io::streams::StreamResult;
18
19pub struct TcpSocket {
21 pub(crate) inner: P3Socket,
22 pub(crate) in_progress_operation: Option<AsyncOperation>,
23 pub(crate) listener: Option<TcpListenStream>,
24 reader: Option<TcpReader>,
25 writer: Option<TcpWriter>,
26}
27
28#[derive(Clone, Copy, Debug, PartialEq, Eq)]
29pub(crate) enum AsyncOperation {
30 Bind,
31 Connect,
32 Listen,
33}
34
35impl TcpSocket {
36 pub(crate) fn new(inner: P3Socket) -> Self {
37 Self {
38 inner,
39 in_progress_operation: None,
40 listener: None,
41 reader: None,
42 writer: None,
43 }
44 }
45 pub(crate) fn take_streams(&mut self) -> SocketResult<(DynInputStream, DynOutputStream)> {
46 let reader = TcpReader::new(self.inner.take_receive_stream()?);
47 let writer = TcpWriter::new(self.inner.take_send_stream()?);
48 self.reader = Some(reader.clone());
49 self.writer = Some(writer.clone());
50 let input: DynInputStream = Box::new(reader);
51 let output: DynOutputStream = Box::new(writer);
52 Ok((input, output))
53 }
54 pub(crate) fn shutdown(&mut self, how: Shutdown) -> SocketResult<()> {
55 let reader = self.reader.as_mut().ok_or(ErrorCode::InvalidState)?;
56 let writer = self.writer.as_mut().ok_or(ErrorCode::InvalidState)?;
57
58 if let Shutdown::Both | Shutdown::Read = how {
59 reader.0.lock().unwrap().shutdown();
60 }
61
62 if let Shutdown::Both | Shutdown::Write = how {
63 writer.0.lock().unwrap().shutdown();
64 }
65
66 Ok(())
67 }
68}
69
70enum ReadState {
71 Open(TcpReceiveStream),
72 Closed,
73}
74impl ReadState {
75 fn read(&mut self, size: usize) -> StreamResult<bytes::Bytes> {
76 let Self::Open(stream) = self else {
77 return Err(StreamError::Closed);
78 };
79 if size == 0 {
80 return Ok(bytes::Bytes::new());
81 }
82 let mut buf = bytes::BytesMut::zeroed(size.min(crate::MAX_READ_SIZE_ALLOC));
83 let n = match poll_now(|cx| stream.poll_read(cx, &mut buf)) {
84 None => 0,
85 Some(Ok(0)) => {
86 *self = ReadState::Closed;
87 return Err(StreamError::Closed);
88 }
89 Some(Ok(n)) => n,
90 Some(Err(e)) => {
91 *self = ReadState::Closed;
92 return Err(StreamError::LastOperationFailed(e.into()));
93 }
94 };
95
96 buf.truncate(n);
97 Ok(buf.freeze())
98 }
99
100 fn shutdown(&mut self) {
101 *self = ReadState::Closed;
102 }
103
104 fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> Poll<()> {
105 match self {
106 Self::Open(stream) => stream.poll_ready(cx),
107 Self::Closed => Poll::Ready(()),
108 }
109 }
110}
111
112#[derive(Clone)]
113struct TcpReader(Arc<Mutex<ReadState>>);
114impl TcpReader {
115 fn new(stream: TcpReceiveStream) -> Self {
116 Self(Arc::new(Mutex::new(ReadState::Open(stream))))
117 }
118}
119
120#[async_trait::async_trait]
121impl InputStream for TcpReader {
122 fn read(&mut self, size: usize) -> StreamResult<bytes::Bytes> {
123 self.0.lock().unwrap().read(size)
124 }
125}
126
127#[async_trait::async_trait]
128impl Pollable for TcpReader {
129 async fn ready(&mut self) {
130 std::future::poll_fn(|cx| self.0.lock().unwrap().poll_ready(cx)).await
131 }
132}
133
134#[derive(Debug, Clone)]
136enum WriteError {
137 Closed,
138 LastOperationFailed(ErrorCode),
139}
140impl From<WriteError> for StreamError {
141 fn from(err: WriteError) -> Self {
142 match err {
143 WriteError::Closed => StreamError::Closed,
144 WriteError::LastOperationFailed(e) => StreamError::LastOperationFailed(e.into()),
145 }
146 }
147}
148
149enum WriteState {
150 Ready(TcpSendStream, usize),
151 Writing(MaybeSpawned<Result<TcpSendStream, WriteError>>),
152 Closing(MaybeSpawned<Result<(), WriteError>>),
153 Closed(WriteError),
154}
155
156impl WriteState {
157 fn take(&mut self) -> WriteState {
158 mem::replace(self, WriteState::Closed(WriteError::Closed))
159 }
160
161 fn check_write(&mut self) -> StreamResult<usize> {
162 match poll_now(|cx| self.poll_ready(cx)) {
163 None => Ok(0),
164 Some(Ok((_, permit))) => {
165 *permit = MAX_READ_SIZE_ALLOC;
166 Ok(*permit)
167 }
168 Some(Err(e)) => Err(e),
169 }
170 }
171
172 fn write(&mut self, mut bytes: bytes::Bytes) -> StreamResult<()> {
173 let mut stream = match self {
174 WriteState::Ready(_, permit) if bytes.len() <= *permit => {
175 if bytes.is_empty() {
176 return Ok(());
177 }
178
179 let WriteState::Ready(stream, _) = self.take() else {
180 unreachable!()
181 };
182 stream
183 }
184 WriteState::Closed(e) => {
185 return Err(e.clone().into());
186 }
187 _ => {
188 return Err(StreamError::Trap(wasmtime::format_err!(
189 "not permitted to write {} bytes",
190 bytes.len()
191 )));
192 }
193 };
194
195 *self = WriteState::Writing(MaybeSpawned::poll_or_spawn(async move {
196 while !bytes.is_empty() {
197 match stream.write(&bytes).await {
198 Ok(n) => {
199 let _ = bytes.split_to(n);
200 }
201 Err(crate::sockets::ErrorCode::ConnectionBroken) => {
202 return Err(WriteError::Closed);
203 }
204 Err(e) => {
205 return Err(WriteError::LastOperationFailed(e.into()));
206 }
207 }
208 }
209
210 Ok(stream)
211 }));
212
213 match poll_now(|cx| self.poll_ready(cx)) {
215 None | Some(Ok(_)) => Ok(()),
216 Some(Err(e)) => Err(e),
217 }
218 }
219
220 fn flush(&mut self) -> StreamResult<()> {
221 match self {
225 WriteState::Ready(..) | WriteState::Writing(_) | WriteState::Closing(_) => Ok(()),
226 WriteState::Closed(e) => Err(e.clone().into()),
227 }
228 }
229
230 pub(crate) fn shutdown(&mut self) {
231 *self = match self.take() {
232 WriteState::Ready(..) => WriteState::Closed(WriteError::Closed),
234
235 WriteState::Writing(write) => {
237 WriteState::Closing(MaybeSpawned::poll_or_spawn(async move {
238 _ = write.into_future().await?;
239 Ok(())
240 }))
241 }
242
243 s => s,
244 };
245 }
246
247 fn poll_ready(
248 &mut self,
249 cx: &mut std::task::Context<'_>,
250 ) -> Poll<StreamResult<(&mut TcpSendStream, &mut usize)>> {
251 match self {
252 WriteState::Writing(write) => {
253 ready!(write.poll_ready(cx));
254 let WriteState::Writing(write) = self.take() else {
255 unreachable!()
256 };
257 *self = match write.unwrap_ready() {
258 Ok(stream) => WriteState::Ready(stream, 0),
259 Err(err) => WriteState::Closed(err),
260 };
261 }
262 WriteState::Closing(close) => {
263 ready!(close.poll_ready(cx));
264 let WriteState::Closing(close) = self.take() else {
265 unreachable!()
266 };
267 *self = match close.unwrap_ready() {
268 Ok(()) => WriteState::Closed(WriteError::Closed),
269 Err(err) => WriteState::Closed(err),
270 };
271 }
272 _ => {}
273 }
274
275 match self {
276 WriteState::Ready(stream, permit) => match stream.poll_ready(cx) {
277 Poll::Ready(()) => Poll::Ready(Ok((stream, permit))),
278 Poll::Pending => Poll::Pending,
279 },
280 WriteState::Writing(..) | WriteState::Closing(..) => Poll::Pending,
281 WriteState::Closed(e) => Poll::Ready(Err(e.clone().into())),
282 }
283 }
284}
285
286#[derive(Clone)]
287struct TcpWriter(Arc<Mutex<WriteState>>);
288impl TcpWriter {
289 fn new(stream: TcpSendStream) -> Self {
290 Self(Arc::new(Mutex::new(WriteState::Ready(stream, 0))))
291 }
292}
293
294#[async_trait::async_trait]
295impl OutputStream for TcpWriter {
296 fn write(&mut self, bytes: bytes::Bytes) -> StreamResult<()> {
297 self.0.lock().unwrap().write(bytes)
298 }
299
300 fn flush(&mut self) -> StreamResult<()> {
301 self.0.lock().unwrap().flush()
302 }
303
304 fn check_write(&mut self) -> StreamResult<usize> {
305 self.0.lock().unwrap().check_write()
306 }
307
308 async fn cancel(&mut self) {
309 self.ready().await
312 }
313}
314
315#[async_trait::async_trait]
316impl Pollable for TcpWriter {
317 async fn ready(&mut self) {
318 poll_fn(|cx| self.0.lock().unwrap().poll_ready(cx).map(|_| ())).await;
319 }
320}