From 8b625de6043d51885d521204a25efbc7fa47f273 Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Wed, 22 Jan 2025 15:25:40 +0800 Subject: [PATCH] readv / write for Fd --- Cargo.toml | 1 - src/async/unix_device.rs | 2 +- src/async/win_device.rs | 2 +- src/platform/android/device.rs | 2 +- src/platform/freebsd/device.rs | 2 +- src/platform/ios/device.rs | 2 +- src/platform/linux/device.rs | 2 +- src/platform/macos/device.rs | 2 +- src/platform/ohos/device.rs | 2 +- src/platform/posix/fd.rs | 61 ++++++++++++++++++++++++++++++++++ 10 files changed, 69 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4eaa5e68..4e1dffed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,6 @@ all-features = true crate-type = ["staticlib", "lib"] [features] -default = [] # default = ["async"] async = [ "tokio", diff --git a/src/async/unix_device.rs b/src/async/unix_device.rs index 30787be0..048f13a1 100644 --- a/src/async/unix_device.rs +++ b/src/async/unix_device.rs @@ -21,10 +21,10 @@ use tokio::io::Interest; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio_util::codec::Framed; -use super::TunPacketCodec; use crate::device::AbstractDevice; use crate::platform::posix::{Reader, Writer}; use crate::platform::Device; +use crate::r#async::TunPacketCodec; /// An async TUN device wrapper around a TUN device. pub struct AsyncDevice { diff --git a/src/async/win_device.rs b/src/async/win_device.rs index 04f6a4c6..f447e5e1 100644 --- a/src/async/win_device.rs +++ b/src/async/win_device.rs @@ -12,9 +12,9 @@ // // 0. You just DO WHAT THE FUCK YOU WANT TO. -use super::TunPacketCodec; use crate::device::AbstractDevice; use crate::platform::Device; +use crate::r#async::TunPacketCodec; use core::pin::Pin; use core::task::{Context, Poll}; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; diff --git a/src/platform/android/device.rs b/src/platform/android/device.rs index 3e703eed..0cc776cb 100644 --- a/src/platform/android/device.rs +++ b/src/platform/android/device.rs @@ -24,7 +24,7 @@ use crate::platform::posix::{self, Fd, Tun}; /// A TUN device for Android. pub struct Device { - tun: Tun, + pub(crate) tun: Tun, } impl AsRef for Device { diff --git a/src/platform/freebsd/device.rs b/src/platform/freebsd/device.rs index 78112644..7bd81e84 100644 --- a/src/platform/freebsd/device.rs +++ b/src/platform/freebsd/device.rs @@ -43,7 +43,7 @@ struct Route { /// A TUN device using the TUN/TAP Linux driver. pub struct Device { tun_name: String, - tun: Tun, + pub(crate) tun: Tun, ctl: Fd, route: Option, } diff --git a/src/platform/ios/device.rs b/src/platform/ios/device.rs index 08b29eec..94fbcaec 100644 --- a/src/platform/ios/device.rs +++ b/src/platform/ios/device.rs @@ -27,7 +27,7 @@ use std::{ /// A TUN device for iOS. pub struct Device { - tun: Tun, + pub(crate) tun: Tun, } impl AsRef for Device { diff --git a/src/platform/linux/device.rs b/src/platform/linux/device.rs index a35ee1ab..48184147 100644 --- a/src/platform/linux/device.rs +++ b/src/platform/linux/device.rs @@ -38,7 +38,7 @@ const OVERWRITE_SIZE: usize = std::mem::size_of::( /// A TUN device using the TUN/TAP Linux driver. pub struct Device { tun_name: String, - tun: Tun, + pub(crate) tun: Tun, ctl: Fd, } diff --git a/src/platform/macos/device.rs b/src/platform/macos/device.rs index 30b84d3a..d66b51e8 100644 --- a/src/platform/macos/device.rs +++ b/src/platform/macos/device.rs @@ -49,7 +49,7 @@ struct Route { /// A TUN device using the TUN macOS driver. pub struct Device { tun_name: Option, - tun: posix::Tun, + pub(crate) tun: posix::Tun, ctl: Option, route: Option, } diff --git a/src/platform/ohos/device.rs b/src/platform/ohos/device.rs index 6274a2c0..4e2ff3f8 100644 --- a/src/platform/ohos/device.rs +++ b/src/platform/ohos/device.rs @@ -24,7 +24,7 @@ use crate::platform::posix::{self, Fd, Tun}; /// A TUN device for OpenHarmony. pub struct Device { - tun: Tun, + pub(crate) tun: Tun, } impl AsRef for Device { diff --git a/src/platform/posix/fd.rs b/src/platform/posix/fd.rs index 9934314c..ffc2da6e 100644 --- a/src/platform/posix/fd.rs +++ b/src/platform/posix/fd.rs @@ -41,6 +41,7 @@ impl Fd { } } + #[inline] pub fn read(&self, buf: &mut [u8]) -> std::io::Result { let fd = self.as_raw_fd(); let amount = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut _, buf.len()) }; @@ -50,6 +51,26 @@ impl Fd { Ok(amount as usize) } + #[allow(dead_code)] + #[inline] + fn readv(&self, bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result { + if bufs.len() > max_iov() { + return Err(std::io::Error::from(std::io::ErrorKind::InvalidInput)); + } + let amount = unsafe { + libc::readv( + self.as_raw_fd(), + bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec, + bufs.len() as libc::c_int, + ) + }; + if amount < 0 { + return Err(std::io::Error::last_os_error()); + } + Ok(amount as usize) + } + + #[inline] pub fn write(&self, buf: &[u8]) -> std::io::Result { let fd = self.as_raw_fd(); let amount = unsafe { libc::write(fd, buf.as_ptr() as *const _, buf.len()) }; @@ -58,6 +79,25 @@ impl Fd { } Ok(amount as usize) } + + #[allow(dead_code)] + #[inline] + pub fn writev(&self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result { + if bufs.len() > max_iov() { + return Err(std::io::Error::from(std::io::ErrorKind::InvalidInput)); + } + let amount = unsafe { + libc::writev( + self.as_raw_fd(), + bufs.as_ptr() as *const libc::iovec, + bufs.len() as libc::c_int, + ) + }; + if amount < 0 { + return Err(std::io::Error::last_os_error()); + } + Ok(amount as usize) + } } impl AsRawFd for Fd { @@ -81,3 +121,24 @@ impl Drop for Fd { } } } + +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_vendor = "apple", +))] +pub(crate) const fn max_iov() -> usize { + libc::IOV_MAX as usize +} + +#[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "linux", + target_os = "nto", +))] +pub(crate) const fn max_iov() -> usize { + libc::UIO_MAXIOV as usize +}