This commit is contained in:
nirvanalinlei 2026-04-01 09:47:24 +08:00 committed by GitHub
commit 3faeadacdb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 58 additions and 19 deletions

View file

@ -46,7 +46,7 @@ public static class ProcUtils
return null; return null;
} }
public static void RebootAsAdmin(bool blAdmin = true) public static bool RebootAsAdmin(bool blAdmin = true)
{ {
try try
{ {
@ -58,11 +58,12 @@ public static class ProcUtils
FileName = Utils.GetExePath().AppendQuotes(), FileName = Utils.GetExePath().AppendQuotes(),
Verb = blAdmin ? "runas" : null, Verb = blAdmin ? "runas" : null,
}; };
_ = Process.Start(startInfo); return Process.Start(startInfo) != null;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
return false;
} }
} }
} }

View file

@ -144,10 +144,16 @@ public sealed class AppManager
AppEvents.ShutdownRequested.Publish(byUser); AppEvents.ShutdownRequested.Publish(byUser);
} }
public async Task RebootAsAdmin() public async Task<bool> RebootAsAdmin()
{ {
ProcUtils.RebootAsAdmin(); var started = ProcUtils.RebootAsAdmin();
if (!started)
{
return false;
}
await AppManager.Instance.AppExitAsync(true); await AppManager.Instance.AppExitAsync(true);
return true;
} }
#endregion App #endregion App

View file

@ -345,6 +345,14 @@ public partial class CoreConfigSingboxService
{ {
try try
{ {
// The synthetic TUN relay outbound talks to the local Xray shadowsocks relay.
// Xray cannot terminate sing-box h2mux, so muxing here turns local relay traffic
// into sp.mux.sing-box.arpa pseudo-destinations and breaks DNS over TUN.
if (IsTunRelayProxyOutbound())
{
return;
}
var muxEnabled = _node.MuxEnabled ?? _config.CoreBasicItem.MuxEnabled; var muxEnabled = _node.MuxEnabled ?? _config.CoreBasicItem.MuxEnabled;
if (muxEnabled && _config.Mux4SboxItem.Protocol.IsNotEmpty()) if (muxEnabled && _config.Mux4SboxItem.Protocol.IsNotEmpty())
{ {
@ -364,6 +372,21 @@ public partial class CoreConfigSingboxService
} }
} }
private bool IsTunRelayProxyOutbound()
{
if (!context.IsTunEnabled
|| _node.ConfigType != EConfigType.Shadowsocks
|| _node.Address != Global.Loopback
|| _node.Port != context.ProxyRelaySsPort
|| _node.Password != Global.None)
{
return false;
}
var protocolExtra = _node.GetProtocolExtra();
return protocolExtra.SsMethod == Global.None;
}
private void FillOutboundTls(Outbound4Sbox outbound) private void FillOutboundTls(Outbound4Sbox outbound)
{ {
try try

View file

@ -469,31 +469,40 @@ public class StatusBarViewModel : MyReactiveObject
return; return;
} }
_config.TunModeItem.EnableTun = EnableTun; var allowEnableTun = AllowEnableTun();
if (PrepareTunConfigForPrivilegeEscalation(_config, EnableTun, allowEnableTun, Utils.IsWindows()))
if (EnableTun && AllowEnableTun() == false)
{ {
// When running as a non-administrator, reboot to administrator mode await ConfigHandler.SaveConfig(_config);
if (Utils.IsWindows()) if (!await AppManager.Instance.RebootAsAdmin())
{
_config.TunModeItem.EnableTun = false;
EnableTun = false;
await ConfigHandler.SaveConfig(_config);
NoticeManager.Instance.SendMessageEx(ResUI.OperationFailed);
}
return;
}
if (EnableTun && !allowEnableTun)
{
bool? passwordResult = await _updateView?.Invoke(EViewAction.PasswordInput, null);
if (passwordResult == false)
{ {
_config.TunModeItem.EnableTun = false; _config.TunModeItem.EnableTun = false;
await AppManager.Instance.RebootAsAdmin();
return; return;
} }
else
{
bool? passwordResult = await _updateView?.Invoke(EViewAction.PasswordInput, null);
if (passwordResult == false)
{
_config.TunModeItem.EnableTun = false;
return;
}
}
} }
await ConfigHandler.SaveConfig(_config); await ConfigHandler.SaveConfig(_config);
AppEvents.ReloadRequested.Publish(); AppEvents.ReloadRequested.Publish();
} }
private static bool PrepareTunConfigForPrivilegeEscalation(Config config, bool enableTun, bool allowEnableTun, bool isWindows)
{
config.TunModeItem.EnableTun = enableTun;
return enableTun && !allowEnableTun && isWindows;
}
private bool AllowEnableTun() private bool AllowEnableTun()
{ {
if (Utils.IsWindows()) if (Utils.IsWindows())