add makefile

This commit is contained in:
Jett Chen 2023-12-17 01:26:37 +08:00
parent 94233874e6
commit 261f24d9ef
24 changed files with 207 additions and 293 deletions

View file

@ -15,4 +15,4 @@ mod options;
pub mod tokio;
pub use options::TunOptions;
pub use os_imp::{retrieve, TunInterface, TunQueue};
pub use os_imp::{TunInterface, TunQueue};

View file

@ -16,8 +16,6 @@ pub struct TunOptions {
pub no_pi: bool,
/// (Linux) Avoid opening an existing persistant device.
pub tun_excl: bool,
/// (MacOS) Whether to seek the first available utun device.
pub seek_utun: Option<i32>,
/// (Linux) The IP address of the tun interface.
pub address: Option<String>,
}

View file

@ -39,11 +39,11 @@ impl TunInterface {
}) {
Ok(result) => {
tracing::debug!("HORRAY");
return result;
return result
}
Err(_would_block) => {
tracing::debug!("WouldBlock");
continue;
continue
}
}
}

View file

@ -1,24 +1,24 @@
use std::{
io::{Error, IoSlice},
mem,
mem::{self, ManuallyDrop},
net::{Ipv4Addr, SocketAddrV4},
os::fd::{AsRawFd, RawFd},
os::fd::{AsRawFd, FromRawFd, RawFd},
};
use byteorder::{ByteOrder, NetworkEndian};
use fehler::throws;
use libc::{c_char, iovec, writev, AF_INET, AF_INET6};
use socket2::{Domain, SockAddr, Socket, Type};
use tracing::{self, debug, instrument};
use tracing::{self, instrument};
mod kern_control;
pub mod kern_control;
pub mod sys;
use crate::retrieve;
use kern_control::SysControlSocket;
pub use super::queue::TunQueue;
use super::{ifname_to_string, string_to_ifname, TunOptions};
use super::{ifname_to_string, string_to_ifname};
use crate::TunOptions;
#[derive(Debug)]
pub struct TunInterface {
@ -35,18 +35,41 @@ impl TunInterface {
#[throws]
#[instrument]
pub fn new_with_options(options: TunOptions) -> TunInterface {
debug!("Opening tun interface with options: {:?}", &options);
let ti = if let Some(n) = options.seek_utun {
retrieve().ok_or(Error::new(std::io::ErrorKind::NotFound, "No utun found"))?
} else {
TunInterface::connect(0)?
};
let ti = TunInterface::connect(0)?;
ti.configure(options)?;
ti
}
pub fn retrieve() -> Option<TunInterface> {
(3..100)
.filter_map(|fd| unsafe {
let peer_addr = socket2::SockAddr::init(|storage, len| {
*len = mem::size_of::<sys::sockaddr_ctl>() as u32;
libc::getpeername(fd, storage as *mut _, len);
Ok(())
})
.map(|(_, addr)| (fd, addr));
peer_addr.ok()
})
.filter(|(_fd, addr)| {
let ctl_addr = unsafe { &*(addr.as_ptr() as *const libc::sockaddr_ctl) };
addr.family() == libc::AF_SYSTEM as u8
&& ctl_addr.ss_sysaddr == libc::AF_SYS_CONTROL as u16
})
.map(|(fd, _)| {
let socket = unsafe { socket2::Socket::from_raw_fd(fd) };
TunInterface { socket }
})
.next()
}
#[throws]
fn configure(&self, options: TunOptions) {
if let Some(addr) = options.address {
if let Ok(addr) = addr.parse() {
ti.set_ipv4_addr(addr)?;
self.set_ipv4_addr(addr)?;
}
}
ti
}
#[throws]

View file

@ -1,13 +1,9 @@
use std::mem::size_of;
use std::{
io::{Error, Read},
mem,
os::fd::{AsRawFd, FromRawFd, IntoRawFd, RawFd},
};
use tracing::{debug, error, instrument};
use super::{syscall, TunOptions};
use tracing::instrument;
mod queue;
@ -19,13 +15,9 @@ mod imp;
#[path = "linux/mod.rs"]
mod imp;
use crate::os_imp::imp::sys;
use crate::os_imp::imp::sys::resolve_ctl_info;
use fehler::throws;
pub use imp::TunInterface;
use libc::{getpeername, sockaddr_ctl, sockaddr_storage, socklen_t, AF_SYSTEM, AF_SYS_CONTROL};
pub use queue::TunQueue;
use socket2::SockAddr;
impl AsRawFd for TunInterface {
fn as_raw_fd(&self) -> RawFd {
@ -82,35 +74,3 @@ pub fn string_to_ifname(name: &str) -> [libc::c_char; libc::IFNAMSIZ] {
buf[..len].copy_from_slice(unsafe { &*(name.as_bytes() as *const _ as *const [libc::c_char]) });
buf
}
#[cfg(any(target_os = "linux", target_vendor = "apple"))]
pub fn retrieve() -> Option<TunInterface> {
(3..100)
.filter_map(|i| {
let result = unsafe {
let mut addr = sockaddr_ctl {
sc_len: size_of::<sockaddr_ctl>() as u8,
sc_family: 0,
ss_sysaddr: 0,
sc_id: 0,
sc_unit: 0,
sc_reserved: Default::default(),
};
let mut len = mem::size_of::<sockaddr_ctl>() as libc::socklen_t;
let res = syscall!(getpeername(i, &mut addr as *mut _ as *mut _, len as *mut _));
tracing::debug!("getpeername{}: {:?}", i, res);
if res.is_err() {
return None;
}
if addr.sc_family == sys::AF_SYSTEM as u8
&& addr.ss_sysaddr == sys::AF_SYS_CONTROL as u16
{
Some(TunInterface::from_raw_fd(i))
} else {
None
}
};
result
})
.next()
}