修复TUN/TAP启动时会被无关适配器的异常所中断导致启动失败

This commit is contained in:
ChsBuffer
2020-08-10 23:34:48 +08:00
parent e60f8e7c4a
commit e8fbde707b
2 changed files with 54 additions and 49 deletions

View File

@@ -92,8 +92,7 @@ namespace Netch.Controllers
RedirectStandardOutput = RedirectStd,
UseShellExecute = !RedirectStd,
WindowStyle = ProcessWindowStyle.Hidden
},
EnableRaisingEvents = true
}
};
}
@@ -111,11 +110,12 @@ namespace Netch.Controllers
{
// 初始化程序
InitInstance(argument);
Instance.EnableRaisingEvents = true;
if (RedirectStd)
{
// 清理日志
_logPath ??= Path.Combine(Global.NetchDir, $"logging\\{Name}.log");
if (_logFileStream == null && File.Exists(_logPath))
if (File.Exists(_logPath))
File.Delete(_logPath);
_logFileStream = new FileStream(_logPath, FileMode.Create, FileAccess.Write);
@@ -239,7 +239,7 @@ namespace Netch.Controllers
}
catch (Exception e)
{
Logging.Error($"写入 {Name} 日志错误:\n" + e.Message);
Logging.Warning($"写入 {Name} 日志错误:\n" + e.Message);
}
}
}

View File

@@ -285,58 +285,63 @@ namespace Netch.Controllers
}
}
// 根据 IP Index 寻找 出口适配器
var errorAdaptersId = new List<string>();
try
{
try
var adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ =>
{
var adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ => _.GetIPProperties().GetIPv4Properties().Index == Global.Adapter.Index);
Global.Adapter.Address = adapter.GetIPProperties().UnicastAddresses.First(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork).Address;
Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop);
Logging.Info($"出口 IPv4 地址:{Global.Adapter.Address}");
Logging.Info($"出口 网关 地址:{Global.Adapter.Gateway}");
Logging.Info($"出口适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.Adapter.Index}");
// Ex NetworkInformationException: 此接口不支持 IPv4 协议。
// Ex NetworkInformationException: Windows 系统函数调用失败。
// Ex System.ArgumentNullException: source 或 predicate 为 null。
}
catch (Exception e)
{
if (e is InvalidOperationException)
Logging.Error($"找不到网络接口索引为 {Global.Adapter.Index} 的出口适配器");
throw;
}
try
{
var adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ => _.Id == Global.TUNTAP.ComponentID);
Global.TUNTAP.Adapter = adapter;
Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index;
Logging.Info($"TAP 适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.TUNTAP.Index}");
}
catch (Exception e)
{
if (e is InvalidOperationException)
Logging.Error($"找不到标识符为 {Global.TUNTAP.ComponentID} 的 TAP 适配器");
throw;
}
return true;
try
{
return _.GetIPProperties().GetIPv4Properties().Index == Global.Adapter.Index;
}
catch (NetworkInformationException)
{
errorAdaptersId.Add(_.Id);
return false;
}
});
Global.Adapter.Address = adapter.GetIPProperties().UnicastAddresses.First(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork).Address;
Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop);
Logging.Info($"出口 IPv4 地址:{Global.Adapter.Address}");
Logging.Info($"出口 网关 地址:{Global.Adapter.Gateway}");
Logging.Info($"出口适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.Adapter.Index}");
}
catch (InvalidOperationException)
catch (Exception e)
{
Logging.Error($"找不到 IP Index 为 {Global.Adapter.Index} 的出口适配器: {e.Message}");
PrintAdapters();
return false;
}
// 根据 ComponentID 寻找 Tap适配器
try
{
var adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ => _.Id == Global.TUNTAP.ComponentID);
Global.TUNTAP.Adapter = adapter;
Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index;
Logging.Info($"TAP 适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.TUNTAP.Index}");
}
catch (Exception e)
{
var msg = e switch
{
InvalidOperationException _ => $"找不到标识符为 {Global.TUNTAP.ComponentID} 的 TAP 适配器: {e.Message}",
NetworkInformationException _ => $"获取 Tap 适配器信息错误: {e.Message}",
_ => $"Tap 适配器其他异常: {e}"
};
Logging.Error(msg);
PrintAdapters();
return false;
}
return true;
void PrintAdapters()
{
// 理论上如果得到了网络接口的索引/网络适配器的标识符不会找不到网卡
// 只是异常处理
Logging.Info("所有适配器:\n" +
NetworkInterface.GetAllNetworkInterfaces().Aggregate(string.Empty, (current, adapter)
=> current + $"{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.TUNTAP.Index}{Global.EOF}"));
return false;
}
catch (NetworkInformationException e)
{
if (e.ErrorCode == 10043)
MessageBoxX.Show("适配器未开启IPv4协议", LogLevel.ERROR, owner: Global.MainForm);
return false;
=> current + $"{ /*如果加了 * 代表遍历中出现异常的适配器 */(errorAdaptersId.Contains(adapter.Id) ? "*" : "")}{adapter.Name} {adapter.Id} {adapter.Description}{Global.EOF}"));
}
}