This commit is contained in:
lubeilin
2023-03-13 22:11:52 +08:00
parent 5b2c2435d5
commit 6f7992ea9f
46 changed files with 760 additions and 2124 deletions
-149
View File
@@ -1,149 +0,0 @@
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <[email protected]> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
use std::io;
use byteorder::{NativeEndian, NetworkEndian, WriteBytesExt};
use bytes::{BufMut, Bytes, BytesMut};
use tokio_util::codec::{Decoder, Encoder};
/// A packet protocol IP version
#[derive(Debug)]
enum PacketProtocol {
IPv4,
IPv6,
Other(u8),
}
// Note: the protocol in the packet information header is platform dependent.
impl PacketProtocol {
#[cfg(any(target_os = "linux", target_os = "android"))]
fn into_pi_field(&self) -> Result<u16, io::Error> {
match self {
PacketProtocol::IPv4 => Ok(libc::ETH_P_IP as u16),
PacketProtocol::IPv6 => Ok(libc::ETH_P_IPV6 as u16),
PacketProtocol::Other(_) => Err(io::Error::new(
io::ErrorKind::Other,
"neither an IPv4 or IPv6 packet",
)),
}
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
fn into_pi_field(&self) -> Result<u16, io::Error> {
match self {
PacketProtocol::IPv4 => Ok(libc::PF_INET as u16),
PacketProtocol::IPv6 => Ok(libc::PF_INET6 as u16),
PacketProtocol::Other(_) => Err(io::Error::new(
io::ErrorKind::Other,
"neither an IPv4 or IPv6 packet",
)),
}
}
}
/// A Tun Packet to be sent or received on the TUN interface.
#[derive(Debug)]
pub struct TunPacket(PacketProtocol, Bytes);
/// Infer the protocol based on the first nibble in the packet buffer.
fn infer_proto(buf: &[u8]) -> PacketProtocol {
match buf[0] >> 4 {
4 => PacketProtocol::IPv4,
6 => PacketProtocol::IPv6,
p => PacketProtocol::Other(p),
}
}
impl TunPacket {
/// Create a new `TunPacket` based on a byte slice.
pub fn new(bytes: Vec<u8>) -> TunPacket {
let proto = infer_proto(&bytes);
TunPacket(proto, Bytes::from(bytes))
}
/// Return this packet's bytes.
pub fn get_bytes(&self) -> &[u8] {
&self.1
}
pub fn into_bytes(self) -> Bytes {
self.1
}
}
/// A TunPacket Encoder/Decoder.
pub struct TunPacketCodec(bool, i32);
impl TunPacketCodec {
/// Create a new `TunPacketCodec` specifying whether the underlying
/// tunnel Device has enabled the packet information header.
pub fn new(pi: bool, mtu: i32) -> TunPacketCodec {
TunPacketCodec(pi, mtu)
}
}
impl Decoder for TunPacketCodec {
type Item = TunPacket;
type Error = io::Error;
fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
if buf.is_empty() {
return Ok(None);
}
let mut pkt = buf.split_to(buf.len());
// reserve enough space for the next packet
if self.0 {
buf.reserve(self.1 as usize + 4);
} else {
buf.reserve(self.1 as usize);
}
// if the packet information is enabled we have to ignore the first 4 bytes
if self.0 {
let _ = pkt.split_to(4);
}
let proto = infer_proto(pkt.as_ref());
Ok(Some(TunPacket(proto, pkt.freeze())))
}
}
impl Encoder<TunPacket> for TunPacketCodec {
type Error = io::Error;
fn encode(&mut self, item: TunPacket, dst: &mut BytesMut) -> Result<(), Self::Error> {
dst.reserve(item.get_bytes().len() + 4);
match item {
TunPacket(proto, bytes) if self.0 => {
// build the packet information header comprising of 2 u16
// fields: flags and protocol.
let mut buf = Vec::<u8>::with_capacity(4);
// flags is always 0
buf.write_u16::<NativeEndian>(0).unwrap();
// write the protocol as network byte order
buf.write_u16::<NetworkEndian>(proto.into_pi_field()?)
.unwrap();
dst.put_slice(&buf);
dst.put(bytes);
}
TunPacket(_, bytes) => dst.put(bytes),
}
Ok(())
}
}
-201
View File
@@ -1,201 +0,0 @@
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <[email protected]> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
use std::io;
use std::io::{IoSlice, Read, Write};
use core::pin::Pin;
use core::task::{Context, Poll};
use futures_core::ready;
use tokio::io::unix::AsyncFd;
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use tokio_util::codec::Framed;
use crate::device::Device as D;
use crate::platform::{Device, Queue};
use crate::r#async::codec::*;
/// An async TUN device wrapper around a TUN device.
pub struct AsyncDevice {
inner: AsyncFd<Device>,
}
impl AsyncDevice {
/// Create a new `AsyncDevice` wrapping around a `Device`.
pub fn new(device: Device) -> io::Result<AsyncDevice> {
device.set_nonblock()?;
Ok(AsyncDevice {
inner: AsyncFd::new(device)?,
})
}
/// Returns a shared reference to the underlying Device object
pub fn get_ref(&self) -> &Device {
self.inner.get_ref()
}
/// Returns a mutable reference to the underlying Device object
pub fn get_mut(&mut self) -> &mut Device {
self.inner.get_mut()
}
/// Consumes this AsyncDevice and return a Framed object (unified Stream and Sink interface)
pub fn into_framed(mut self) -> Framed<Self, TunPacketCodec> {
let pi = self.get_mut().has_packet_information();
let codec = TunPacketCodec::new(pi, self.inner.get_ref().mtu().unwrap_or(1504));
Framed::new(self, codec)
}
}
impl AsyncRead for AsyncDevice {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut ReadBuf,
) -> Poll<io::Result<()>> {
loop {
let mut guard = ready!(self.inner.poll_read_ready_mut(cx))?;
let rbuf = buf.initialize_unfilled();
match guard.try_io(|inner| inner.get_mut().read(rbuf)) {
Ok(res) => return Poll::Ready(res.map(|n| buf.advance(n))),
Err(_wb) => continue,
}
}
}
}
impl AsyncWrite for AsyncDevice {
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
loop {
let mut guard = ready!(self.inner.poll_write_ready_mut(cx))?;
match guard.try_io(|inner| inner.get_mut().write(buf)) {
Ok(res) => return Poll::Ready(res),
Err(_wb) => continue,
}
}
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
loop {
let mut guard = ready!(self.inner.poll_write_ready_mut(cx))?;
match guard.try_io(|inner| inner.get_mut().flush()) {
Ok(res) => return Poll::Ready(res),
Err(_wb) => continue,
}
}
}
fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(()))
}
fn poll_write_vectored(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[IoSlice<'_>],
) -> Poll<Result<usize, io::Error>> {
loop {
let mut guard = ready!(self.inner.poll_write_ready_mut(cx))?;
match guard.try_io(|inner| inner.get_mut().write_vectored(bufs)) {
Ok(res) => return Poll::Ready(res),
Err(_wb) => continue,
}
}
}
fn is_write_vectored(&self) -> bool {
true
}
}
/// An async TUN device queue wrapper around a TUN device queue.
pub struct AsyncQueue {
inner: AsyncFd<Queue>,
}
impl AsyncQueue {
/// Create a new `AsyncQueue` wrapping around a `Queue`.
pub fn new(queue: Queue) -> io::Result<AsyncQueue> {
queue.set_nonblock()?;
Ok(AsyncQueue {
inner: AsyncFd::new(queue)?,
})
}
/// Returns a shared reference to the underlying Queue object
pub fn get_ref(&self) -> &Queue {
self.inner.get_ref()
}
/// Returns a mutable reference to the underlying Queue object
pub fn get_mut(&mut self) -> &mut Queue {
self.inner.get_mut()
}
/// Consumes this AsyncQueue and return a Framed object (unified Stream and Sink interface)
pub fn into_framed(mut self) -> Framed<Self, TunPacketCodec> {
let pi = self.get_mut().has_packet_information();
let codec = TunPacketCodec::new(pi, 1504);
Framed::new(self, codec)
}
}
impl AsyncRead for AsyncQueue {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut ReadBuf,
) -> Poll<io::Result<()>> {
loop {
let mut guard = ready!(self.inner.poll_read_ready_mut(cx))?;
let rbuf = buf.initialize_unfilled();
match guard.try_io(|inner| inner.get_mut().read(rbuf)) {
Ok(res) => return Poll::Ready(res.map(|n| buf.advance(n))),
Err(_wb) => continue,
}
}
}
}
impl AsyncWrite for AsyncQueue {
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
loop {
let mut guard = ready!(self.inner.poll_write_ready_mut(cx))?;
match guard.try_io(|inner| inner.get_mut().write(buf)) {
Ok(res) => return Poll::Ready(res),
Err(_wb) => continue,
}
}
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
loop {
let mut guard = ready!(self.inner.poll_write_ready_mut(cx))?;
match guard.try_io(|inner| inner.get_mut().flush()) {
Ok(res) => return Poll::Ready(res),
Err(_wb) => continue,
}
}
}
fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(()))
}
}
-32
View File
@@ -1,32 +0,0 @@
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <[email protected]> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
//! Async specific modules.
use crate::error;
use crate::configuration::Configuration;
use crate::platform::create;
mod device;
pub use self::device::{AsyncDevice, AsyncQueue};
mod codec;
pub use self::codec::{TunPacket, TunPacketCodec};
/// Create a TUN device with the given name.
pub fn create_as_async(configuration: &Configuration) -> Result<AsyncDevice, error::Error> {
let device = create(&configuration)?;
AsyncDevice::new(device).map_err(|err| err.into())
}
+3 -4
View File
@@ -12,15 +12,14 @@
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
use std::io::{Read, Write};
use std::net::Ipv4Addr;
use crate::configuration::Configuration;
use crate::error::*;
/// A TUN device.
pub trait Device: Read + Write {
type Queue: Read + Write;
pub trait Device {
type Queue ;
/// Reconfigure the device.
fn configure(&mut self, config: &Configuration) -> Result<()> {
@@ -91,5 +90,5 @@ pub trait Device: Read + Write {
fn set_mtu(&mut self, value: i32) -> Result<()>;
/// Get a device queue.
fn queue(&mut self, index: usize) -> Option<&mut Self::Queue>;
fn queue(&self, index: usize) -> Option<&Self::Queue>;
}
-21
View File
@@ -27,27 +27,6 @@ pub use crate::configuration::{Configuration, Layer};
pub mod platform;
pub use crate::platform::create;
#[cfg(all(
feature = "async",
any(
target_os = "linux",
target_os = "macos",
target_os = "ios",
target_os = "android"
)
))]
pub mod r#async;
#[cfg(all(
feature = "async",
any(
target_os = "linux",
target_os = "macos",
target_os = "ios",
target_os = "android"
)
))]
pub use r#async::*;
pub fn configure() -> Configuration {
Configuration::default()
}
@@ -1,214 +0,0 @@
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <[email protected]> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
#![allow(unused_variables)]
use std::io::{self, Read, Write};
use std::net::Ipv4Addr;
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
use std::sync::Arc;
use crate::configuration::Configuration;
use crate::device::Device as D;
use crate::error::*;
use crate::platform::posix::{self, Fd};
/// A TUN device for Android.
pub struct Device {
queue: Queue,
}
impl Device {
/// Create a new `Device` for the given `Configuration`.
pub fn new(config: &Configuration) -> Result<Self> {
let fd = match config.raw_fd {
Some(raw_fd) => raw_fd,
_ => return Err(Error::InvalidConfig),
};
let device = {
let tun = Fd::new(fd).map_err(|_| io::Error::last_os_error())?;
Device {
queue: Queue { tun: tun },
}
};
Ok(device)
}
/// Split the interface into a `Reader` and `Writer`.
pub fn split(self) -> (posix::Reader, posix::Writer) {
let fd = Arc::new(self.queue.tun);
(posix::Reader(fd.clone()), posix::Writer(fd.clone()))
}
/// Return whether the device has packet information
pub fn has_packet_information(&self) -> bool {
self.queue.has_packet_information()
}
/// Set non-blocking mode
pub fn set_nonblock(&self) -> io::Result<()> {
self.queue.set_nonblock()
}
}
impl Read for Device {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.queue.tun.read(buf)
}
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
self.queue.tun.read_vectored(bufs)
}
}
impl Write for Device {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.queue.tun.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.queue.tun.flush()
}
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
self.queue.tun.write_vectored(bufs)
}
}
impl D for Device {
type Queue = Queue;
fn name(&self) -> &str {
return "";
}
fn set_name(&mut self, value: &str) -> Result<()> {
Err(Error::NotImplemented)
}
fn enabled(&mut self, value: bool) -> Result<()> {
Ok(())
}
fn address(&self) -> Result<Ipv4Addr> {
Err(Error::NotImplemented)
}
fn set_address(&mut self, value: Ipv4Addr) -> Result<()> {
Ok(())
}
fn destination(&self) -> Result<Ipv4Addr> {
Err(Error::NotImplemented)
}
fn set_destination(&mut self, value: Ipv4Addr) -> Result<()> {
Ok(())
}
fn broadcast(&self) -> Result<Ipv4Addr> {
Err(Error::NotImplemented)
}
fn set_broadcast(&mut self, value: Ipv4Addr) -> Result<()> {
Ok(())
}
fn netmask(&self) -> Result<Ipv4Addr> {
Err(Error::NotImplemented)
}
fn set_netmask(&mut self, value: Ipv4Addr) -> Result<()> {
Ok(())
}
fn mtu(&self) -> Result<i32> {
Err(Error::NotImplemented)
}
fn set_mtu(&mut self, value: i32) -> Result<()> {
Ok(())
}
fn queue(&mut self, index: usize) -> Option<&mut Self::Queue> {
if index > 0 {
return None;
}
Some(&mut self.queue)
}
}
impl AsRawFd for Device {
fn as_raw_fd(&self) -> RawFd {
self.queue.as_raw_fd()
}
}
impl IntoRawFd for Device {
fn into_raw_fd(self) -> RawFd {
self.queue.into_raw_fd()
}
}
pub struct Queue {
tun: Fd,
}
impl Queue {
pub fn has_packet_information(&self) -> bool {
// on Android this is always the case
false
}
pub fn set_nonblock(&self) -> io::Result<()> {
self.tun.set_nonblock()
}
}
impl AsRawFd for Queue {
fn as_raw_fd(&self) -> RawFd {
self.tun.as_raw_fd()
}
}
impl IntoRawFd for Queue {
fn into_raw_fd(self) -> RawFd {
self.tun.into_raw_fd()
}
}
impl Read for Queue {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.tun.read(buf)
}
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
self.tun.read_vectored(bufs)
}
}
impl Write for Queue {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.tun.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.tun.flush()
}
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
self.tun.write_vectored(bufs)
}
}
@@ -1,30 +0,0 @@
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <[email protected]> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
//! Android specific functionality.
mod device;
pub use self::device::{Device, Queue};
use crate::configuration::Configuration as C;
use crate::error::*;
/// Android-only interface configuration.
#[derive(Copy, Clone, Default, Debug)]
pub struct Configuration {}
/// Create a TUN device with the given name.
pub fn create(configuration: &C) -> Result<Device> {
Device::new(&configuration)
}
-214
View File
@@ -1,214 +0,0 @@
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <[email protected]> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
#![allow(unused_variables)]
use std::io::{self, Read, Write};
use std::net::Ipv4Addr;
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
use std::sync::Arc;
use crate::configuration::Configuration;
use crate::device::Device as D;
use crate::error::*;
use crate::platform::posix::{self, Fd};
/// A TUN device for iOS.
pub struct Device {
queue: Queue,
}
impl Device {
/// Create a new `Device` for the given `Configuration`.
pub fn new(config: &Configuration) -> Result<Self> {
let fd = match config.raw_fd {
Some(raw_fd) => raw_fd,
_ => return Err(Error::InvalidConfig),
};
let mut device = unsafe {
let tun = Fd::new(fd).map_err(|_| io::Error::last_os_error())?;
Device {
queue: Queue { tun: tun },
}
};
Ok(device)
}
/// Split the interface into a `Reader` and `Writer`.
pub fn split(self) -> (posix::Reader, posix::Writer) {
let fd = Arc::new(self.queue.tun);
(posix::Reader(fd.clone()), posix::Writer(fd.clone()))
}
/// Return whether the device has packet information
pub fn has_packet_information(&self) -> bool {
self.queue.has_packet_information()
}
/// Set non-blocking mode
pub fn set_nonblock(&self) -> io::Result<()> {
self.queue.set_nonblock()
}
}
impl Read for Device {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.queue.tun.read(buf)
}
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
self.queue.tun.read_vectored(bufs)
}
}
impl Write for Device {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.queue.tun.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.queue.tun.flush()
}
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
self.queue.tun.write_vectored(bufs)
}
}
impl D for Device {
type Queue = Queue;
fn name(&self) -> &str {
return "";
}
fn set_name(&mut self, value: &str) -> Result<()> {
Err(Error::NotImplemented)
}
fn enabled(&mut self, value: bool) -> Result<()> {
Ok(())
}
fn address(&self) -> Result<Ipv4Addr> {
Err(Error::NotImplemented)
}
fn set_address(&mut self, value: Ipv4Addr) -> Result<()> {
Ok(())
}
fn destination(&self) -> Result<Ipv4Addr> {
Err(Error::NotImplemented)
}
fn set_destination(&mut self, value: Ipv4Addr) -> Result<()> {
Ok(())
}
fn broadcast(&self) -> Result<Ipv4Addr> {
Err(Error::NotImplemented)
}
fn set_broadcast(&mut self, value: Ipv4Addr) -> Result<()> {
Ok(())
}
fn netmask(&self) -> Result<Ipv4Addr> {
Err(Error::NotImplemented)
}
fn set_netmask(&mut self, value: Ipv4Addr) -> Result<()> {
Ok(())
}
fn mtu(&self) -> Result<i32> {
Err(Error::NotImplemented)
}
fn set_mtu(&mut self, value: i32) -> Result<()> {
Ok(())
}
fn queue(&mut self, index: usize) -> Option<&mut Self::Queue> {
if index > 0 {
return None;
}
Some(&mut self.queue)
}
}
impl AsRawFd for Device {
fn as_raw_fd(&self) -> RawFd {
self.queue.as_raw_fd()
}
}
impl IntoRawFd for Device {
fn into_raw_fd(self) -> RawFd {
self.queue.into_raw_fd()
}
}
pub struct Queue {
tun: Fd,
}
impl Queue {
pub fn has_packet_information(&self) -> bool {
// on ios this is always the case
true
}
pub fn set_nonblock(&self) -> io::Result<()> {
self.tun.set_nonblock()
}
}
impl AsRawFd for Queue {
fn as_raw_fd(&self) -> RawFd {
self.tun.as_raw_fd()
}
}
impl IntoRawFd for Queue {
fn into_raw_fd(self) -> RawFd {
self.tun.into_raw_fd()
}
}
impl Read for Queue {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.tun.read(buf)
}
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
self.tun.read_vectored(bufs)
}
}
impl Write for Queue {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.tun.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.tun.flush()
}
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
self.tun.write_vectored(bufs)
}
}
-30
View File
@@ -1,30 +0,0 @@
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <[email protected]> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
//! iOS specific functionality.
mod device;
pub use self::device::{Device, Queue};
use crate::configuration::Configuration as C;
use crate::error::*;
/// iOS-only interface configuration.
#[derive(Copy, Clone, Default, Debug)]
pub struct Configuration {}
/// Create a TUN device with the given name.
pub fn create(configuration: &C) -> Result<Device> {
Device::new(&configuration)
}
+47 -120
View File
@@ -13,10 +13,10 @@
// 0. You just DO WHAT THE FUCK YOU WANT TO.
use std::ffi::{CStr, CString};
use std::io::{self, Read, Write};
use std::io;
use std::mem;
use std::net::Ipv4Addr;
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
use std::os::unix::io::AsRawFd;
use std::ptr;
use std::sync::Arc;
use std::vec::Vec;
@@ -77,10 +77,10 @@ impl Device {
req.ifru.flags = device_type
| if config.platform.packet_information {
0
} else {
IFF_NO_PI
}
0
} else {
IFF_NO_PI
}
| if queues_num > 1 { IFF_MULTI_QUEUE } else { 0 };
for _ in 0..queues_num {
@@ -92,7 +92,7 @@ impl Device {
}
queues.push(Queue {
tun,
tun: Arc::new(tun),
pi_enabled: config.platform.packet_information,
});
}
@@ -126,45 +126,40 @@ impl Device {
req
}
/// Make the device persistent.
pub fn persist(&mut self) -> Result<()> {
unsafe {
if tunsetpersist(self.as_raw_fd(), &1) < 0 {
Err(io::Error::last_os_error().into())
} else {
Ok(())
}
}
}
// /// Make the device persistent.
// pub fn persist(&mut self) -> Result<()> {
// unsafe {
// if tunsetpersist(self.as_raw_fd(), &1) < 0 {
// Err(io::Error::last_os_error().into())
// } else {
// Ok(())
// }
// }
// }
/// Set the owner of the device.
pub fn user(&mut self, value: i32) -> Result<()> {
unsafe {
if tunsetowner(self.as_raw_fd(), &value) < 0 {
Err(io::Error::last_os_error().into())
} else {
Ok(())
}
}
}
/// Set the group of the device.
pub fn group(&mut self, value: i32) -> Result<()> {
unsafe {
if tunsetgroup(self.as_raw_fd(), &value) < 0 {
Err(io::Error::last_os_error().into())
} else {
Ok(())
}
}
}
pub fn split(mut self) -> (posix::Reader, posix::Writer) {
let queue = self.queues.swap_remove(0);
let fd = Arc::new(queue.tun);
(posix::Reader(fd.clone()), posix::Writer(fd.clone()))
}
// /// Set the owner of the device.
// pub fn user(&mut self, value: i32) -> Result<()> {
// unsafe {
// if tunsetowner(self.as_raw_fd(), &value) < 0 {
// Err(io::Error::last_os_error().into())
// } else {
// Ok(())
// }
// }
// }
//
// /// Set the group of the device.
// pub fn group(&mut self, value: i32) -> Result<()> {
// unsafe {
// if tunsetgroup(self.as_raw_fd(), &value) < 0 {
// Err(io::Error::last_os_error().into())
// } else {
// Ok(())
// }
// }
// }
/// Return whether the device has packet information
pub fn has_packet_information(&mut self) -> bool {
pub fn has_packet_information(&self) -> bool {
self.queues[0].has_packet_information()
}
@@ -174,30 +169,6 @@ impl Device {
}
}
impl Read for Device {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.queues[0].read(buf)
}
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
self.queues[0].read_vectored(bufs)
}
}
impl Write for Device {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.queues[0].write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.queues[0].flush()
}
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
self.queues[0].write_vectored(bufs)
}
}
impl D for Device {
type Queue = Queue;
@@ -377,73 +348,29 @@ impl D for Device {
}
}
fn queue(&mut self, index: usize) -> Option<&mut Self::Queue> {
self.queues.get_mut(index)
}
}
impl AsRawFd for Device {
fn as_raw_fd(&self) -> RawFd {
self.queues[0].as_raw_fd()
}
}
impl IntoRawFd for Device {
fn into_raw_fd(mut self) -> RawFd {
// It is Ok to swap the first queue with the last one, because the self will be dropped afterwards
let queue = self.queues.swap_remove(0);
queue.into_raw_fd()
fn queue(&self, index: usize) -> Option<&Self::Queue> {
self.queues.get(index)
}
}
pub struct Queue {
tun: Fd,
tun: Arc<Fd>,
pi_enabled: bool,
}
impl Queue {
pub fn has_packet_information(&mut self) -> bool {
pub fn has_packet_information(&self) -> bool {
self.pi_enabled
}
pub fn set_nonblock(&self) -> io::Result<()> {
self.tun.set_nonblock()
}
}
impl Read for Queue {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.tun.read(buf)
pub fn reader(&self) -> posix::Reader {
posix::Reader(self.tun.clone())
}
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
self.tun.read_vectored(bufs)
}
}
impl Write for Queue {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.tun.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.tun.flush()
}
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
self.tun.write_vectored(bufs)
}
}
impl AsRawFd for Queue {
fn as_raw_fd(&self) -> RawFd {
self.tun.as_raw_fd()
}
}
impl IntoRawFd for Queue {
fn into_raw_fd(self) -> RawFd {
self.tun.into_raw_fd()
pub fn writer(&self) -> posix::Writer {
posix::Writer(self.tun.clone())
}
}
+85 -78
View File
@@ -14,15 +14,15 @@
#![allow(unused_variables)]
use std::ffi::CStr;
use std::io::{self, Read, Write};
use std::io;
use std::mem;
use std::net::Ipv4Addr;
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
use std::os::unix::io::AsRawFd;
use std::ptr;
use std::sync::Arc;
use libc;
use libc::{c_char, c_uint, c_void, sockaddr, socklen_t, AF_INET, SOCK_DGRAM};
use libc::{AF_INET, c_char, c_uint, c_void, SOCK_DGRAM, sockaddr, socklen_t};
use crate::configuration::{Configuration, Layer};
use crate::device::Device as D;
@@ -121,7 +121,7 @@ impl Device {
name: CStr::from_ptr(name.as_ptr() as *const c_char)
.to_string_lossy()
.into(),
queue: Queue { tun: tun },
queue: Queue { tun: Arc::new(tun) },
ctl: ctl,
}
};
@@ -165,11 +165,11 @@ impl Device {
}
}
/// Split the interface into a `Reader` and `Writer`.
pub fn split(self) -> (posix::Reader, posix::Writer) {
let fd = Arc::new(self.queue.tun);
(posix::Reader(fd.clone()), posix::Writer(fd.clone()))
}
// /// Split the interface into a `Reader` and `Writer`.
// pub fn split(self) -> (posix::Reader, posix::Writer) {
// let fd = Arc::new(self.queue.tun);
// (posix::Reader(fd.clone()), posix::Writer(fd.clone()))
// }
/// Return whether the device has packet information
pub fn has_packet_information(&self) -> bool {
@@ -182,29 +182,29 @@ impl Device {
}
}
impl Read for Device {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.queue.tun.read(buf)
}
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
self.queue.tun.read_vectored(bufs)
}
}
impl Write for Device {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.queue.tun.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.queue.tun.flush()
}
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
self.queue.tun.write_vectored(bufs)
}
}
// impl Read for Device {
// fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
// self.queue.tun.read(buf)
// }
//
// fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
// self.queue.tun.read_vectored(bufs)
// }
// }
//
// impl Write for Device {
// fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
// self.queue.tun.write(buf)
// }
//
// fn flush(&mut self) -> io::Result<()> {
// self.queue.tun.flush()
// }
//
// fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
// self.queue.tun.write_vectored(bufs)
// }
// }
impl D for Device {
type Queue = Queue;
@@ -365,29 +365,29 @@ impl D for Device {
}
}
fn queue(&mut self, index: usize) -> Option<&mut Self::Queue> {
fn queue(&self, index: usize) -> Option<&Self::Queue> {
if index > 0 {
return None;
}
Some(&mut self.queue)
Some(&self.queue)
}
}
impl AsRawFd for Device {
fn as_raw_fd(&self) -> RawFd {
self.queue.as_raw_fd()
}
}
impl IntoRawFd for Device {
fn into_raw_fd(self) -> RawFd {
self.queue.into_raw_fd()
}
}
// impl AsRawFd for Device {
// fn as_raw_fd(&self) -> RawFd {
// self.queue.as_raw_fd()
// }
// }
//
// impl IntoRawFd for Device {
// fn into_raw_fd(self) -> RawFd {
// self.queue.into_raw_fd()
// }
// }
pub struct Queue {
tun: Fd,
tun: Arc<Fd>,
}
impl Queue {
@@ -399,40 +399,47 @@ impl Queue {
pub fn set_nonblock(&self) -> io::Result<()> {
self.tun.set_nonblock()
}
}
impl AsRawFd for Queue {
fn as_raw_fd(&self) -> RawFd {
self.tun.as_raw_fd()
pub fn reader(&self) -> posix::Reader {
posix::Reader(self.tun.clone())
}
pub fn writer(&self) -> posix::Writer {
posix::Writer(self.tun.clone())
}
}
impl IntoRawFd for Queue {
fn into_raw_fd(self) -> RawFd {
self.tun.into_raw_fd()
}
}
// impl AsRawFd for Queue {
// fn as_raw_fd(&self) -> RawFd {
// self.tun.as_raw_fd()
// }
// }
//
// impl IntoRawFd for Queue {
// fn into_raw_fd(self) -> RawFd {
// self.tun.into_raw_fd()
// }
// }
impl Read for Queue {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.tun.read(buf)
}
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
self.tun.read_vectored(bufs)
}
}
impl Write for Queue {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.tun.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.tun.flush()
}
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
self.tun.write_vectored(bufs)
}
}
// impl Read for Queue {
// fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
// self.tun.read(buf)
// }
//
// fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
// self.tun.read_vectored(bufs)
// }
// }
//
// impl Write for Queue {
// fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
// self.tun.write(buf)
// }
//
// fn flush(&mut self) -> io::Result<()> {
// self.tun.flush()
// }
//
// fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
// self.tun.write_vectored(bufs)
// }
// }
+32 -17
View File
@@ -12,22 +12,24 @@
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
use std::io::{self, Read, Write};
use std::io;
use std::mem;
use std::os::unix::io::{AsRawFd, RawFd};
use std::os::unix::io::{AsRawFd,RawFd};
use std::sync::Arc;
use crate::platform::posix::Fd;
use libc;
/// Read-only end for a file descriptor.
#[derive(Clone)]
pub struct Reader(pub(crate) Arc<Fd>);
/// Write-only end for a file descriptor.
#[derive(Clone)]
pub struct Writer(pub(crate) Arc<Fd>);
impl Read for Reader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
impl Reader {
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
unsafe {
let amount = libc::read(self.0.as_raw_fd(), buf.as_mut_ptr() as *mut _, buf.len());
@@ -39,7 +41,7 @@ impl Read for Reader {
}
}
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
pub fn read_vectored(&self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
unsafe {
let mut msg: libc::msghdr = mem::zeroed();
// msg.msg_name: NULL
@@ -57,8 +59,8 @@ impl Read for Reader {
}
}
impl Write for Writer {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
impl Writer {
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
unsafe {
let amount = libc::write(self.0.as_raw_fd(), buf.as_ptr() as *const _, buf.len());
@@ -70,11 +72,8 @@ impl Write for Writer {
}
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
pub fn write_vectored(&self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
unsafe {
let mut msg: libc::msghdr = mem::zeroed();
// msg.msg_name = NULL
@@ -90,6 +89,22 @@ impl Write for Writer {
Ok(n as usize)
}
}
pub fn write_all(&self, mut buf: &[u8]) -> io::Result<()> {
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => {
return Err(io::Error::new(
io::ErrorKind::WriteZero,
"failed to write whole buffer",
));
}
Ok(n) => buf = &buf[n..],
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
}
impl AsRawFd for Reader {
@@ -97,9 +112,9 @@ impl AsRawFd for Reader {
self.0.as_raw_fd()
}
}
impl AsRawFd for Writer {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
//
// impl AsRawFd for Writer {
// fn as_raw_fd(&self) -> RawFd {
// self.0.as_raw_fd()
// }
// }