mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-24 00:00:11 +02:00
wasm: add wasm32-wasip2 networking support (#7933)
Motivation This adds networking support for the `wasm32-wasip2` target platform, which includes more extensive support for sockets than `wasm32-wasip1`. Solution The bulk of the changes are in https://github.com/tokio-rs/mio/pull/1931. This patch mainly tweaks a few `cfg` directives to indicate `wasm32-wasip2`'s additional capabilities. Note that this is a draft PR until until https://github.com/tokio-rs/mio/pull/1931 and https://github.com/rust-lang/socket2/pull/639 have been include in stable releases of their respective projects. Also note that I've added a `wasm32-wasip2` target to CI and triaged each test which was previously disabled for WASI into one of three categories: - Disabled on both WASIp1 and p2 due to not-yet-supported features such as multithreading - Disabled on p1 but enabled on p2 - Disabled on p1 and _temporarily_ disabled on p2 due to `wasi-libc` bugfixes which have been merged but not yet included in a Rust release. I'll open an issue to re-enable them when the fixes land in Rust. Future Work In the future, we could consider adding support for `tokio::net::lookup_host`. WASIp2 natively supports asynchronous DNS lookups and is single threaded, whereas Tokio currently assumes DNS lookups are blocking and require multithreading to emulate async lookups. A WASIp2-specific implementation could do the lookup directly without multithreading. WASIp2 also supports single-threaded, asynchronous file I/O, timers, etc. We could either support those directly or wait for WASIp3's multithreading support, in which case most of `tokio::fs` (as well as `tokio::net::lookup_host`, etc.) _should_ work unchanged via `wasi-libc` and worker threads. Currently, building for WASIp2 requires RUSTFLAGS="--cfg tokio_unstable"`. Once we have a solid maintenance plan, we can remove that requirement.
This commit is contained in:
@@ -1117,6 +1117,32 @@ jobs:
|
||||
CARGO_TARGET_WASM32_WASIP1_THREADS_RUNNER: "wasmtime run -W bulk-memory=y -W threads=y -W shared-memory=y -S threads=y --"
|
||||
RUSTFLAGS: --cfg tokio_unstable -Dwarnings -C target-feature=+atomics,+bulk-memory -C link-args=--max-memory=67108864
|
||||
|
||||
wasm32-wasip2:
|
||||
name: test tokio for wasm32-wasip2
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust ${{ env.rust_stable }}
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: ${{ env.rust_stable }}
|
||||
targets: wasm32-wasip2
|
||||
|
||||
- name: Install cargo-nextest, wasmtime
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-nextest,wasmtime-cli
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: test tokio --target wasm32-wasip2
|
||||
run: cargo nextest run --target wasm32-wasip2 --features net,macros,rt,io-util
|
||||
working-directory: tokio
|
||||
env:
|
||||
RUSTFLAGS: --cfg tokio_unstable
|
||||
CARGO_TARGET_WASM32_WASIP2_RUNNER: wasmtime run -Sinherit-network
|
||||
|
||||
check-external-types:
|
||||
name: check-external-types (${{ matrix.os }})
|
||||
needs: basics
|
||||
|
||||
+2
-1
@@ -1,4 +1,4 @@
|
||||
313
|
||||
314
|
||||
&
|
||||
+
|
||||
<
|
||||
@@ -310,5 +310,6 @@ wakers
|
||||
Wakers
|
||||
wakeup
|
||||
wakeups
|
||||
WASI
|
||||
workstealing
|
||||
ZST
|
||||
|
||||
+7
-4
@@ -96,11 +96,11 @@ pin-project-lite = "0.2.11"
|
||||
|
||||
# Everything else is optional...
|
||||
bytes = { version = "1.2.1", optional = true }
|
||||
mio = { version = "1.0.1", optional = true, default-features = false }
|
||||
mio = { version = "1.2.0", optional = true, default-features = false }
|
||||
parking_lot = { version = "0.12.0", optional = true }
|
||||
|
||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
||||
socket2 = { version = "0.6.0", optional = true, features = ["all"] }
|
||||
[target.'cfg(any(not(target_family = "wasm"), all(target_os = "wasi", not(target_env = "p1"))))'.dependencies]
|
||||
socket2 = { version = "0.6.3", optional = true, features = ["all"] }
|
||||
|
||||
# Currently unstable. The API exposed by these features may be broken at any time.
|
||||
# Requires `--cfg tokio_unstable` to enable.
|
||||
@@ -112,7 +112,7 @@ tracing = { version = "0.1.29", default-features = false, features = ["std"], op
|
||||
[target.'cfg(all(tokio_unstable, target_os = "linux"))'.dependencies]
|
||||
io-uring = { version = "0.7.11", default-features = false, optional = true }
|
||||
libc = { version = "0.2.168", optional = true }
|
||||
mio = { version = "1.0.1", default-features = false, features = ["os-poll", "os-ext"], optional = true }
|
||||
mio = { version = "1.2.0", default-features = false, features = ["os-poll", "os-ext"], optional = true }
|
||||
slab = { version = "0.4.9", optional = true }
|
||||
backtrace = { version = "0.3.58", optional = true }
|
||||
|
||||
@@ -120,6 +120,9 @@ backtrace = { version = "0.3.58", optional = true }
|
||||
libc = { version = "0.2.168", optional = true }
|
||||
signal-hook-registry = { version = "1.1.1", optional = true }
|
||||
|
||||
[target.'cfg(target_os = "wasi")'.dependencies]
|
||||
libc = { version = "0.2.168", optional = true }
|
||||
|
||||
[target.'cfg(unix)'.dev-dependencies]
|
||||
libc = { version = "0.2.168" }
|
||||
nix = { version = "0.29.0", default-features = false, features = ["aio", "fs", "socket"] }
|
||||
|
||||
@@ -58,6 +58,18 @@ macro_rules! cfg_unix {
|
||||
}
|
||||
}
|
||||
|
||||
/// Enables Unix-specific code, including WASI.
|
||||
/// Use this macro instead of `cfg(any(unix, target_os = "wasi"))` to generate docs properly.
|
||||
macro_rules! cfg_unix_or_wasi {
|
||||
($($item:item)*) => {
|
||||
$(
|
||||
#[cfg(any(all(doc, docsrs), unix, target_os = "wasi"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(unix, target_os = "wasi"))))]
|
||||
$item
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
/// Enables unstable Windows-specific code.
|
||||
/// Use this macro instead of `cfg(windows)` to generate docs properly.
|
||||
macro_rules! cfg_unstable_windows {
|
||||
@@ -674,6 +686,15 @@ macro_rules! cfg_not_wasi {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! cfg_not_wasip1 {
|
||||
($($item:item)*) => {
|
||||
$(
|
||||
#[cfg(not(all(target_os = "wasi", target_env = "p1")))]
|
||||
$item
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! cfg_is_wasm_not_wasi {
|
||||
($($item:item)*) => {
|
||||
$(
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
//! [`AsyncFd`]: crate::io::unix::AsyncFd
|
||||
|
||||
mod addr;
|
||||
cfg_not_wasi! {
|
||||
cfg_not_wasip1! {
|
||||
#[cfg(feature = "net")]
|
||||
pub(crate) use addr::to_socket_addrs;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ cfg_net! {
|
||||
pub mod tcp;
|
||||
pub use tcp::listener::TcpListener;
|
||||
pub use tcp::stream::TcpStream;
|
||||
cfg_not_wasi! {
|
||||
cfg_not_wasip1! {
|
||||
pub use tcp::socket::TcpSocket;
|
||||
|
||||
mod udp;
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::io::{Interest, PollEvented};
|
||||
use crate::net::tcp::TcpStream;
|
||||
use crate::util::check_socket_for_blocking;
|
||||
|
||||
cfg_not_wasi! {
|
||||
cfg_not_wasip1! {
|
||||
use crate::net::{to_socket_addrs, ToSocketAddrs};
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ cfg_net! {
|
||||
}
|
||||
|
||||
impl TcpListener {
|
||||
cfg_not_wasi! {
|
||||
cfg_not_wasip1! {
|
||||
/// Creates a new `TcpListener`, which will be bound to the specified address.
|
||||
///
|
||||
/// The returned listener is ready for accepting connections.
|
||||
@@ -292,7 +292,7 @@ impl TcpListener {
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
{
|
||||
use std::os::wasi::io::{FromRawFd, IntoRawFd};
|
||||
use std::os::fd::{FromRawFd, IntoRawFd};
|
||||
self.io
|
||||
.into_inner()
|
||||
.map(|io| io.into_raw_fd())
|
||||
@@ -300,7 +300,7 @@ impl TcpListener {
|
||||
}
|
||||
}
|
||||
|
||||
cfg_not_wasi! {
|
||||
cfg_not_wasip1! {
|
||||
pub(crate) fn new(listener: mio::net::TcpListener) -> io::Result<TcpListener> {
|
||||
let io = PollEvented::new(listener)?;
|
||||
Ok(TcpListener { io })
|
||||
@@ -427,7 +427,7 @@ cfg_unstable! {
|
||||
#[cfg(target_os = "wasi")]
|
||||
mod sys {
|
||||
use super::TcpListener;
|
||||
use std::os::wasi::prelude::*;
|
||||
use std::os::fd::{RawFd, BorrowedFd, AsRawFd, AsFd};
|
||||
|
||||
impl AsRawFd for TcpListener {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
pub(crate) mod listener;
|
||||
|
||||
cfg_not_wasi! {
|
||||
cfg_not_wasip1! {
|
||||
pub(crate) mod socket;
|
||||
}
|
||||
|
||||
|
||||
+31
-21
@@ -4,8 +4,8 @@ use std::fmt;
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
|
||||
#[cfg(not(windows))]
|
||||
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use std::time::Duration;
|
||||
|
||||
cfg_windows! {
|
||||
@@ -170,7 +170,8 @@ impl TcpSocket {
|
||||
target_os = "illumos",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
target_os = "openbsd",
|
||||
target_os = "wasi",
|
||||
))]
|
||||
let ty = ty.nonblocking();
|
||||
let inner = socket2::Socket::new(domain, ty, Some(socket2::Protocol::TCP))?;
|
||||
@@ -182,7 +183,8 @@ impl TcpSocket {
|
||||
target_os = "illumos",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
target_os = "openbsd",
|
||||
target_os = "wasi",
|
||||
)))]
|
||||
inner.set_nonblocking(true)?;
|
||||
Ok(TcpSocket { inner })
|
||||
@@ -597,7 +599,8 @@ impl TcpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
)))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
@@ -606,7 +609,8 @@ impl TcpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
))))
|
||||
)]
|
||||
pub fn tos_v4(&self) -> io::Result<u32> {
|
||||
@@ -625,7 +629,8 @@ impl TcpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
)))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
@@ -634,7 +639,8 @@ impl TcpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
))))
|
||||
)]
|
||||
pub fn tos(&self) -> io::Result<u32> {
|
||||
@@ -657,7 +663,8 @@ impl TcpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
)))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
@@ -666,7 +673,8 @@ impl TcpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
))))
|
||||
)]
|
||||
pub fn set_tos_v4(&self, tos: u32) -> io::Result<()> {
|
||||
@@ -685,7 +693,8 @@ impl TcpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
)))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
@@ -694,7 +703,8 @@ impl TcpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
))))
|
||||
)]
|
||||
pub fn set_tos(&self, tos: u32) -> io::Result<()> {
|
||||
@@ -826,7 +836,7 @@ impl TcpSocket {
|
||||
/// ```
|
||||
pub async fn connect(self, addr: SocketAddr) -> io::Result<TcpStream> {
|
||||
if let Err(err) = self.inner.connect(&addr.into()) {
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(windows))]
|
||||
if err.raw_os_error() != Some(libc::EINPROGRESS) {
|
||||
return Err(err);
|
||||
}
|
||||
@@ -835,9 +845,9 @@ impl TcpSocket {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(windows))]
|
||||
let mio = {
|
||||
use std::os::unix::io::{FromRawFd, IntoRawFd};
|
||||
use std::os::fd::{FromRawFd, IntoRawFd};
|
||||
|
||||
let raw_fd = self.inner.into_raw_fd();
|
||||
unsafe { mio::net::TcpStream::from_raw_fd(raw_fd) }
|
||||
@@ -891,9 +901,9 @@ impl TcpSocket {
|
||||
/// ```
|
||||
pub fn listen(self, backlog: u32) -> io::Result<TcpListener> {
|
||||
self.inner.listen(backlog as i32)?;
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(windows))]
|
||||
let mio = {
|
||||
use std::os::unix::io::{FromRawFd, IntoRawFd};
|
||||
use std::os::fd::{FromRawFd, IntoRawFd};
|
||||
|
||||
let raw_fd = self.inner.into_raw_fd();
|
||||
unsafe { mio::net::TcpListener::from_raw_fd(raw_fd) }
|
||||
@@ -945,9 +955,9 @@ impl TcpSocket {
|
||||
/// }
|
||||
/// ```
|
||||
pub fn from_std_stream(std_stream: std::net::TcpStream) -> TcpSocket {
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
use std::os::unix::io::{FromRawFd, IntoRawFd};
|
||||
use std::os::fd::{FromRawFd, IntoRawFd};
|
||||
|
||||
let raw_fd = std_stream.into_raw_fd();
|
||||
unsafe { TcpSocket::from_raw_fd(raw_fd) }
|
||||
@@ -981,8 +991,8 @@ impl fmt::Debug for TcpSocket {
|
||||
|
||||
// These trait implementations can't be build on Windows, so we completely
|
||||
// ignore them, even when building documentation.
|
||||
#[cfg(unix)]
|
||||
cfg_unix! {
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
cfg_unix_or_wasi! {
|
||||
impl AsRawFd for TcpSocket {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.inner.as_raw_fd()
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
cfg_not_wasi! {
|
||||
use std::time::Duration;
|
||||
}
|
||||
|
||||
cfg_not_wasip1! {
|
||||
use crate::net::{to_socket_addrs, ToSocketAddrs};
|
||||
use std::future::poll_fn;
|
||||
use std::time::Duration;
|
||||
}
|
||||
|
||||
use crate::io::{AsyncRead, AsyncWrite, Interest, PollEvented, ReadBuf, Ready};
|
||||
@@ -73,7 +76,7 @@ cfg_net! {
|
||||
}
|
||||
|
||||
impl TcpStream {
|
||||
cfg_not_wasi! {
|
||||
cfg_not_wasip1! {
|
||||
/// Opens a TCP connection to a remote host.
|
||||
///
|
||||
/// `addr` is an address of the remote host. Anything which implements the
|
||||
@@ -272,7 +275,7 @@ impl TcpStream {
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
{
|
||||
use std::os::wasi::io::{FromRawFd, IntoRawFd};
|
||||
use std::os::fd::{FromRawFd, IntoRawFd};
|
||||
self.io
|
||||
.into_inner()
|
||||
.map(|io| io.into_raw_fd())
|
||||
@@ -1564,7 +1567,7 @@ cfg_windows! {
|
||||
#[cfg(all(tokio_unstable, target_os = "wasi"))]
|
||||
mod sys {
|
||||
use super::TcpStream;
|
||||
use std::os::wasi::prelude::*;
|
||||
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd};
|
||||
|
||||
impl AsRawFd for TcpStream {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
|
||||
+20
-12
@@ -254,9 +254,9 @@ impl UdpSocket {
|
||||
/// [`std::net::UdpSocket`]: std::net::UdpSocket
|
||||
/// [`set_nonblocking`]: fn@std::net::UdpSocket::set_nonblocking
|
||||
pub fn into_std(self) -> io::Result<std::net::UdpSocket> {
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
use std::os::unix::io::{FromRawFd, IntoRawFd};
|
||||
use std::os::fd::{FromRawFd, IntoRawFd};
|
||||
self.io
|
||||
.into_inner()
|
||||
.map(IntoRawFd::into_raw_fd)
|
||||
@@ -2084,7 +2084,8 @@ impl UdpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
)))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
@@ -2093,7 +2094,8 @@ impl UdpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
))))
|
||||
)]
|
||||
pub fn tos_v4(&self) -> io::Result<u32> {
|
||||
@@ -2112,7 +2114,8 @@ impl UdpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
)))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
@@ -2121,7 +2124,8 @@ impl UdpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
))))
|
||||
)]
|
||||
pub fn tos(&self) -> io::Result<u32> {
|
||||
@@ -2144,7 +2148,8 @@ impl UdpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
)))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
@@ -2153,7 +2158,8 @@ impl UdpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
))))
|
||||
)]
|
||||
pub fn set_tos_v4(&self, tos: u32) -> io::Result<()> {
|
||||
@@ -2172,7 +2178,8 @@ impl UdpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
)))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
@@ -2181,7 +2188,8 @@ impl UdpSocket {
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi",
|
||||
))))
|
||||
)]
|
||||
pub fn set_tos(&self, tos: u32) -> io::Result<()> {
|
||||
@@ -2297,10 +2305,10 @@ impl fmt::Debug for UdpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[cfg(not(windows))]
|
||||
mod sys {
|
||||
use super::UdpSocket;
|
||||
use std::os::unix::prelude::*;
|
||||
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd};
|
||||
|
||||
impl AsRawFd for UdpSocket {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
|
||||
@@ -118,7 +118,7 @@ impl Registration {
|
||||
|
||||
// Uses the poll path, requiring the caller to ensure mutual exclusion for
|
||||
// correctness. Only the last task to call this function is notified.
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
#[cfg(not(all(target_os = "wasi", target_env = "p1")))]
|
||||
pub(crate) fn poll_read_io<R>(
|
||||
&self,
|
||||
cx: &mut Context<'_>,
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support panic recovery or bind
|
||||
// WASIp1 doesn't support bind
|
||||
// No `socket` on miri.
|
||||
#![cfg(all(
|
||||
feature = "net",
|
||||
feature = "macros",
|
||||
feature = "rt",
|
||||
feature = "io-util",
|
||||
not(all(target_os = "wasi", target_env = "p1")),
|
||||
not(miri)
|
||||
))]
|
||||
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support direct socket operations
|
||||
// WASIp1 doesn't support direct socket operations
|
||||
#![cfg(all(
|
||||
feature = "net",
|
||||
feature = "macros",
|
||||
feature = "rt",
|
||||
feature = "io-util",
|
||||
not(all(target_os = "wasi", target_env = "p1")),
|
||||
))]
|
||||
|
||||
use tokio::net;
|
||||
use tokio_test::assert_ok;
|
||||
@@ -22,6 +29,13 @@ async fn lookup_str_socket_addr() {
|
||||
assert_eq!(vec![addr], actual);
|
||||
}
|
||||
|
||||
// Note that WASIp2 _does_ support asynchronous name lookups without requiring a
|
||||
// worker thread, so this test could be ungated for WASI if/when that's
|
||||
// implemented.
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "net::lookup_host requires multithreading, which WASI does not yet support"
|
||||
)]
|
||||
#[tokio::test]
|
||||
#[cfg_attr(miri, ignore)] // No `getaddrinfo` in miri.
|
||||
async fn resolve_dns() -> io::Result<()> {
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
|
||||
// No `socket` on miri.
|
||||
// WASIp1 doesn't support bind
|
||||
// No `socket` on miri.
|
||||
#![cfg(all(
|
||||
feature = "net",
|
||||
feature = "macros",
|
||||
feature = "rt",
|
||||
feature = "io-util",
|
||||
not(all(target_os = "wasi", target_env = "p1")),
|
||||
not(miri)
|
||||
))]
|
||||
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
@@ -10,8 +18,9 @@ use std::io;
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
|
||||
macro_rules! test_accept {
|
||||
($(($ident:ident, $target:expr),)*) => {
|
||||
($($(#[$attribute:meta])*($ident:ident, $target:expr),)*) => {
|
||||
$(
|
||||
$(#[$attribute])*
|
||||
#[tokio::test]
|
||||
async fn $ident() {
|
||||
let listener = assert_ok!(TcpListener::bind($target).await);
|
||||
@@ -35,6 +44,10 @@ macro_rules! test_accept {
|
||||
|
||||
test_accept! {
|
||||
(ip_str, "127.0.0.1:0"),
|
||||
// Note that WASIp2 _does_ support asynchronous name lookups without
|
||||
// requiring a worker thread, so this test could be ungated if/when that's
|
||||
// implemented.
|
||||
#[cfg_attr(target_os = "wasi", ignore = "net::lookup_host requires multithreading, which WASI does not yet support")]
|
||||
(host_str, "localhost:0"),
|
||||
(socket_addr, "127.0.0.1:0".parse::<SocketAddr>().unwrap()),
|
||||
(str_port_tuple, ("127.0.0.1", 0)),
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
|
||||
// No `socket` on miri.
|
||||
// WASIp1 doesn't support bind
|
||||
// No `socket` on miri.
|
||||
#![cfg(all(
|
||||
feature = "net",
|
||||
feature = "macros",
|
||||
feature = "rt",
|
||||
feature = "io-util",
|
||||
not(all(target_os = "wasi", target_env = "p1")),
|
||||
not(miri)
|
||||
))]
|
||||
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
use tokio::sync::oneshot;
|
||||
@@ -96,6 +104,13 @@ async fn connect_addr_ip_str_slice() {
|
||||
join!(server, client);
|
||||
}
|
||||
|
||||
// Note that WASIp2 _does_ support asynchronous name lookups without
|
||||
// requiring a worker thread, so this test could be ungated if/when that's
|
||||
// implemented.
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "net::lookup_host requires multithreading, which WASI does not yet support"
|
||||
)]
|
||||
#[tokio::test]
|
||||
async fn connect_addr_host_string() {
|
||||
let srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
@@ -147,6 +162,13 @@ async fn connect_addr_ip_str_port_tuple() {
|
||||
join!(server, client);
|
||||
}
|
||||
|
||||
// Note that WASIp2 _does_ support asynchronous name lookups without
|
||||
// requiring a worker thread, so this test could be ungated if/when that's
|
||||
// implemented.
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "net::lookup_host requires multithreading, which WASI does not yet support"
|
||||
)]
|
||||
#[tokio::test]
|
||||
async fn connect_addr_host_str_port_tuple() {
|
||||
let srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
|
||||
+10
-2
@@ -1,6 +1,14 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
|
||||
// No socket on miri.
|
||||
// WASIp1 doesn't support bind
|
||||
// No `socket` on miri.
|
||||
#![cfg(all(
|
||||
feature = "net",
|
||||
feature = "macros",
|
||||
feature = "rt",
|
||||
feature = "io-util",
|
||||
not(all(target_os = "wasi", target_env = "p1")),
|
||||
not(miri)
|
||||
))]
|
||||
|
||||
use tokio::io::{self, AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support multithreading or peeking
|
||||
// No `socket` on miri.
|
||||
|
||||
use std::io::{Error, ErrorKind, Result};
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
|
||||
// No socket on `miri`.
|
||||
// WASIp1 doesn't support bind
|
||||
// No `socket` on miri.
|
||||
#![cfg(all(
|
||||
feature = "net",
|
||||
feature = "macros",
|
||||
feature = "rt",
|
||||
feature = "io-util",
|
||||
not(all(target_os = "wasi", target_env = "p1")),
|
||||
not(miri)
|
||||
))]
|
||||
|
||||
use std::io::Read;
|
||||
use std::io::Result;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support peeking
|
||||
// No `socket` on miri.
|
||||
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support mulithreading
|
||||
// No `socket` on miri.
|
||||
|
||||
use tokio::io::{self, AsyncReadExt, AsyncWriteExt};
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
|
||||
// No `socket` on miri.
|
||||
// WASIp1 doesn't support bind
|
||||
// No `socket` on miri.
|
||||
#![cfg(all(
|
||||
feature = "net",
|
||||
feature = "macros",
|
||||
feature = "rt",
|
||||
feature = "io-util",
|
||||
not(all(target_os = "wasi", target_env = "p1")),
|
||||
not(miri)
|
||||
))]
|
||||
|
||||
use std::time::Duration;
|
||||
use tokio::net::TcpSocket;
|
||||
@@ -61,6 +69,7 @@ async fn bind_before_connect() {
|
||||
let _ = assert_ok!(srv.accept().await);
|
||||
}
|
||||
|
||||
#[cfg_attr(target_os = "wasi", ignore = "WASI does not yet support `SO_LINGER`")]
|
||||
#[tokio::test]
|
||||
async fn basic_linger() {
|
||||
// Create server
|
||||
@@ -154,6 +163,7 @@ test!(
|
||||
);
|
||||
|
||||
test!(
|
||||
#[cfg_attr(target_os = "wasi", ignore = "WASI does not yet support `SO_LINGER`")]
|
||||
#[expect(deprecated, reason = "set_linger is deprecated")]
|
||||
linger,
|
||||
set_linger(Some(Duration::from_secs(10)))
|
||||
@@ -179,6 +189,7 @@ test!(IPv6 tclass_v6, set_tclass_v6(96));
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi"
|
||||
)))]
|
||||
test!(IPv4 tos_v4, set_tos_v4(96));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support peeking
|
||||
// No `socket` on miri.
|
||||
|
||||
use std::io::Result;
|
||||
|
||||
+47
-14
@@ -1,5 +1,14 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support bind
|
||||
// WASIp1 doesn't support bind
|
||||
// No `socket` on miri.
|
||||
#![cfg(all(
|
||||
feature = "net",
|
||||
feature = "macros",
|
||||
feature = "rt",
|
||||
feature = "io-util",
|
||||
not(all(target_os = "wasi", target_env = "p1")),
|
||||
not(miri)
|
||||
))]
|
||||
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt, Interest};
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
@@ -10,9 +19,11 @@ use tokio_test::{assert_ok, assert_pending, assert_ready_ok};
|
||||
use std::future::poll_fn;
|
||||
use std::io;
|
||||
use std::task::Poll;
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
use std::time::Duration;
|
||||
|
||||
#[tokio::test]
|
||||
#[cfg(not(target_os = "wasi"))] // WASI does not yet support `SO_LINGER`
|
||||
#[cfg_attr(miri, ignore)] // No `socket` on miri.
|
||||
#[expect(deprecated)] // set_linger is deprecated
|
||||
async fn set_linger() {
|
||||
@@ -33,6 +44,10 @@ async fn set_linger() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "temporarily disabled for WASI pending https://github.com/WebAssembly/wasi-libc/pull/734"
|
||||
)]
|
||||
#[cfg_attr(miri, ignore)] // No `socket` on miri.
|
||||
async fn try_read_write() {
|
||||
const DATA: &[u8] = b"this is some data to write to the socket";
|
||||
@@ -98,6 +113,7 @@ async fn try_read_write() {
|
||||
}
|
||||
|
||||
written.clear();
|
||||
written.reserve(10 * 1024 * 1024);
|
||||
client.writable().await.unwrap();
|
||||
|
||||
// Fill the write buffer using vectored I/O
|
||||
@@ -108,7 +124,9 @@ async fn try_read_write() {
|
||||
assert_ready_ok!(writable.poll());
|
||||
|
||||
match client.try_write_vectored(&data_bufs) {
|
||||
Ok(n) => written.extend(&DATA[..n]),
|
||||
Ok(n) => {
|
||||
written.extend(&DATA[..n]);
|
||||
}
|
||||
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
|
||||
break;
|
||||
}
|
||||
@@ -145,13 +163,16 @@ async fn try_read_write() {
|
||||
// Now, we listen for shutdown
|
||||
drop(client);
|
||||
|
||||
loop {
|
||||
let ready = server.ready(Interest::READABLE).await.unwrap();
|
||||
#[cfg(not(target_os = "wasi"))] // WASI does not yet support `POLLHUP` or `POLLRDHUP`
|
||||
{
|
||||
loop {
|
||||
let ready = server.ready(Interest::READABLE).await.unwrap();
|
||||
|
||||
if ready.is_read_closed() {
|
||||
return;
|
||||
} else {
|
||||
tokio::task::yield_now().await;
|
||||
if ready.is_read_closed() {
|
||||
return;
|
||||
} else {
|
||||
tokio::task::yield_now().await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -359,19 +380,31 @@ async fn try_read_buf() {
|
||||
// Now, we listen for shutdown
|
||||
drop(client);
|
||||
|
||||
loop {
|
||||
let ready = server.ready(Interest::READABLE).await.unwrap();
|
||||
#[cfg(not(target_os = "wasi"))] // WASI does not yet support `POLLHUP` or `POLLRDHUP`
|
||||
{
|
||||
let mut count = 0;
|
||||
loop {
|
||||
count += 1;
|
||||
if count > 100 {
|
||||
panic!("loop 4")
|
||||
}
|
||||
let ready = server.ready(Interest::READABLE).await.unwrap();
|
||||
|
||||
if ready.is_read_closed() {
|
||||
return;
|
||||
} else {
|
||||
tokio::task::yield_now().await;
|
||||
if ready.is_read_closed() {
|
||||
return;
|
||||
} else {
|
||||
tokio::task::yield_now().await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// read_closed is a best effort event, so test only for no false positives.
|
||||
#[tokio::test]
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "temporarily disabled for WASI pending https://github.com/WebAssembly/wasi-libc/pull/732"
|
||||
)]
|
||||
#[cfg_attr(miri, ignore)] // No `socket` on miri.
|
||||
async fn read_closed() {
|
||||
let (client, mut server) = create_pair().await;
|
||||
|
||||
+49
-3
@@ -1,6 +1,14 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi does not support bind or UDP
|
||||
// No `socket` on miri.
|
||||
// WASIp1 doesn't support bind
|
||||
// No `socket` on miri.
|
||||
#![cfg(all(
|
||||
feature = "net",
|
||||
feature = "macros",
|
||||
feature = "rt",
|
||||
feature = "io-util",
|
||||
not(all(target_os = "wasi", target_env = "p1")),
|
||||
not(miri)
|
||||
))]
|
||||
|
||||
use std::future::poll_fn;
|
||||
use std::io;
|
||||
@@ -47,6 +55,10 @@ async fn send_recv_poll() -> std::io::Result<()> {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "temporarily disabled for WASI pending https://github.com/WebAssembly/wasi-libc/pull/734"
|
||||
)]
|
||||
async fn send_to_recv_from() -> std::io::Result<()> {
|
||||
let sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let receiver = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
@@ -63,6 +75,10 @@ async fn send_to_recv_from() -> std::io::Result<()> {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "temporarily disabled for WASI pending https://github.com/WebAssembly/wasi-libc/pull/734"
|
||||
)]
|
||||
async fn send_to_recv_from_poll() -> std::io::Result<()> {
|
||||
let sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let receiver = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
@@ -79,6 +95,7 @@ async fn send_to_recv_from_poll() -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg_attr(target_os = "wasi", ignore = "WASI does not yet support peeking")]
|
||||
#[tokio::test]
|
||||
async fn send_to_peek_from() -> std::io::Result<()> {
|
||||
let sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
@@ -107,6 +124,7 @@ async fn send_to_peek_from() -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg_attr(target_os = "wasi", ignore = "WASI does not yet support peeking")]
|
||||
#[tokio::test]
|
||||
async fn send_to_try_peek_from() -> std::io::Result<()> {
|
||||
let sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
@@ -146,6 +164,7 @@ async fn send_to_try_peek_from() -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg_attr(target_os = "wasi", ignore = "WASI does not yet support peeking")]
|
||||
#[tokio::test]
|
||||
async fn send_to_peek_from_poll() -> std::io::Result<()> {
|
||||
let sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
@@ -174,6 +193,7 @@ async fn send_to_peek_from_poll() -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg_attr(target_os = "wasi", ignore = "WASI does not yet support peeking")]
|
||||
#[tokio::test]
|
||||
async fn peek_sender() -> std::io::Result<()> {
|
||||
let sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
@@ -199,6 +219,7 @@ async fn peek_sender() -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg_attr(target_os = "wasi", ignore = "WASI does not yet support peeking")]
|
||||
#[tokio::test]
|
||||
async fn poll_peek_sender() -> std::io::Result<()> {
|
||||
let sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
@@ -225,6 +246,7 @@ async fn poll_peek_sender() -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg_attr(target_os = "wasi", ignore = "WASI does not yet support peeking")]
|
||||
#[tokio::test]
|
||||
async fn try_peek_sender() -> std::io::Result<()> {
|
||||
let sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
@@ -353,6 +375,10 @@ async fn split_chan_poll() -> std::io::Result<()> {
|
||||
// **not** be okay because it's resources are completion based (via IOCP).
|
||||
// If data is sent and not yet received, attempting to send more data will
|
||||
// result in `ErrorKind::WouldBlock` until the first operation completes.
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "WASI does not yet support multithreading"
|
||||
)]
|
||||
#[tokio::test]
|
||||
async fn try_send_spawn() {
|
||||
const MSG2: &[u8] = b"world!";
|
||||
@@ -439,6 +465,10 @@ async fn try_send_recv() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "temporarily disabled for WASI pending https://github.com/WebAssembly/wasi-libc/pull/734"
|
||||
)]
|
||||
async fn try_send_to_recv_from() {
|
||||
// Create listener
|
||||
let server = UdpSocket::bind("127.0.0.1:0").await.unwrap();
|
||||
@@ -543,6 +573,10 @@ async fn recv_buf() -> std::io::Result<()> {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "temporarily disabled for WASI pending https://github.com/WebAssembly/wasi-libc/pull/734"
|
||||
)]
|
||||
async fn try_recv_buf_from() {
|
||||
// Create listener
|
||||
let server = UdpSocket::bind("127.0.0.1:0").await.unwrap();
|
||||
@@ -586,6 +620,10 @@ async fn try_recv_buf_from() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "temporarily disabled for WASI pending https://github.com/WebAssembly/wasi-libc/pull/734"
|
||||
)]
|
||||
async fn recv_buf_from() -> std::io::Result<()> {
|
||||
let sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let receiver = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
@@ -603,6 +641,10 @@ async fn recv_buf_from() -> std::io::Result<()> {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[cfg_attr(
|
||||
target_os = "wasi",
|
||||
ignore = "temporarily disabled for WASI pending https://github.com/WebAssembly/wasi-libc/pull/734"
|
||||
)]
|
||||
async fn poll_ready() {
|
||||
// Create listener
|
||||
let server = UdpSocket::bind("127.0.0.1:0").await.unwrap();
|
||||
@@ -690,13 +732,16 @@ macro_rules! test {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "wasi"))] // WASI does not yet support broadcast
|
||||
test!(broadcast, set_broadcast(true));
|
||||
|
||||
#[cfg(not(target_os = "wasi"))] // WASI does not yet support multicast
|
||||
test!(IPv4 multicast_loop_v4, set_multicast_loop_v4(false));
|
||||
|
||||
#[cfg(target_os = "linux")] // broken on non-Linux platforms https://github.com/rust-lang/socket2/pull/630
|
||||
test!(multicast_ttl_v4, set_multicast_ttl_v4(40));
|
||||
|
||||
#[cfg(not(target_os = "wasi"))] // WASI does not yet support multicast
|
||||
test!(IPv6 multicast_loop_v6, set_multicast_loop_v6(false));
|
||||
|
||||
#[cfg(any(
|
||||
@@ -719,6 +764,7 @@ test!(IPv4 ttl, set_ttl(40));
|
||||
target_os = "redox",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "haiku"
|
||||
target_os = "haiku",
|
||||
target_os = "wasi"
|
||||
)))]
|
||||
test!(IPv4 tos_v4, set_tos_v4(96));
|
||||
|
||||
Reference in New Issue
Block a user