add no-proxy mode

This commit is contained in:
Remy D. Farley 2024-04-03 14:20:05 +00:00
parent 361cf95f4e
commit 5e99c9f874
3 changed files with 122 additions and 0 deletions

View file

@ -249,6 +249,14 @@ impl std::fmt::Display for ArgProxy {
impl ArgProxy { impl ArgProxy {
pub fn from_url(s: &str) -> Result<ArgProxy> { pub fn from_url(s: &str) -> Result<ArgProxy> {
if s == "none" {
return Ok(ArgProxy {
proxy_type: ProxyType::None,
addr: "0.0.0.0:0".parse().unwrap(),
credentials: None,
});
}
let e = format!("`{s}` is not a valid proxy URL"); let e = format!("`{s}` is not a valid proxy URL");
let url = url::Url::parse(s).map_err(|_| Error::from(&e))?; let url = url::Url::parse(s).map_err(|_| Error::from(&e))?;
let e = format!("`{s}` does not contain a host"); let e = format!("`{s}` does not contain a host");
@ -299,6 +307,7 @@ pub enum ProxyType {
Socks4, Socks4,
#[default] #[default]
Socks5, Socks5,
None,
} }
impl std::fmt::Display for ProxyType { impl std::fmt::Display for ProxyType {
@ -307,6 +316,7 @@ impl std::fmt::Display for ProxyType {
ProxyType::Socks4 => write!(f, "socks4"), ProxyType::Socks4 => write!(f, "socks4"),
ProxyType::Socks5 => write!(f, "socks5"), ProxyType::Socks5 => write!(f, "socks5"),
ProxyType::Http => write!(f, "http"), ProxyType::Http => write!(f, "http"),
ProxyType::None => write!(f, "none"),
} }
} }
} }

View file

@ -1,6 +1,7 @@
use crate::{ use crate::{
directions::{IncomingDataEvent, IncomingDirection, OutgoingDirection}, directions::{IncomingDataEvent, IncomingDirection, OutgoingDirection},
http::HttpManager, http::HttpManager,
no_proxy::NoProxyManager,
session_info::{IpProtocol, SessionInfo}, session_info::{IpProtocol, SessionInfo},
virtual_dns::VirtualDns, virtual_dns::VirtualDns,
}; };
@ -42,6 +43,7 @@ mod dump_logger;
mod error; mod error;
mod http; mod http;
mod mobile_api; mod mobile_api;
mod no_proxy;
mod proxy_handler; mod proxy_handler;
mod session_info; mod session_info;
mod socks; mod socks;
@ -81,6 +83,7 @@ where
ProxyType::Socks5 => Arc::new(SocksProxyManager::new(server_addr, V5, key)) as Arc<dyn ProxyHandlerManager>, ProxyType::Socks5 => Arc::new(SocksProxyManager::new(server_addr, V5, key)) as Arc<dyn ProxyHandlerManager>,
ProxyType::Socks4 => Arc::new(SocksProxyManager::new(server_addr, V4, key)) as Arc<dyn ProxyHandlerManager>, ProxyType::Socks4 => Arc::new(SocksProxyManager::new(server_addr, V4, key)) as Arc<dyn ProxyHandlerManager>,
ProxyType::Http => Arc::new(HttpManager::new(server_addr, key)) as Arc<dyn ProxyHandlerManager>, ProxyType::Http => Arc::new(HttpManager::new(server_addr, key)) as Arc<dyn ProxyHandlerManager>,
ProxyType::None => Arc::new(NoProxyManager::new(server_addr)) as Arc<dyn ProxyHandlerManager>,
}; };
let mut ipstack_config = ipstack::IpStackConfig::default(); let mut ipstack_config = ipstack::IpStackConfig::default();

109
src/no_proxy.rs Normal file
View file

@ -0,0 +1,109 @@
use crate::{
directions::{IncomingDataEvent, IncomingDirection, OutgoingDataEvent, OutgoingDirection},
proxy_handler::{ProxyHandler, ProxyHandlerManager},
session_info::SessionInfo,
};
use std::{collections::VecDeque, net::SocketAddr, sync::Arc};
use tokio::sync::Mutex;
struct NoProxyHandler {
info: SessionInfo,
domain_name: Option<String>,
client_outbuf: VecDeque<u8>,
server_outbuf: VecDeque<u8>,
udp_associate: bool,
}
#[async_trait::async_trait]
impl ProxyHandler for NoProxyHandler {
fn get_session_info(&self) -> SessionInfo {
self.info
}
fn get_domain_name(&self) -> Option<String> {
self.domain_name.clone()
}
async fn push_data(&mut self, event: IncomingDataEvent<'_>) -> std::io::Result<()> {
let IncomingDataEvent { direction, buffer } = event;
match direction {
IncomingDirection::FromServer => {
self.client_outbuf.extend(buffer.iter());
}
IncomingDirection::FromClient => {
self.server_outbuf.extend(buffer.iter());
}
}
Ok(())
}
fn consume_data(&mut self, dir: OutgoingDirection, size: usize) {
let buffer = match dir {
OutgoingDirection::ToServer => &mut self.server_outbuf,
OutgoingDirection::ToClient => &mut self.client_outbuf,
};
buffer.drain(0..size);
}
fn peek_data(&mut self, dir: OutgoingDirection) -> OutgoingDataEvent {
let buffer = match dir {
OutgoingDirection::ToServer => &mut self.server_outbuf,
OutgoingDirection::ToClient => &mut self.client_outbuf,
};
OutgoingDataEvent {
direction: dir,
buffer: buffer.make_contiguous(),
}
}
fn connection_established(&self) -> bool {
true
}
fn data_len(&self, dir: OutgoingDirection) -> usize {
match dir {
OutgoingDirection::ToServer => self.server_outbuf.len(),
OutgoingDirection::ToClient => self.client_outbuf.len(),
}
}
fn reset_connection(&self) -> bool {
false
}
fn get_udp_associate(&self) -> Option<SocketAddr> {
self.udp_associate.then_some(self.info.dst)
}
}
pub(crate) struct NoProxyManager {
server: SocketAddr,
}
#[async_trait::async_trait]
impl ProxyHandlerManager for NoProxyManager {
async fn new_proxy_handler(
&self,
info: SessionInfo,
domain_name: Option<String>,
udp_associate: bool,
) -> std::io::Result<Arc<Mutex<dyn ProxyHandler>>> {
Ok(Arc::new(Mutex::new(NoProxyHandler {
info,
domain_name,
client_outbuf: VecDeque::default(),
server_outbuf: VecDeque::default(),
udp_associate,
})))
}
fn get_server_addr(&self) -> SocketAddr {
self.server
}
}
impl NoProxyManager {
pub(crate) fn new(server: SocketAddr) -> Self {
Self { server }
}
}