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

View file

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

View file

@ -1,8 +1,8 @@
use crate::{
error::Error,
tun2proxy::{
ConnectionInfo, ConnectionManager, Direction, IncomingDataEvent, IncomingDirection,
OutgoingDataEvent, OutgoingDirection, TcpProxy,
ConnectionInfo, ConnectionManager, Direction, IncomingDataEvent, IncomingDirection, OutgoingDataEvent,
OutgoingDirection, TcpProxy,
},
};
use base64::Engine;
@ -89,11 +89,9 @@ impl HttpConnection {
fn send_tunnel_request(&mut self) -> Result<(), Error> {
self.server_outbuf.extend(b"CONNECT ");
self.server_outbuf
.extend(self.destination.to_string().as_bytes());
self.server_outbuf.extend(self.destination.to_string().as_bytes());
self.server_outbuf.extend(b" HTTP/1.1\r\nHost: ");
self.server_outbuf
.extend(self.destination.to_string().as_bytes());
self.server_outbuf.extend(self.destination.to_string().as_bytes());
self.server_outbuf.extend(b"\r\n");
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 response = state.as_mut().unwrap().respond(&context)?;
self.server_outbuf.extend(
format!(
"{}: {}\r\n",
PROXY_AUTHORIZATION,
response.to_header_string()
)
.as_bytes(),
);
self.server_outbuf
.extend(format!("{}: {}\r\n", PROXY_AUTHORIZATION, response.to_header_string()).as_bytes());
}
AuthenticationScheme::Basic => {
let cred = format!("{}:{}", credentials.username, credentials.password);
@ -198,8 +190,11 @@ impl HttpConnection {
}
if status_code != 407 {
let e =
format!("Expected success status code. Server replied with {status_code} [Reason: {}].", res.reason.unwrap());
let e = format!(
"Expected success status code. Server replied with {} [Reason: {}].",
status_code,
res.reason.unwrap()
);
return Err(e.into());
}
@ -371,9 +366,7 @@ impl TcpProxy for HttpConnection {
match dir {
Direction::Incoming(incoming) => match incoming {
IncomingDirection::FromServer => !self.server_inbuf.is_empty(),
IncomingDirection::FromClient => {
!self.client_inbuf.is_empty() || !self.data_buf.is_empty()
}
IncomingDirection::FromClient => !self.client_inbuf.is_empty() || !self.data_buf.is_empty(),
},
Direction::Outgoing(outgoing) => match outgoing {
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 credentials = proxy.credentials.clone();
let server = proxy.addr;
#[rustfmt::skip]
let mgr = match proxy.proxy_type {
ProxyType::Socks4 => Rc::new(SocksProxyManager::new(server, Version::V4, credentials))
as Rc<dyn ConnectionManager>,
ProxyType::Socks5 => Rc::new(SocksProxyManager::new(server, Version::V5, credentials))
as Rc<dyn ConnectionManager>,
ProxyType::Http => {
Rc::new(HttpManager::new(server, credentials)) as Rc<dyn ConnectionManager>
}
ProxyType::Socks4 => Rc::new(SocksProxyManager::new(server, Version::V4, credentials)) as Rc<dyn ConnectionManager>,
ProxyType::Socks5 => Rc::new(SocksProxyManager::new(server, Version::V5, credentials)) as Rc<dyn ConnectionManager>,
ProxyType::Http => Rc::new(HttpManager::new(server, credentials)) as Rc<dyn ConnectionManager>,
};
ttp.add_connection_manager(mgr);
Ok(ttp)
}
pub fn main_entry(
interface: &NetworkInterface,
proxy: &Proxy,
options: Options,
) -> Result<(), Error> {
pub fn main_entry(interface: &NetworkInterface, proxy: &Proxy, options: Options) -> Result<(), Error> {
let mut ttp = tun_to_proxy(interface, proxy, options)?;
ttp.run()?;
Ok(())

View file

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

View file

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

View file

@ -1,14 +1,12 @@
use crate::{
error::Error,
tun2proxy::{
ConnectionInfo, ConnectionManager, Direction, IncomingDataEvent, IncomingDirection,
OutgoingDataEvent, OutgoingDirection, TcpProxy,
ConnectionInfo, ConnectionManager, Direction, IncomingDataEvent, IncomingDirection, OutgoingDataEvent,
OutgoingDirection, TcpProxy,
},
};
use smoltcp::wire::IpProtocol;
use socks5_impl::protocol::{
self, handshake, password_method, Address, AuthMethod, StreamOperation, UserKey, Version,
};
use socks5_impl::protocol::{self, handshake, password_method, Address, AuthMethod, StreamOperation, UserKey, Version};
use std::{collections::VecDeque, net::SocketAddr};
#[derive(Eq, PartialEq, Debug)]
@ -36,11 +34,7 @@ struct SocksProxyImpl {
}
impl SocksProxyImpl {
pub fn new(
info: &ConnectionInfo,
credentials: Option<UserKey>,
version: Version,
) -> Result<Self, Error> {
fn new(info: &ConnectionInfo, credentials: Option<UserKey>, version: Version) -> Result<Self, Error> {
let mut result = Self {
info: info.clone(),
state: SocksState::ServerHello,
@ -60,8 +54,7 @@ impl SocksProxyImpl {
let credentials = &self.credentials;
self.server_outbuf
.extend(&[self.version as u8, protocol::Command::Connect.into()]);
self.server_outbuf
.extend(self.info.dst.port().to_be_bytes());
self.server_outbuf.extend(self.info.dst.port().to_be_bytes());
let mut ip_vec = Vec::<u8>::new();
let mut name_vec = Vec::<u8>::new();
match &self.info.dst {
@ -94,11 +87,7 @@ impl SocksProxyImpl {
let credentials = &self.credentials;
// Providing unassigned methods is supposed to bypass China's GFW.
// For details, refer to https://github.com/blechschmidt/tun2proxy/issues/35.
let mut methods = vec![
AuthMethod::NoAuth,
AuthMethod::from(4_u8),
AuthMethod::from(100_u8),
];
let mut methods = vec![AuthMethod::NoAuth, AuthMethod::from(4_u8), AuthMethod::from(100_u8)];
if credentials.is_some() {
methods.push(AuthMethod::UserPass);
}
@ -151,8 +140,7 @@ impl SocksProxyImpl {
let auth_method = respones.method;
if auth_method != AuthMethod::NoAuth && self.credentials.is_none()
|| (auth_method != AuthMethod::NoAuth && auth_method != AuthMethod::UserPass)
&& self.credentials.is_some()
|| (auth_method != AuthMethod::NoAuth && auth_method != AuthMethod::UserPass) && self.credentials.is_some()
{
return Err("SOCKS5 server requires an unsupported authentication method.".into());
}
@ -240,7 +228,7 @@ impl SocksProxyImpl {
Ok(())
}
pub fn state_change(&mut self) -> Result<(), Error> {
fn state_change(&mut self) -> Result<(), Error> {
match self.state {
SocksState::ServerHello => self.receive_server_hello(),
@ -308,9 +296,7 @@ impl TcpProxy for SocksProxyImpl {
match dir {
Direction::Incoming(incoming) => match incoming {
IncomingDirection::FromServer => !self.server_inbuf.is_empty(),
IncomingDirection::FromClient => {
!self.client_inbuf.is_empty() || !self.data_buf.is_empty()
}
IncomingDirection::FromClient => !self.client_inbuf.is_empty() || !self.data_buf.is_empty(),
},
Direction::Outgoing(outgoing) => match outgoing {
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> {
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))?
}
NetworkInterface::Fd(fd) => TunTapInterface::from_fd(*fd, Medium::Ip, options.mtu.unwrap_or(1500))?,
};
let poll = Poll::new()?;
poll.registry().register(
&mut SourceFd(&tun.as_raw_fd()),
TUN_TOKEN,
Interest::READABLE,
)?;
poll.registry()
.register(&mut SourceFd(&tun.as_raw_fd()), TUN_TOKEN, Interest::READABLE)?;
let (exit_sender, mut exit_receiver) = mio::unix::pipe::new()?;
poll.registry()
.register(&mut exit_receiver, EXIT_TOKEN, Interest::READABLE)?;
#[rustfmt::skip]
let config = match tun.capabilities().medium {
Medium::Ethernet => Config::new(
smoltcp::wire::EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into(),
),
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!(),
};
@ -285,8 +279,7 @@ impl<'a> TunToProxy<'a> {
}
fn expect_smoltcp_send(&mut self) -> Result<(), Error> {
self.iface
.poll(Instant::now(), &mut self.device, &mut self.sockets);
self.iface.poll(Instant::now(), &mut self.device, &mut self.sockets);
while let Some(vec) = self.device.exfiltrate_packet() {
let slice = vec.as_slice();
@ -314,7 +307,7 @@ impl<'a> TunToProxy<'a> {
let token = &conn.token;
self.token_to_info.remove(token);
_ = self.poll.registry().deregister(&mut conn.mio_stream);
log::info!("CLOSE {}", info);
log::info!("Close {}", info);
}
Ok(())
}
@ -429,8 +422,7 @@ impl<'a> TunToProxy<'a> {
interest = Interest::READABLE | Interest::WRITABLE;
}
poll.registry()
.register(&mut state.mio_stream, state.token, interest)?;
poll.registry().register(&mut state.mio_stream, state.token, interest)?;
Ok(())
}
@ -524,10 +516,8 @@ impl<'a> TunToProxy<'a> {
let payload = &frame[payload_offset..payload_offset + payload_size];
let 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 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);
socket.bind(dst)?;
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> {
if let Some(state) = self.connection_map.get_mut(info) {
let event = state
.tcp_proxy_handler
.peek_data(OutgoingDirection::ToServer);
let event = state.tcp_proxy_handler.peek_data(OutgoingDirection::ToServer);
let buffer_size = event.buffer.len();
if buffer_size == 0 {
state.wait_write = false;
@ -590,9 +578,7 @@ impl<'a> TunToProxy<'a> {
Some(handle) => handle,
None => break,
};
let event = state
.tcp_proxy_handler
.peek_data(OutgoingDirection::ToClient);
let event = state.tcp_proxy_handler.peek_data(OutgoingDirection::ToClient);
let buflen = event.buffer.len();
let consumed;
{
@ -662,10 +648,7 @@ impl<'a> TunToProxy<'a> {
}
};
let server = self
.get_connection_manager(&conn_info)
.ok_or(e)?
.get_server_addr();
let server = self.get_connection_manager(&conn_info).ok_or(e)?.get_server_addr();
let mut block = || -> Result<(), Error> {
if event.is_readable() || event.is_read_closed() {

View file

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

View file

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