@@ -12,10 +12,10 @@ use regex::Regex;
1212use tokio:: process:: Child ;
1313
1414use kasumi_core:: core:: default_tun_for;
15- use kasumi_core:: enums:: { CoreEngine , TunEngine , tun_from_marker} ;
15+ use kasumi_core:: enums:: { CoreEngine , NO_TUN_MARKER , TunEngine , tun_from_marker} ;
1616use kasumi_core:: hev_config:: build_hev_config;
1717use kasumi_core:: singbox_config:: build_singbox_bridge_config;
18- use kasumi_core:: state:: { AppState , DEFAULT_LOCAL_SOCKS_PORT } ;
18+ use kasumi_core:: state:: { AppState , DEFAULT_LOCAL_SOCKS_PORT , ProxyMode } ;
1919use kasumi_core:: tun2socks_config:: build_tun2socks_config;
2020// Aliased: `tun` alone would shadow the many `tun: TunEngine` params here.
2121use kasumi_core:: tun as tun_addr;
@@ -24,7 +24,7 @@ use kasumi_core::tun::TunOptions;
2424use crate :: commands:: { CommandError , build_profile_config} ;
2525use crate :: fs:: { exists, read_text, remove_file, write_text} ;
2626use crate :: fsjson:: { read_json, write_text_atomic} ;
27- use crate :: platform:: { Engine , Platform } ;
27+ use crate :: platform:: { Platform , StartDataPath } ;
2828use crate :: proc:: { RunOpts , pid_matches_bin, run, spawn_logged} ;
2929
3030/// Map a hex digit to a consonant so the interface name starts with a letter
@@ -58,12 +58,12 @@ pub fn random_tun_iface() -> String {
5858}
5959
6060/// Build the config for `profile_id` (else the active profile), write it and the
61- /// engine marker, and return the engine + resolved TUN engine + external- engine
62- /// tuning + local SOCKS port.
61+ /// engine marker, and return the resolved [`StartDataPath`] ( engine, TUN engine,
62+ /// external-engine tuning, SOCKS port, proxy mode) .
6363pub async fn resolve_and_write_config (
6464 platform : & dyn Platform ,
6565 profile_id : Option < & str > ,
66- ) -> Result < ( Engine , TunEngine , TunOptions , u16 ) , CommandError > {
66+ ) -> Result < StartDataPath , CommandError > {
6767 let paths = platform. paths ( ) ;
6868 let state = read_json :: < AppState > ( & paths. app_state ) . await ;
6969 let id = profile_id
@@ -91,7 +91,20 @@ pub async fn resolve_and_write_config(
9191 . local_socks_port
9292 . unwrap_or ( DEFAULT_LOCAL_SOCKS_PORT ) ;
9393 let tun_opts = settings. tun_options ( ) ;
94- Ok ( ( engine, tun, tun_opts, socks_port) )
94+ // Same normalization as the config build: a platform without proxy-mode
95+ // support always starts in tun mode.
96+ let mode = if platform. supports_proxy_modes ( ) {
97+ settings. proxy_mode
98+ } else {
99+ ProxyMode :: Tun
100+ } ;
101+ Ok ( StartDataPath {
102+ engine,
103+ tun,
104+ tun_opts,
105+ socks_port,
106+ mode,
107+ } )
95108}
96109
97110/// The core engine's on-disk label (written to `paths.engine_file` at config
@@ -130,6 +143,11 @@ pub fn running_external_engine(
130143 marker : Option < & str > ,
131144 engine_label : Option < & str > ,
132145) -> Option < TunEngine > {
146+ // A no-tun data-path (proxy-only/system/pac) runs no helper whatever the
147+ // core — never fall back to the engine default there.
148+ if marker. map ( str:: trim) == Some ( NO_TUN_MARKER ) {
149+ return None ;
150+ }
133151 let core = engine_label. and_then ( core_from_label) ;
134152 if let Some ( tun) = marker. map ( str:: trim) . and_then ( tun_from_marker) {
135153 // Native only when we're sure it's the sing-box core with its own tun; an
@@ -522,6 +540,16 @@ mod tests {
522540 running_external_engine( Some ( " \n " ) , Some ( "xray" ) ) ,
523541 Some ( TunEngine :: Tun2socks )
524542 ) ;
543+ // A no-tun data-path expects no helper, even for xray (no engine-default
544+ // fallback).
545+ assert_eq ! (
546+ running_external_engine( Some ( NO_TUN_MARKER ) , Some ( "xray" ) ) ,
547+ None
548+ ) ;
549+ assert_eq ! (
550+ running_external_engine( Some ( "no-tun\n " ) , Some ( "sing-box" ) ) ,
551+ None
552+ ) ;
525553 }
526554
527555 #[ test]
@@ -572,10 +600,12 @@ mod tests {
572600 . unwrap ( ) ;
573601
574602 // No explicit id → uses active_id.
575- let ( engine, tun, _tun_opts, socks) = resolve_and_write_config ( & p, None ) . await . unwrap ( ) ;
576- assert_eq ! ( engine, CoreEngine :: Xray ) ;
577- assert_eq ! ( tun, TunEngine :: Tun2socks ) ;
578- assert_eq ! ( socks, 11080 ) ;
603+ let opts = resolve_and_write_config ( & p, None ) . await . unwrap ( ) ;
604+ assert_eq ! ( opts. engine, CoreEngine :: Xray ) ;
605+ assert_eq ! ( opts. tun, TunEngine :: Tun2socks ) ;
606+ assert_eq ! ( opts. socks_port, 11080 ) ;
607+ // TestPlatform doesn't support proxy modes → always normalized to tun.
608+ assert_eq ! ( opts. mode, ProxyMode :: Tun ) ;
579609 assert_eq ! (
580610 read_text( & p. paths( ) . engine_file) . await . as_deref( ) ,
581611 Some ( "xray" )
0 commit comments