tun2proxy/src/wintuninterface.rs

207 lines
6.1 KiB
Rust
Raw Normal View History

2023-09-23 16:09:44 +08:00
use mio::{event, windows::NamedPipe, Interest, Registry, Token};
2023-09-18 21:40:56 +08:00
use smoltcp::{
phy::{self, Device, DeviceCapabilities, Medium},
time::Instant,
};
use std::{
2023-09-23 21:43:40 +08:00
cell::RefCell,
2023-09-23 16:09:44 +08:00
fs::OpenOptions,
2023-09-23 21:43:40 +08:00
io::{self, Read, Write},
2023-09-18 21:40:56 +08:00
net::{IpAddr, Ipv4Addr},
2023-09-23 16:09:44 +08:00
os::windows::prelude::{FromRawHandle, IntoRawHandle, OpenOptionsExt},
2023-09-23 21:43:40 +08:00
rc::Rc,
2023-09-18 21:40:56 +08:00
sync::Arc,
vec::Vec,
};
2023-09-23 21:57:00 +08:00
use windows::Win32::Storage::FileSystem::FILE_FLAG_OVERLAPPED;
2023-09-23 16:09:44 +08:00
fn server() -> io::Result<(NamedPipe, String)> {
2023-09-23 21:57:00 +08:00
use rand::Rng;
let num: u64 = rand::thread_rng().gen();
2023-09-23 16:09:44 +08:00
let name = format!(r"\\.\pipe\my-pipe-{}", num);
let pipe = NamedPipe::new(&name)?;
Ok((pipe, name))
}
fn client(name: &str) -> io::Result<NamedPipe> {
let mut opts = OpenOptions::new();
opts.read(true).write(true).custom_flags(FILE_FLAG_OVERLAPPED.0);
let file = opts.open(name)?;
unsafe { Ok(NamedPipe::from_raw_handle(file.into_raw_handle())) }
}
2023-09-23 21:57:00 +08:00
pub(crate) fn pipe() -> io::Result<(NamedPipe, NamedPipe)> {
2023-09-23 16:09:44 +08:00
let (pipe, name) = server()?;
Ok((pipe, client(&name)?))
}
2023-09-18 21:40:56 +08:00
/// A virtual TUN (IP) interface.
pub struct WinTunInterface {
inner: Arc<wintun::Session>,
mtu: usize,
medium: Medium,
2023-09-23 21:43:40 +08:00
pipe_server: Rc<RefCell<NamedPipe>>,
_pipe_client: Rc<RefCell<NamedPipe>>,
2023-09-18 21:40:56 +08:00
}
2023-09-19 12:55:02 +08:00
impl event::Source for WinTunInterface {
2023-09-23 16:09:44 +08:00
fn register(&mut self, registry: &Registry, token: Token, interests: Interest) -> io::Result<()> {
2023-09-23 21:43:40 +08:00
self.pipe_server.borrow_mut().register(registry, token, interests)?;
2023-09-23 16:09:44 +08:00
Ok(())
2023-09-19 12:55:02 +08:00
}
2023-09-23 16:09:44 +08:00
fn reregister(&mut self, registry: &Registry, token: Token, interests: Interest) -> io::Result<()> {
2023-09-23 21:43:40 +08:00
self.pipe_server.borrow_mut().reregister(registry, token, interests)?;
2023-09-23 16:09:44 +08:00
Ok(())
2023-09-19 12:55:02 +08:00
}
2023-09-23 16:09:44 +08:00
fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
2023-09-23 21:43:40 +08:00
self.pipe_server.borrow_mut().deregister(registry)?;
2023-09-23 16:09:44 +08:00
Ok(())
2023-09-19 12:55:02 +08:00
}
}
2023-09-18 21:40:56 +08:00
impl WinTunInterface {
pub fn new(name: &str, medium: Medium) -> io::Result<WinTunInterface> {
let wintun = unsafe { wintun::load() }.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let tun_name = name;
let adapter = match wintun::Adapter::open(&wintun, tun_name) {
Ok(a) => a,
Err(_) => wintun::Adapter::create(&wintun, tun_name, tun_name, None)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?,
};
let address = Ipv4Addr::new(10, 1, 0, 33);
let mask = Ipv4Addr::new(255, 255, 255, 0);
let gateway = Some(IpAddr::V4(Ipv4Addr::new(10, 1, 0, 1)));
adapter
.set_network_addresses_tuple(IpAddr::V4(address), IpAddr::V4(mask), gateway)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let session = adapter
.start_session(wintun::MAX_RING_CAPACITY)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let inner = Arc::new(session);
2023-09-23 16:09:44 +08:00
let (pipe_server, pipe_client) = pipe()?;
2023-09-18 21:40:56 +08:00
// let inner = WinTunInterfaceDesc::new(name, medium)?;
// let mtu = inner.interface_mtu()?;
let mtu = 1500;
2023-09-23 16:09:44 +08:00
Ok(WinTunInterface {
inner,
mtu,
medium,
2023-09-23 21:43:40 +08:00
pipe_server: Rc::new(RefCell::new(pipe_server)),
_pipe_client: Rc::new(RefCell::new(pipe_client)),
2023-09-23 16:09:44 +08:00
})
2023-09-18 21:40:56 +08:00
}
}
impl Drop for WinTunInterface {
fn drop(&mut self) {
if let Err(e) = self.inner.shutdown() {
log::error!("phy: failed to shutdown interface: {}", e);
}
}
}
impl Device for WinTunInterface {
type RxToken<'a> = RxToken;
type TxToken<'a> = TxToken;
fn capabilities(&self) -> DeviceCapabilities {
let mut v = DeviceCapabilities::default();
v.max_transmission_unit = self.mtu;
v.medium = self.medium;
v
}
fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
2023-09-23 21:43:40 +08:00
/*
2023-09-18 21:40:56 +08:00
let inner = self.inner.clone();
match inner.receive_blocking() {
Ok(read_pack) => Some((
RxToken {
buffer: read_pack.bytes().to_vec(),
},
TxToken { inner },
)),
Err(err) => {
log::error!("phy: failed to receive packet: {}", err);
None
}
}
2023-09-23 21:43:40 +08:00
*/
let mut buffer = vec![0; self.mtu];
match self.pipe_server.borrow_mut().read(&mut buffer[..]) {
Ok(size) => {
buffer.resize(size, 0);
let rx = RxToken { buffer };
let tx = TxToken {
pipe_server: self.pipe_server.clone(),
};
Some((rx, tx))
}
Err(err) if err.kind() == io::ErrorKind::WouldBlock => None,
Err(err) => panic!("{}", err),
}
2023-09-18 21:40:56 +08:00
}
fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
Some(TxToken {
2023-09-23 21:43:40 +08:00
pipe_server: self.pipe_server.clone(),
2023-09-18 21:40:56 +08:00
})
}
}
#[doc(hidden)]
pub struct RxToken {
buffer: Vec<u8>,
}
impl phy::RxToken for RxToken {
fn consume<R, F>(mut self, f: F) -> R
where
F: FnOnce(&mut [u8]) -> R,
{
f(&mut self.buffer[..])
}
}
#[doc(hidden)]
pub struct TxToken {
2023-09-23 21:43:40 +08:00
pipe_server: Rc<RefCell<NamedPipe>>,
2023-09-18 21:40:56 +08:00
}
impl phy::TxToken for TxToken {
fn consume<R, F>(self, len: usize, f: F) -> R
where
F: FnOnce(&mut [u8]) -> R,
{
let mut buffer = vec![0; len];
let result = f(&mut buffer);
2023-09-23 21:43:40 +08:00
/*
let inner = self.inner.clone();
2023-09-18 21:40:56 +08:00
let write_pack = inner.allocate_send_packet(len as u16);
if let Ok(mut write_pack) = write_pack {
write_pack.bytes_mut().copy_from_slice(&buffer[..]);
inner.send_packet(write_pack);
} else if let Err(err) = write_pack {
log::error!("phy: failed to allocate send packet: {}", err);
}
2023-09-23 21:43:40 +08:00
*/
2023-09-18 21:40:56 +08:00
2023-09-23 21:43:40 +08:00
match self.pipe_server.borrow_mut().write(&buffer[..]) {
Ok(_) => {}
Err(err) if err.kind() == io::ErrorKind::WouldBlock => {
log::error!("phy: tx failed due to WouldBlock")
}
Err(err) => panic!("{}", err),
}
2023-09-18 21:40:56 +08:00
result
}
}