re-formatting with max_width = 120

This commit is contained in:
ssrlive 2023-08-08 23:45:16 +08:00
parent 4d9b10fd1c
commit ff9c258fbd
11 changed files with 64 additions and 191 deletions

1
rustfmt.toml Normal file
View file

@ -0,0 +1 @@
max_width = 120

View file

@ -23,9 +23,7 @@ pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_run(
) -> jint { ) -> jint {
let log_level = if verbose != 0 { "trace" } else { "info" }; let log_level = if verbose != 0 { "trace" } else { "info" };
let filter_str = &format!("off,tun2proxy={log_level}"); let filter_str = &format!("off,tun2proxy={log_level}");
let filter = android_logger::FilterBuilder::new() let filter = android_logger::FilterBuilder::new().parse(filter_str).build();
.parse(filter_str)
.build();
android_logger::init_once( android_logger::init_once(
android_logger::Config::default() android_logger::Config::default()
.with_tag("tun2proxy") .with_tag("tun2proxy")
@ -61,10 +59,7 @@ pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_run(
/// ///
/// Shutdown tun2proxy /// Shutdown tun2proxy
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_stop( pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_stop(_env: JNIEnv, _: JClass) -> jint {
_env: JNIEnv,
_clazz: JClass,
) -> jint {
match &mut TUN_TO_PROXY { match &mut TUN_TO_PROXY {
None => { None => {
log::error!("tun2proxy not started"); log::error!("tun2proxy not started");

View file

@ -7,11 +7,7 @@ use trust_dns_proto::{
}; };
#[cfg(feature = "use-rand")] #[cfg(feature = "use-rand")]
pub fn build_dns_request( pub fn build_dns_request(domain: &str, query_type: RecordType, used_by_tcp: bool) -> Result<Vec<u8>, String> {
domain: &str,
query_type: RecordType,
used_by_tcp: bool,
) -> Result<Vec<u8>, String> {
// [dependencies] // [dependencies]
// rand = "0.8" // rand = "0.8"
use rand::{rngs::StdRng, Rng, SeedableRng}; use rand::{rngs::StdRng, Rng, SeedableRng};
@ -34,12 +30,7 @@ pub fn build_dns_request(
} }
} }
pub fn build_dns_response( pub fn build_dns_response(mut request: Message, domain: &str, ip: IpAddr, ttl: u32) -> Result<Message, String> {
mut request: Message,
domain: &str,
ip: IpAddr,
ttl: u32,
) -> Result<Message, String> {
let record = match ip { let record = match ip {
IpAddr::V4(ip) => { IpAddr::V4(ip) => {
let mut record = Record::with(Name::from_str(domain)?, RecordType::A, ttl); let mut record = Record::with(Name::from_str(domain)?, RecordType::A, ttl);
@ -62,10 +53,7 @@ pub fn extract_ipaddr_from_dns_message(message: &Message) -> Result<IpAddr, Stri
} }
let mut cname = None; let mut cname = None;
for answer in message.answers() { for answer in message.answers() {
match answer match answer.data().ok_or("DNS response not contains answer data")? {
.data()
.ok_or("DNS response not contains answer data")?
{
RData::A(addr) => { RData::A(addr) => {
return Ok(IpAddr::V4(*addr)); return Ok(IpAddr::V4(*addr));
} }

View file

@ -1,8 +1,8 @@
use crate::{ use crate::{
error::Error, error::Error,
tun2proxy::{ tun2proxy::{
ConnectionInfo, ConnectionManager, Direction, IncomingDataEvent, IncomingDirection, ConnectionInfo, ConnectionManager, Direction, IncomingDataEvent, IncomingDirection, OutgoingDataEvent,
OutgoingDataEvent, OutgoingDirection, TcpProxy, OutgoingDirection, TcpProxy,
}, },
}; };
use base64::Engine; use base64::Engine;
@ -89,11 +89,9 @@ impl HttpConnection {
fn send_tunnel_request(&mut self) -> Result<(), Error> { fn send_tunnel_request(&mut self) -> Result<(), Error> {
self.server_outbuf.extend(b"CONNECT "); self.server_outbuf.extend(b"CONNECT ");
self.server_outbuf self.server_outbuf.extend(self.destination.to_string().as_bytes());
.extend(self.destination.to_string().as_bytes());
self.server_outbuf.extend(b" HTTP/1.1\r\nHost: "); self.server_outbuf.extend(b" HTTP/1.1\r\nHost: ");
self.server_outbuf self.server_outbuf.extend(self.destination.to_string().as_bytes());
.extend(self.destination.to_string().as_bytes());
self.server_outbuf.extend(b"\r\n"); self.server_outbuf.extend(b"\r\n");
self.send_auth_data(if self.digest_state.borrow().is_none() { self.send_auth_data(if self.digest_state.borrow().is_none() {
@ -126,14 +124,8 @@ impl HttpConnection {
let mut state = self.digest_state.borrow_mut(); let mut state = self.digest_state.borrow_mut();
let response = state.as_mut().unwrap().respond(&context)?; let response = state.as_mut().unwrap().respond(&context)?;
self.server_outbuf.extend( self.server_outbuf
format!( .extend(format!("{}: {}\r\n", PROXY_AUTHORIZATION, response.to_header_string()).as_bytes());
"{}: {}\r\n",
PROXY_AUTHORIZATION,
response.to_header_string()
)
.as_bytes(),
);
} }
AuthenticationScheme::Basic => { AuthenticationScheme::Basic => {
let cred = format!("{}:{}", credentials.username, credentials.password); let cred = format!("{}:{}", credentials.username, credentials.password);
@ -198,8 +190,11 @@ impl HttpConnection {
} }
if status_code != 407 { if status_code != 407 {
let e = let e = format!(
format!("Expected success status code. Server replied with {status_code} [Reason: {}].", res.reason.unwrap()); "Expected success status code. Server replied with {} [Reason: {}].",
status_code,
res.reason.unwrap()
);
return Err(e.into()); return Err(e.into());
} }
@ -371,9 +366,7 @@ impl TcpProxy for HttpConnection {
match dir { match dir {
Direction::Incoming(incoming) => match incoming { Direction::Incoming(incoming) => match incoming {
IncomingDirection::FromServer => !self.server_inbuf.is_empty(), IncomingDirection::FromServer => !self.server_inbuf.is_empty(),
IncomingDirection::FromClient => { IncomingDirection::FromClient => !self.client_inbuf.is_empty() || !self.data_buf.is_empty(),
!self.client_inbuf.is_empty() || !self.data_buf.is_empty()
}
}, },
Direction::Outgoing(outgoing) => match outgoing { Direction::Outgoing(outgoing) => match outgoing {
OutgoingDirection::ToServer => !self.server_outbuf.is_empty(), OutgoingDirection::ToServer => !self.server_outbuf.is_empty(),

View file

@ -124,24 +124,17 @@ pub fn tun_to_proxy<'a>(
let mut ttp = TunToProxy::new(interface, options)?; let mut ttp = TunToProxy::new(interface, options)?;
let credentials = proxy.credentials.clone(); let credentials = proxy.credentials.clone();
let server = proxy.addr; let server = proxy.addr;
#[rustfmt::skip]
let mgr = match proxy.proxy_type { let mgr = match proxy.proxy_type {
ProxyType::Socks4 => Rc::new(SocksProxyManager::new(server, Version::V4, credentials)) ProxyType::Socks4 => Rc::new(SocksProxyManager::new(server, Version::V4, credentials)) as Rc<dyn ConnectionManager>,
as Rc<dyn ConnectionManager>, ProxyType::Socks5 => Rc::new(SocksProxyManager::new(server, Version::V5, credentials)) as Rc<dyn ConnectionManager>,
ProxyType::Socks5 => Rc::new(SocksProxyManager::new(server, Version::V5, credentials)) ProxyType::Http => Rc::new(HttpManager::new(server, credentials)) as Rc<dyn ConnectionManager>,
as Rc<dyn ConnectionManager>,
ProxyType::Http => {
Rc::new(HttpManager::new(server, credentials)) as Rc<dyn ConnectionManager>
}
}; };
ttp.add_connection_manager(mgr); ttp.add_connection_manager(mgr);
Ok(ttp) Ok(ttp)
} }
pub fn main_entry( pub fn main_entry(interface: &NetworkInterface, proxy: &Proxy, options: Options) -> Result<(), Error> {
interface: &NetworkInterface,
proxy: &Proxy,
options: Options,
) -> Result<(), Error> {
let mut ttp = tun_to_proxy(interface, proxy, options)?; let mut ttp = tun_to_proxy(interface, proxy, options)?;
ttp.run()?; ttp.run()?;
Ok(()) Ok(())

View file

@ -26,13 +26,7 @@ struct Args {
proxy: Proxy, proxy: Proxy,
/// DNS handling /// DNS handling
#[arg( #[arg(short, long, value_name = "method", value_enum, default_value = "virtual")]
short,
long,
value_name = "method",
value_enum,
default_value = "virtual"
)]
dns: ArgDns, dns: ArgDns,
/// Routing and system setup /// Routing and system setup
@ -102,12 +96,7 @@ fn main() -> ExitCode {
Some(addr) => addr, Some(addr) => addr,
None => args.proxy.addr.ip(), None => args.proxy.addr.ip(),
}; };
setup = Setup::new( setup = Setup::new(&args.tun, &bypass_tun_ip, get_default_cidrs(), args.bypass_ip.is_some());
&args.tun,
&bypass_tun_ip,
get_default_cidrs(),
args.bypass_ip.is_some(),
);
setup.configure()?; setup.configure()?;

View file

@ -59,13 +59,7 @@ where
cmdline.append(&mut args); cmdline.append(&mut args);
let command = cmdline.as_slice().join(" "); let command = cmdline.as_slice().join(" ");
match String::from_utf8(output.stderr.clone()) { match String::from_utf8(output.stderr.clone()) {
Ok(output) => Err(format!( Ok(output) => Err(format!("[{}] Command `{}` failed: {}", nix::unistd::getpid(), command, output).into()),
"[{}] Command `{}` failed: {}",
nix::unistd::getpid(),
command,
output
)
.into()),
Err(_) => Err(format!( Err(_) => Err(format!(
"Command `{:?}` failed with exit code {}", "Command `{:?}` failed with exit code {}",
command, command,
@ -126,14 +120,7 @@ impl Setup {
} }
let (addr_str, prefix_len_str) = match dst_str.split_once(['/']) { let (addr_str, prefix_len_str) = match dst_str.split_once(['/']) {
None => ( None => (dst_str, if self.tunnel_bypass_addr.is_ipv6() { "128" } else { "32" }),
dst_str,
if self.tunnel_bypass_addr.is_ipv6() {
"128"
} else {
"32"
},
),
Some((addr_str, prefix_len_str)) => (addr_str, prefix_len_str), Some((addr_str, prefix_len_str)) => (addr_str, prefix_len_str),
}; };
@ -215,13 +202,8 @@ impl Setup {
fn shutdown(&mut self) -> Result<(), Error> { fn shutdown(&mut self) -> Result<(), Error> {
self.set_up = false; self.set_up = false;
log::info!( log::info!("[{}] Restoring network configuration", nix::unistd::getpid());
"[{}] Restoring network configuration", let _ = Command::new("ip").args(["link", "del", self.tun.as_str()]).output();
nix::unistd::getpid()
);
let _ = Command::new("ip")
.args(["link", "del", self.tun.as_str()])
.output();
if self.delete_proxy_route { if self.delete_proxy_route {
let _ = Command::new("ip") let _ = Command::new("ip")
.args(["route", "del", self.tunnel_bypass_addr.to_string().as_str()]) .args(["route", "del", self.tunnel_bypass_addr.to_string().as_str()])
@ -235,15 +217,7 @@ impl Setup {
if let Err(e) = (|| -> Result<(), Error> { if let Err(e) = (|| -> Result<(), Error> {
nix::unistd::close(read_from_child)?; nix::unistd::close(read_from_child)?;
run_iproute( run_iproute(
[ ["ip", "tuntap", "add", "name", self.tun.as_str(), "mode", "tun"],
"ip",
"tuntap",
"add",
"name",
self.tun.as_str(),
"mode",
"tun",
],
"failed to create tunnel device", "failed to create tunnel device",
true, true,
)?; )?;
@ -306,10 +280,7 @@ impl Setup {
} }
pub fn configure(&mut self) -> Result<(), Error> { pub fn configure(&mut self) -> Result<(), Error> {
log::info!( log::info!("[{}] Setting up network configuration", nix::unistd::getpid());
"[{}] Setting up network configuration",
nix::unistd::getpid()
);
if nix::unistd::getuid() != 0.into() { if nix::unistd::getuid() != 0.into() {
return Err("Automatic setup requires root privileges".into()); return Err("Automatic setup requires root privileges".into());
} }
@ -345,10 +316,7 @@ impl Setup {
} }
pub fn restore(&mut self) -> Result<(), Error> { pub fn restore(&mut self) -> Result<(), Error> {
nix::sys::signal::kill( nix::sys::signal::kill(nix::unistd::Pid::from_raw(self.child), nix::sys::signal::SIGINT)?;
nix::unistd::Pid::from_raw(self.child),
nix::sys::signal::SIGINT,
)?;
nix::sys::wait::waitpid(nix::unistd::Pid::from_raw(self.child), None)?; nix::sys::wait::waitpid(nix::unistd::Pid::from_raw(self.child), None)?;
Ok(()) Ok(())
} }

View file

@ -1,14 +1,12 @@
use crate::{ use crate::{
error::Error, error::Error,
tun2proxy::{ tun2proxy::{
ConnectionInfo, ConnectionManager, Direction, IncomingDataEvent, IncomingDirection, ConnectionInfo, ConnectionManager, Direction, IncomingDataEvent, IncomingDirection, OutgoingDataEvent,
OutgoingDataEvent, OutgoingDirection, TcpProxy, OutgoingDirection, TcpProxy,
}, },
}; };
use smoltcp::wire::IpProtocol; use smoltcp::wire::IpProtocol;
use socks5_impl::protocol::{ use socks5_impl::protocol::{self, handshake, password_method, Address, AuthMethod, StreamOperation, UserKey, Version};
self, handshake, password_method, Address, AuthMethod, StreamOperation, UserKey, Version,
};
use std::{collections::VecDeque, net::SocketAddr}; use std::{collections::VecDeque, net::SocketAddr};
#[derive(Eq, PartialEq, Debug)] #[derive(Eq, PartialEq, Debug)]
@ -36,11 +34,7 @@ struct SocksProxyImpl {
} }
impl SocksProxyImpl { impl SocksProxyImpl {
pub fn new( fn new(info: &ConnectionInfo, credentials: Option<UserKey>, version: Version) -> Result<Self, Error> {
info: &ConnectionInfo,
credentials: Option<UserKey>,
version: Version,
) -> Result<Self, Error> {
let mut result = Self { let mut result = Self {
info: info.clone(), info: info.clone(),
state: SocksState::ServerHello, state: SocksState::ServerHello,
@ -60,8 +54,7 @@ impl SocksProxyImpl {
let credentials = &self.credentials; let credentials = &self.credentials;
self.server_outbuf self.server_outbuf
.extend(&[self.version as u8, protocol::Command::Connect.into()]); .extend(&[self.version as u8, protocol::Command::Connect.into()]);
self.server_outbuf self.server_outbuf.extend(self.info.dst.port().to_be_bytes());
.extend(self.info.dst.port().to_be_bytes());
let mut ip_vec = Vec::<u8>::new(); let mut ip_vec = Vec::<u8>::new();
let mut name_vec = Vec::<u8>::new(); let mut name_vec = Vec::<u8>::new();
match &self.info.dst { match &self.info.dst {
@ -94,11 +87,7 @@ impl SocksProxyImpl {
let credentials = &self.credentials; let credentials = &self.credentials;
// Providing unassigned methods is supposed to bypass China's GFW. // Providing unassigned methods is supposed to bypass China's GFW.
// For details, refer to https://github.com/blechschmidt/tun2proxy/issues/35. // For details, refer to https://github.com/blechschmidt/tun2proxy/issues/35.
let mut methods = vec![ let mut methods = vec![AuthMethod::NoAuth, AuthMethod::from(4_u8), AuthMethod::from(100_u8)];
AuthMethod::NoAuth,
AuthMethod::from(4_u8),
AuthMethod::from(100_u8),
];
if credentials.is_some() { if credentials.is_some() {
methods.push(AuthMethod::UserPass); methods.push(AuthMethod::UserPass);
} }
@ -151,8 +140,7 @@ impl SocksProxyImpl {
let auth_method = respones.method; let auth_method = respones.method;
if auth_method != AuthMethod::NoAuth && self.credentials.is_none() if auth_method != AuthMethod::NoAuth && self.credentials.is_none()
|| (auth_method != AuthMethod::NoAuth && auth_method != AuthMethod::UserPass) || (auth_method != AuthMethod::NoAuth && auth_method != AuthMethod::UserPass) && self.credentials.is_some()
&& self.credentials.is_some()
{ {
return Err("SOCKS5 server requires an unsupported authentication method.".into()); return Err("SOCKS5 server requires an unsupported authentication method.".into());
} }
@ -240,7 +228,7 @@ impl SocksProxyImpl {
Ok(()) Ok(())
} }
pub fn state_change(&mut self) -> Result<(), Error> { fn state_change(&mut self) -> Result<(), Error> {
match self.state { match self.state {
SocksState::ServerHello => self.receive_server_hello(), SocksState::ServerHello => self.receive_server_hello(),
@ -308,9 +296,7 @@ impl TcpProxy for SocksProxyImpl {
match dir { match dir {
Direction::Incoming(incoming) => match incoming { Direction::Incoming(incoming) => match incoming {
IncomingDirection::FromServer => !self.server_inbuf.is_empty(), IncomingDirection::FromServer => !self.server_inbuf.is_empty(),
IncomingDirection::FromClient => { IncomingDirection::FromClient => !self.client_inbuf.is_empty() || !self.data_buf.is_empty(),
!self.client_inbuf.is_empty() || !self.data_buf.is_empty()
}
}, },
Direction::Outgoing(outgoing) => match outgoing { Direction::Outgoing(outgoing) => match outgoing {
OutgoingDirection::ToServer => !self.server_outbuf.is_empty(), OutgoingDirection::ToServer => !self.server_outbuf.is_empty(),

View file

@ -222,25 +222,19 @@ impl<'a> TunToProxy<'a> {
pub fn new(interface: &NetworkInterface, options: Options) -> Result<Self, Error> { pub fn new(interface: &NetworkInterface, options: Options) -> Result<Self, Error> {
let tun = match interface { let tun = match interface {
NetworkInterface::Named(name) => TunTapInterface::new(name.as_str(), Medium::Ip)?, NetworkInterface::Named(name) => TunTapInterface::new(name.as_str(), Medium::Ip)?,
NetworkInterface::Fd(fd) => { NetworkInterface::Fd(fd) => TunTapInterface::from_fd(*fd, Medium::Ip, options.mtu.unwrap_or(1500))?,
TunTapInterface::from_fd(*fd, Medium::Ip, options.mtu.unwrap_or(1500))?
}
}; };
let poll = Poll::new()?; let poll = Poll::new()?;
poll.registry().register( poll.registry()
&mut SourceFd(&tun.as_raw_fd()), .register(&mut SourceFd(&tun.as_raw_fd()), TUN_TOKEN, Interest::READABLE)?;
TUN_TOKEN,
Interest::READABLE,
)?;
let (exit_sender, mut exit_receiver) = mio::unix::pipe::new()?; let (exit_sender, mut exit_receiver) = mio::unix::pipe::new()?;
poll.registry() poll.registry()
.register(&mut exit_receiver, EXIT_TOKEN, Interest::READABLE)?; .register(&mut exit_receiver, EXIT_TOKEN, Interest::READABLE)?;
#[rustfmt::skip]
let config = match tun.capabilities().medium { let config = match tun.capabilities().medium {
Medium::Ethernet => Config::new( Medium::Ethernet => Config::new(smoltcp::wire::EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into()),
smoltcp::wire::EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into(),
),
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip), Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => todo!(), Medium::Ieee802154 => todo!(),
}; };
@ -285,8 +279,7 @@ impl<'a> TunToProxy<'a> {
} }
fn expect_smoltcp_send(&mut self) -> Result<(), Error> { fn expect_smoltcp_send(&mut self) -> Result<(), Error> {
self.iface self.iface.poll(Instant::now(), &mut self.device, &mut self.sockets);
.poll(Instant::now(), &mut self.device, &mut self.sockets);
while let Some(vec) = self.device.exfiltrate_packet() { while let Some(vec) = self.device.exfiltrate_packet() {
let slice = vec.as_slice(); let slice = vec.as_slice();
@ -314,7 +307,7 @@ impl<'a> TunToProxy<'a> {
let token = &conn.token; let token = &conn.token;
self.token_to_info.remove(token); self.token_to_info.remove(token);
_ = self.poll.registry().deregister(&mut conn.mio_stream); _ = self.poll.registry().deregister(&mut conn.mio_stream);
log::info!("CLOSE {}", info); log::info!("Close {}", info);
} }
Ok(()) Ok(())
} }
@ -429,8 +422,7 @@ impl<'a> TunToProxy<'a> {
interest = Interest::READABLE | Interest::WRITABLE; interest = Interest::READABLE | Interest::WRITABLE;
} }
poll.registry() poll.registry().register(&mut state.mio_stream, state.token, interest)?;
.register(&mut state.mio_stream, state.token, interest)?;
Ok(()) Ok(())
} }
@ -524,10 +516,8 @@ impl<'a> TunToProxy<'a> {
let payload = &frame[payload_offset..payload_offset + payload_size]; let payload = &frame[payload_offset..payload_offset + payload_size];
let response = virtual_dns.receive_query(payload)?; let response = virtual_dns.receive_query(payload)?;
{ {
let rx_buffer = let rx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 4096]);
udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 4096]); let tx_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 mut socket = udp::Socket::new(rx_buffer, tx_buffer);
socket.bind(dst)?; socket.bind(dst)?;
let meta = UdpMetadata::from(connection_info.src); let meta = UdpMetadata::from(connection_info.src);
@ -551,9 +541,7 @@ impl<'a> TunToProxy<'a> {
fn write_to_server(&mut self, info: &ConnectionInfo) -> Result<(), Error> { fn write_to_server(&mut self, info: &ConnectionInfo) -> Result<(), Error> {
if let Some(state) = self.connection_map.get_mut(info) { if let Some(state) = self.connection_map.get_mut(info) {
let event = state let event = state.tcp_proxy_handler.peek_data(OutgoingDirection::ToServer);
.tcp_proxy_handler
.peek_data(OutgoingDirection::ToServer);
let buffer_size = event.buffer.len(); let buffer_size = event.buffer.len();
if buffer_size == 0 { if buffer_size == 0 {
state.wait_write = false; state.wait_write = false;
@ -590,9 +578,7 @@ impl<'a> TunToProxy<'a> {
Some(handle) => handle, Some(handle) => handle,
None => break, None => break,
}; };
let event = state let event = state.tcp_proxy_handler.peek_data(OutgoingDirection::ToClient);
.tcp_proxy_handler
.peek_data(OutgoingDirection::ToClient);
let buflen = event.buffer.len(); let buflen = event.buffer.len();
let consumed; let consumed;
{ {
@ -662,10 +648,7 @@ impl<'a> TunToProxy<'a> {
} }
}; };
let server = self let server = self.get_connection_manager(&conn_info).ok_or(e)?.get_server_addr();
.get_connection_manager(&conn_info)
.ok_or(e)?
.get_server_addr();
let mut block = || -> Result<(), Error> { let mut block = || -> Result<(), Error> {
if event.is_readable() || event.is_read_closed() { if event.is_readable() || event.is_read_closed() {

View file

@ -120,9 +120,7 @@ impl VirtualDns {
let started_at = self.next_addr; let started_at = self.next_addr;
loop { loop {
if let RawEntryMut::Vacant(vacant) = if let RawEntryMut::Vacant(vacant) = self.lru_cache.raw_entry_mut().from_key(&self.next_addr) {
self.lru_cache.raw_entry_mut().from_key(&self.next_addr)
{
let expiry = Instant::now() + Duration::from_secs(MAPPING_TIMEOUT); let expiry = Instant::now() + Duration::from_secs(MAPPING_TIMEOUT);
let name0 = name.clone(); let name0 = name.clone();
vacant.insert(self.next_addr, NameCacheEntry { name, expiry }); vacant.insert(self.next_addr, NameCacheEntry { name, expiry });

View file

@ -22,8 +22,7 @@ mod tests {
static TUN_TEST_DEVICE: &str = "tun0"; static TUN_TEST_DEVICE: &str = "tun0";
fn proxy_from_env(env_var: &str) -> Result<Proxy, String> { fn proxy_from_env(env_var: &str) -> Result<Proxy, String> {
let url = let url = env::var(env_var).map_err(|_| format!("{env_var} environment variable not found"))?;
env::var(env_var).map_err(|_| format!("{env_var} environment variable not found"))?;
Proxy::from_url(url.as_str()).map_err(|_| format!("{env_var} URL cannot be parsed")) Proxy::from_url(url.as_str()).map_err(|_| format!("{env_var} URL cannot be parsed"))
} }
@ -71,15 +70,13 @@ mod tests {
Ok(ip_str) => IpAddr::from_str(ip_str.as_str()).unwrap(), Ok(ip_str) => IpAddr::from_str(ip_str.as_str()).unwrap(),
}; };
let mut setup = let mut setup = Setup::new(TUN_TEST_DEVICE, &bypass_ip, get_default_cidrs(), false);
Setup::new(TUN_TEST_DEVICE, &bypass_ip, get_default_cidrs(), false);
setup.configure().unwrap(); setup.configure().unwrap();
match fork::fork() { match fork::fork() {
Ok(Fork::Parent(child)) => { Ok(Fork::Parent(child)) => {
test_function(); test_function();
signal::kill(Pid::from_raw(child), signal::SIGINT) signal::kill(Pid::from_raw(child), signal::SIGINT).expect("failed to kill child");
.expect("failed to kill child");
setup.restore().unwrap(); setup.restore().unwrap();
} }
Ok(Fork::Child) => { Ok(Fork::Child) => {
@ -109,59 +106,41 @@ mod tests {
#[test_log::test] #[test_log::test]
fn test_socks4() { fn test_socks4() {
require_var("SOCKS4_SERVER"); require_var("SOCKS4_SERVER");
run_test( run_test(|test| test.proxy.proxy_type == ProxyType::Socks4, request_ip_host_http)
|test| test.proxy.proxy_type == ProxyType::Socks4,
request_ip_host_http,
)
} }
#[serial] #[serial]
#[test_log::test] #[test_log::test]
fn test_socks5() { fn test_socks5() {
require_var("SOCKS5_SERVER"); require_var("SOCKS5_SERVER");
run_test( run_test(|test| test.proxy.proxy_type == ProxyType::Socks5, request_ip_host_http)
|test| test.proxy.proxy_type == ProxyType::Socks5,
request_ip_host_http,
)
} }
#[serial] #[serial]
#[test_log::test] #[test_log::test]
fn test_http() { fn test_http() {
require_var("HTTP_SERVER"); require_var("HTTP_SERVER");
run_test( run_test(|test| test.proxy.proxy_type == ProxyType::Http, request_ip_host_http)
|test| test.proxy.proxy_type == ProxyType::Http,
request_ip_host_http,
)
} }
#[serial] #[serial]
#[test_log::test] #[test_log::test]
fn test_socks4_dns() { fn test_socks4_dns() {
require_var("SOCKS4_SERVER"); require_var("SOCKS4_SERVER");
run_test( run_test(|test| test.proxy.proxy_type == ProxyType::Socks4, request_example_https)
|test| test.proxy.proxy_type == ProxyType::Socks4,
request_example_https,
)
} }
#[serial] #[serial]
#[test_log::test] #[test_log::test]
fn test_socks5_dns() { fn test_socks5_dns() {
require_var("SOCKS5_SERVER"); require_var("SOCKS5_SERVER");
run_test( run_test(|test| test.proxy.proxy_type == ProxyType::Socks5, request_example_https)
|test| test.proxy.proxy_type == ProxyType::Socks5,
request_example_https,
)
} }
#[serial] #[serial]
#[test_log::test] #[test_log::test]
fn test_http_dns() { fn test_http_dns() {
require_var("HTTP_SERVER"); require_var("HTTP_SERVER");
run_test( run_test(|test| test.proxy.proxy_type == ProxyType::Http, request_example_https)
|test| test.proxy.proxy_type == ProxyType::Http,
request_example_https,
)
} }
} }