alnyan/yggdrasil: implement UDP sockets

This commit is contained in:
2024-01-22 14:42:33 +02:00
parent c123bfb0f6
commit 6388aab487
12 changed files with 550 additions and 130 deletions
+6
View File
@@ -2,7 +2,9 @@
#[cfg(all(test, not(target_os = "emscripten")))]
mod tests;
#[cfg(not(target_os = "yggdrasil"))]
use crate::sys::net::netc as c;
#[cfg(not(target_os = "yggdrasil"))]
use crate::sys_common::{FromInner, IntoInner};
#[stable(feature = "ip_addr", since = "1.7.0")]
@@ -14,6 +16,7 @@ pub use core::net::{Ipv4Addr, Ipv6Addr};
#[unstable(feature = "ip", issue = "27709")]
pub use core::net::Ipv6MulticastScope;
#[cfg(not(target_os = "yggdrasil"))]
impl IntoInner<c::in_addr> for Ipv4Addr {
#[inline]
fn into_inner(self) -> c::in_addr {
@@ -22,17 +25,20 @@ impl IntoInner<c::in_addr> for Ipv4Addr {
c::in_addr { s_addr: u32::from_ne_bytes(self.octets()) }
}
}
#[cfg(not(target_os = "yggdrasil"))]
impl FromInner<c::in_addr> for Ipv4Addr {
fn from_inner(addr: c::in_addr) -> Ipv4Addr {
Ipv4Addr::from(addr.s_addr.to_ne_bytes())
}
}
#[cfg(not(target_os = "yggdrasil"))]
impl IntoInner<c::in6_addr> for Ipv6Addr {
fn into_inner(self) -> c::in6_addr {
c::in6_addr { s6_addr: self.octets() }
}
}
#[cfg(not(target_os = "yggdrasil"))]
impl FromInner<c::in6_addr> for Ipv6Addr {
#[inline]
fn from_inner(addr: c::in6_addr) -> Ipv6Addr {
+7
View File
@@ -4,24 +4,29 @@ mod tests;
use crate::io;
use crate::iter;
#[cfg(not(target_os = "yggdrasil"))]
use crate::mem;
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use crate::option;
use crate::slice;
#[cfg(not(target_os = "yggdrasil"))]
use crate::sys::net::netc as c;
use crate::sys_common::net::LookupHost;
#[cfg(not(target_os = "yggdrasil"))]
use crate::sys_common::{FromInner, IntoInner};
use crate::vec;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
#[cfg(not(target_os = "yggdrasil"))]
impl FromInner<c::sockaddr_in> for SocketAddrV4 {
fn from_inner(addr: c::sockaddr_in) -> SocketAddrV4 {
SocketAddrV4::new(Ipv4Addr::from_inner(addr.sin_addr), u16::from_be(addr.sin_port))
}
}
#[cfg(not(target_os = "yggdrasil"))]
impl FromInner<c::sockaddr_in6> for SocketAddrV6 {
fn from_inner(addr: c::sockaddr_in6) -> SocketAddrV6 {
SocketAddrV6::new(
@@ -33,6 +38,7 @@ impl FromInner<c::sockaddr_in6> for SocketAddrV6 {
}
}
#[cfg(not(target_os = "yggdrasil"))]
impl IntoInner<c::sockaddr_in> for SocketAddrV4 {
fn into_inner(self) -> c::sockaddr_in {
c::sockaddr_in {
@@ -44,6 +50,7 @@ impl IntoInner<c::sockaddr_in> for SocketAddrV4 {
}
}
#[cfg(not(target_os = "yggdrasil"))]
impl IntoInner<c::sockaddr_in6> for SocketAddrV6 {
fn into_inner(self) -> c::sockaddr_in6 {
c::sockaddr_in6 {
+3
View File
@@ -15,6 +15,9 @@ pub mod terminal;
// Public exports
#[unstable(feature = "yggdrasil_os", issue = "none")]
pub use net::raw_socket;
#[stable(feature = "io_safety", since = "1.63.0")]
pub use owned::*;
#[stable(feature = "rust1", since = "1.0.0")]
-45
View File
@@ -1,45 +0,0 @@
use crate::os::yggdrasil::io::OwnedFd;
use crate::os::yggdrasil::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
use crate::{net, sys};
macro_rules! impl_as_raw_fd {
($($t:ident)*) => {$(
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::$t {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.as_inner().socket().as_raw_fd()
}
}
)*};
}
macro_rules! impl_from_raw_fd {
($($t:ident)*) => {$(
#[stable(feature = "rust1", since = "1.0.0")]
impl FromRawFd for net::$t {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> net::$t {
let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd)));
net::$t::from_inner(sys_common::net::$t::from_inner(socket))
}
}
)*};
}
macro_rules! impl_into_raw_fd {
($($t:ident)*) => {$(
#[stable(feature = "rust1", since = "1.0.0")]
impl IntoRawFd for net::$t {
#[inline]
fn into_raw_fd(self) -> RawFd {
self.into_inner().into_socket().into_inner().into_raw_fd()
}
}
)*};
}
impl_as_raw_fd! { TcpStream TcpListener UdpSocket }
impl_from_raw_fd! { TcpStream TcpListener UdpSocket }
impl_into_raw_fd! { TcpStream TcpListener UdpSocket }
@@ -0,0 +1 @@
pub mod raw_socket;
@@ -0,0 +1,49 @@
#![unstable(feature = "yggdrasil_os", issue = "none")]
use yggdrasil_rt::{
net::{MacAddress, SocketInterfaceQuery, SocketOption, SocketType},
sys as syscall,
};
use crate::io;
use crate::mem::MaybeUninit;
use crate::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use crate::os::fd::{AsRawFd, FromRawFd};
use crate::sys::cvt_io;
use crate::sys::io::FileDesc;
#[unstable(feature = "yggdrasil_os", issue = "none")]
pub struct RawSocket(FileDesc);
impl RawSocket {
#[unstable(feature = "yggdrasil_os", issue = "none")]
pub fn bind<'a, Q: Into<SocketInterfaceQuery<'a>>>(interface: Q) -> io::Result<Self> {
// TODO this is atrocious
let query = interface.into();
let bind_address = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0));
let raw = cvt_io(unsafe { syscall::bind_socket(&bind_address, SocketType::RawPacket) })?;
let inner = unsafe { FileDesc::from_raw_fd(raw) };
cvt_io(unsafe {
syscall::set_socket_option(inner.as_raw_fd(), &SocketOption::BindInterface(query))
})?;
Ok(Self(inner))
}
pub fn send(&self, data: &[u8]) -> io::Result<usize> {
cvt_io(unsafe { syscall::send_to(self.0.as_raw_fd(), data, &None) })
}
pub fn recv(&self, data: &mut [u8]) -> io::Result<usize> {
let mut discard = MaybeUninit::uninit();
cvt_io(unsafe { syscall::receive_from(self.0.as_raw_fd(), data, &mut discard) })
}
pub fn hardware_address(&self) -> io::Result<[u8; 6]> {
let mut value = SocketOption::BoundHardwareAddress(MacAddress::BROADCAST);
cvt_io(unsafe { syscall::get_socket_option(self.0.as_raw_fd(), &mut value) })?;
let SocketOption::BoundHardwareAddress(value) = value else {
unreachable!();
};
Ok(value.into())
}
}
+3
View File
@@ -166,6 +166,9 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
| Ok(OsError::InvalidOperation) => ErrorKind::InvalidInput,
Ok(OsError::NotImplemented) => ErrorKind::Unsupported,
// Network
Ok(OsError::HostUnreachable) => ErrorKind::HostUnreachable,
// Uncategorized
Ok(OsError::InvalidFile) => ErrorKind::Uncategorized,
Err(_) => ErrorKind::Uncategorized,
+198
View File
@@ -0,0 +1,198 @@
#![allow(dead_code)]
// use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
// use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
// use crate::os::yggdrasil::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
// use crate::sys::io::FileDesc;
// use crate::sys_common::{AsInner, FromInner, IntoInner};
// use crate::time::Duration;
//
// pub use crate::sys::{cvt, cvt_r};
// pub use super::yggdrasil_rt::netc;
mod tcp_listener;
mod tcp_stream;
mod udp;
pub use tcp_listener::TcpListener;
pub use tcp_stream::TcpStream;
pub use udp::UdpSocket;
use crate::net::SocketAddr;
pub struct LookupHost(!);
impl LookupHost {
pub fn port(&self) -> u16 {
todo!()
}
}
impl Iterator for LookupHost {
type Item = SocketAddr;
fn next(&mut self) -> Option<SocketAddr> {
todo!()
}
}
impl TryFrom<&str> for LookupHost {
type Error = crate::io::Error;
fn try_from(_s: &str) -> crate::io::Result<Self> {
todo!()
}
}
impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
type Error = crate::io::Error;
fn try_from(_s: (&'a str, u16)) -> crate::io::Result<Self> {
todo!()
}
}
// pub type wrlen_t = usize;
// #[derive(Debug)]
// pub struct Socket(FileDesc);
//
// impl Socket {
// pub fn new(_addr: &SocketAddr, _ty: i32) -> io::Result<Socket> {
// todo!()
// }
//
// pub fn connect_timeout(&self, _addr: &SocketAddr, _timeout: Duration) -> io::Result<()> {
// todo!()
// }
//
// pub fn set_linger(&self, _linger: Option<Duration>) -> io::Result<()> {
// todo!()
// }
//
// pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> {
// todo!()
// }
//
// pub fn linger(&self) -> io::Result<Option<Duration>> {
// todo!()
// }
//
// pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> {
// todo!()
// }
//
// pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
// todo!()
// }
//
// pub fn accept(
// &self,
// _storage: *mut netc::sockaddr,
// _len: *mut netc::socklen_t,
// ) -> io::Result<Self> {
// todo!()
// }
//
// pub fn duplicate(&self) -> io::Result<Self> {
// todo!()
// }
//
// #[inline]
// pub fn is_read_vectored(&self) -> bool {
// todo!()
// }
//
// pub fn recv_from(&self, _buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
// todo!()
// }
//
// pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
// todo!()
// }
//
// pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result<usize> {
// todo!()
// }
//
// pub fn is_write_vectored(&self) -> bool {
// todo!()
// }
//
// pub fn set_timeout(&self, _dur: Option<Duration>, _kind: i32) -> io::Result<()> {
// todo!()
// }
//
// pub fn timeout(&self, _kind: i32) -> io::Result<Option<Duration>> {
// todo!()
// }
//
// pub fn set_nodelay(&self, _nodelay: bool) -> io::Result<()> {
// todo!()
// }
//
// pub fn nodelay(&self) -> io::Result<bool> {
// todo!()
// }
//
// pub fn take_error(&self) -> io::Result<Option<io::Error>> {
// todo!()
// }
//
// pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> {
// todo!()
// }
//
// pub fn peek_from(&self, _buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
// todo!()
// }
//
// pub fn peek(&self, _buf: &mut [u8]) -> io::Result<usize> {
// todo!()
// }
//
// pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
// todo!()
// }
//
// pub fn as_raw(&self) -> RawFd {
// self.0.as_raw_fd()
// }
// }
//
// impl AsInner<FileDesc> for Socket {
// fn as_inner(&self) -> &FileDesc {
// &self.0
// }
// }
//
// impl IntoInner<FileDesc> for Socket {
// fn into_inner(self) -> FileDesc {
// self.0
// }
// }
//
// impl FromInner<FileDesc> for Socket {
// fn from_inner(fd: FileDesc) -> Self {
// Self(fd)
// }
// }
//
// impl AsFd for Socket {
// fn as_fd(&self) -> BorrowedFd<'_> {
// self.0.as_fd()
// }
// }
//
// impl AsRawFd for Socket {
// fn as_raw_fd(&self) -> RawFd {
// self.0.as_raw_fd()
// }
// }
//
pub fn init() {}
//
// pub fn cvt_gai(_err: i32) -> io::Result<()> {
// unimplemented!("No networking support");
// }
@@ -0,0 +1,49 @@
use crate::io;
use crate::net::SocketAddr;
use super::TcpStream;
#[derive(Debug)]
pub struct TcpListener(!);
impl TcpListener {
pub fn bind(_addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
todo!()
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
todo!()
}
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
todo!()
}
pub fn duplicate(&self) -> io::Result<TcpListener> {
todo!()
}
pub fn set_ttl(&self, _ttl: u32) -> io::Result<()> {
todo!()
}
pub fn ttl(&self) -> io::Result<u32> {
todo!()
}
pub fn set_only_v6(&self, _only_v6: bool) -> io::Result<()> {
todo!()
}
pub fn only_v6(&self) -> io::Result<bool> {
todo!()
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
todo!()
}
pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> {
todo!()
}
}
@@ -1,43 +1,36 @@
#![allow(dead_code)]
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
use crate::net::{Shutdown, SocketAddr};
use crate::os::yggdrasil::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
use crate::sys::io::FileDesc;
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::time::Duration;
pub use crate::sys::{cvt, cvt_r};
pub use super::yggdrasil_rt::netc;
pub type wrlen_t = usize;
#[derive(Debug)]
pub struct Socket(FileDesc);
pub struct TcpStream(!);
impl Socket {
pub fn new(_addr: &SocketAddr, _ty: i32) -> io::Result<Socket> {
impl TcpStream {
pub fn connect(_addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
todo!()
}
pub fn connect_timeout(&self, _addr: &SocketAddr, _timeout: Duration) -> io::Result<()> {
pub fn connect_timeout(_addr: &SocketAddr, _timeout: Duration) -> io::Result<TcpStream> {
todo!()
}
pub fn set_linger(&self, _linger: Option<Duration>) -> io::Result<()> {
pub fn set_read_timeout(&self, _dur: Option<Duration>) -> io::Result<()> {
todo!()
}
pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> {
pub fn set_write_timeout(&self, _dur: Option<Duration>) -> io::Result<()> {
todo!()
}
pub fn linger(&self) -> io::Result<Option<Duration>> {
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
todo!()
}
pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> {
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
todo!()
}
pub fn peek(&self, _buf: &mut [u8]) -> io::Result<usize> {
todo!()
}
@@ -45,15 +38,11 @@ impl Socket {
todo!()
}
pub fn accept(
&self,
_storage: *mut netc::sockaddr,
_len: *mut netc::socklen_t,
) -> io::Result<Self> {
pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> {
todo!()
}
pub fn duplicate(&self) -> io::Result<Self> {
pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
todo!()
}
@@ -62,10 +51,6 @@ impl Socket {
todo!()
}
pub fn recv_from(&self, _buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
todo!()
}
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
todo!()
}
@@ -74,15 +59,32 @@ impl Socket {
todo!()
}
#[inline]
pub fn is_write_vectored(&self) -> bool {
todo!()
}
pub fn set_timeout(&self, _dur: Option<Duration>, _kind: i32) -> io::Result<()> {
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
todo!()
}
pub fn timeout(&self, _kind: i32) -> io::Result<Option<Duration>> {
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
todo!()
}
pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> {
todo!()
}
pub fn duplicate(&self) -> io::Result<TcpStream> {
todo!()
}
pub fn set_linger(&self, _linger: Option<Duration>) -> io::Result<()> {
todo!()
}
pub fn linger(&self) -> io::Result<Option<Duration>> {
todo!()
}
@@ -94,6 +96,14 @@ impl Socket {
todo!()
}
pub fn set_ttl(&self, _ttl: u32) -> io::Result<()> {
todo!()
}
pub fn ttl(&self) -> io::Result<u32> {
todo!()
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
todo!()
}
@@ -101,58 +111,4 @@ impl Socket {
pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> {
todo!()
}
pub fn peek_from(&self, _buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
todo!()
}
pub fn peek(&self, _buf: &mut [u8]) -> io::Result<usize> {
todo!()
}
pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
todo!()
}
pub fn as_raw(&self) -> RawFd {
self.0.as_raw_fd()
}
}
impl AsInner<FileDesc> for Socket {
fn as_inner(&self) -> &FileDesc {
&self.0
}
}
impl IntoInner<FileDesc> for Socket {
fn into_inner(self) -> FileDesc {
self.0
}
}
impl FromInner<FileDesc> for Socket {
fn from_inner(fd: FileDesc) -> Self {
Self(fd)
}
}
impl AsFd for Socket {
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
}
}
impl AsRawFd for Socket {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
pub fn init() {
todo!();
}
pub fn cvt_gai(_err: i32) -> io::Result<()> {
unimplemented!("No networking support");
}
+192
View File
@@ -0,0 +1,192 @@
use crate::io;
use crate::mem::MaybeUninit;
use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
use crate::os::fd::{AsRawFd, FromRawFd, RawFd};
use crate::sys::{cvt_io, io::FileDesc};
use crate::sys_common::{AsInner, IntoInner};
use crate::time::Duration;
use yggdrasil_rt::{
net::{SocketOption, SocketType},
sys as syscall,
};
#[derive(Debug)]
pub struct UdpSocket {
fd: FileDesc,
local: SocketAddr,
remote: Option<SocketAddr>,
}
impl UdpSocket {
pub fn bind(listen: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
let listen = listen?;
let raw = cvt_io(unsafe { syscall::bind_socket(listen, SocketType::UdpPacket) })?;
let inner = unsafe { FileDesc::from_raw_fd(raw) };
Ok(Self { fd: inner, local: *listen, remote: None })
}
pub fn connect(&self, _remote: io::Result<&SocketAddr>) -> io::Result<()> {
todo!()
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
todo!()
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
todo!()
}
pub fn recv(&self, _buffer: &mut [u8]) -> io::Result<usize> {
todo!()
}
pub fn recv_from(&self, buffer: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
let mut remote = MaybeUninit::uninit();
let len =
cvt_io(unsafe { syscall::receive_from(self.fd.as_raw_fd(), buffer, &mut remote) })?;
Ok((len, unsafe { remote.assume_init() }))
}
pub fn send(&self, _buffer: &[u8]) -> io::Result<usize> {
todo!()
}
pub fn send_to(&self, buffer: &[u8], dst: &SocketAddr) -> io::Result<usize> {
let dst = Some(*dst);
cvt_io(unsafe { syscall::send_to(self.fd.as_raw_fd(), buffer, &dst) })
}
pub fn peek(&self, _buf: &mut [u8]) -> io::Result<usize> {
todo!()
}
pub fn peek_from(&self, _buffer: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
todo!()
}
pub fn duplicate(&self) -> io::Result<UdpSocket> {
todo!()
}
pub fn set_read_timeout(&self, _dur: Option<Duration>) -> io::Result<()> {
todo!()
}
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
todo!()
}
pub fn set_write_timeout(&self, _dur: Option<Duration>) -> io::Result<()> {
todo!()
}
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
todo!()
}
pub fn set_ttl(&self, _ttl: u32) -> io::Result<()> {
todo!()
}
pub fn ttl(&self) -> io::Result<u32> {
todo!()
}
pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> {
todo!()
}
pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
cvt_io(unsafe {
syscall::set_socket_option(self.fd.as_raw_fd(), &SocketOption::Broadcast(broadcast))
})
}
pub fn broadcast(&self) -> io::Result<bool> {
let mut value = SocketOption::Broadcast(false);
cvt_io(unsafe { syscall::get_socket_option(self.fd.as_raw_fd(), &mut value) })?;
let SocketOption::Broadcast(value) = value else {
unreachable!();
};
Ok(value)
}
pub fn set_multicast_loop_v4(&self, _loop_v4: bool) -> io::Result<()> {
todo!()
}
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
todo!()
}
pub fn set_multicast_ttl_v4(&self, _ttl: u32) -> io::Result<()> {
todo!()
}
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
todo!()
}
pub fn set_multicast_loop_v6(&self, _loop_v6: bool) -> io::Result<()> {
todo!()
}
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
todo!()
}
pub fn join_multicast_v6(&self, _multiaddr: &Ipv6Addr, _interface: u32) -> io::Result<()> {
todo!()
}
pub fn join_multicast_v4(
&self,
_multiaddr: &Ipv4Addr,
_interface: &Ipv4Addr,
) -> io::Result<()> {
todo!()
}
pub fn leave_multicast_v6(&self, _multiaddr: &Ipv6Addr, _interface: u32) -> io::Result<()> {
todo!()
}
pub fn leave_multicast_v4(
&self,
_multiaddr: &Ipv4Addr,
_interface: &Ipv4Addr,
) -> io::Result<()> {
todo!()
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
todo!()
}
}
impl IntoInner<FileDesc> for UdpSocket {
fn into_inner(self) -> FileDesc {
self.fd
}
}
impl AsInner<FileDesc> for UdpSocket {
fn as_inner(&self) -> &FileDesc {
&self.fd
}
}
impl AsRawFd for UdpSocket {
fn as_raw_fd(&self) -> RawFd {
self.fd.as_raw_fd()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for crate::net::UdpSocket {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().as_raw_fd()
}
}
+1
View File
@@ -45,6 +45,7 @@ cfg_if::cfg_if! {
cfg_if::cfg_if! {
if #[cfg(any(target_os = "l4re",
feature = "restricted-std",
target_os = "yggdrasil",
all(target_family = "wasm", not(target_os = "emscripten")),
all(target_vendor = "fortanix", target_env = "sgx")))] {
pub use crate::sys::net;