From a55436d7631dad618ab2c89e46eea3b81288608e Mon Sep 17 00:00:00 2001 From: iHsin Date: Tue, 9 Apr 2024 20:11:34 +0800 Subject: [PATCH] refactor: respect proxy node specific iface & mark --- clash_lib/src/proxy/converters/shadowsocks.rs | 2 +- clash_lib/src/proxy/direct/mod.rs | 14 +++------- clash_lib/src/proxy/mod.rs | 26 ++----------------- clash_lib/src/proxy/shadowsocks/mod.rs | 12 +++------ clash_lib/src/proxy/socks/inbound/stream.rs | 2 -- clash_lib/src/proxy/trojan/mod.rs | 13 +++------- clash_lib/src/proxy/utils/socket_helpers.rs | 26 ++++++++++--------- clash_lib/src/proxy/vmess/mod.rs | 13 +++------- 8 files changed, 33 insertions(+), 75 deletions(-) diff --git a/clash_lib/src/proxy/converters/shadowsocks.rs b/clash_lib/src/proxy/converters/shadowsocks.rs index b99573417..1e0afe6c7 100644 --- a/clash_lib/src/proxy/converters/shadowsocks.rs +++ b/clash_lib/src/proxy/converters/shadowsocks.rs @@ -2,7 +2,7 @@ use crate::{ config::internal::proxy::OutboundShadowsocks, proxy::{ shadowsocks::{Handler, HandlerOptions, OBFSOption}, - AnyOutboundHandler + AnyOutboundHandler, }, Error, }; diff --git a/clash_lib/src/proxy/direct/mod.rs b/clash_lib/src/proxy/direct/mod.rs index 8abf99ff1..34e339f1e 100644 --- a/clash_lib/src/proxy/direct/mod.rs +++ b/clash_lib/src/proxy/direct/mod.rs @@ -53,7 +53,6 @@ impl OutboundHandler for Handler { sess.destination.host().as_str(), sess.destination.port(), None, - #[cfg(any(target_os = "linux", target_os = "android"))] None, ) .await?; @@ -74,17 +73,12 @@ impl OutboundHandler for Handler { async fn connect_datagram( &self, - sess: &Session, + _sess: &Session, resolver: ThreadSafeDNSResolver, ) -> std::io::Result { - let d = new_udp_socket( - None, - sess.iface.as_ref(), - #[cfg(any(target_os = "linux", target_os = "android"))] - None, - ) - .await - .map(|x| OutboundDatagramImpl::new(x, resolver))?; + let d = new_udp_socket(None, None, None) + .await + .map(|x| OutboundDatagramImpl::new(x, resolver))?; let d = ChainedDatagramWrapper::new(d); d.append_to_chain(self.name()).await; diff --git a/clash_lib/src/proxy/mod.rs b/clash_lib/src/proxy/mod.rs index f143ac62b..7508c7cfd 100644 --- a/clash_lib/src/proxy/mod.rs +++ b/clash_lib/src/proxy/mod.rs @@ -88,34 +88,12 @@ pub type AnyOutboundDatagram = #[allow(dead_code)] #[derive(Default, Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct CommonOption { - #[serde(rename = "interface-name")] - so_mark: Option, #[serde(rename = "routing-mark")] + so_mark: Option, + #[serde(rename = "interface-name")] iface: Option, } -impl CommonOption { - pub fn merge<'a>(&'a self, sess: &'a Session) -> (Option, Option<&'a Interface>) { - let so_mark = if let Some(so_mark) = self.so_mark { - Some(so_mark) - } else if let Some(so_mark) = sess.packet_mark { - Some(so_mark) - } else { - None - }; - - let iface = if let Some(iface) = self.iface.as_ref() { - Some(iface) - } else if let Some(iface) = sess.iface.as_ref() { - Some(iface) - } else { - None - }; - - (so_mark, iface) - } -} - #[async_trait] pub trait InboundListener: Send + Sync + Unpin { /// support tcp or not diff --git a/clash_lib/src/proxy/shadowsocks/mod.rs b/clash_lib/src/proxy/shadowsocks/mod.rs index f0fecc960..6fa10c951 100644 --- a/clash_lib/src/proxy/shadowsocks/mod.rs +++ b/clash_lib/src/proxy/shadowsocks/mod.rs @@ -213,14 +213,12 @@ impl OutboundHandler for Handler { sess: &Session, resolver: ThreadSafeDNSResolver, ) -> io::Result { - let (packet_mark, iface) = self.opts.common_opts.merge(sess); let stream = new_tcp_stream( resolver.clone(), self.opts.server.as_str(), self.opts.port, - iface, - #[cfg(any(target_os = "linux", target_os = "android"))] - packet_mark, + self.opts.common_opts.iface.as_ref(), + self.opts.common_opts.so_mark, ) .map_err(|x| { io::Error::new( @@ -309,12 +307,10 @@ impl OutboundHandler for Handler { _ => return Err(io::Error::new(io::ErrorKind::Other, "unsupported cipher")), }, ); - let (packet_mark, iface) = self.opts.common_opts.merge(sess); let socket = new_udp_socket( None, - iface, - #[cfg(any(target_os = "linux", target_os = "android"))] - packet_mark, + self.opts.common_opts.iface.as_ref(), + self.opts.common_opts.so_mark, ) .await?; let socket = ProxySocket::from_socket(UdpSocketType::Client, ctx, &cfg, socket); diff --git a/clash_lib/src/proxy/socks/inbound/stream.rs b/clash_lib/src/proxy/socks/inbound/stream.rs index d518c8ca9..53243a713 100644 --- a/clash_lib/src/proxy/socks/inbound/stream.rs +++ b/clash_lib/src/proxy/socks/inbound/stream.rs @@ -166,8 +166,6 @@ pub async fn handle_tcp<'a>( let sess = Session { network: Network::Udp, typ: Type::Socks5, - packet_mark: None, - iface: None, ..Default::default() }; diff --git a/clash_lib/src/proxy/trojan/mod.rs b/clash_lib/src/proxy/trojan/mod.rs index f6fa9cae5..96cc0c57d 100644 --- a/clash_lib/src/proxy/trojan/mod.rs +++ b/clash_lib/src/proxy/trojan/mod.rs @@ -151,15 +151,12 @@ impl OutboundHandler for Handler { sess: &Session, resolver: ThreadSafeDNSResolver, ) -> io::Result { - let (packet_mark, iface) = self.opts.common_opts.merge(sess); - let stream = new_tcp_stream( resolver.clone(), self.opts.server.as_str(), self.opts.port, - iface, - #[cfg(any(target_os = "linux", target_os = "android"))] - packet_mark, + self.opts.common_opts.iface.as_ref(), + self.opts.common_opts.so_mark, ) .map_err(|x| { io::Error::new( @@ -193,14 +190,12 @@ impl OutboundHandler for Handler { sess: &Session, resolver: ThreadSafeDNSResolver, ) -> io::Result { - let (packet_mark, iface) = self.opts.common_opts.merge(sess); let stream = new_tcp_stream( resolver.clone(), self.opts.server.as_str(), self.opts.port, - iface, - #[cfg(any(target_os = "linux", target_os = "android"))] - packet_mark, + self.opts.common_opts.iface.as_ref(), + self.opts.common_opts.so_mark, ) .map_err(|x| { io::Error::new( diff --git a/clash_lib/src/proxy/utils/socket_helpers.rs b/clash_lib/src/proxy/utils/socket_helpers.rs index 1f163db5c..700e049ad 100644 --- a/clash_lib/src/proxy/utils/socket_helpers.rs +++ b/clash_lib/src/proxy/utils/socket_helpers.rs @@ -14,7 +14,7 @@ use tokio::{ use tracing::warn; use super::Interface; -use crate::{app::dns::ThreadSafeDNSResolver, proxy::AnyStream}; +use crate::{app::dns::ThreadSafeDNSResolver, get_iface, proxy::AnyStream, session::get_somark}; pub fn apply_tcp_options(s: TcpStream) -> std::io::Result { #[cfg(not(target_os = "windows"))] @@ -71,8 +71,8 @@ pub async fn new_tcp_stream<'a>( resolver: ThreadSafeDNSResolver, address: &'a str, port: u16, - iface: Option<&'a Interface>, - #[cfg(any(target_os = "linux", target_os = "android"))] packet_mark: Option, + iface: Option<&Interface>, + packet_mark: Option, ) -> io::Result { let dial_addr = resolver .resolve(address, false) @@ -99,12 +99,13 @@ pub async fn new_tcp_stream<'a>( } }; - if let Some(iface) = iface { - must_bind_socket_on_interface(&socket, iface)?; + let global_iface = get_iface(); + if let Some(iface) = iface.or_else(|| global_iface.as_ref()) { + must_bind_socket_on_interface(&socket, &iface)?; } - #[cfg(any(target_os = "linux", target_os = "android"))] - if let Some(packet_mark) = packet_mark { + #[cfg(target_os = "linux")] + if let Some(packet_mark) = packet_mark.or_else(|| get_somark()) { socket.set_mark(packet_mark)?; } @@ -124,7 +125,7 @@ pub async fn new_tcp_stream<'a>( pub async fn new_udp_socket( src: Option<&SocketAddr>, iface: Option<&Interface>, - #[cfg(any(target_os = "linux", target_os = "android"))] packet_mark: Option, + packet_mark: Option, ) -> io::Result { let socket = match src { Some(src) => { @@ -141,12 +142,13 @@ pub async fn new_udp_socket( socket.bind(&(*src).into())?; } - if let Some(iface) = iface { - must_bind_socket_on_interface(&socket, iface)?; + let global_iface = get_iface(); + if let Some(iface) = iface.or_else(|| global_iface.as_ref()) { + must_bind_socket_on_interface(&socket, &iface)?; } - #[cfg(any(target_os = "linux", target_os = "android"))] - if let Some(packet_mark) = packet_mark { + #[cfg(target_os = "linux")] + if let Some(packet_mark) = packet_mark.or_else(|| get_somark()) { socket.set_mark(packet_mark)?; } diff --git a/clash_lib/src/proxy/vmess/mod.rs b/clash_lib/src/proxy/vmess/mod.rs index 1c70f9dab..e85b3672f 100644 --- a/clash_lib/src/proxy/vmess/mod.rs +++ b/clash_lib/src/proxy/vmess/mod.rs @@ -2,7 +2,6 @@ use std::{collections::HashMap, io, net::IpAddr, sync::Arc}; use async_trait::async_trait; use futures::TryFutureExt; -use tracing::debug; mod vmess_impl; @@ -169,14 +168,12 @@ impl OutboundHandler for Handler { sess: &Session, resolver: ThreadSafeDNSResolver, ) -> io::Result { - let (packet_mark, iface) = self.opts.common_opts.merge(sess); let stream = new_tcp_stream( resolver, self.opts.server.as_str(), self.opts.port, - iface, - #[cfg(any(target_os = "linux", target_os = "android"))] - packet_mark, + self.opts.common_opts.iface.as_ref(), + self.opts.common_opts.so_mark, ) .map_err(|x| { io::Error::new( @@ -210,14 +207,12 @@ impl OutboundHandler for Handler { sess: &Session, resolver: ThreadSafeDNSResolver, ) -> io::Result { - let (packet_mark, iface) = self.opts.common_opts.merge(sess); let stream = new_tcp_stream( resolver.clone(), self.opts.server.as_str(), self.opts.port, - iface, - #[cfg(any(target_os = "linux", target_os = "android"))] - packet_mark, + self.opts.common_opts.iface.as_ref(), + self.opts.common_opts.so_mark, ) .map_err(|x| { io::Error::new(