Skip to content

Commit

Permalink
refactor: respect proxy node specific iface & mark
Browse files Browse the repository at this point in the history
  • Loading branch information
iHsin committed Apr 9, 2024
1 parent 0541a40 commit a55436d
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 75 deletions.
2 changes: 1 addition & 1 deletion clash_lib/src/proxy/converters/shadowsocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
config::internal::proxy::OutboundShadowsocks,
proxy::{
shadowsocks::{Handler, HandlerOptions, OBFSOption},
AnyOutboundHandler
AnyOutboundHandler,
},
Error,
};
Expand Down
14 changes: 4 additions & 10 deletions clash_lib/src/proxy/direct/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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?;
Expand All @@ -74,17 +73,12 @@ impl OutboundHandler for Handler {

async fn connect_datagram(
&self,
sess: &Session,
_sess: &Session,
resolver: ThreadSafeDNSResolver,
) -> std::io::Result<BoxedChainedDatagram> {
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;
Expand Down
26 changes: 2 additions & 24 deletions clash_lib/src/proxy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u32>,
#[serde(rename = "routing-mark")]
so_mark: Option<u32>,
#[serde(rename = "interface-name")]
iface: Option<Interface>,
}

impl CommonOption {
pub fn merge<'a>(&'a self, sess: &'a Session) -> (Option<u32>, 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
Expand Down
12 changes: 4 additions & 8 deletions clash_lib/src/proxy/shadowsocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,12 @@ impl OutboundHandler for Handler {
sess: &Session,
resolver: ThreadSafeDNSResolver,
) -> io::Result<BoxedChainedStream> {
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(
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 0 additions & 2 deletions clash_lib/src/proxy/socks/inbound/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
};

Expand Down
13 changes: 4 additions & 9 deletions clash_lib/src/proxy/trojan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,12 @@ impl OutboundHandler for Handler {
sess: &Session,
resolver: ThreadSafeDNSResolver,
) -> io::Result<BoxedChainedStream> {
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(
Expand Down Expand Up @@ -193,14 +190,12 @@ impl OutboundHandler for Handler {
sess: &Session,
resolver: ThreadSafeDNSResolver,
) -> io::Result<BoxedChainedDatagram> {
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(
Expand Down
26 changes: 14 additions & 12 deletions clash_lib/src/proxy/utils/socket_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<TcpStream> {
#[cfg(not(target_os = "windows"))]
Expand Down Expand Up @@ -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<u32>,
iface: Option<&Interface>,
packet_mark: Option<u32>,
) -> io::Result<AnyStream> {
let dial_addr = resolver
.resolve(address, false)
Expand All @@ -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)?;
}

Expand All @@ -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<u32>,
packet_mark: Option<u32>,
) -> io::Result<UdpSocket> {
let socket = match src {
Some(src) => {
Expand All @@ -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)?;
}

Expand Down
13 changes: 4 additions & 9 deletions clash_lib/src/proxy/vmess/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -169,14 +168,12 @@ impl OutboundHandler for Handler {
sess: &Session,
resolver: ThreadSafeDNSResolver,
) -> io::Result<BoxedChainedStream> {
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(
Expand Down Expand Up @@ -210,14 +207,12 @@ impl OutboundHandler for Handler {
sess: &Session,
resolver: ThreadSafeDNSResolver,
) -> io::Result<BoxedChainedDatagram> {
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(
Expand Down

0 comments on commit a55436d

Please sign in to comment.