Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit 251c2a1

Browse files
committed
fixup! feat(wasip3): add wasi:[email protected]
1 parent 5e0c8d6 commit 251c2a1

File tree

3 files changed

+332
-162
lines changed

3 files changed

+332
-162
lines changed

crates/wasi/src/p3/sockets/host/types/tcp.rs

Lines changed: 55 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,14 @@ use core::net::SocketAddr;
44

55
use anyhow::{ensure, Context as _};
66
use rustix::io::Errno;
7-
use rustix::net::sockopt;
8-
use wasmtime::component::{for_any, stream, FutureReader, Resource, StreamReader};
7+
use wasmtime::component::{for_any, FutureReader, Resource, StreamReader};
98
use wasmtime::StoreContextMut;
109

10+
use crate::p3::bindings::sockets::types::{
11+
Duration, ErrorCode, HostTcpSocket, IpAddressFamily, IpSocketAddress, TcpSocket,
12+
};
1113
use crate::p3::sockets::tcp::{bind, connect, TcpState};
1214
use crate::p3::sockets::{SocketAddrUse, WasiSocketsImpl, WasiSocketsView};
13-
use crate::p3::{
14-
bindings::sockets::types::{
15-
Duration, ErrorCode, HostTcpSocket, IpAddressFamily, IpSocketAddress, TcpSocket,
16-
},
17-
sockets::SocketAddressFamily,
18-
};
1915

2016
impl<T> HostTcpSocket for WasiSocketsImpl<&mut T>
2117
where
@@ -260,21 +256,7 @@ where
260256
.table()
261257
.get(&socket)
262258
.context("failed to get socket resource from table")?;
263-
match &sock.tcp_state {
264-
TcpState::Bound(socket) => match socket.local_addr() {
265-
Ok(addr) => Ok(Ok(addr.into())),
266-
Err(err) => Ok(Err(err.into())),
267-
},
268-
TcpState::Connected(stream) => match stream.local_addr() {
269-
Ok(addr) => Ok(Ok(addr.into())),
270-
Err(err) => Ok(Err(err.into())),
271-
},
272-
TcpState::Listening(listener) => match listener.local_addr() {
273-
Ok(addr) => Ok(Ok(addr.into())),
274-
Err(err) => Ok(Err(err.into())),
275-
},
276-
_ => Ok(Err(ErrorCode::InvalidState)),
277-
}
259+
Ok(sock.local_address())
278260
}
279261

280262
fn remote_address(
@@ -285,67 +267,35 @@ where
285267
.table()
286268
.get(&socket)
287269
.context("failed to get socket resource from table")?;
288-
match &sock.tcp_state {
289-
TcpState::Connected(stream) => match stream.peer_addr() {
290-
Ok(addr) => Ok(Ok(addr.into())),
291-
Err(err) => Ok(Err(err.into())),
292-
},
293-
_ => Ok(Err(ErrorCode::InvalidState)),
294-
}
270+
Ok(sock.remote_address())
295271
}
296272

297273
fn is_listening(&mut self, socket: Resource<TcpSocket>) -> wasmtime::Result<bool> {
298274
let sock = self
299275
.table()
300276
.get(&socket)
301277
.context("failed to get socket from table")?;
302-
Ok(matches!(sock.tcp_state, TcpState::Listening { .. }))
278+
Ok(sock.is_listening())
303279
}
304280

305281
fn address_family(&mut self, socket: Resource<TcpSocket>) -> wasmtime::Result<IpAddressFamily> {
306282
let sock = self
307283
.table()
308284
.get(&socket)
309285
.context("failed to get socket from table")?;
310-
match sock.family {
311-
SocketAddressFamily::Ipv4 => Ok(IpAddressFamily::Ipv4),
312-
SocketAddressFamily::Ipv6 => Ok(IpAddressFamily::Ipv6),
313-
}
286+
Ok(sock.address_family())
314287
}
315288

316289
fn set_listen_backlog_size(
317290
&mut self,
318291
socket: Resource<TcpSocket>,
319292
value: u64,
320293
) -> wasmtime::Result<Result<(), ErrorCode>> {
321-
const MAX_BACKLOG: u32 = i32::MAX as u32; // OS'es will most likely limit it down even further.
322-
323294
let sock = self
324295
.table()
325296
.get_mut(&socket)
326297
.context("failed to get socket from table")?;
327-
// Silently clamp backlog size. This is OK for us to do, because operating systems do this too.
328-
if value == 0 {
329-
return Ok(Err(ErrorCode::InvalidArgument));
330-
}
331-
let value = value.try_into().unwrap_or(MAX_BACKLOG).min(MAX_BACKLOG);
332-
match &sock.tcp_state {
333-
TcpState::Default(..) | TcpState::Bound(..) => {
334-
// Socket not listening yet. Stash value for first invocation to `listen`.
335-
sock.listen_backlog_size = value;
336-
Ok(Ok(()))
337-
}
338-
TcpState::Listening(listener) => {
339-
// Try to update the backlog by calling `listen` again.
340-
// Not all platforms support this. We'll only update our own value if the OS supports changing the backlog size after the fact.
341-
if rustix::net::listen(&listener, value.try_into().unwrap_or(i32::MAX)).is_err() {
342-
return Ok(Err(ErrorCode::NotSupported));
343-
}
344-
sock.listen_backlog_size = value;
345-
Ok(Ok(()))
346-
}
347-
_ => Ok(Err(ErrorCode::InvalidState.into())),
348-
}
298+
Ok(sock.set_listen_backlog_size(value))
349299
}
350300

351301
fn keep_alive_enabled(
@@ -356,20 +306,7 @@ where
356306
.table()
357307
.get(&socket)
358308
.context("failed to get socket from table")?;
359-
match &sock.tcp_state {
360-
TcpState::Default(socket) | TcpState::Bound(socket) => {
361-
Ok(sockopt::get_socket_keepalive(socket).map_err(Into::into))
362-
}
363-
TcpState::Connected(stream) => {
364-
Ok(sockopt::get_socket_keepalive(stream).map_err(Into::into))
365-
}
366-
TcpState::Listening(listener) => {
367-
Ok(sockopt::get_socket_keepalive(listener).map_err(Into::into))
368-
}
369-
TcpState::BindStarted | TcpState::Connecting | TcpState::Closed => {
370-
Ok(Err(ErrorCode::InvalidState))
371-
}
372-
}
309+
Ok(sock.keep_alive_enabled())
373310
}
374311

375312
fn set_keep_alive_enabled(
@@ -381,20 +318,7 @@ where
381318
.table()
382319
.get(&socket)
383320
.context("failed to get socket from table")?;
384-
match &sock.tcp_state {
385-
TcpState::Default(socket) | TcpState::Bound(socket) => {
386-
Ok(sockopt::set_socket_keepalive(socket, value).map_err(Into::into))
387-
}
388-
TcpState::Connected(stream) => {
389-
Ok(sockopt::set_socket_keepalive(stream, value).map_err(Into::into))
390-
}
391-
TcpState::Listening(listener) => {
392-
Ok(sockopt::set_socket_keepalive(listener, value).map_err(Into::into))
393-
}
394-
TcpState::BindStarted | TcpState::Connecting | TcpState::Closed => {
395-
Ok(Err(ErrorCode::InvalidState))
396-
}
397-
}
321+
Ok(sock.set_keep_alive_enabled(value))
398322
}
399323

400324
fn keep_alive_idle_time(
@@ -405,58 +329,19 @@ where
405329
.table()
406330
.get(&socket)
407331
.context("failed to get socket from table")?;
408-
match match &sock.tcp_state {
409-
TcpState::Default(socket) | TcpState::Bound(socket) => {
410-
sockopt::get_tcp_keepidle(socket)
411-
}
412-
TcpState::Connected(stream) => sockopt::get_tcp_keepidle(stream),
413-
TcpState::Listening(listener) => sockopt::get_tcp_keepidle(listener),
414-
TcpState::BindStarted | TcpState::Connecting | TcpState::Closed => {
415-
return Ok(Err(ErrorCode::InvalidState))
416-
}
417-
} {
418-
Ok(t) => Ok(Ok(t.as_nanos().try_into().unwrap_or(u64::MAX))),
419-
Err(err) => Ok(Err(err.into())),
420-
}
332+
Ok(sock.keep_alive_idle_time())
421333
}
422334

423335
fn set_keep_alive_idle_time(
424336
&mut self,
425337
socket: Resource<TcpSocket>,
426338
value: Duration,
427339
) -> wasmtime::Result<Result<(), ErrorCode>> {
428-
// Ensure that the value passed to the actual syscall never gets rounded down to 0.
429-
const MIN_SECS: core::time::Duration = core::time::Duration::from_secs(1);
430-
431-
// Cap it at Linux' maximum, which appears to have the lowest limit across our supported platforms.
432-
const MAX_SECS: core::time::Duration = core::time::Duration::from_secs(i16::MAX as u64);
433-
434-
if value == 0 {
435-
// WIT: "If the provided value is 0, an `invalid-argument` error is returned."
436-
return Ok(Err(ErrorCode::InvalidArgument));
437-
}
438-
let value = core::time::Duration::from_nanos(value).clamp(MIN_SECS, MAX_SECS);
439340
let sock = self
440341
.table()
441342
.get_mut(&socket)
442343
.context("failed to get socket from table")?;
443-
match match &sock.tcp_state {
444-
TcpState::Default(socket) | TcpState::Bound(socket) => {
445-
sockopt::set_tcp_keepidle(socket, value)
446-
}
447-
TcpState::Connected(stream) => sockopt::set_tcp_keepidle(stream, value),
448-
TcpState::Listening(listener) => sockopt::set_tcp_keepidle(listener, value),
449-
_ => return Ok(Err(ErrorCode::InvalidState)),
450-
} {
451-
Ok(()) => {
452-
#[cfg(target_os = "macos")]
453-
{
454-
sock.keep_alive_idle_time = Some(value);
455-
}
456-
Ok(Ok(()))
457-
}
458-
Err(err) => Ok(Err(err.into())),
459-
}
344+
Ok(sock.set_keep_alive_idle_time(value))
460345
}
461346

462347
fn keep_alive_interval(
@@ -467,27 +352,19 @@ where
467352
.table()
468353
.get(&socket)
469354
.context("failed to get socket from table")?;
470-
match match &sock.tcp_state {
471-
TcpState::Default(socket) | TcpState::Bound(socket) => {
472-
sockopt::get_tcp_keepintvl(socket)
473-
}
474-
TcpState::Connected(stream) => sockopt::get_tcp_keepintvl(stream),
475-
TcpState::Listening(listener) => sockopt::get_tcp_keepintvl(listener),
476-
TcpState::BindStarted | TcpState::Connecting | TcpState::Closed => {
477-
return Ok(Err(ErrorCode::InvalidState))
478-
}
479-
} {
480-
Ok(t) => Ok(Ok(t.as_nanos().try_into().unwrap_or(u64::MAX))),
481-
Err(err) => Ok(Err(err.into())),
482-
}
355+
Ok(sock.keep_alive_interval())
483356
}
484357

485358
fn set_keep_alive_interval(
486359
&mut self,
487360
socket: Resource<TcpSocket>,
488361
value: Duration,
489362
) -> wasmtime::Result<Result<(), ErrorCode>> {
490-
todo!()
363+
let sock = self
364+
.table()
365+
.get(&socket)
366+
.context("failed to get socket from table")?;
367+
Ok(sock.set_keep_alive_interval(value))
491368
}
492369

493370
fn keep_alive_count(
@@ -498,71 +375,88 @@ where
498375
.table()
499376
.get(&socket)
500377
.context("failed to get socket from table")?;
501-
match &sock.tcp_state {
502-
TcpState::Default(socket) | TcpState::Bound(socket) => {
503-
Ok(sockopt::get_tcp_keepcnt(socket).map_err(Into::into))
504-
}
505-
TcpState::Connected(stream) => Ok(sockopt::get_tcp_keepcnt(stream).map_err(Into::into)),
506-
TcpState::Listening(listener) => {
507-
Ok(sockopt::get_tcp_keepcnt(listener).map_err(Into::into))
508-
}
509-
TcpState::BindStarted | TcpState::Connecting | TcpState::Closed => {
510-
Ok(Err(ErrorCode::InvalidState))
511-
}
512-
}
378+
Ok(sock.keep_alive_count())
513379
}
514380

515381
fn set_keep_alive_count(
516382
&mut self,
517383
socket: Resource<TcpSocket>,
518384
value: u32,
519385
) -> wasmtime::Result<Result<(), ErrorCode>> {
520-
todo!()
386+
let sock = self
387+
.table()
388+
.get(&socket)
389+
.context("failed to get socket from table")?;
390+
Ok(sock.set_keep_alive_count(value))
521391
}
522392

523393
fn hop_limit(
524394
&mut self,
525395
socket: Resource<TcpSocket>,
526396
) -> wasmtime::Result<Result<u8, ErrorCode>> {
527-
todo!()
397+
let sock = self
398+
.table()
399+
.get(&socket)
400+
.context("failed to get socket from table")?;
401+
Ok(sock.hop_limit())
528402
}
529403

530404
fn set_hop_limit(
531405
&mut self,
532406
socket: Resource<TcpSocket>,
533407
value: u8,
534408
) -> wasmtime::Result<Result<(), ErrorCode>> {
535-
todo!()
409+
let sock = self
410+
.table()
411+
.get(&socket)
412+
.context("failed to get socket from table")?;
413+
Ok(sock.set_hop_limit(value))
536414
}
537415

538416
fn receive_buffer_size(
539417
&mut self,
540418
socket: Resource<TcpSocket>,
541419
) -> wasmtime::Result<Result<u64, ErrorCode>> {
542-
todo!()
420+
let sock = self
421+
.table()
422+
.get(&socket)
423+
.context("failed to get socket from table")?;
424+
Ok(sock.receive_buffer_size())
543425
}
544426

545427
fn set_receive_buffer_size(
546428
&mut self,
547429
socket: Resource<TcpSocket>,
548430
value: u64,
549431
) -> wasmtime::Result<Result<(), ErrorCode>> {
550-
todo!()
432+
let sock = self
433+
.table()
434+
.get_mut(&socket)
435+
.context("failed to get socket from table")?;
436+
Ok(sock.set_receive_buffer_size(value))
551437
}
552438

553439
fn send_buffer_size(
554440
&mut self,
555441
socket: Resource<TcpSocket>,
556442
) -> wasmtime::Result<Result<u64, ErrorCode>> {
557-
todo!()
443+
let sock = self
444+
.table()
445+
.get(&socket)
446+
.context("failed to get socket from table")?;
447+
Ok(sock.send_buffer_size())
558448
}
559449

560450
fn set_send_buffer_size(
561451
&mut self,
562452
socket: Resource<TcpSocket>,
563453
value: u64,
564454
) -> wasmtime::Result<Result<(), ErrorCode>> {
565-
todo!()
455+
let sock = self
456+
.table()
457+
.get_mut(&socket)
458+
.context("failed to get socket from table")?;
459+
Ok(sock.set_send_buffer_size(value))
566460
}
567461

568462
fn drop(&mut self, rep: Resource<TcpSocket>) -> wasmtime::Result<()> {

0 commit comments

Comments
 (0)