mirror of
https://github.com/2dust/v2rayN.git
synced 2026-11-14 08:24:59 +03:00
fix: report Linux TUN startup failures (#10556)
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
namespace ServiceLib.Tests.Handler;
|
||||
|
||||
public class CoreConfigHandlerTests
|
||||
{
|
||||
[Test]
|
||||
public async Task GenerateClientConfig_CustomProfileWithMissingSource_ShouldIncludeSourcePath()
|
||||
{
|
||||
var sourcePath = Path.Combine(Path.GetTempPath(), $"v2rayN-missing-{Guid.NewGuid():N}.json");
|
||||
var outputPath = Path.Combine(Path.GetTempPath(), $"v2rayN-output-{Guid.NewGuid():N}.json");
|
||||
var node = new ProfileItem
|
||||
{
|
||||
ConfigType = EConfigType.Custom,
|
||||
Address = sourcePath,
|
||||
Remarks = "missing custom config",
|
||||
};
|
||||
var context = new CoreConfigContext
|
||||
{
|
||||
Node = node,
|
||||
RunCoreType = ECoreType.Xray,
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var result = await CoreConfigHandler.GenerateClientConfig(context, outputPath);
|
||||
|
||||
await result.Success.Should().BeFalse();
|
||||
await result.Msg.Should().Contain(ResUI.FailedReadConfiguration);
|
||||
await result.Msg.Should().Contain(sourcePath);
|
||||
await File.Exists(outputPath).Should().BeFalse();
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(outputPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,9 @@ public static class CoreConfigHandler
|
||||
}
|
||||
if (!File.Exists(addressFileName))
|
||||
{
|
||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
var message = $"{ResUI.FailedReadConfiguration}: {addressFileName}";
|
||||
Logging.SaveLog($"{_tag}: {message}");
|
||||
ret.Msg = message;
|
||||
return ret;
|
||||
}
|
||||
File.Copy(addressFileName, fileName);
|
||||
@@ -74,7 +76,9 @@ public static class CoreConfigHandler
|
||||
//check again
|
||||
if (!File.Exists(fileName))
|
||||
{
|
||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
var message = $"{ResUI.FailedReadConfiguration}: {fileName}";
|
||||
Logging.SaveLog($"{_tag}: {message}");
|
||||
ret.Msg = message;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,9 +91,19 @@ public class CoreManager
|
||||
await WindowsUtils.RemoveTunDevice();
|
||||
}
|
||||
|
||||
await CoreStart(mainContext);
|
||||
if (!await CoreStart(mainContext))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await WaitForProxyPort(preContext);
|
||||
await CoreStartPreService(preContext);
|
||||
if (!await CoreStartPreService(preContext))
|
||||
{
|
||||
// Keep the ordinary proxy core available when only the optional TUN
|
||||
// protection core failed. The error is reported above and the caller
|
||||
// must not treat this as a successful TUN startup.
|
||||
return;
|
||||
}
|
||||
|
||||
AppManager.Instance.RunningCoreType = preContext?.RunCoreType ?? mainContext.RunCoreType;
|
||||
|
||||
@@ -176,7 +186,7 @@ public class CoreManager
|
||||
|
||||
#region Private
|
||||
|
||||
private async Task CoreStart(CoreConfigContext context)
|
||||
private async Task<bool> CoreStart(CoreConfigContext context)
|
||||
{
|
||||
var node = context.Node;
|
||||
var coreType = AppManager.Instance.GetCoreType(node, node.ConfigType);
|
||||
@@ -186,29 +196,45 @@ public class CoreManager
|
||||
var proc = await RunProcess(coreInfo, Global.CoreConfigFileName, displayLog, true, context.IsTunEnabled);
|
||||
if (proc is null)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
_processService = proc;
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task CoreStartPreService(CoreConfigContext? preContext)
|
||||
private async Task<bool> CoreStartPreService(CoreConfigContext? preContext)
|
||||
{
|
||||
if (_processService is { HasExited: false } && preContext != null)
|
||||
if (preContext is null)
|
||||
{
|
||||
var preCoreType = preContext?.Node?.CoreType ?? ECoreType.sing_box;
|
||||
var fileName = Utils.GetBinConfigPath(Global.CorePreConfigFileName);
|
||||
var result = await CoreConfigHandler.GenerateClientConfig(preContext, fileName);
|
||||
if (result.Success)
|
||||
{
|
||||
var coreInfo = CoreInfoManager.Instance.GetCoreInfo(preCoreType);
|
||||
var proc = await RunProcess(coreInfo, Global.CorePreConfigFileName, true, true, preContext.IsTunEnabled);
|
||||
if (proc is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_processPreService = proc;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_processService is not { HasExited: false })
|
||||
{
|
||||
await UpdateFunc(true, ResUI.FailedToRunCore);
|
||||
return false;
|
||||
}
|
||||
|
||||
var preCoreType = preContext.Node?.CoreType ?? ECoreType.sing_box;
|
||||
var fileName = Utils.GetBinConfigPath(Global.CorePreConfigFileName);
|
||||
var result = await CoreConfigHandler.GenerateClientConfig(preContext, fileName);
|
||||
if (!result.Success)
|
||||
{
|
||||
// Previously this result was ignored, so a missing/invalid
|
||||
// configPre.json made Linux TUN fail without any actionable error.
|
||||
await UpdateFunc(true, result.Msg ?? ResUI.FailedGenDefaultConfiguration);
|
||||
return false;
|
||||
}
|
||||
|
||||
var coreInfo = CoreInfoManager.Instance.GetCoreInfo(preCoreType);
|
||||
var proc = await RunProcess(coreInfo, Global.CorePreConfigFileName, true, true, preContext.IsTunEnabled);
|
||||
if (proc is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_processPreService = proc;
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task UpdateFunc(bool notify, string msg)
|
||||
@@ -307,7 +333,7 @@ public class CoreManager
|
||||
var fileName = CoreInfoManager.Instance.GetCoreExecFile(coreInfo, out var msg);
|
||||
if (fileName.IsNullOrEmpty())
|
||||
{
|
||||
await UpdateFunc(false, msg);
|
||||
await UpdateFunc(mayNeedSudo, msg);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user