2023-03-22 22:19:00 +08:00
|
|
|
use crate::error::Error;
|
2022-08-01 14:36:58 +00:00
|
|
|
use crate::virtdevice::VirtualTunDevice;
|
2023-04-10 23:24:53 +02:00
|
|
|
use crate::{Credentials, NetworkInterface, Options};
|
2022-08-16 16:18:25 +02:00
|
|
|
use log::{error, info};
|
2021-09-02 11:30:23 +02:00
|
|
|
use mio::event::Event;
|
2022-08-01 14:36:58 +00:00
|
|
|
use mio::net::TcpStream;
|
2021-09-02 11:30:23 +02:00
|
|
|
use mio::unix::SourceFd;
|
2022-08-01 14:36:58 +00:00
|
|
|
use mio::{Events, Interest, Poll, Token};
|
2023-03-20 15:34:41 +01:00
|
|
|
use smoltcp::iface::{Config, Interface, SocketHandle, SocketSet};
|
2021-09-02 11:30:23 +02:00
|
|
|
use smoltcp::phy::{Device, Medium, RxToken, TunTapInterface, TxToken};
|
2023-04-03 20:31:31 +02:00
|
|
|
use smoltcp::socket::tcp::State;
|
2023-03-24 14:31:22 +08:00
|
|
|
use smoltcp::socket::{tcp, udp};
|
2021-09-02 11:30:23 +02:00
|
|
|
use smoltcp::time::Instant;
|
2023-03-23 19:02:20 +01:00
|
|
|
use smoltcp::wire::{IpCidr, IpProtocol, Ipv4Packet, Ipv6Packet, TcpPacket, UdpPacket};
|
2023-03-23 13:03:01 +01:00
|
|
|
use std::collections::{HashMap, HashSet};
|
2023-03-23 20:00:59 +08:00
|
|
|
use std::convert::{From, TryFrom};
|
2022-08-01 14:36:58 +00:00
|
|
|
use std::io::{Read, Write};
|
2021-09-02 21:02:17 +02:00
|
|
|
use std::net::Shutdown::Both;
|
2023-04-03 20:31:31 +02:00
|
|
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
2022-08-01 14:36:58 +00:00
|
|
|
use std::os::unix::io::AsRawFd;
|
2023-03-23 16:31:33 +08:00
|
|
|
use std::rc::Rc;
|
2023-03-23 19:02:20 +01:00
|
|
|
use std::str::FromStr;
|
2021-09-02 11:30:23 +02:00
|
|
|
|
2023-04-04 00:18:50 +02:00
|
|
|
#[derive(Hash, Clone, Eq, PartialEq, Debug)]
|
2023-03-25 13:07:39 +01:00
|
|
|
pub(crate) enum DestinationHost {
|
2023-03-22 19:11:28 +01:00
|
|
|
Address(IpAddr),
|
|
|
|
Hostname(String),
|
|
|
|
}
|
|
|
|
|
2023-03-25 16:44:33 +08:00
|
|
|
impl std::fmt::Display for DestinationHost {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
2023-03-22 19:11:28 +01:00
|
|
|
match self {
|
2023-03-25 10:58:16 +01:00
|
|
|
DestinationHost::Address(addr) => addr.fmt(f),
|
2023-03-25 13:07:39 +01:00
|
|
|
DestinationHost::Hostname(name) => name.fmt(f),
|
2023-03-22 19:11:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-04 00:18:50 +02:00
|
|
|
#[derive(Hash, Clone, Eq, PartialEq, Debug)]
|
2023-03-22 19:11:28 +01:00
|
|
|
pub(crate) struct Destination {
|
|
|
|
pub(crate) host: DestinationHost,
|
|
|
|
pub(crate) port: u16,
|
|
|
|
}
|
|
|
|
|
2023-03-23 20:00:59 +08:00
|
|
|
impl TryFrom<Destination> for SocketAddr {
|
|
|
|
type Error = Error;
|
|
|
|
fn try_from(value: Destination) -> Result<Self, Self::Error> {
|
2023-03-23 18:01:25 +01:00
|
|
|
let ip = match value.host {
|
|
|
|
DestinationHost::Address(addr) => addr,
|
2023-03-25 13:07:39 +01:00
|
|
|
DestinationHost::Hostname(e) => {
|
2023-03-23 18:01:25 +01:00
|
|
|
return Err(e.into());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Ok(SocketAddr::new(ip, value.port))
|
2023-03-22 19:11:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<SocketAddr> for Destination {
|
|
|
|
fn from(addr: SocketAddr) -> Self {
|
|
|
|
Self {
|
|
|
|
host: DestinationHost::Address(addr.ip()),
|
|
|
|
port: addr.port(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-25 16:44:33 +08:00
|
|
|
impl std::fmt::Display for Destination {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
2023-03-25 10:58:16 +01:00
|
|
|
if let DestinationHost::Address(IpAddr::V6(addr)) = self.host {
|
|
|
|
write!(f, "[{}]:{}", addr, self.port)
|
|
|
|
} else {
|
|
|
|
write!(f, "{}:{}", self.host, self.port)
|
|
|
|
}
|
2023-03-22 19:11:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-04 00:18:50 +02:00
|
|
|
#[derive(Hash, Clone, Eq, PartialEq, Debug)]
|
2023-03-22 19:11:28 +01:00
|
|
|
pub(crate) struct Connection {
|
2023-03-23 20:00:59 +08:00
|
|
|
pub(crate) src: SocketAddr,
|
2023-03-22 19:11:28 +01:00
|
|
|
pub(crate) dst: Destination,
|
2023-03-25 00:24:02 +08:00
|
|
|
pub(crate) proto: IpProtocol,
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-03-23 13:03:01 +01:00
|
|
|
impl Connection {
|
|
|
|
fn to_named(&self, name: String) -> Self {
|
|
|
|
let mut result = self.clone();
|
2023-03-25 13:07:39 +01:00
|
|
|
result.dst.host = DestinationHost::Hostname(name);
|
2023-03-23 13:03:01 +01:00
|
|
|
result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-25 16:44:33 +08:00
|
|
|
impl std::fmt::Display for Connection {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
2021-09-02 21:02:17 +02:00
|
|
|
write!(f, "{} -> {}", self.src, self.dst)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-02 11:30:23 +02:00
|
|
|
#[derive(Eq, PartialEq, Debug)]
|
|
|
|
pub(crate) enum IncomingDirection {
|
|
|
|
FromServer,
|
2022-08-01 14:36:58 +00:00
|
|
|
FromClient,
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Eq, PartialEq, Debug)]
|
|
|
|
pub(crate) enum OutgoingDirection {
|
|
|
|
ToServer,
|
2022-08-01 14:36:58 +00:00
|
|
|
ToClient,
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-04-04 00:18:50 +02:00
|
|
|
#[derive(Eq, PartialEq, Debug)]
|
|
|
|
pub(crate) enum Direction {
|
|
|
|
Incoming(IncomingDirection),
|
|
|
|
Outgoing(OutgoingDirection),
|
|
|
|
}
|
|
|
|
|
2021-09-02 11:30:23 +02:00
|
|
|
#[allow(dead_code)]
|
|
|
|
pub(crate) enum ConnectionEvent<'a> {
|
|
|
|
NewConnection(&'a Connection),
|
2022-08-01 14:36:58 +00:00
|
|
|
ConnectionClosed(&'a Connection),
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) struct DataEvent<'a, T> {
|
|
|
|
pub(crate) direction: T,
|
2022-08-01 14:36:58 +00:00
|
|
|
pub(crate) buffer: &'a [u8],
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) type IncomingDataEvent<'a> = DataEvent<'a, IncomingDirection>;
|
|
|
|
pub(crate) type OutgoingDataEvent<'a> = DataEvent<'a, OutgoingDirection>;
|
|
|
|
|
2022-08-01 14:36:58 +00:00
|
|
|
fn get_transport_info(
|
2023-03-25 00:24:02 +08:00
|
|
|
proto: IpProtocol,
|
2022-08-01 14:36:58 +00:00
|
|
|
transport_offset: usize,
|
|
|
|
packet: &[u8],
|
|
|
|
) -> Option<((u16, u16), bool, usize, usize)> {
|
2023-04-10 09:58:17 +08:00
|
|
|
match proto {
|
|
|
|
IpProtocol::Udp => match UdpPacket::new_checked(packet) {
|
2022-08-01 14:36:58 +00:00
|
|
|
Ok(result) => Some((
|
|
|
|
(result.src_port(), result.dst_port()),
|
|
|
|
false,
|
|
|
|
transport_offset + 8,
|
|
|
|
packet.len() - 8,
|
|
|
|
)),
|
|
|
|
Err(_) => None,
|
2023-04-10 09:58:17 +08:00
|
|
|
},
|
|
|
|
IpProtocol::Tcp => match TcpPacket::new_checked(packet) {
|
2022-08-01 14:36:58 +00:00
|
|
|
Ok(result) => Some((
|
|
|
|
(result.src_port(), result.dst_port()),
|
|
|
|
result.syn() && !result.ack(),
|
|
|
|
transport_offset + result.header_len() as usize,
|
|
|
|
packet.len(),
|
|
|
|
)),
|
|
|
|
Err(_) => None,
|
2023-04-10 09:58:17 +08:00
|
|
|
},
|
|
|
|
_ => None,
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn connection_tuple(frame: &[u8]) -> Option<(Connection, bool, usize, usize)> {
|
2022-08-01 14:36:58 +00:00
|
|
|
if let Ok(packet) = Ipv4Packet::new_checked(frame) {
|
2023-03-25 00:24:02 +08:00
|
|
|
let proto = packet.next_header();
|
2022-08-01 14:36:58 +00:00
|
|
|
|
|
|
|
let mut a: [u8; 4] = Default::default();
|
|
|
|
a.copy_from_slice(packet.src_addr().as_bytes());
|
|
|
|
let src_addr = IpAddr::from(a);
|
|
|
|
a.copy_from_slice(packet.dst_addr().as_bytes());
|
|
|
|
let dst_addr = IpAddr::from(a);
|
|
|
|
|
2023-03-23 13:24:33 +01:00
|
|
|
return if let Some((ports, first_packet, payload_offset, payload_size)) = get_transport_info(
|
2022-08-01 14:36:58 +00:00
|
|
|
proto,
|
|
|
|
packet.header_len().into(),
|
|
|
|
&frame[packet.header_len().into()..],
|
|
|
|
) {
|
|
|
|
let connection = Connection {
|
|
|
|
src: SocketAddr::new(src_addr, ports.0),
|
2023-03-22 19:11:28 +01:00
|
|
|
dst: SocketAddr::new(dst_addr, ports.1).into(),
|
2022-08-01 14:36:58 +00:00
|
|
|
proto,
|
|
|
|
};
|
2023-03-23 13:24:33 +01:00
|
|
|
Some((connection, first_packet, payload_offset, payload_size))
|
2022-08-01 14:36:58 +00:00
|
|
|
} else {
|
2023-03-23 13:24:33 +01:00
|
|
|
None
|
|
|
|
};
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
match Ipv6Packet::new_checked(frame) {
|
|
|
|
Ok(packet) => {
|
|
|
|
// TODO: Support extension headers.
|
2023-03-25 00:24:02 +08:00
|
|
|
let proto = packet.next_header();
|
2021-09-02 11:30:23 +02:00
|
|
|
|
|
|
|
let mut a: [u8; 16] = Default::default();
|
|
|
|
a.copy_from_slice(packet.src_addr().as_bytes());
|
|
|
|
let src_addr = IpAddr::from(a);
|
|
|
|
a.copy_from_slice(packet.dst_addr().as_bytes());
|
|
|
|
let dst_addr = IpAddr::from(a);
|
|
|
|
|
2022-08-01 14:36:58 +00:00
|
|
|
if let Some((ports, first_packet, payload_offset, payload_size)) =
|
|
|
|
get_transport_info(proto, packet.header_len(), &frame[packet.header_len()..])
|
|
|
|
{
|
2021-09-02 11:30:23 +02:00
|
|
|
let connection = Connection {
|
|
|
|
src: SocketAddr::new(src_addr, ports.0),
|
2023-03-22 19:11:28 +01:00
|
|
|
dst: SocketAddr::new(dst_addr, ports.1).into(),
|
2022-08-01 14:36:58 +00:00
|
|
|
proto,
|
2021-09-02 11:30:23 +02:00
|
|
|
};
|
|
|
|
Some((connection, first_packet, payload_offset, payload_size))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
2022-08-01 14:36:58 +00:00
|
|
|
_ => None,
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-03 20:31:31 +02:00
|
|
|
const SERVER_WRITE_CLOSED: u8 = 1;
|
|
|
|
const CLIENT_WRITE_CLOSED: u8 = 2;
|
2023-03-23 13:03:01 +01:00
|
|
|
|
2021-09-02 11:30:23 +02:00
|
|
|
struct ConnectionState {
|
|
|
|
smoltcp_handle: SocketHandle,
|
|
|
|
mio_stream: TcpStream,
|
2021-09-02 22:36:47 +02:00
|
|
|
token: Token,
|
2023-03-23 16:31:33 +08:00
|
|
|
handler: Box<dyn TcpProxy>,
|
2023-04-03 20:31:31 +02:00
|
|
|
close_state: u8,
|
2023-04-04 00:18:50 +02:00
|
|
|
wait_read: bool,
|
|
|
|
wait_write: bool,
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) trait TcpProxy {
|
2023-03-22 22:19:00 +08:00
|
|
|
fn push_data(&mut self, event: IncomingDataEvent<'_>) -> Result<(), Error>;
|
2021-09-02 11:30:23 +02:00
|
|
|
fn consume_data(&mut self, dir: OutgoingDirection, size: usize);
|
|
|
|
fn peek_data(&mut self, dir: OutgoingDirection) -> OutgoingDataEvent;
|
2021-09-02 21:02:17 +02:00
|
|
|
fn connection_established(&self) -> bool;
|
2023-04-04 00:18:50 +02:00
|
|
|
fn have_data(&mut self, dir: Direction) -> bool;
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) trait ConnectionManager {
|
|
|
|
fn handles_connection(&self, connection: &Connection) -> bool;
|
2023-03-22 01:02:27 +01:00
|
|
|
fn new_connection(
|
|
|
|
&self,
|
|
|
|
connection: &Connection,
|
2023-03-23 16:31:33 +08:00
|
|
|
manager: Rc<dyn ConnectionManager>,
|
2023-03-25 01:39:46 +01:00
|
|
|
) -> Result<Option<Box<dyn TcpProxy>>, Error>;
|
2023-03-21 01:08:44 +01:00
|
|
|
fn close_connection(&self, connection: &Connection);
|
2021-09-02 11:30:23 +02:00
|
|
|
fn get_server(&self) -> SocketAddr;
|
2023-03-22 12:18:41 +01:00
|
|
|
fn get_credentials(&self) -> &Option<Credentials>;
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-03-23 16:31:33 +08:00
|
|
|
const TCP_TOKEN: Token = Token(0);
|
|
|
|
const UDP_TOKEN: Token = Token(1);
|
2023-04-14 17:27:37 +08:00
|
|
|
const EXIT_TOKEN: Token = Token(34255);
|
|
|
|
|
|
|
|
const EXIT_LISTENER: &str = "127.0.0.1:34255";
|
2023-03-23 13:03:01 +01:00
|
|
|
|
2021-09-02 11:30:23 +02:00
|
|
|
pub(crate) struct TunToProxy<'a> {
|
|
|
|
tun: TunTapInterface,
|
|
|
|
poll: Poll,
|
2023-03-20 15:34:41 +01:00
|
|
|
iface: Interface,
|
2021-09-02 11:30:23 +02:00
|
|
|
connections: HashMap<Connection, ConnectionState>,
|
2023-03-23 16:31:33 +08:00
|
|
|
connection_managers: Vec<Rc<dyn ConnectionManager>>,
|
2021-09-02 11:30:23 +02:00
|
|
|
next_token: usize,
|
|
|
|
token_to_connection: HashMap<Token, Connection>,
|
2023-03-20 15:34:41 +01:00
|
|
|
sockets: SocketSet<'a>,
|
|
|
|
device: VirtualTunDevice,
|
2023-03-23 13:03:01 +01:00
|
|
|
options: Options,
|
|
|
|
write_sockets: HashSet<Token>,
|
2023-04-14 17:27:37 +08:00
|
|
|
_exit_listener: mio::net::TcpListener,
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> TunToProxy<'a> {
|
2023-04-10 23:24:53 +02:00
|
|
|
pub(crate) fn new(interface: &NetworkInterface, options: Options) -> Result<Self, Error> {
|
|
|
|
let tun = match interface {
|
|
|
|
NetworkInterface::Named(name) => TunTapInterface::new(name.as_str(), Medium::Ip)?,
|
|
|
|
NetworkInterface::Fd(fd) => {
|
|
|
|
TunTapInterface::from_fd(*fd, Medium::Ip, options.mtu.unwrap_or(1500))?
|
|
|
|
}
|
|
|
|
};
|
2023-03-24 09:27:31 +08:00
|
|
|
let poll = Poll::new()?;
|
|
|
|
poll.registry().register(
|
|
|
|
&mut SourceFd(&tun.as_raw_fd()),
|
|
|
|
TCP_TOKEN,
|
|
|
|
Interest::READABLE,
|
|
|
|
)?;
|
2021-09-02 11:30:23 +02:00
|
|
|
|
2023-04-14 17:27:37 +08:00
|
|
|
let mut _exit_listener = mio::net::TcpListener::bind(EXIT_LISTENER.parse()?)?;
|
|
|
|
poll.registry()
|
|
|
|
.register(&mut _exit_listener, EXIT_TOKEN, Interest::READABLE)?;
|
|
|
|
|
2023-04-10 09:58:17 +08:00
|
|
|
let config = match tun.capabilities().medium {
|
|
|
|
Medium::Ethernet => Config::new(
|
|
|
|
smoltcp::wire::EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into(),
|
|
|
|
),
|
|
|
|
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
|
|
|
|
Medium::Ieee802154 => todo!(),
|
|
|
|
};
|
2023-03-20 15:34:41 +01:00
|
|
|
let mut virt = VirtualTunDevice::new(tun.capabilities());
|
2023-03-24 15:31:05 +01:00
|
|
|
let gateway4: Ipv4Addr = Ipv4Addr::from_str("0.0.0.1")?;
|
|
|
|
let gateway6: Ipv6Addr = Ipv6Addr::from_str("::1")?;
|
2023-03-20 15:34:41 +01:00
|
|
|
let mut iface = Interface::new(config, &mut virt);
|
|
|
|
iface.update_ip_addrs(|ip_addrs| {
|
2023-03-24 09:27:31 +08:00
|
|
|
ip_addrs.push(IpCidr::new(gateway4.into(), 0)).unwrap();
|
|
|
|
ip_addrs.push(IpCidr::new(gateway6.into(), 0)).unwrap()
|
2023-03-20 15:34:41 +01:00
|
|
|
});
|
2023-03-24 09:27:31 +08:00
|
|
|
iface.routes_mut().add_default_ipv4_route(gateway4.into())?;
|
|
|
|
iface.routes_mut().add_default_ipv6_route(gateway6.into())?;
|
2023-03-20 15:34:41 +01:00
|
|
|
iface.set_any_ip(true);
|
2021-09-02 11:30:23 +02:00
|
|
|
|
2023-03-24 09:27:31 +08:00
|
|
|
let tun = Self {
|
2021-09-02 11:30:23 +02:00
|
|
|
tun,
|
|
|
|
poll,
|
|
|
|
iface,
|
2023-03-24 14:31:22 +08:00
|
|
|
connections: HashMap::default(),
|
2021-09-02 11:30:23 +02:00
|
|
|
next_token: 2,
|
2023-03-24 14:31:22 +08:00
|
|
|
token_to_connection: HashMap::default(),
|
|
|
|
connection_managers: Vec::default(),
|
2023-03-20 15:34:41 +01:00
|
|
|
sockets: SocketSet::new([]),
|
|
|
|
device: virt,
|
2023-03-23 13:03:01 +01:00
|
|
|
options,
|
2023-03-24 14:31:22 +08:00
|
|
|
write_sockets: HashSet::default(),
|
2023-04-14 17:27:37 +08:00
|
|
|
_exit_listener,
|
2023-03-24 09:27:31 +08:00
|
|
|
};
|
|
|
|
Ok(tun)
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-03-23 16:31:33 +08:00
|
|
|
pub(crate) fn add_connection_manager(&mut self, manager: Rc<dyn ConnectionManager>) {
|
2021-09-02 11:30:23 +02:00
|
|
|
self.connection_managers.push(manager);
|
|
|
|
}
|
|
|
|
|
2023-03-24 14:31:22 +08:00
|
|
|
fn expect_smoltcp_send(&mut self) -> Result<(), Error> {
|
2023-03-20 17:56:54 +01:00
|
|
|
self.iface
|
|
|
|
.poll(Instant::now(), &mut self.device, &mut self.sockets);
|
2021-09-02 11:30:23 +02:00
|
|
|
|
2023-03-20 15:34:41 +01:00
|
|
|
while let Some(vec) = self.device.exfiltrate_packet() {
|
2021-09-02 11:30:23 +02:00
|
|
|
let slice = vec.as_slice();
|
|
|
|
|
|
|
|
// TODO: Actual write. Replace.
|
2022-08-01 14:36:58 +00:00
|
|
|
self.tun
|
2023-03-20 15:34:41 +01:00
|
|
|
.transmit(Instant::now())
|
2023-03-24 14:31:22 +08:00
|
|
|
.ok_or("tx token not available")?
|
2023-03-20 15:34:41 +01:00
|
|
|
.consume(slice.len(), |buf| {
|
2022-08-01 14:36:58 +00:00
|
|
|
buf[..].clone_from_slice(slice);
|
2023-03-20 15:34:41 +01:00
|
|
|
});
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
2023-03-24 14:31:22 +08:00
|
|
|
Ok(())
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-03-24 14:31:22 +08:00
|
|
|
fn remove_connection(&mut self, connection: &Connection) -> Result<(), Error> {
|
2023-04-04 00:18:50 +02:00
|
|
|
if let Some(mut conn) = self.connections.remove(connection) {
|
|
|
|
let token = &conn.token;
|
|
|
|
self.token_to_connection.remove(token);
|
|
|
|
_ = self.poll.registry().deregister(&mut conn.mio_stream);
|
|
|
|
info!("CLOSE {}", connection);
|
|
|
|
}
|
2023-03-24 14:31:22 +08:00
|
|
|
Ok(())
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-03-23 16:31:33 +08:00
|
|
|
fn get_connection_manager(&self, connection: &Connection) -> Option<Rc<dyn ConnectionManager>> {
|
2021-09-02 11:30:23 +02:00
|
|
|
for manager in self.connection_managers.iter() {
|
|
|
|
if manager.handles_connection(connection) {
|
2023-03-22 01:02:27 +01:00
|
|
|
return Some(manager.clone());
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
2023-04-03 20:31:31 +02:00
|
|
|
fn check_change_close_state(&mut self, connection: &Connection) -> Result<(), Error> {
|
2023-04-04 00:18:50 +02:00
|
|
|
let state = self.connections.get_mut(connection);
|
|
|
|
if state.is_none() {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
let state = state.unwrap();
|
2023-04-03 20:31:31 +02:00
|
|
|
let mut closed_ends = 0;
|
2023-04-04 00:18:50 +02:00
|
|
|
if (state.close_state & SERVER_WRITE_CLOSED) == SERVER_WRITE_CLOSED
|
|
|
|
&& !state
|
|
|
|
.handler
|
|
|
|
.have_data(Direction::Incoming(IncomingDirection::FromServer))
|
|
|
|
&& !state
|
|
|
|
.handler
|
|
|
|
.have_data(Direction::Outgoing(OutgoingDirection::ToClient))
|
|
|
|
{
|
|
|
|
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
|
|
|
socket.close();
|
|
|
|
closed_ends += 1;
|
2023-04-03 20:31:31 +02:00
|
|
|
}
|
2021-09-02 11:30:23 +02:00
|
|
|
|
2023-04-04 00:18:50 +02:00
|
|
|
if (state.close_state & CLIENT_WRITE_CLOSED) == CLIENT_WRITE_CLOSED
|
|
|
|
&& !state
|
|
|
|
.handler
|
|
|
|
.have_data(Direction::Incoming(IncomingDirection::FromClient))
|
|
|
|
&& !state
|
|
|
|
.handler
|
|
|
|
.have_data(Direction::Outgoing(OutgoingDirection::ToServer))
|
|
|
|
{
|
|
|
|
_ = state.mio_stream.shutdown(Shutdown::Write);
|
|
|
|
closed_ends += 1;
|
2023-04-03 20:31:31 +02:00
|
|
|
}
|
2021-09-02 11:30:23 +02:00
|
|
|
|
2023-04-03 20:31:31 +02:00
|
|
|
if closed_ends == 2 {
|
|
|
|
self.remove_connection(connection)?;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2023-03-23 13:03:01 +01:00
|
|
|
|
2023-04-03 20:31:31 +02:00
|
|
|
fn tunsocket_read_and_forward(&mut self, connection: &Connection) -> Result<(), Error> {
|
|
|
|
// Scope for mutable borrow of self.
|
|
|
|
{
|
2023-04-04 00:18:50 +02:00
|
|
|
let state = self.connections.get_mut(connection);
|
|
|
|
if state.is_none() {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
let state = state.unwrap();
|
2023-04-03 20:31:31 +02:00
|
|
|
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
|
|
|
let mut error = Ok(());
|
|
|
|
while socket.can_recv() && error.is_ok() {
|
|
|
|
socket.recv(|data| {
|
|
|
|
let event = IncomingDataEvent {
|
|
|
|
direction: IncomingDirection::FromClient,
|
|
|
|
buffer: data,
|
|
|
|
};
|
|
|
|
error = state.handler.push_data(event);
|
|
|
|
(data.len(), ())
|
|
|
|
})?;
|
|
|
|
}
|
|
|
|
|
|
|
|
if !socket.may_recv()
|
|
|
|
&& socket.state() != State::Listen
|
|
|
|
&& socket.state() != State::SynSent
|
|
|
|
&& socket.state() != State::SynReceived
|
|
|
|
{
|
|
|
|
// We cannot yet close the write end of the mio stream here because we may still
|
|
|
|
// need to send data.
|
|
|
|
state.close_state |= CLIENT_WRITE_CLOSED;
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
2023-04-03 20:31:31 +02:00
|
|
|
|
|
|
|
// Expect ACKs etc. from smoltcp sockets.
|
|
|
|
self.expect_smoltcp_send()?;
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
2023-04-03 20:31:31 +02:00
|
|
|
|
|
|
|
self.check_change_close_state(connection)?;
|
|
|
|
|
2023-03-24 14:31:22 +08:00
|
|
|
Ok(())
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-04-04 00:18:50 +02:00
|
|
|
// Update the poll registry depending on the connection's event interests.
|
|
|
|
fn update_mio_socket_interest(&mut self, connection: &Connection) -> Result<(), Error> {
|
|
|
|
let state = self
|
|
|
|
.connections
|
|
|
|
.get_mut(connection)
|
|
|
|
.ok_or("connection not found")?;
|
|
|
|
|
|
|
|
// Maybe we did not listen for any events before. Therefore, just swallow the error.
|
|
|
|
_ = self.poll.registry().deregister(&mut state.mio_stream);
|
|
|
|
|
|
|
|
// If we do not wait for read or write events, we do not need to register them.
|
|
|
|
if !state.wait_read && !state.wait_write {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
|
|
|
// This ugliness is due to the way Interest is implemented (as a NonZeroU8 wrapper).
|
|
|
|
let interest;
|
|
|
|
if state.wait_read && !state.wait_write {
|
|
|
|
interest = Interest::READABLE;
|
|
|
|
} else if state.wait_write && !state.wait_read {
|
|
|
|
interest = Interest::WRITABLE;
|
|
|
|
} else {
|
|
|
|
interest = Interest::READABLE | Interest::WRITABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.poll
|
|
|
|
.registry()
|
|
|
|
.register(&mut state.mio_stream, state.token, interest)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
// A raw packet was received on the tunnel interface.
|
2023-03-24 14:31:22 +08:00
|
|
|
fn receive_tun(&mut self, frame: &mut [u8]) -> Result<(), Error> {
|
2022-08-01 14:36:58 +00:00
|
|
|
if let Some((connection, first_packet, _payload_offset, _payload_size)) =
|
|
|
|
connection_tuple(frame)
|
|
|
|
{
|
2023-03-24 13:26:31 +01:00
|
|
|
let resolved_conn = match &mut self.options.virtdns {
|
2023-03-23 13:03:01 +01:00
|
|
|
None => connection.clone(),
|
|
|
|
Some(virt_dns) => {
|
2023-03-24 14:31:22 +08:00
|
|
|
let ip = SocketAddr::try_from(connection.dst.clone())?.ip();
|
2023-03-24 13:26:31 +01:00
|
|
|
virt_dns.touch_ip(&ip);
|
|
|
|
match virt_dns.resolve_ip(&ip) {
|
2023-03-23 13:03:01 +01:00
|
|
|
None => connection.clone(),
|
|
|
|
Some(name) => connection.to_named(name.clone()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2023-03-26 15:21:56 +02:00
|
|
|
let dst = connection.dst;
|
|
|
|
(|| -> Result<(), Error> {
|
|
|
|
if resolved_conn.proto == IpProtocol::Tcp {
|
|
|
|
let cm = self.get_connection_manager(&resolved_conn);
|
|
|
|
if cm.is_none() {
|
2023-03-27 22:26:57 +08:00
|
|
|
log::trace!("no connect manager");
|
2023-03-26 15:21:56 +02:00
|
|
|
return Ok(());
|
|
|
|
}
|
2023-03-27 22:26:57 +08:00
|
|
|
let server = cm.unwrap().get_server();
|
2023-03-26 15:21:56 +02:00
|
|
|
if first_packet {
|
|
|
|
for manager in self.connection_managers.iter_mut() {
|
|
|
|
if let Some(handler) =
|
|
|
|
manager.new_connection(&resolved_conn, manager.clone())?
|
|
|
|
{
|
|
|
|
let mut socket = tcp::Socket::new(
|
2023-04-04 10:17:13 +02:00
|
|
|
tcp::SocketBuffer::new(vec![0; 1024 * 128]),
|
|
|
|
tcp::SocketBuffer::new(vec![0; 1024 * 128]),
|
2023-03-26 15:21:56 +02:00
|
|
|
);
|
|
|
|
socket.set_ack_delay(None);
|
|
|
|
let dst = SocketAddr::try_from(dst)?;
|
|
|
|
socket.listen(dst)?;
|
|
|
|
let handle = self.sockets.add(socket);
|
|
|
|
|
|
|
|
let client = TcpStream::connect(server)?;
|
|
|
|
|
|
|
|
let token = Token(self.next_token);
|
|
|
|
self.next_token += 1;
|
|
|
|
|
|
|
|
let mut state = ConnectionState {
|
|
|
|
smoltcp_handle: handle,
|
|
|
|
mio_stream: client,
|
|
|
|
token,
|
|
|
|
handler,
|
2023-04-03 20:31:31 +02:00
|
|
|
close_state: 0,
|
2023-04-04 00:18:50 +02:00
|
|
|
wait_read: true,
|
|
|
|
wait_write: false,
|
2023-03-26 15:21:56 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
self.token_to_connection
|
|
|
|
.insert(token, resolved_conn.clone());
|
|
|
|
self.poll.registry().register(
|
|
|
|
&mut state.mio_stream,
|
|
|
|
token,
|
2023-04-04 00:18:50 +02:00
|
|
|
Interest::READABLE,
|
2023-03-26 15:21:56 +02:00
|
|
|
)?;
|
|
|
|
|
|
|
|
self.connections.insert(resolved_conn.clone(), state);
|
|
|
|
|
|
|
|
info!("CONNECT {}", resolved_conn,);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if !self.connections.contains_key(&resolved_conn) {
|
|
|
|
return Ok(());
|
|
|
|
}
|
2021-09-02 11:30:23 +02:00
|
|
|
|
2023-03-26 15:21:56 +02:00
|
|
|
// Inject the packet to advance the smoltcp socket state
|
|
|
|
self.device.inject_packet(frame);
|
2021-09-02 11:30:23 +02:00
|
|
|
|
2023-03-26 15:21:56 +02:00
|
|
|
// Having advanced the socket state, we expect the socket to ACK
|
|
|
|
// Exfiltrate the response packets generated by the socket and inject them
|
|
|
|
// into the tunnel interface.
|
|
|
|
self.expect_smoltcp_send()?;
|
2021-09-02 11:30:23 +02:00
|
|
|
|
2023-03-26 15:21:56 +02:00
|
|
|
// Read from the smoltcp socket and push the data to the connection handler.
|
|
|
|
self.tunsocket_read_and_forward(&resolved_conn)?;
|
|
|
|
|
|
|
|
// The connection handler builds up the connection or encapsulates the data.
|
|
|
|
// Therefore, we now expect it to write data to the server.
|
|
|
|
self.write_to_server(&resolved_conn)?;
|
|
|
|
} else if resolved_conn.proto == IpProtocol::Udp && resolved_conn.dst.port == 53 {
|
|
|
|
if let Some(virtual_dns) = &mut self.options.virtdns {
|
|
|
|
let payload = &frame[_payload_offset.._payload_offset + _payload_size];
|
|
|
|
if let Some(response) = virtual_dns.receive_query(payload) {
|
|
|
|
let rx_buffer = udp::PacketBuffer::new(
|
|
|
|
vec![udp::PacketMetadata::EMPTY],
|
|
|
|
vec![0; 4096],
|
|
|
|
);
|
|
|
|
let tx_buffer = udp::PacketBuffer::new(
|
|
|
|
vec![udp::PacketMetadata::EMPTY],
|
|
|
|
vec![0; 4096],
|
|
|
|
);
|
|
|
|
let mut socket = udp::Socket::new(rx_buffer, tx_buffer);
|
|
|
|
let dst = SocketAddr::try_from(dst)?;
|
|
|
|
socket.bind(dst)?;
|
|
|
|
socket
|
|
|
|
.send_slice(response.as_slice(), resolved_conn.src.into())
|
|
|
|
.expect("failed to send DNS response");
|
|
|
|
let handle = self.sockets.add(socket);
|
|
|
|
self.expect_smoltcp_send()?;
|
|
|
|
self.sockets.remove(handle);
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
}
|
2023-03-26 15:21:56 +02:00
|
|
|
// Otherwise, UDP is not yet supported.
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
2023-03-26 15:21:56 +02:00
|
|
|
Ok(())
|
|
|
|
})()
|
|
|
|
.or_else(|error| {
|
|
|
|
log::error! {"{error}"}
|
|
|
|
Ok::<(), Error>(())
|
|
|
|
})?;
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
2023-03-24 14:31:22 +08:00
|
|
|
Ok(())
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-03-26 15:21:56 +02:00
|
|
|
fn write_to_server(&mut self, connection: &Connection) -> Result<(), Error> {
|
2022-08-01 14:36:58 +00:00
|
|
|
if let Some(state) = self.connections.get_mut(connection) {
|
2021-09-02 22:36:47 +02:00
|
|
|
let event = state.handler.peek_data(OutgoingDirection::ToServer);
|
2023-04-04 00:18:50 +02:00
|
|
|
let buffer_size = event.buffer.len();
|
|
|
|
if buffer_size == 0 {
|
|
|
|
state.wait_write = false;
|
|
|
|
self.update_mio_socket_interest(connection)?;
|
2023-04-03 20:31:31 +02:00
|
|
|
self.check_change_close_state(connection)?;
|
2023-03-26 15:21:56 +02:00
|
|
|
return Ok(());
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
2021-09-02 22:36:47 +02:00
|
|
|
let result = state.mio_stream.write(event.buffer);
|
2021-09-02 11:30:23 +02:00
|
|
|
match result {
|
2023-04-04 00:18:50 +02:00
|
|
|
Ok(written) => {
|
2022-08-01 14:36:58 +00:00
|
|
|
state
|
|
|
|
.handler
|
2023-04-04 00:18:50 +02:00
|
|
|
.consume_data(OutgoingDirection::ToServer, written);
|
|
|
|
state.wait_write = written < buffer_size;
|
|
|
|
self.update_mio_socket_interest(connection)?;
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
2022-08-01 14:36:58 +00:00
|
|
|
Err(error) if error.kind() != std::io::ErrorKind::WouldBlock => {
|
2023-03-26 15:21:56 +02:00
|
|
|
return Err(error.into());
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
2023-04-04 00:18:50 +02:00
|
|
|
_ => {
|
|
|
|
// WOULDBLOCK case
|
|
|
|
state.wait_write = true;
|
|
|
|
self.update_mio_socket_interest(connection)?;
|
|
|
|
}
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
}
|
2023-04-04 00:18:50 +02:00
|
|
|
self.check_change_close_state(connection)?;
|
2023-03-26 15:21:56 +02:00
|
|
|
Ok(())
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-03-24 14:31:22 +08:00
|
|
|
fn write_to_client(&mut self, token: Token, connection: &Connection) -> Result<(), Error> {
|
2023-04-03 20:31:31 +02:00
|
|
|
while let Some(state) = self.connections.get_mut(connection) {
|
|
|
|
let socket_handle = state.smoltcp_handle;
|
|
|
|
let event = state.handler.peek_data(OutgoingDirection::ToClient);
|
|
|
|
let buflen = event.buffer.len();
|
|
|
|
let consumed;
|
|
|
|
{
|
|
|
|
let socket = self.sockets.get_mut::<tcp::Socket>(socket_handle);
|
|
|
|
if socket.may_send() {
|
|
|
|
if let Some(virtdns) = &mut self.options.virtdns {
|
|
|
|
// Unwrapping is fine because every smoltcp socket is bound to an.
|
|
|
|
virtdns.touch_ip(&IpAddr::from(socket.local_endpoint().unwrap().addr));
|
|
|
|
}
|
|
|
|
consumed = socket.send_slice(event.buffer)?;
|
|
|
|
state
|
|
|
|
.handler
|
|
|
|
.consume_data(OutgoingDirection::ToClient, consumed);
|
|
|
|
self.expect_smoltcp_send()?;
|
|
|
|
if consumed < buflen {
|
|
|
|
self.write_sockets.insert(token);
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
self.write_sockets.remove(&token);
|
|
|
|
if consumed == 0 {
|
2023-03-23 13:03:01 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-04-03 20:31:31 +02:00
|
|
|
} else {
|
2023-03-23 13:03:01 +01:00
|
|
|
break;
|
|
|
|
}
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
2023-04-03 20:31:31 +02:00
|
|
|
|
|
|
|
self.check_change_close_state(connection)?;
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
2023-03-24 14:31:22 +08:00
|
|
|
Ok(())
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-03-24 14:31:22 +08:00
|
|
|
fn tun_event(&mut self, event: &Event) -> Result<(), Error> {
|
2021-09-02 11:30:23 +02:00
|
|
|
if event.is_readable() {
|
2023-03-20 15:34:41 +01:00
|
|
|
while let Some((rx_token, _)) = self.tun.receive(Instant::now()) {
|
2023-03-24 14:31:22 +08:00
|
|
|
rx_token.consume(|frame| self.receive_tun(frame))?;
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
}
|
2023-03-24 14:31:22 +08:00
|
|
|
Ok(())
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2023-03-24 14:31:22 +08:00
|
|
|
fn send_to_smoltcp(&mut self) -> Result<(), Error> {
|
2023-03-23 13:03:01 +01:00
|
|
|
let cloned = self.write_sockets.clone();
|
|
|
|
for token in cloned.iter() {
|
|
|
|
if let Some(connection) = self.token_to_connection.get(token) {
|
2023-03-26 15:21:56 +02:00
|
|
|
let connection = connection.clone();
|
|
|
|
if let Err(error) = self.write_to_client(*token, &connection) {
|
|
|
|
self.remove_connection(&connection)?;
|
|
|
|
log::error!("Write to client: {}: ", error);
|
|
|
|
}
|
2023-03-23 13:03:01 +01:00
|
|
|
}
|
|
|
|
}
|
2023-03-24 14:31:22 +08:00
|
|
|
Ok(())
|
2023-03-23 13:03:01 +01:00
|
|
|
}
|
|
|
|
|
2023-03-24 14:31:22 +08:00
|
|
|
fn mio_socket_event(&mut self, event: &Event) -> Result<(), Error> {
|
|
|
|
let e = "connection not found";
|
|
|
|
let conn_ref = self.token_to_connection.get(&event.token());
|
2023-03-27 17:04:52 +02:00
|
|
|
// We may have closed the connection in an earlier iteration over the poll
|
|
|
|
// events, e.g. because an event through the tunnel interface indicated that the connection
|
|
|
|
// should be closed.
|
2023-03-27 12:14:43 +02:00
|
|
|
if conn_ref.is_none() {
|
2023-03-27 22:26:57 +08:00
|
|
|
log::trace!("{e}");
|
2023-03-27 12:14:43 +02:00
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
let connection = conn_ref.unwrap().clone();
|
2023-03-26 15:21:56 +02:00
|
|
|
|
|
|
|
(|| -> Result<(), Error> {
|
|
|
|
if event.is_readable() || event.is_read_closed() {
|
|
|
|
{
|
|
|
|
let state = self.connections.get_mut(&connection).ok_or(e)?;
|
|
|
|
|
|
|
|
// TODO: Move this reading process to its own function.
|
|
|
|
let mut vecbuf = Vec::<u8>::new();
|
|
|
|
let read_result = state.mio_stream.read_to_end(&mut vecbuf);
|
|
|
|
let read = match read_result {
|
|
|
|
Ok(read_result) => read_result,
|
|
|
|
Err(error) => {
|
|
|
|
if error.kind() != std::io::ErrorKind::WouldBlock {
|
|
|
|
error!("Read from proxy: {}", error);
|
|
|
|
}
|
|
|
|
vecbuf.len()
|
2022-12-10 21:29:57 +01:00
|
|
|
}
|
2023-03-26 15:21:56 +02:00
|
|
|
};
|
2021-09-02 21:02:17 +02:00
|
|
|
|
2023-03-26 15:21:56 +02:00
|
|
|
let data = vecbuf.as_slice();
|
|
|
|
let data_event = IncomingDataEvent {
|
|
|
|
direction: IncomingDirection::FromServer,
|
|
|
|
buffer: &data[0..read],
|
|
|
|
};
|
|
|
|
if let Err(error) = state.handler.push_data(data_event) {
|
|
|
|
state.mio_stream.shutdown(Both)?;
|
|
|
|
{
|
|
|
|
let socket = self.sockets.get_mut::<tcp::Socket>(
|
|
|
|
self.connections.get(&connection).ok_or(e)?.smoltcp_handle,
|
|
|
|
);
|
|
|
|
socket.close();
|
|
|
|
}
|
|
|
|
self.expect_smoltcp_send()?;
|
|
|
|
log::error! {"{error}"}
|
|
|
|
self.remove_connection(&connection.clone())?;
|
|
|
|
return Ok(());
|
|
|
|
}
|
2023-04-03 20:31:31 +02:00
|
|
|
|
|
|
|
if read == 0 || event.is_read_closed() {
|
2023-04-04 00:18:50 +02:00
|
|
|
state.wait_read = false;
|
2023-04-03 20:31:31 +02:00
|
|
|
state.close_state |= SERVER_WRITE_CLOSED;
|
2023-04-04 00:18:50 +02:00
|
|
|
self.update_mio_socket_interest(&connection)?;
|
2023-04-03 20:31:31 +02:00
|
|
|
self.check_change_close_state(&connection)?;
|
|
|
|
self.expect_smoltcp_send()?;
|
2023-03-24 14:31:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-26 15:21:56 +02:00
|
|
|
// We have read from the proxy server and pushed the data to the connection handler.
|
|
|
|
// Thus, expect data to be processed (e.g. decapsulated) and forwarded to the client.
|
|
|
|
self.write_to_client(event.token(), &connection)?;
|
2023-04-04 00:18:50 +02:00
|
|
|
|
|
|
|
// The connection handler could have produced data that is to be written to the
|
|
|
|
// server.
|
|
|
|
self.write_to_server(&connection)?;
|
2023-03-26 15:21:56 +02:00
|
|
|
}
|
2023-04-04 00:18:50 +02:00
|
|
|
|
2023-03-26 15:21:56 +02:00
|
|
|
if event.is_writable() {
|
|
|
|
self.write_to_server(&connection)?;
|
|
|
|
}
|
2023-04-04 00:18:50 +02:00
|
|
|
|
2023-03-26 15:21:56 +02:00
|
|
|
Ok(())
|
|
|
|
})()
|
|
|
|
.or_else(|error| {
|
|
|
|
log::error! {"{error}"}
|
2023-04-04 00:18:50 +02:00
|
|
|
self.remove_connection(&connection)?;
|
2023-03-26 15:21:56 +02:00
|
|
|
Ok(())
|
|
|
|
})
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
|
2022-08-01 14:36:58 +00:00
|
|
|
fn udp_event(&mut self, _event: &Event) {}
|
2021-09-02 11:30:23 +02:00
|
|
|
|
2023-03-23 16:31:33 +08:00
|
|
|
pub(crate) fn run(&mut self) -> Result<(), Error> {
|
2021-09-02 11:30:23 +02:00
|
|
|
let mut events = Events::with_capacity(1024);
|
|
|
|
loop {
|
2023-03-24 18:11:04 +01:00
|
|
|
match self.poll.poll(&mut events, None) {
|
|
|
|
Ok(()) => {
|
|
|
|
for event in events.iter() {
|
|
|
|
match event.token() {
|
2023-04-14 17:27:37 +08:00
|
|
|
EXIT_TOKEN => {
|
|
|
|
log::info!("exiting...");
|
|
|
|
return Ok(());
|
|
|
|
}
|
2023-03-24 18:11:04 +01:00
|
|
|
TCP_TOKEN => self.tun_event(event)?,
|
|
|
|
UDP_TOKEN => self.udp_event(event),
|
|
|
|
_ => self.mio_socket_event(event)?,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.send_to_smoltcp()?;
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
if e.kind() != std::io::ErrorKind::Interrupted {
|
2023-03-24 18:14:31 +01:00
|
|
|
return Err(e.into());
|
2023-04-04 00:18:50 +02:00
|
|
|
} else {
|
2023-04-14 17:27:37 +08:00
|
|
|
log::warn!("Poll interrupted: {e}")
|
2023-03-24 18:11:04 +01:00
|
|
|
}
|
2021-09-02 11:30:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-04-14 17:27:37 +08:00
|
|
|
|
|
|
|
pub(crate) fn shutdown() -> Result<(), Error> {
|
|
|
|
let addr: SocketAddr = EXIT_LISTENER.parse()?;
|
|
|
|
let _ = std::net::TcpStream::connect(addr)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
2022-08-01 14:36:58 +00:00
|
|
|
}
|