Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/mark #362

Closed
wants to merge 9 commits into from
Closed
1 change: 0 additions & 1 deletion clash_lib/src/app/dns/dhcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ async fn listen_dhcp_client(iface: &str) -> io::Result<UdpSocket> {
new_udp_socket(
Some(&listen_addr.parse().expect("must parse")),
Some(&Interface::Name(iface.to_string())),
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
)
.await
Expand Down
1 change: 0 additions & 1 deletion clash_lib/src/common/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ impl Service<Uri> for LocalConnector {
},
}),
None,
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
)
.await
Expand Down
13 changes: 13 additions & 0 deletions clash_lib/src/config/internal/proxy.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::common::utils::default_bool_true;
use crate::config::utils;
use crate::proxy::CommonOption;
use crate::Error;
use serde::de::value::MapDeserializer;
use serde::Deserialize;
Expand Down Expand Up @@ -116,6 +117,8 @@ impl Display for OutboundProxyProtocol {

#[derive(serde::Serialize, serde::Deserialize, Debug, Default)]
pub struct OutboundShadowsocks {
#[serde(flatten)]
pub common_opts: CommonOption,
pub name: String,
pub server: String,
pub port: u16,
Expand All @@ -130,6 +133,8 @@ pub struct OutboundShadowsocks {

#[derive(serde::Serialize, serde::Deserialize, Debug, Default)]
pub struct OutboundSocks5 {
#[serde(flatten)]
pub common_opts: CommonOption,
pub name: String,
pub server: String,
pub port: u16,
Expand All @@ -142,6 +147,8 @@ pub struct OutboundSocks5 {

#[derive(serde::Serialize, serde::Deserialize, Debug, Default)]
pub struct WsOpt {
#[serde(flatten)]
pub common_opts: CommonOption,
pub path: Option<String>,
pub headers: Option<HashMap<String, String>>,
pub max_early_data: Option<i32>,
Expand All @@ -163,6 +170,8 @@ pub struct GrpcOpt {
#[derive(serde::Serialize, serde::Deserialize, Debug, Default)]
#[serde(rename_all = "kebab-case")]
pub struct OutboundTrojan {
#[serde(flatten)]
pub common_opts: CommonOption,
pub name: String,
pub server: String,
pub port: u16,
Expand All @@ -179,6 +188,8 @@ pub struct OutboundTrojan {
#[derive(serde::Serialize, serde::Deserialize, Debug, Default)]
#[serde(rename_all = "kebab-case")]
pub struct OutboundVmess {
#[serde(flatten)]
pub common_opts: CommonOption,
pub name: String,
pub server: String,
pub port: u16,
Expand All @@ -200,6 +211,8 @@ pub struct OutboundVmess {
#[derive(serde::Serialize, serde::Deserialize, Debug, Default, Clone)]
#[serde(rename_all = "kebab-case")]
pub struct OutboundWireguard {
#[serde(flatten)]
pub common_opts: CommonOption,
pub name: String,
pub server: String,
pub port: u16,
Expand Down
2 changes: 1 addition & 1 deletion clash_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ mod common;
mod config;
mod proxy;
mod session;

pub use config::def::Config as ClashConfigDef;
pub use config::def::DNS as ClashDNSConfigDef;
pub use config::DNSListen as ClashDNSListen;
pub use config::RuntimeConfig as ClashRuntimeConfig;
pub use session::{get_iface, get_somark, set_iface, set_somark};

#[derive(Error, Debug)]
pub enum Error {
Expand Down
4 changes: 2 additions & 2 deletions 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, CommonOption,
AnyOutboundHandler,
},
Error,
};
Expand All @@ -21,7 +21,7 @@ impl TryFrom<&OutboundShadowsocks> for AnyOutboundHandler {
fn try_from(s: &OutboundShadowsocks) -> Result<Self, Self::Error> {
let h = Handler::new(HandlerOptions {
name: s.name.to_owned(),
common_opts: CommonOption::default(),
common_opts: s.common_opts.clone(),
server: s.server.to_owned(),
port: s.port,
password: s.password.to_owned(),
Expand Down
4 changes: 2 additions & 2 deletions clash_lib/src/proxy/converters/trojan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
proxy::{
options::{GrpcOption, WsOption},
trojan::{Handler, Opts, Transport},
AnyOutboundHandler, CommonOption,
AnyOutboundHandler,
},
Error,
};
Expand All @@ -29,7 +29,7 @@ impl TryFrom<&OutboundTrojan> for AnyOutboundHandler {

let h = Handler::new(Opts {
name: s.name.to_owned(),
common_opts: CommonOption::default(),
common_opts: s.common_opts.clone(),
server: s.server.to_owned(),
port: s.port,
password: s.password.clone(),
Expand Down
4 changes: 2 additions & 2 deletions clash_lib/src/proxy/converters/vmess.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
options::{GrpcOption, Http2Option, WsOption},
transport::TLSOptions,
vmess::{Handler, HandlerOptions, VmessTransport},
AnyOutboundHandler, CommonOption,
AnyOutboundHandler,
},
Error,
};
Expand All @@ -30,7 +30,7 @@ impl TryFrom<&OutboundVmess> for AnyOutboundHandler {

let h = Handler::new(HandlerOptions {
name: s.name.to_owned(),
common_opts: CommonOption::default(),
common_opts: s.common_opts.clone(),
server: s.server.to_owned(),
port: s.port,
uuid: s.uuid.clone(),
Expand Down
2 changes: 1 addition & 1 deletion clash_lib/src/proxy/converters/wireguard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl TryFrom<&OutboundWireguard> for AnyOutboundHandler {
fn try_from(s: &OutboundWireguard) -> Result<Self, Self::Error> {
let h = Handler::new(HandlerOpts {
name: s.name.to_owned(),
common_opts: Default::default(),
common_opts: s.common_opts.clone(),
server: s.server.to_owned(),
port: s.port,
ip: s
Expand Down
18 changes: 6 additions & 12 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 @@ -66,25 +65,20 @@ impl OutboundHandler for Handler {
async fn proxy_stream(
&self,
s: AnyStream,
#[allow(unused_variables)] sess: &Session,
#[allow(unused_variables)] _resolver: ThreadSafeDNSResolver,
_sess: &Session,
_resolver: ThreadSafeDNSResolver,
) -> std::io::Result<AnyStream> {
Ok(s)
}

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
1 change: 0 additions & 1 deletion clash_lib/src/proxy/http/inbound/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ impl tower::Service<Uri> for Connector {
typ: Type::Http,
source: src,
destination: destination.ok_or(ProxyError::InvalidUrl(url.to_string()))?,
..Default::default()
};

tokio::spawn(async move {
Expand Down
2 changes: 0 additions & 2 deletions clash_lib/src/proxy/http/inbound/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ async fn proxy(
typ: Type::HttpConnect,
source: src,
destination: addr,

..Default::default()
};

dispatcher.dispatch_stream(sess, upgraded).await
Expand Down
6 changes: 4 additions & 2 deletions clash_lib/src/proxy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,12 @@ impl<T, U> OutboundDatagram<U> for T where
pub type AnyOutboundDatagram =
Box<dyn OutboundDatagram<UdpPacket, Item = UdpPacket, Error = io::Error>>;

#[derive(Default, Debug, Clone)]
#[allow(dead_code)]
#[derive(Default, Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct CommonOption {
#[allow(dead_code)]
#[serde(rename = "routing-mark")]
so_mark: Option<u32>,
#[serde(rename = "interface-name")]
iface: Option<Interface>,
}

Expand Down
1 change: 0 additions & 1 deletion clash_lib/src/proxy/relay/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ impl OutboundHandler for Handler {
remote_addr.host().as_str(),
remote_addr.port(),
None,
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
)
.await?;
Expand Down
6 changes: 2 additions & 4 deletions clash_lib/src/proxy/shadowsocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,7 @@ impl OutboundHandler for Handler {
self.opts.server.as_str(),
self.opts.port,
self.opts.common_opts.iface.as_ref(),
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
self.opts.common_opts.so_mark,
)
.map_err(|x| {
io::Error::new(
Expand Down Expand Up @@ -311,8 +310,7 @@ impl OutboundHandler for Handler {
let socket = new_udp_socket(
None,
self.opts.common_opts.iface.as_ref(),
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
self.opts.common_opts.so_mark,
)
.await?;
let socket = ProxySocket::from_socket(UdpSocketType::Client, ctx, &cfg, socket);
Expand Down
10 changes: 1 addition & 9 deletions clash_lib/src/proxy/socks/inbound/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,7 @@ pub async fn handle_tcp<'a>(
}
socks_command::UDP_ASSOCIATE => {
let udp_addr = SocketAddr::new(s.local_addr()?.ip(), 0);
let udp_inbound = new_udp_socket(
Some(&udp_addr),
None,
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
)
.await?;
let udp_inbound = new_udp_socket(Some(&udp_addr), None, None).await?;

trace!(
"Got a UDP_ASSOCIATE request from {}, UDP assigned at {}",
Expand All @@ -166,8 +160,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
6 changes: 2 additions & 4 deletions clash_lib/src/proxy/trojan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,7 @@ impl OutboundHandler for Handler {
self.opts.server.as_str(),
self.opts.port,
self.opts.common_opts.iface.as_ref(),
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
self.opts.common_opts.so_mark,
)
.map_err(|x| {
io::Error::new(
Expand Down Expand Up @@ -196,8 +195,7 @@ impl OutboundHandler for Handler {
self.opts.server.as_str(),
self.opts.port,
self.opts.common_opts.iface.as_ref(),
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
self.opts.common_opts.so_mark,
)
.map_err(|x| {
io::Error::new(
Expand Down
1 change: 0 additions & 1 deletion clash_lib/src/proxy/tun/inbound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ async fn handle_inbound_stream(
typ: Type::Tun,
source: local_addr,
destination: remote_addr.into(),
..Default::default()
};

dispatcher.dispatch_stream(sess, stream).await;
Expand Down
46 changes: 35 additions & 11 deletions clash_lib/src/proxy/utils/socket_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ fn must_bind_socket_on_interface(socket: &socket2::Socket, iface: &Interface) ->
}
}

pub async fn new_tcp_stream<'a>(
pub async fn new_tcp_stream(
resolver: ThreadSafeDNSResolver,
address: &'a str,
address: &str,
port: u16,
iface: Option<&'a Interface>,
#[cfg(any(target_os = "linux", target_os = "android"))] packet_mark: Option<u32>,
iface: Option<&Interface>,
#[allow(unused_variables)] 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 {
let global_iface = crate::get_iface();
if let Some(iface) = iface.or(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(crate::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>,
#[allow(unused_variables)] 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 {
let global_iface = crate::get_iface();
if let Some(iface) = iface.or(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(crate::get_somark) {
socket.set_mark(packet_mark)?;
}

Expand All @@ -155,6 +157,28 @@ pub async fn new_udp_socket(

UdpSocket::from_std(socket.into())
}
/// An extension to std::net::{UdpSocket, TcpStream}
pub trait StdSocketExt {
fn set_mark(&self, mark: u32) -> io::Result<()>;
}
impl StdSocketExt for std::net::UdpSocket {
fn set_mark(&self, mark: u32) -> io::Result<()> {
set_mark(socket2::SockRef::from(self), mark)
}
}
impl StdSocketExt for std::net::TcpStream {
fn set_mark(&self, mark: u32) -> io::Result<()> {
set_mark(socket2::SockRef::from(self), mark)
}
}

#[allow(unused_variables)]
fn set_mark(socket: socket2::SockRef<'_>, mark: u32) -> io::Result<()> {
#[cfg(target_os = "linux")]
return socket.set_mark(mark);
#[cfg(not(target_os = "linux"))]
return Ok(());
}

#[cfg(test)]
mod tests {
Expand Down
Loading