Skip to content

Commit

Permalink
feat(tun): route all on linux (#594)
Browse files Browse the repository at this point in the history
  • Loading branch information
ibigbug authored Sep 19, 2024
1 parent fe265d1 commit 96374d6
Show file tree
Hide file tree
Showing 40 changed files with 568 additions and 206 deletions.
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ target-dir = "target"
rustflags = ["--cfg", "tokio_unstable"]

[env]
RUST_LOG = { value = "clash=trace" }
RUST_LOG = { value = "clash=trace" }
5 changes: 4 additions & 1 deletion clash/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ struct Cli {
help = "Test configuration and exit"
)]
test_config: bool,

#[clap(short, long, help = "Additinally log to file")]
log_file: Option<String>,
}

fn main() {
Expand Down Expand Up @@ -64,7 +67,7 @@ fn main() {
config: clash::Config::File(file),
cwd: cli.directory.map(|x| x.to_string_lossy().to_string()),
rt: Some(TokioRuntime::MultiThread),
log_file: None,
log_file: cli.log_file,
}) {
Ok(_) => {}
Err(_) => {
Expand Down
1 change: 1 addition & 0 deletions clash/tests/data/config/rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ tun:
device-id: "dev://utun1989"
route-all: true
gateway: "198.19.0.1/32"
so-mark: 3389
# routes:
# - 0.0.0.0/1
# - 128.0.0.0/1
Expand Down
32 changes: 10 additions & 22 deletions clash_lib/src/app/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use serde::Serialize;
use tokio::sync::broadcast::Sender;

use tracing::{debug, error};
use tracing_appender::non_blocking::{NonBlocking, WorkerGuard};
use tracing_appender::non_blocking::WorkerGuard;
use tracing_oslog::OsLogger;
use tracing_subscriber::{filter, filter::Directive, prelude::*, EnvFilter, Layer};

Expand Down Expand Up @@ -76,24 +76,6 @@ where
}
}

struct W(Option<NonBlocking>);

impl std::io::Write for W {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
match self.0 {
Some(ref mut w) => w.write(buf),
None => Ok(buf.len()),
}
}

fn flush(&mut self) -> std::io::Result<()> {
match self.0 {
Some(ref mut w) => w.flush(),
None => Ok(()),
}
}
}

pub fn setup_logging(
level: LogLevel,
collector: EventCollector,
Expand Down Expand Up @@ -165,6 +147,15 @@ pub fn setup_logging(
.with(filter)
.with(collector)
.with(console_layer)
.with(appender.map(|x| {
tracing_subscriber::fmt::Layer::new()
.with_ansi(false)
.compact()
.with_file(true)
.with_line_number(true)
.with_level(true)
.with_writer(x)
}))
.with(
tracing_subscriber::fmt::Layer::new()
.with_ansi(std::io::stdout().is_terminal())
Expand All @@ -174,9 +165,6 @@ pub fn setup_logging(
.with_line_number(true)
.with_level(true)
.with_thread_ids(true)
.with_writer(move || -> Box<dyn std::io::Write> {
Box::new(W(appender.clone()))
})
.with_writer(std::io::stdout),
)
.with(ios_os_log);
Expand Down
20 changes: 14 additions & 6 deletions clash_lib/src/app/outbound/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,9 @@ impl OutboundManager {
let relay = relay::Handler::new(
relay::HandlerOptions {
name: proto.name.clone(),
shared_opts: crate::proxy::HandlerSharedOptions {
common_opts: crate::proxy::HandlerCommonOptions {
icon: proto.icon.clone(),
..Default::default()
},
},
providers,
Expand Down Expand Up @@ -446,8 +447,9 @@ impl OutboundManager {
let url_test = urltest::Handler::new(
urltest::HandlerOptions {
name: proto.name.clone(),
shared_opts: crate::proxy::HandlerSharedOptions {
common_opts: crate::proxy::HandlerCommonOptions {
icon: proto.icon.clone(),
..Default::default()
},
..Default::default()
},
Expand Down Expand Up @@ -502,8 +504,9 @@ impl OutboundManager {
let fallback = fallback::Handler::new(
fallback::HandlerOptions {
name: proto.name.clone(),
shared_opts: crate::proxy::HandlerSharedOptions {
common_opts: crate::proxy::HandlerCommonOptions {
icon: proto.icon.clone(),
..Default::default()
},
..Default::default()
},
Expand Down Expand Up @@ -557,8 +560,9 @@ impl OutboundManager {
let load_balance = loadbalance::Handler::new(
loadbalance::HandlerOptions {
name: proto.name.clone(),
shared_opts: crate::proxy::HandlerSharedOptions {
common_opts: crate::proxy::HandlerCommonOptions {
icon: proto.icon.clone(),
..Default::default()
},
..Default::default()
},
Expand Down Expand Up @@ -616,8 +620,9 @@ impl OutboundManager {
selector::HandlerOptions {
name: proto.name.clone(),
udp: proto.udp.unwrap_or(true),
shared_opts: crate::proxy::HandlerSharedOptions {
common_opts: crate::proxy::HandlerCommonOptions {
icon: proto.icon.clone(),
..Default::default()
},
},
providers,
Expand Down Expand Up @@ -654,7 +659,10 @@ impl OutboundManager {
selector::HandlerOptions {
name: PROXY_GLOBAL.to_owned(),
udp: true,
shared_opts: crate::proxy::HandlerSharedOptions { icon: None },
common_opts: crate::proxy::HandlerCommonOptions {
icon: None,
..Default::default()
},
},
vec![pd.clone()],
stored_selection,
Expand Down
4 changes: 4 additions & 0 deletions clash_lib/src/config/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ pub struct TunConfig {
#[serde(default)]
pub route_all: bool,
pub mtu: Option<i32>,
/// fwmark on Linux only
pub so_mark: Option<u32>,
/// policy routing table on Linux only
pub route_table: Option<u32>,
}

#[derive(Serialize, Deserialize, Default, Copy, Clone)]
Expand Down
4 changes: 4 additions & 0 deletions clash_lib/src/config/internal/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ impl TryFrom<def::Config> for Config {
Error::InvalidConfig(format!("parse tun gateway: {}", x))
})?,
mtu: t.mtu,
so_mark: t.so_mark,
route_table: t.route_table,
},
None => TunConfig::default(),
},
Expand Down Expand Up @@ -300,6 +302,8 @@ pub struct TunConfig {
pub routes: Vec<IpNet>,
pub gateway: IpNet,
pub mtu: Option<i32>,
pub so_mark: Option<u32>,
pub route_table: Option<u32>,
}

#[derive(Clone, Default)]
Expand Down
14 changes: 7 additions & 7 deletions clash_lib/src/config/internal/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl Display for OutboundProxyProtocol {

#[derive(serde::Serialize, serde::Deserialize, Debug, Default, Clone)]
#[serde(rename_all = "kebab-case")]
pub struct CommonOption {
pub struct CommonConfigOptions {
pub name: String,
pub server: String,
pub port: u16,
Expand All @@ -144,7 +144,7 @@ pub struct CommonOption {
#[serde(rename_all = "kebab-case")]
pub struct OutboundShadowsocks {
#[serde(flatten)]
pub common_opts: CommonOption,
pub common_opts: CommonConfigOptions,
pub cipher: String,
pub password: String,
#[serde(default = "default_bool_true")]
Expand All @@ -157,7 +157,7 @@ pub struct OutboundShadowsocks {
#[serde(rename_all = "kebab-case")]
pub struct OutboundSocks5 {
#[serde(flatten)]
pub common_opts: CommonOption,
pub common_opts: CommonConfigOptions,
pub username: Option<String>,
pub password: Option<String>,
#[serde(default = "Default::default")]
Expand Down Expand Up @@ -194,7 +194,7 @@ pub struct GrpcOpt {
#[serde(rename_all = "kebab-case")]
pub struct OutboundTrojan {
#[serde(flatten)]
pub common_opts: CommonOption,
pub common_opts: CommonConfigOptions,
pub password: String,
pub alpn: Option<Vec<String>>,
pub sni: Option<String>,
Expand All @@ -209,7 +209,7 @@ pub struct OutboundTrojan {
#[serde(rename_all = "kebab-case")]
pub struct OutboundVmess {
#[serde(flatten)]
pub common_opts: CommonOption,
pub common_opts: CommonConfigOptions,
pub uuid: String,
#[serde(alias = "alterId")]
pub alter_id: u16,
Expand All @@ -229,7 +229,7 @@ pub struct OutboundVmess {
#[serde(rename_all = "kebab-case")]
pub struct OutboundWireguard {
#[serde(flatten)]
pub common_opts: CommonOption,
pub common_opts: CommonConfigOptions,
pub private_key: String,
pub public_key: String,
pub preshared_key: Option<String>,
Expand All @@ -253,7 +253,7 @@ pub struct OutboundTor {
#[serde(rename_all = "kebab-case")]
pub struct OutboundTuic {
#[serde(flatten)]
pub common_opts: CommonOption,
pub common_opts: CommonConfigOptions,
pub uuid: Uuid,
pub password: String,
/// override field 'server' dns record, not used for now
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 @@ -7,7 +7,7 @@ use crate::{
Handler, HandlerOptions, OBFSOption, ShadowTlsOption, SimpleOBFSMode,
SimpleOBFSOption, V2RayOBFSOption,
},
CommonOption,
HandlerCommonOptions,
},
Error,
};
Expand All @@ -26,7 +26,7 @@ impl TryFrom<&OutboundShadowsocks> for Handler {
fn try_from(s: &OutboundShadowsocks) -> Result<Self, Self::Error> {
let h = Handler::new(HandlerOptions {
name: s.common_opts.name.to_owned(),
common_opts: CommonOption {
common_opts: HandlerCommonOptions {
connector: s.common_opts.connect_via.clone(),
..Default::default()
},
Expand Down
4 changes: 2 additions & 2 deletions clash_lib/src/proxy/converters/socks5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
config::internal::proxy::OutboundSocks5,
proxy::{
socks::{Handler, HandlerOptions},
CommonOption,
HandlerCommonOptions,
},
};

Expand All @@ -20,7 +20,7 @@ impl TryFrom<&OutboundSocks5> for Handler {
fn try_from(s: &OutboundSocks5) -> Result<Self, Self::Error> {
let h = Handler::new(HandlerOptions {
name: s.common_opts.name.to_owned(),
common_opts: CommonOption {
common_opts: HandlerCommonOptions {
connector: s.common_opts.connect_via.clone(),
..Default::default()
},
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, HandlerOptions, Transport},
CommonOption,
HandlerCommonOptions,
},
Error,
};
Expand All @@ -32,7 +32,7 @@ impl TryFrom<&OutboundTrojan> for Handler {

let h = Handler::new(HandlerOptions {
name: s.common_opts.name.to_owned(),
common_opts: CommonOption {
common_opts: HandlerCommonOptions {
connector: s.common_opts.connect_via.clone(),
..Default::default()
},
Expand Down
4 changes: 2 additions & 2 deletions clash_lib/src/proxy/converters/tuic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
config::internal::proxy::OutboundTuic,
proxy::{
tuic::{types::CongestionControl, Handler, HandlerOptions},
CommonOption,
HandlerCommonOptions,
},
};

Expand All @@ -25,7 +25,7 @@ impl TryFrom<&OutboundTuic> for Handler {
Ok(Handler::new(HandlerOptions {
name: s.common_opts.name.to_owned(),
server: s.common_opts.server.to_owned(),
common_opts: CommonOption {
common_opts: HandlerCommonOptions {
connector: s.common_opts.connect_via.clone(),
..Default::default()
},
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},
CommonOption,
HandlerCommonOptions,
},
Error,
};
Expand All @@ -33,7 +33,7 @@ impl TryFrom<&OutboundVmess> for Handler {

let h = Handler::new(HandlerOptions {
name: s.common_opts.name.to_owned(),
common_opts: CommonOption {
common_opts: HandlerCommonOptions {
connector: s.common_opts.connect_via.clone(),
..Default::default()
},
Expand Down
4 changes: 2 additions & 2 deletions clash_lib/src/proxy/converters/wireguard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
config::internal::proxy::OutboundWireguard,
proxy::{
wg::{Handler, HandlerOptions},
CommonOption,
HandlerCommonOptions,
},
Error,
};
Expand All @@ -23,7 +23,7 @@ impl TryFrom<&OutboundWireguard> for Handler {
fn try_from(s: &OutboundWireguard) -> Result<Self, Self::Error> {
let h = Handler::new(HandlerOptions {
name: s.common_opts.name.to_owned(),
common_opts: CommonOption {
common_opts: HandlerCommonOptions {
connector: s.common_opts.connect_via.clone(),
..Default::default()
},
Expand Down
8 changes: 4 additions & 4 deletions clash_lib/src/proxy/direct/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl OutboundHandler for Handler {
(remote_ip, sess.destination.port()).into(),
sess.iface.clone(),
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
sess.so_mark,
)
.await?;

Expand All @@ -92,7 +92,7 @@ impl OutboundHandler for Handler {
None,
sess.iface.clone(),
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
sess.so_mark,
)
.await
.map(|x| OutboundDatagramImpl::new(x, resolver))?;
Expand All @@ -119,7 +119,7 @@ impl OutboundHandler for Handler {
sess.destination.port(),
sess.iface.as_ref(),
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
sess.so_mark,
)
.await?;
let s = ChainedStreamWrapper::new(s);
Expand All @@ -140,7 +140,7 @@ impl OutboundHandler for Handler {
sess.destination.clone(),
sess.iface.clone(),
#[cfg(any(target_os = "linux", target_os = "android"))]
None,
sess.so_mark,
)
.await?;
let d = ChainedDatagramWrapper::new(d);
Expand Down
Loading

0 comments on commit 96374d6

Please sign in to comment.