Path: blob/main/crates/wasi/src/p2/host/network.rs
3068 views
use crate::p2::SocketError;1use crate::p2::bindings::sockets::network::{2self, ErrorCode, IpAddress, IpAddressFamily, IpSocketAddress, Ipv4SocketAddress,3Ipv6SocketAddress,4};5use crate::sockets::WasiSocketsCtxView;6use crate::sockets::util::{from_ipv4_addr, from_ipv6_addr, to_ipv4_addr, to_ipv6_addr};7use rustix::io::Errno;8use std::io;9use wasmtime::Error;10use wasmtime::component::Resource;1112impl network::Host for WasiSocketsCtxView<'_> {13fn convert_error_code(&mut self, error: SocketError) -> wasmtime::Result<ErrorCode> {14error.downcast()15}1617fn network_error_code(&mut self, err: Resource<Error>) -> wasmtime::Result<Option<ErrorCode>> {18let err = self.table.get(&err)?;1920if let Some(err) = err.downcast_ref::<std::io::Error>() {21return Ok(Some(ErrorCode::from(err)));22}2324Ok(None)25}26}2728impl crate::p2::bindings::sockets::network::HostNetwork for WasiSocketsCtxView<'_> {29fn drop(&mut self, this: Resource<network::Network>) -> Result<(), wasmtime::Error> {30self.table.delete(this)?;3132Ok(())33}34}3536impl From<io::Error> for ErrorCode {37fn from(value: io::Error) -> Self {38(&value).into()39}40}4142impl From<&io::Error> for ErrorCode {43fn from(value: &io::Error) -> Self {44// Attempt the more detailed native error code first:45if let Some(errno) = Errno::from_io_error(value) {46return errno.into();47}4849match value.kind() {50std::io::ErrorKind::AddrInUse => ErrorCode::AddressInUse,51std::io::ErrorKind::AddrNotAvailable => ErrorCode::AddressNotBindable,52std::io::ErrorKind::ConnectionAborted => ErrorCode::ConnectionAborted,53std::io::ErrorKind::ConnectionRefused => ErrorCode::ConnectionRefused,54std::io::ErrorKind::ConnectionReset => ErrorCode::ConnectionReset,55std::io::ErrorKind::Interrupted => ErrorCode::WouldBlock,56std::io::ErrorKind::InvalidInput => ErrorCode::InvalidArgument,57std::io::ErrorKind::NotConnected => ErrorCode::InvalidState,58std::io::ErrorKind::OutOfMemory => ErrorCode::OutOfMemory,59std::io::ErrorKind::PermissionDenied => ErrorCode::AccessDenied,60std::io::ErrorKind::TimedOut => ErrorCode::Timeout,61std::io::ErrorKind::Unsupported => ErrorCode::NotSupported,62std::io::ErrorKind::WouldBlock => ErrorCode::WouldBlock,6364_ => {65tracing::debug!("unknown I/O error: {value}");66ErrorCode::Unknown67}68}69}70}7172impl From<Errno> for ErrorCode {73fn from(value: Errno) -> Self {74(&value).into()75}76}7778impl From<&Errno> for ErrorCode {79fn from(value: &Errno) -> Self {80match *value {81Errno::WOULDBLOCK => ErrorCode::WouldBlock,82#[allow(83unreachable_patterns,84reason = "EWOULDBLOCK and EAGAIN can have the same value"85)]86Errno::AGAIN => ErrorCode::WouldBlock,87Errno::INTR => ErrorCode::WouldBlock,88#[cfg(not(windows))]89Errno::PERM => ErrorCode::AccessDenied,90Errno::ACCESS => ErrorCode::AccessDenied,91Errno::ADDRINUSE => ErrorCode::AddressInUse,92Errno::ADDRNOTAVAIL => ErrorCode::AddressNotBindable,93Errno::ALREADY => ErrorCode::ConcurrencyConflict,94Errno::TIMEDOUT => ErrorCode::Timeout,95Errno::CONNREFUSED => ErrorCode::ConnectionRefused,96Errno::CONNRESET => ErrorCode::ConnectionReset,97Errno::CONNABORTED => ErrorCode::ConnectionAborted,98Errno::INVAL => ErrorCode::InvalidArgument,99Errno::HOSTUNREACH => ErrorCode::RemoteUnreachable,100Errno::HOSTDOWN => ErrorCode::RemoteUnreachable,101Errno::NETDOWN => ErrorCode::RemoteUnreachable,102Errno::NETUNREACH => ErrorCode::RemoteUnreachable,103#[cfg(target_os = "linux")]104Errno::NONET => ErrorCode::RemoteUnreachable,105Errno::ISCONN => ErrorCode::InvalidState,106Errno::NOTCONN => ErrorCode::InvalidState,107Errno::DESTADDRREQ => ErrorCode::InvalidState,108#[cfg(not(windows))]109Errno::NFILE => ErrorCode::NewSocketLimit,110Errno::MFILE => ErrorCode::NewSocketLimit,111Errno::MSGSIZE => ErrorCode::DatagramTooLarge,112#[cfg(not(windows))]113Errno::NOMEM => ErrorCode::OutOfMemory,114Errno::NOBUFS => ErrorCode::OutOfMemory,115Errno::OPNOTSUPP => ErrorCode::NotSupported,116Errno::NOPROTOOPT => ErrorCode::NotSupported,117Errno::PFNOSUPPORT => ErrorCode::NotSupported,118Errno::PROTONOSUPPORT => ErrorCode::NotSupported,119Errno::PROTOTYPE => ErrorCode::NotSupported,120Errno::SOCKTNOSUPPORT => ErrorCode::NotSupported,121Errno::AFNOSUPPORT => ErrorCode::NotSupported,122123// FYI, EINPROGRESS should have already been handled by connect.124_ => {125tracing::debug!("unknown I/O error: {value}");126ErrorCode::Unknown127}128}129}130}131132impl From<std::net::IpAddr> for IpAddress {133fn from(addr: std::net::IpAddr) -> Self {134match addr {135std::net::IpAddr::V4(v4) => Self::Ipv4(from_ipv4_addr(v4)),136std::net::IpAddr::V6(v6) => Self::Ipv6(from_ipv6_addr(v6)),137}138}139}140141impl From<IpSocketAddress> for std::net::SocketAddr {142fn from(addr: IpSocketAddress) -> Self {143match addr {144IpSocketAddress::Ipv4(ipv4) => Self::V4(ipv4.into()),145IpSocketAddress::Ipv6(ipv6) => Self::V6(ipv6.into()),146}147}148}149150impl From<std::net::SocketAddr> for IpSocketAddress {151fn from(addr: std::net::SocketAddr) -> Self {152match addr {153std::net::SocketAddr::V4(v4) => Self::Ipv4(v4.into()),154std::net::SocketAddr::V6(v6) => Self::Ipv6(v6.into()),155}156}157}158159impl From<Ipv4SocketAddress> for std::net::SocketAddrV4 {160fn from(addr: Ipv4SocketAddress) -> Self {161Self::new(to_ipv4_addr(addr.address), addr.port)162}163}164165impl From<std::net::SocketAddrV4> for Ipv4SocketAddress {166fn from(addr: std::net::SocketAddrV4) -> Self {167Self {168address: from_ipv4_addr(*addr.ip()),169port: addr.port(),170}171}172}173174impl From<Ipv6SocketAddress> for std::net::SocketAddrV6 {175fn from(addr: Ipv6SocketAddress) -> Self {176Self::new(177to_ipv6_addr(addr.address),178addr.port,179addr.flow_info,180addr.scope_id,181)182}183}184185impl From<std::net::SocketAddrV6> for Ipv6SocketAddress {186fn from(addr: std::net::SocketAddrV6) -> Self {187Self {188address: from_ipv6_addr(*addr.ip()),189port: addr.port(),190flow_info: addr.flowinfo(),191scope_id: addr.scope_id(),192}193}194}195196impl std::net::ToSocketAddrs for IpSocketAddress {197type Iter = <std::net::SocketAddr as std::net::ToSocketAddrs>::Iter;198199fn to_socket_addrs(&self) -> io::Result<Self::Iter> {200std::net::SocketAddr::from(*self).to_socket_addrs()201}202}203204impl std::net::ToSocketAddrs for Ipv4SocketAddress {205type Iter = <std::net::SocketAddrV4 as std::net::ToSocketAddrs>::Iter;206207fn to_socket_addrs(&self) -> io::Result<Self::Iter> {208std::net::SocketAddrV4::from(*self).to_socket_addrs()209}210}211212impl std::net::ToSocketAddrs for Ipv6SocketAddress {213type Iter = <std::net::SocketAddrV6 as std::net::ToSocketAddrs>::Iter;214215fn to_socket_addrs(&self) -> io::Result<Self::Iter> {216std::net::SocketAddrV6::from(*self).to_socket_addrs()217}218}219220impl From<IpAddressFamily> for cap_net_ext::AddressFamily {221fn from(family: IpAddressFamily) -> Self {222match family {223IpAddressFamily::Ipv4 => cap_net_ext::AddressFamily::Ipv4,224IpAddressFamily::Ipv6 => cap_net_ext::AddressFamily::Ipv6,225}226}227}228229impl From<cap_net_ext::AddressFamily> for IpAddressFamily {230fn from(family: cap_net_ext::AddressFamily) -> Self {231match family {232cap_net_ext::AddressFamily::Ipv4 => IpAddressFamily::Ipv4,233cap_net_ext::AddressFamily::Ipv6 => IpAddressFamily::Ipv6,234}235}236}237238239