pipe_client_event

This commit is contained in:
ssrlive 2023-09-24 00:30:25 +08:00
parent 8bed7d4b5c
commit f1f3a730d0
2 changed files with 62 additions and 10 deletions

View file

@ -11,12 +11,10 @@ use smoltcp::phy::RawSocket;
// #[cfg(any(target_os = "linux", target_os = "android"))] // #[cfg(any(target_os = "linux", target_os = "android"))]
// use smoltcp::phy::TunTapInterface; // use smoltcp::phy::TunTapInterface;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use crate::wintuninterface::WinTunInterface; use crate::wintuninterface::{NamedPipeSource, WinTunInterface};
#[cfg(target_family = "unix")]
use smoltcp::phy::{RxToken, TxToken};
use smoltcp::{ use smoltcp::{
iface::{Config, Interface, SocketHandle, SocketSet}, iface::{Config, Interface, SocketHandle, SocketSet},
phy::{Device, Medium}, phy::{Device, Medium, RxToken, TxToken},
socket::{tcp, tcp::State, udp, udp::UdpMetadata}, socket::{tcp, tcp::State, udp, udp::UdpMetadata},
time::Instant, time::Instant,
wire::{IpCidr, IpProtocol, Ipv4Packet, Ipv6Packet, TcpPacket, UdpPacket, UDP_HEADER_LEN}, wire::{IpCidr, IpProtocol, Ipv4Packet, Ipv6Packet, TcpPacket, UdpPacket, UDP_HEADER_LEN},
@ -211,7 +209,8 @@ pub(crate) trait ConnectionManager {
} }
const TUN_TOKEN: Token = Token(0); const TUN_TOKEN: Token = Token(0);
const EXIT_TOKEN: Token = Token(1); const PIPE_TOKEN: Token = Token(1);
const EXIT_TOKEN: Token = Token(2);
pub struct TunToProxy<'a> { pub struct TunToProxy<'a> {
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
@ -261,7 +260,11 @@ impl<'a> TunToProxy<'a> {
.register(&mut SourceFd(&tun.as_raw_fd()), TUN_TOKEN, Interest::READABLE)?; .register(&mut SourceFd(&tun.as_raw_fd()), TUN_TOKEN, Interest::READABLE)?;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{
poll.registry().register(&mut tun, TUN_TOKEN, Interest::READABLE)?; poll.registry().register(&mut tun, TUN_TOKEN, Interest::READABLE)?;
let mut pipe = NamedPipeSource(tun.pipe_client());
poll.registry().register(&mut pipe, PIPE_TOKEN, Interest::READABLE)?;
}
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
let (exit_sender, mut exit_receiver) = mio::unix::pipe::new()?; let (exit_sender, mut exit_receiver) = mio::unix::pipe::new()?;
@ -324,7 +327,6 @@ impl<'a> TunToProxy<'a> {
let _slice = vec.as_slice(); let _slice = vec.as_slice();
// TODO: Actual write. Replace. // TODO: Actual write. Replace.
#[cfg(target_family = "unix")]
self.tun self.tun
.transmit(Instant::now()) .transmit(Instant::now())
.ok_or("tx token not available")? .ok_or("tx token not available")?
@ -931,7 +933,6 @@ impl<'a> TunToProxy<'a> {
fn tun_event(&mut self, event: &Event) -> Result<(), Error> { fn tun_event(&mut self, event: &Event) -> Result<(), Error> {
if event.is_readable() { if event.is_readable() {
#[cfg(target_family = "unix")]
while let Some((rx_token, _)) = self.tun.receive(Instant::now()) { while let Some((rx_token, _)) = self.tun.receive(Instant::now()) {
rx_token.consume(|frame| self.receive_tun(frame))?; rx_token.consume(|frame| self.receive_tun(frame))?;
} }
@ -939,6 +940,14 @@ impl<'a> TunToProxy<'a> {
Ok(()) Ok(())
} }
fn pipe_event(&mut self, event: &Event) -> Result<(), Error> {
if event.is_readable() {
#[cfg(target_os = "windows")]
self.tun.pipe_client_event()?;
}
Ok(())
}
fn send_to_smoltcp(&mut self) -> Result<(), Error> { fn send_to_smoltcp(&mut self) -> Result<(), Error> {
for token in self.write_sockets.clone().into_iter() { for token in self.write_sockets.clone().into_iter() {
if let Some(connection) = self.find_info_by_token(token) { if let Some(connection) = self.find_info_by_token(token) {
@ -1132,6 +1141,7 @@ impl<'a> TunToProxy<'a> {
return Ok(()); return Ok(());
} }
TUN_TOKEN => self.tun_event(event)?, TUN_TOKEN => self.tun_event(event)?,
PIPE_TOKEN => self.pipe_event(event)?,
_ => self.mio_socket_event(event)?, _ => self.mio_socket_event(event)?,
} }
} }

View file

@ -41,7 +41,7 @@ pub struct WinTunInterface {
mtu: usize, mtu: usize,
medium: Medium, medium: Medium,
pipe_server: Rc<RefCell<NamedPipe>>, pipe_server: Rc<RefCell<NamedPipe>>,
_pipe_client: Rc<RefCell<NamedPipe>>, pipe_client: Rc<RefCell<NamedPipe>>,
} }
impl event::Source for WinTunInterface { impl event::Source for WinTunInterface {
@ -93,9 +93,35 @@ impl WinTunInterface {
mtu, mtu,
medium, medium,
pipe_server: Rc::new(RefCell::new(pipe_server)), pipe_server: Rc::new(RefCell::new(pipe_server)),
_pipe_client: Rc::new(RefCell::new(pipe_client)), pipe_client: Rc::new(RefCell::new(pipe_client)),
}) })
} }
pub fn pipe_client(&self) -> Rc<RefCell<NamedPipe>> {
self.pipe_client.clone()
}
// pub fn pipe_server(&self) -> Rc<RefCell<NamedPipe>> {
// self.pipe_server.clone()
// }
pub fn pipe_client_event(&self) -> Result<(), io::Error> {
let mut buffer = vec![0; self.mtu];
match self.pipe_client.borrow_mut().read(&mut buffer) {
Ok(len) => {
let write_pack = self.inner.allocate_send_packet(len as u16);
if let Ok(mut write_pack) = write_pack {
write_pack.bytes_mut().copy_from_slice(&buffer[..len]);
self.inner.send_packet(write_pack);
} else if let Err(err) = write_pack {
log::error!("phy: failed to allocate send packet: {}", err);
}
}
Err(err) if err.kind() == io::ErrorKind::WouldBlock => {}
Err(err) => panic!("{}", err),
}
Ok(())
}
} }
impl Drop for WinTunInterface { impl Drop for WinTunInterface {
@ -204,3 +230,19 @@ impl phy::TxToken for TxToken {
result result
} }
} }
pub struct NamedPipeSource(pub Rc<RefCell<NamedPipe>>);
impl event::Source for NamedPipeSource {
fn register(&mut self, registry: &Registry, token: Token, interests: Interest) -> io::Result<()> {
self.0.borrow_mut().register(registry, token, interests)
}
fn reregister(&mut self, registry: &Registry, token: Token, interests: Interest) -> io::Result<()> {
self.0.borrow_mut().reregister(registry, token, interests)
}
fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
self.0.borrow_mut().deregister(registry)
}
}