Use the TUN context snapshot in remaining launch-path reads (#9831)

Follow-up to #9830: audit of all TunModeItem.EnableTun usages found
three more launch-path reads of the live mutable config where the
behavior must agree with the context snapshot that generated the
config:

- CoreConfigClashService (mihomo custom config): the tun section was
  decided from the live config while the mihomo launch elevation uses
  the snapshot; a mid-reload toggle could produce a config containing
  tun launched without sudo, the same failure fixed in #9830. The tun
  state is now passed in as a snapshot.
- CoreManager.LoadCore: the Windows RemoveTunDevice cleanup now checks
  the main/pre context snapshots.
- CoreManager.WaitForProxyPort: preContext.AppConfig is a shared live
  reference; use preContext.IsTunEnabled instead.

Reads that intentionally stay live: StatusBarViewModel (UI state
source), CoreConfigContextBuilder (the snapshot capture point),
GetPreSocksItem (called during snapshot construction, self-consistent),
and AppManager.StatePort2 (transient mid-reload skew only, self-heals
after reload).
This commit is contained in:
hyjhyj111
2026-07-27 21:13:28 +08:00
committed by GitHub
parent 611ce0fd2c
commit 02df430172
3 changed files with 9 additions and 7 deletions

View File

@@ -17,7 +17,7 @@ public static class CoreConfigHandler
{
result = node.CoreType switch
{
ECoreType.mihomo => await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName),
ECoreType.mihomo => await new CoreConfigClashService(config, context.IsTunEnabled).GenerateClientCustomConfig(node, fileName),
_ => await GenerateClientCustomConfig(node, fileName)
};
}

View File

@@ -85,7 +85,7 @@ public class CoreManager
await CoreStop();
await Task.Delay(100);
if (Utils.IsWindows() && _config.TunModeItem.EnableTun)
if (Utils.IsWindows() && (mainContext?.IsTunEnabled == true || preContext?.IsTunEnabled == true))
{
await Task.Delay(100);
await WindowsUtils.RemoveTunDevice();
@@ -222,7 +222,7 @@ public class CoreManager
{
return;
}
if (!preContext.AppConfig.TunModeItem.EnableTun)
if (!preContext.IsTunEnabled)
{
return;
}

View File

@@ -1,9 +1,11 @@
namespace ServiceLib.Services.CoreConfig;
/// <summary>
/// Core configuration file processing class
/// Core configuration file processing class.
/// The TUN state is taken as a snapshot so the generated config always agrees
/// with the launch elevation decision (see CoreManager.ShouldRunAsSudo).
/// </summary>
public class CoreConfigClashService(Config config)
public class CoreConfigClashService(Config config, bool isTunEnabled)
{
private static readonly string _tag = "CoreConfigClashService";
@@ -102,7 +104,7 @@ public class CoreConfigClashService(Config config)
}
//enable tun mode
if (config.TunModeItem.EnableTun)
if (isTunEnabled)
{
var tun = EmbedUtils.GetEmbedText(Global.ClashTunYaml);
if (tun.IsNotEmpty())
@@ -171,7 +173,7 @@ public class CoreConfigClashService(Config config)
}
foreach (var item in mixinContent)
{
if (!config.TunModeItem.EnableTun && item.Key == "tun")
if (!isTunEnabled && item.Key == "tun")
{
continue;
}