diff --git a/crates/test-programs/src/bin/p2_tcp_listen.rs b/crates/test-programs/src/bin/p2_tcp_listen.rs new file mode 100644 index 000000000000..600e808874bf --- /dev/null +++ b/crates/test-programs/src/bin/p2_tcp_listen.rs @@ -0,0 +1,21 @@ +use test_programs::sockets::supports_ipv6; +use test_programs::wasi::sockets::network::{ErrorCode, IpAddressFamily}; +use test_programs::wasi::sockets::tcp::TcpSocket; + +/// Socket must be explicitly bound before listening. +fn test_tcp_listen_without_bind(family: IpAddressFamily) { + let sock = TcpSocket::new(family).unwrap(); + + assert!(matches!( + sock.blocking_listen(), + Err(ErrorCode::InvalidState) + )); +} + +fn main() { + test_tcp_listen_without_bind(IpAddressFamily::Ipv4); + + if supports_ipv6() { + test_tcp_listen_without_bind(IpAddressFamily::Ipv6); + } +} diff --git a/crates/test-programs/src/bin/p2_udp_connect.rs b/crates/test-programs/src/bin/p2_udp_connect.rs index 7ce1ad56f689..89ff5a4d43b8 100644 --- a/crates/test-programs/src/bin/p2_udp_connect.rs +++ b/crates/test-programs/src/bin/p2_udp_connect.rs @@ -76,6 +76,18 @@ fn test_udp_connect_wrong_family(net: &Network, family: IpAddressFamily) { )); } +/// Socket must be explicitly bound before connecting. +fn test_udp_connect_without_bind(family: IpAddressFamily) { + let remote_addr = IpSocketAddress::new(IpAddress::new_loopback(family), SOME_PORT); + + let sock = UdpSocket::new(family).unwrap(); + + assert!(matches!( + sock.stream(Some(remote_addr)), + Err(ErrorCode::InvalidState) + )); +} + fn test_udp_connect_dual_stack(net: &Network) { // Set-up: let v4_server = UdpSocket::new(IpAddressFamily::Ipv4).unwrap(); @@ -120,5 +132,8 @@ fn main() { test_udp_connect_wrong_family(&net, IpAddressFamily::Ipv4); test_udp_connect_wrong_family(&net, IpAddressFamily::Ipv6); + test_udp_connect_without_bind(IpAddressFamily::Ipv4); + test_udp_connect_without_bind(IpAddressFamily::Ipv6); + test_udp_connect_dual_stack(&net); } diff --git a/crates/test-programs/src/bin/p3_sockets_tcp_listen.rs b/crates/test-programs/src/bin/p3_sockets_tcp_listen.rs new file mode 100644 index 000000000000..3cd22f3ad6bb --- /dev/null +++ b/crates/test-programs/src/bin/p3_sockets_tcp_listen.rs @@ -0,0 +1,45 @@ +use test_programs::p3::wasi::sockets::types::{ + IpAddress, IpAddressFamily, IpSocketAddress, TcpSocket, +}; +use test_programs::sockets::supports_ipv6; + +struct Component; + +test_programs::p3::export!(Component); + +/// Listen should perform implicit bind. +fn test_tcp_listen_without_bind(family: IpAddressFamily) { + let sock = TcpSocket::create(family).unwrap(); + + assert!(matches!(sock.get_local_address(), Err(_))); + assert!(matches!(sock.listen(), Ok(_))); + assert!(matches!(sock.get_local_address(), Ok(_))); +} + +/// Listen should work in combination with an explicit bind. +fn test_tcp_listen_with_bind(family: IpAddressFamily) { + let bind_addr = IpSocketAddress::new(IpAddress::new_unspecified(family), 0); + let sock = TcpSocket::create(family).unwrap(); + + sock.bind(bind_addr).unwrap(); + let local_addr = sock.get_local_address().unwrap(); + + assert!(matches!(sock.listen(), Ok(_))); + assert_eq!(sock.get_local_address(), Ok(local_addr)); +} + +impl test_programs::p3::exports::wasi::cli::run::Guest for Component { + async fn run() -> Result<(), ()> { + test_tcp_listen_without_bind(IpAddressFamily::Ipv4); + test_tcp_listen_with_bind(IpAddressFamily::Ipv4); + + if supports_ipv6() { + test_tcp_listen_without_bind(IpAddressFamily::Ipv6); + test_tcp_listen_with_bind(IpAddressFamily::Ipv6); + } + + Ok(()) + } +} + +fn main() {} diff --git a/crates/test-programs/src/bin/p3_sockets_udp_connect.rs b/crates/test-programs/src/bin/p3_sockets_udp_connect.rs index e7ba0dd501ae..ebb03ed39576 100644 --- a/crates/test-programs/src/bin/p3_sockets_udp_connect.rs +++ b/crates/test-programs/src/bin/p3_sockets_udp_connect.rs @@ -9,12 +9,10 @@ test_programs::p3::export!(Component); const SOME_PORT: u16 = 47; // If the tests pass, this will never actually be connected to. fn test_udp_connect_disconnect_reconnect(family: IpAddressFamily) { - let unspecified_addr = IpSocketAddress::new(IpAddress::new_unspecified(family), 0); let remote1 = IpSocketAddress::new(IpAddress::new_loopback(family), 4321); let remote2 = IpSocketAddress::new(IpAddress::new_loopback(family), 4320); let client = UdpSocket::create(family).unwrap(); - client.bind(unspecified_addr).unwrap(); assert_eq!(client.disconnect(), Err(ErrorCode::InvalidState)); assert_eq!(client.get_remote_address(), Err(ErrorCode::InvalidState)); @@ -43,7 +41,6 @@ fn test_udp_connect_unspec(family: IpAddressFamily) { let ip = IpAddress::new_unspecified(family); let addr = IpSocketAddress::new(ip, SOME_PORT); let sock = UdpSocket::create(family).unwrap(); - sock.bind_unspecified().unwrap(); assert!(matches!( sock.connect(addr), @@ -55,7 +52,6 @@ fn test_udp_connect_unspec(family: IpAddressFamily) { fn test_udp_connect_port_0(family: IpAddressFamily) { let addr = IpSocketAddress::new(IpAddress::new_loopback(family), 0); let sock = UdpSocket::create(family).unwrap(); - sock.bind_unspecified().unwrap(); assert!(matches!( sock.connect(addr), @@ -72,7 +68,6 @@ fn test_udp_connect_wrong_family(family: IpAddressFamily) { let remote_addr = IpSocketAddress::new(wrong_ip, SOME_PORT); let sock = UdpSocket::create(family).unwrap(); - sock.bind_unspecified().unwrap(); assert!(matches!( sock.connect(remote_addr), @@ -80,6 +75,30 @@ fn test_udp_connect_wrong_family(family: IpAddressFamily) { )); } +/// Connect should perform implicit bind. +fn test_udp_connect_without_bind(family: IpAddressFamily) { + let remote_addr = IpSocketAddress::new(IpAddress::new_loopback(family), SOME_PORT); + + let sock = UdpSocket::create(family).unwrap(); + + assert!(matches!(sock.get_local_address(), Err(_))); + assert!(matches!(sock.connect(remote_addr), Ok(_))); + assert!(matches!(sock.get_local_address(), Ok(_))); +} + +/// Connect should work in combination with an explicit bind. +fn test_udp_connect_with_bind(family: IpAddressFamily) { + let remote_addr = IpSocketAddress::new(IpAddress::new_loopback(family), SOME_PORT); + + let sock = UdpSocket::create(family).unwrap(); + + sock.bind_unspecified().unwrap(); + + assert!(matches!(sock.get_local_address(), Ok(_))); + assert!(matches!(sock.connect(remote_addr), Ok(_))); + assert!(matches!(sock.get_local_address(), Ok(_))); +} + fn test_udp_connect_dual_stack() { // Set-up: let v4_server = UdpSocket::create(IpAddressFamily::Ipv4).unwrap(); @@ -123,6 +142,12 @@ impl test_programs::p3::exports::wasi::cli::run::Guest for Component { test_udp_connect_wrong_family(IpAddressFamily::Ipv4); test_udp_connect_wrong_family(IpAddressFamily::Ipv6); + test_udp_connect_without_bind(IpAddressFamily::Ipv4); + test_udp_connect_without_bind(IpAddressFamily::Ipv6); + + test_udp_connect_with_bind(IpAddressFamily::Ipv4); + test_udp_connect_with_bind(IpAddressFamily::Ipv6); + test_udp_connect_dual_stack(); Ok(()) } diff --git a/crates/test-programs/src/bin/p3_sockets_udp_receive.rs b/crates/test-programs/src/bin/p3_sockets_udp_receive.rs new file mode 100644 index 000000000000..7392a9a2b19a --- /dev/null +++ b/crates/test-programs/src/bin/p3_sockets_udp_receive.rs @@ -0,0 +1,28 @@ +use test_programs::p3::wasi::sockets::types::{ErrorCode, IpAddressFamily, UdpSocket}; + +struct Component; + +test_programs::p3::export!(Component); + +// Receive requires the socket to be bound. +async fn test_udp_receive_without_bind_or_connect(family: IpAddressFamily) { + let sock = UdpSocket::create(family).unwrap(); + + assert!(matches!(sock.get_local_address(), Err(_))); + + assert!(matches!(sock.receive().await, Err(ErrorCode::InvalidState))); + + assert!(matches!(sock.get_local_address(), Err(_))); + assert!(matches!(sock.get_remote_address(), Err(_))); +} + +impl test_programs::p3::exports::wasi::cli::run::Guest for Component { + async fn run() -> Result<(), ()> { + test_udp_receive_without_bind_or_connect(IpAddressFamily::Ipv4).await; + test_udp_receive_without_bind_or_connect(IpAddressFamily::Ipv6).await; + + Ok(()) + } +} + +fn main() {} diff --git a/crates/test-programs/src/bin/p3_sockets_udp_send.rs b/crates/test-programs/src/bin/p3_sockets_udp_send.rs new file mode 100644 index 000000000000..a5ede23ead12 --- /dev/null +++ b/crates/test-programs/src/bin/p3_sockets_udp_send.rs @@ -0,0 +1,36 @@ +use test_programs::p3::wasi::sockets::types::{ + IpAddress, IpAddressFamily, IpSocketAddress, UdpSocket, +}; + +struct Component; + +test_programs::p3::export!(Component); + +// Send without prior `bind` or `connect` performs an implicit bind. +async fn test_udp_send_without_bind_or_connect(family: IpAddressFamily) { + let message = b"Hello, world!"; + let remote_addr = IpSocketAddress::new(IpAddress::new_loopback(family), 42); + + let sock = UdpSocket::create(family).unwrap(); + + assert!(matches!(sock.get_local_address(), Err(_))); + + assert!(matches!( + sock.send(message.to_vec(), Some(remote_addr)).await, + Ok(_) + )); + + assert!(matches!(sock.get_local_address(), Ok(_))); + assert!(matches!(sock.get_remote_address(), Err(_))); +} + +impl test_programs::p3::exports::wasi::cli::run::Guest for Component { + async fn run() -> Result<(), ()> { + test_udp_send_without_bind_or_connect(IpAddressFamily::Ipv4).await; + test_udp_send_without_bind_or_connect(IpAddressFamily::Ipv6).await; + + Ok(()) + } +} + +fn main() {} diff --git a/crates/test-programs/src/bin/p3_sockets_udp_states.rs b/crates/test-programs/src/bin/p3_sockets_udp_states.rs index 6b36fc162fd6..370acda8d738 100644 --- a/crates/test-programs/src/bin/p3_sockets_udp_states.rs +++ b/crates/test-programs/src/bin/p3_sockets_udp_states.rs @@ -10,7 +10,7 @@ test_programs::p3::export!(Component); async fn test_udp_unbound_state_invariants(family: IpAddressFamily) { let sock = UdpSocket::create(family).unwrap(); - // Skipping: udp::start_bind + // Skipping: udp::bind assert_eq!( sock.send(b"test".into(), None).await, @@ -38,7 +38,7 @@ fn test_udp_bound_state_invariants(family: IpAddressFamily) { sock.bind(bind_address), Err(ErrorCode::InvalidState) )); - // Skipping: udp::stream + // Skipping: udp::connect assert!(matches!(sock.get_local_address(), Ok(_))); assert!(matches!( @@ -59,14 +59,13 @@ fn test_udp_connected_state_invariants(family: IpAddressFamily) { let bind_address = IpSocketAddress::new(IpAddress::new_loopback(family), 0); let connect_address = IpSocketAddress::new(IpAddress::new_loopback(family), 54321); let sock = UdpSocket::create(family).unwrap(); - sock.bind(bind_address).unwrap(); sock.connect(connect_address).unwrap(); assert!(matches!( sock.bind(bind_address), Err(ErrorCode::InvalidState) )); - // Skipping: udp::stream + // Skipping: udp::connect assert!(matches!(sock.get_local_address(), Ok(_))); assert!(matches!(sock.get_remote_address(), Ok(_))); diff --git a/crates/wasi/src/p2/host/tcp.rs b/crates/wasi/src/p2/host/tcp.rs index f806db07def9..a0ac1ee9fa63 100644 --- a/crates/wasi/src/p2/host/tcp.rs +++ b/crates/wasi/src/p2/host/tcp.rs @@ -83,13 +83,13 @@ impl crate::p2::host::tcp::tcp::HostTcpSocket for WasiSocketsCtxView<'_> { fn start_listen(&mut self, this: Resource) -> SocketResult<()> { let socket = self.table.get_mut(&this)?; - socket.start_listen()?; + socket.start_listen_p2()?; Ok(()) } fn finish_listen(&mut self, this: Resource) -> SocketResult<()> { let socket = self.table.get_mut(&this)?; - socket.finish_listen()?; + socket.finish_listen_p2()?; Ok(()) } diff --git a/crates/wasi/src/p2/host/udp.rs b/crates/wasi/src/p2/host/udp.rs index 23a3b53c1ea4..c9ce15a403eb 100644 --- a/crates/wasi/src/p2/host/udp.rs +++ b/crates/wasi/src/p2/host/udp.rs @@ -79,7 +79,7 @@ impl udp::HostUdpSocket for WasiSocketsCtxView<'_> { return Err(ErrorCode::InvalidState.into()); }; check.check(connect_addr, SocketAddrUse::UdpConnect).await?; - socket.connect(connect_addr)?; + socket.connect_p2(connect_addr)?; } let incoming_stream = IncomingDatagramStream { diff --git a/crates/wasi/src/p3/sockets/host/types/tcp.rs b/crates/wasi/src/p3/sockets/host/types/tcp.rs index ba84387dfa13..1eb5a2d72adf 100644 --- a/crates/wasi/src/p3/sockets/host/types/tcp.rs +++ b/crates/wasi/src/p3/sockets/host/types/tcp.rs @@ -267,8 +267,7 @@ impl HostTcpSocketWithStore for WasiSockets { ) -> SocketResult>> { let getter = store.getter(); let socket = get_socket_mut(store.get().table, &socket)?; - socket.start_listen()?; - socket.finish_listen()?; + socket.listen_p3()?; let listener = socket.tcp_listener_arc().unwrap().clone(); let family = socket.address_family(); let options = socket.non_inherited_options().clone(); diff --git a/crates/wasi/src/p3/sockets/host/types/udp.rs b/crates/wasi/src/p3/sockets/host/types/udp.rs index 1028e8f0f30e..96982d30885f 100644 --- a/crates/wasi/src/p3/sockets/host/types/udp.rs +++ b/crates/wasi/src/p3/sockets/host/types/udp.rs @@ -39,23 +39,19 @@ impl HostUdpSocketWithStore for WasiSockets { if data.len() > MAX_UDP_DATAGRAM_SIZE { return Err(ErrorCode::DatagramTooLarge.into()); } + let remote_address = remote_address.map(SocketAddr::from); + if let Some(addr) = remote_address { - let addr = SocketAddr::from(addr); if !is_addr_allowed(store, addr, SocketAddrUse::UdpOutgoingDatagram).await { return Err(ErrorCode::AccessDenied.into()); } - let fut = store.with(|mut view| { - get_socket(view.get().table, &socket).map(|sock| sock.send_to(data, addr)) - })?; - fut.await?; - Ok(()) - } else { - let fut = store.with(|mut view| { - get_socket(view.get().table, &socket).map(|sock| sock.send(data)) - })?; - fut.await?; - Ok(()) } + + let fut = store.with(|mut view| { + get_socket_mut(view.get().table, &socket).map(|sock| sock.send_p3(data, remote_address)) + })?; + fut.await?; + Ok(()) } async fn receive( @@ -63,7 +59,7 @@ impl HostUdpSocketWithStore for WasiSockets { socket: Resource, ) -> SocketResult<(Vec, IpSocketAddress)> { let fut = store - .with(|mut view| get_socket(view.get().table, &socket).map(|sock| sock.receive()))?; + .with(|mut view| get_socket(view.get().table, &socket).map(|sock| sock.receive_p3()))?; let (result, addr) = fut.await?; Ok((result, addr.into())) } @@ -95,7 +91,7 @@ impl HostUdpSocket for WasiSocketsCtxView<'_> { return Err(ErrorCode::AccessDenied.into()); } let socket = get_socket_mut(self.table, &socket)?; - socket.connect(remote_address)?; + socket.connect_p3(remote_address)?; Ok(()) } diff --git a/crates/wasi/src/sockets/tcp.rs b/crates/wasi/src/sockets/tcp.rs index cc4f059ef301..72a4f0c80a6a 100644 --- a/crates/wasi/src/sockets/tcp.rs +++ b/crates/wasi/src/sockets/tcp.rs @@ -381,7 +381,8 @@ impl TcpSocket { } } - pub(crate) fn start_listen(&mut self) -> Result<(), ErrorCode> { + /// Start listening using p2 semantics. (no implicit bind) + pub(crate) fn start_listen_p2(&mut self) -> Result<(), ErrorCode> { match mem::replace(&mut self.tcp_state, TcpState::Closed) { TcpState::Bound(tokio_socket) => { self.tcp_state = TcpState::ListenStarted(tokio_socket); @@ -394,7 +395,7 @@ impl TcpSocket { } } - pub(crate) fn finish_listen(&mut self) -> Result<(), ErrorCode> { + pub(crate) fn finish_listen_p2(&mut self) -> Result<(), ErrorCode> { let tokio_socket = match mem::replace(&mut self.tcp_state, TcpState::Closed) { TcpState::ListenStarted(tokio_socket) => tokio_socket, previous_state => { @@ -403,6 +404,24 @@ impl TcpSocket { } }; + self.listen_common(tokio_socket) + } + + /// Start listening using p3 semantics. (with implicit bind) + #[cfg(feature = "p3")] + pub(crate) fn listen_p3(&mut self) -> Result<(), ErrorCode> { + let tokio_socket = match mem::replace(&mut self.tcp_state, TcpState::Closed) { + TcpState::Default(tokio_socket) | TcpState::Bound(tokio_socket) => tokio_socket, + previous_state => { + self.tcp_state = previous_state; + return Err(ErrorCode::InvalidState); + } + }; + + self.listen_common(tokio_socket) + } + + fn listen_common(&mut self, tokio_socket: tokio::net::TcpSocket) -> Result<(), ErrorCode> { match with_ambient_tokio_runtime(|| tokio_socket.listen(self.listen_backlog_size)) { Ok(listener) => { self.tcp_state = TcpState::Listening { diff --git a/crates/wasi/src/sockets/udp.rs b/crates/wasi/src/sockets/udp.rs index f4475748b50a..76f8cb9bcafc 100644 --- a/crates/wasi/src/sockets/udp.rs +++ b/crates/wasi/src/sockets/udp.rs @@ -129,16 +129,32 @@ impl UdpSocket { Ok(()) } - pub(crate) fn connect(&mut self, addr: SocketAddr) -> Result<(), ErrorCode> { - if !is_valid_address_family(addr.ip(), self.family) || !is_valid_remote_address(addr) { - return Err(ErrorCode::InvalidArgument); + /// Connect using p2 semantics. (no implicit bind) + pub(crate) fn connect_p2(&mut self, addr: SocketAddr) -> Result<(), ErrorCode> { + match self.udp_state { + UdpState::Bound | UdpState::Connected(_) => {} + _ => return Err(ErrorCode::InvalidState), } + self.connect_common(addr) + } + + /// Connect using p3 semantics. (with implicit bind) + #[cfg(feature = "p3")] + pub(crate) fn connect_p3(&mut self, addr: SocketAddr) -> Result<(), ErrorCode> { match self.udp_state { - UdpState::Bound | UdpState::Connected(_) => {} + UdpState::Default | UdpState::Bound | UdpState::Connected(_) => {} _ => return Err(ErrorCode::InvalidState), } + self.connect_common(addr) + } + + fn connect_common(&mut self, addr: SocketAddr) -> Result<(), ErrorCode> { + if !is_valid_address_family(addr.ip(), self.family) || !is_valid_remote_address(addr) { + return Err(ErrorCode::InvalidArgument); + } + // We disconnect & (re)connect in two distinct steps for two reasons: // - To leave our socket instance in a consistent state in case the // connect fails. @@ -163,37 +179,61 @@ impl UdpSocket { Ok(()) } + /// Send data using p3 semantics. (with implicit bind) #[cfg(feature = "p3")] - pub(crate) fn send(&self, buf: Vec) -> impl Future> + use<> { - let socket = if let UdpState::Connected(..) = self.udp_state { - Ok(Arc::clone(&self.socket)) - } else { - Err(ErrorCode::InvalidArgument) - }; - async move { - let socket = socket?; - send(&socket, &buf).await - } - } - - #[cfg(feature = "p3")] - pub(crate) fn send_to( - &self, + pub(crate) fn send_p3( + &mut self, buf: Vec, - addr: SocketAddr, + addr: Option, ) -> impl Future> + use<> { enum Mode { Send(Arc), SendTo(Arc, SocketAddr), } - let socket = match &self.udp_state { - UdpState::BindStarted => Err(ErrorCode::InvalidState), - UdpState::Default | UdpState::Bound => Ok(Mode::SendTo(Arc::clone(&self.socket), addr)), - UdpState::Connected(caddr) if addr == *caddr => { - Ok(Mode::Send(Arc::clone(&self.socket))) + let mut socket = match (&self.udp_state, addr) { + (UdpState::BindStarted, _) => Err(ErrorCode::InvalidState), + (UdpState::Default | UdpState::Bound, None) => Err(ErrorCode::InvalidArgument), + (UdpState::Default | UdpState::Bound, Some(addr)) => { + Ok(Mode::SendTo(Arc::clone(&self.socket), addr)) + } + (UdpState::Connected(..), None) => Ok(Mode::Send(Arc::clone(&self.socket))), + (UdpState::Connected(caddr), Some(addr)) => { + if addr == *caddr { + Ok(Mode::Send(Arc::clone(&self.socket))) + } else { + Err(ErrorCode::InvalidArgument) + } } - UdpState::Connected(..) => Err(ErrorCode::InvalidArgument), }; + + // Send may be called without a prior bind or connect. In that case, the + // first send will automatically assign a free local port. This is + // normally performed by the OS itself. However, if the `send` syscall + // failed, we can't reliably know which state the socket is in at the + // kernel level and our own `udp_state` bookkeeping may have become + // out-of-sync. + // To avoid that, we perform the implicit bind ourselves here. This way, + // we always leave the socket in a consistent state: Bound. + if socket.is_ok() + && let UdpState::Default = self.udp_state + { + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + + let ip_addr = match self.family { + SocketAddressFamily::Ipv4 => IpAddr::V4(Ipv4Addr::UNSPECIFIED), + SocketAddressFamily::Ipv6 => IpAddr::V6(Ipv6Addr::UNSPECIFIED), + }; + let sock_addr = SocketAddr::new(ip_addr, 0); + match udp_bind(&self.socket, sock_addr) { + Ok(()) => { + self.udp_state = UdpState::Bound; + } + Err(e) => { + socket = Err(e); + } + } + } + async move { match socket? { Mode::Send(socket) => send(&socket, &buf).await, @@ -202,8 +242,9 @@ impl UdpSocket { } } + /// Receive data using p3 semantics. #[cfg(feature = "p3")] - pub(crate) fn receive( + pub(crate) fn receive_p3( &self, ) -> impl Future, SocketAddr), ErrorCode>> + use<> { enum Mode { diff --git a/crates/wasi/tests/all/p2/async_.rs b/crates/wasi/tests/all/p2/async_.rs index 0d9680b8ce4b..737af190779d 100644 --- a/crates/wasi/tests/all/p2/async_.rs +++ b/crates/wasi/tests/all/p2/async_.rs @@ -302,6 +302,10 @@ async fn p2_tcp_connect() { run(P2_TCP_CONNECT_COMPONENT, false).await.unwrap() } #[test_log::test(tokio::test(flavor = "multi_thread"))] +async fn p2_tcp_listen() { + run(P2_TCP_LISTEN_COMPONENT, false).await.unwrap() +} +#[test_log::test(tokio::test(flavor = "multi_thread"))] async fn p2_udp_sockopts() { run(P2_UDP_SOCKOPTS_COMPONENT, false).await.unwrap() } diff --git a/crates/wasi/tests/all/p2/sync.rs b/crates/wasi/tests/all/p2/sync.rs index c7f0986ba7c3..9cab6bac8624 100644 --- a/crates/wasi/tests/all/p2/sync.rs +++ b/crates/wasi/tests/all/p2/sync.rs @@ -288,6 +288,10 @@ fn p2_tcp_connect() { run(P2_TCP_CONNECT_COMPONENT, false).unwrap() } #[test_log::test] +fn p2_tcp_listen() { + run(P2_TCP_LISTEN_COMPONENT, false).unwrap() +} +#[test_log::test] fn p2_udp_sockopts() { run(P2_UDP_SOCKOPTS_COMPONENT, false).unwrap() } diff --git a/crates/wasi/tests/all/p3/mod.rs b/crates/wasi/tests/all/p3/mod.rs index 5bbdcbd13bae..7c9535f0a571 100644 --- a/crates/wasi/tests/all/p3/mod.rs +++ b/crates/wasi/tests/all/p3/mod.rs @@ -87,6 +87,11 @@ async fn p3_sockets_tcp_connect() -> anyhow::Result<()> { run(P3_SOCKETS_TCP_CONNECT_COMPONENT).await } +#[test_log::test(tokio::test(flavor = "multi_thread"))] +async fn p3_sockets_tcp_listen() -> anyhow::Result<()> { + run(P3_SOCKETS_TCP_LISTEN_COMPONENT).await +} + #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn p3_sockets_tcp_sample_application() -> anyhow::Result<()> { run(P3_SOCKETS_TCP_SAMPLE_APPLICATION_COMPONENT).await @@ -117,11 +122,21 @@ async fn p3_sockets_udp_connect() -> anyhow::Result<()> { run(P3_SOCKETS_UDP_CONNECT_COMPONENT).await } +#[test_log::test(tokio::test(flavor = "multi_thread"))] +async fn p3_sockets_udp_receive() -> anyhow::Result<()> { + run(P3_SOCKETS_UDP_RECEIVE_COMPONENT).await +} + #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn p3_sockets_udp_sample_application() -> anyhow::Result<()> { run(P3_SOCKETS_UDP_SAMPLE_APPLICATION_COMPONENT).await } +#[test_log::test(tokio::test(flavor = "multi_thread"))] +async fn p3_sockets_udp_send() -> anyhow::Result<()> { + run(P3_SOCKETS_UDP_SEND_COMPONENT).await +} + #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn p3_sockets_udp_sockopts() -> anyhow::Result<()> { run(P3_SOCKETS_UDP_SOCKOPTS_COMPONENT).await