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))
|
if (!File.Exists(addressFileName))
|
||||||
{
|
{
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
var message = $"{ResUI.FailedReadConfiguration}: {addressFileName}";
|
||||||
|
Logging.SaveLog($"{_tag}: {message}");
|
||||||
|
ret.Msg = message;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
File.Copy(addressFileName, fileName);
|
File.Copy(addressFileName, fileName);
|
||||||
@@ -74,7 +76,9 @@ public static class CoreConfigHandler
|
|||||||
//check again
|
//check again
|
||||||
if (!File.Exists(fileName))
|
if (!File.Exists(fileName))
|
||||||
{
|
{
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
var message = $"{ResUI.FailedReadConfiguration}: {fileName}";
|
||||||
|
Logging.SaveLog($"{_tag}: {message}");
|
||||||
|
ret.Msg = message;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,9 +91,19 @@ public class CoreManager
|
|||||||
await WindowsUtils.RemoveTunDevice();
|
await WindowsUtils.RemoveTunDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
await CoreStart(mainContext);
|
if (!await CoreStart(mainContext))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await WaitForProxyPort(preContext);
|
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;
|
AppManager.Instance.RunningCoreType = preContext?.RunCoreType ?? mainContext.RunCoreType;
|
||||||
|
|
||||||
@@ -176,7 +186,7 @@ public class CoreManager
|
|||||||
|
|
||||||
#region Private
|
#region Private
|
||||||
|
|
||||||
private async Task CoreStart(CoreConfigContext context)
|
private async Task<bool> CoreStart(CoreConfigContext context)
|
||||||
{
|
{
|
||||||
var node = context.Node;
|
var node = context.Node;
|
||||||
var coreType = AppManager.Instance.GetCoreType(node, node.ConfigType);
|
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);
|
var proc = await RunProcess(coreInfo, Global.CoreConfigFileName, displayLog, true, context.IsTunEnabled);
|
||||||
if (proc is null)
|
if (proc is null)
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
_processService = proc;
|
_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;
|
return true;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
private async Task UpdateFunc(bool notify, string msg)
|
||||||
@@ -307,7 +333,7 @@ public class CoreManager
|
|||||||
var fileName = CoreInfoManager.Instance.GetCoreExecFile(coreInfo, out var msg);
|
var fileName = CoreInfoManager.Instance.GetCoreExecFile(coreInfo, out var msg);
|
||||||
if (fileName.IsNullOrEmpty())
|
if (fileName.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
await UpdateFunc(false, msg);
|
await UpdateFunc(mayNeedSudo, msg);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user