refactor: SetupRouteTable() rules creation order

fix: #397
This commit is contained in:
ChsBuffer
2020-10-13 09:07:54 +08:00
parent 72b094e641
commit 3f902a2d3d
2 changed files with 96 additions and 86 deletions

View File

@@ -19,10 +19,6 @@ namespace Netch.Controllers
{
public bool TestNatRequired { get; } = true;
// ByPassLan IP
private readonly List<string> _bypassLanIPs = new List<string>
{"10.0.0.0/8", "172.16.0.0/16", "192.168.0.0/16"};
private Mode _savedMode = new Mode();
private Server _savedServer = new Server();
@@ -127,85 +123,87 @@ namespace Netch.Controllers
private void SetupRouteTable()
{
Global.MainForm.StatusText(i18N.Translate("SetupBypass"));
Logging.Info("设置路由规则");
Logging.Info("绕行 → 全局绕过 IP");
_directIPs.AddRange(Global.Settings.BypassIPs.Select(IPNetwork.Parse));
#region Rule IPs
Logging.Info("绕行 → 服务器 IP");
if (!IPAddress.IsLoopback(_serverAddresses))
_directIPs.Add(IPNetwork.Parse(_serverAddresses.ToString(), 32));
Logging.Info("绕行 → 局域网 IP");
_directIPs.AddRange(_bypassLanIPs.Select(IPNetwork.Parse));
switch (_savedMode.Type)
if (_savedMode.Type == 1)
{
case 1:
// 代理规则
Logging.Info("代理 → 规则 IP");
_proxyIPs.AddRange(_savedMode.FullRule.Select(IPNetwork.Parse));
// 代理规则
Logging.Info("代理 → 规则 IP");
RouteAction(Action.Create, _savedMode.FullRule.Select(IPNetwork.Parse), RouteType.TUNTAP);
//处理 NAT 类型检测,由于协议的原因,无法仅通过域名确定需要代理的 IP自己记录解析了返回的 IP仅支持默认检测服务器
if (Global.Settings.STUN_Server == "stun.stunprotocol.org")
try
{
Logging.Info("代理 → STUN 服务器 IP");
_proxyIPs.AddRange(new[]
//处理 NAT 类型检测,由于协议的原因,无法仅通过域名确定需要代理的 IP自己记录解析了返回的 IP仅支持默认检测服务器
if (Global.Settings.STUN_Server == "stun.stunprotocol.org")
{
try
{
Logging.Info("代理 → STUN 服务器 IP");
RouteAction(Action.Create,
new[]
{
Dns.GetHostAddresses(Global.Settings.STUN_Server)[0],
Dns.GetHostAddresses("stunresponse.coldthunder11.com")[0]
}.Select(ip => IPNetwork.Parse(ip.ToString(), 32)));
}
catch
{
Logging.Info("NAT 类型测试域名解析失败,将不会被添加到代理列表");
}
if (Global.Settings.TUNTAP.ProxyDNS)
{
Logging.Info("代理 → 自定义 DNS");
if (Global.Settings.TUNTAP.UseCustomDNS)
{
_proxyIPs.AddRange(Global.Settings.TUNTAP.DNS.Select(ip => IPNetwork.Parse(ip, 32)));
}
else
{
_proxyIPs.AddRange(new[] {"1.1.1.1", "8.8.8.8", "9.9.9.9", "185.222.222.222"}.Select(ip => IPNetwork.Parse(ip, 32)));
}
}.Select(ip => IPNetwork.Parse(ip.ToString(), 32)),
RouteType.TUNTAP);
}
break;
case 2:
// 绕过规则
// 将 TUN/TAP 网卡权重放到最高
Process.Start(new ProcessStartInfo
{
FileName = "netsh",
Arguments = $"interface ip set interface {Global.TUNTAP.Index} metric=0",
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = true,
CreateNoWindow = true
}
);
Logging.Info("绕行 → 规则 IP");
_directIPs.AddRange(_savedMode.FullRule.Select(IPNetwork.Parse));
Logging.Info("代理 → 全局");
if (!RouteAction(Action.Create, IPNetwork.Parse("0.0.0.0", 0), RouteType.TUNTAP))
catch
{
State = State.Stopped;
return;
Logging.Info("NAT 类型测试域名解析失败,将不会被添加到代理列表");
}
}
break;
if (Global.Settings.TUNTAP.ProxyDNS)
{
Logging.Info("代理 → 自定义 DNS");
if (Global.Settings.TUNTAP.UseCustomDNS)
{
RouteAction(Action.Create,
Global.Settings.TUNTAP.DNS.Select(ip => IPNetwork.Parse(ip, 32)),
RouteType.TUNTAP);
}
else
{
RouteAction(Action.Create,
new[] {"1.1.1.1", "8.8.8.8", "9.9.9.9", "185.222.222.222"}.Select(ip => IPNetwork.Parse(ip, 32)),
RouteType.TUNTAP);
}
}
}
else if (_savedMode.Type == 2)
{
// 绕过规则
// 将 TUN/TAP 网卡权重放到最高
Process.Start(new ProcessStartInfo
{
FileName = "netsh",
Arguments = $"interface ip set interface {Global.TUNTAP.Index} metric=0",
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = true,
CreateNoWindow = true
}
);
Logging.Info("绕行 → 规则 IP");
RouteAction(Action.Create, _savedMode.FullRule.Select(IPNetwork.Parse), RouteType.Outbound);
}
Logging.Info("设置路由规则");
RouteAction(Action.Create, _directIPs, RouteType.Outbound);
RouteAction(Action.Create, _proxyIPs, RouteType.TUNTAP);
#endregion
Logging.Info("绕行 → 服务器 IP");
if (!IPAddress.IsLoopback(_serverAddresses))
RouteAction(Action.Create, IPNetwork.Parse(_serverAddresses.ToString(), 32), RouteType.Outbound);
Logging.Info("绕行 → 全局绕过 IP");
RouteAction(Action.Create, Global.Settings.BypassIPs.Select(IPNetwork.Parse), RouteType.Outbound);
if (_savedMode.Type == 2)
{
// 绕过规则
Logging.Info("代理 → 全局");
RouteAction(Action.Create, IPNetwork.Parse("0.0.0.0", 0), RouteType.TUNTAP);
}
}
@@ -214,13 +212,9 @@ namespace Netch.Controllers
/// </summary>
private bool ClearRouteTable()
{
switch (_savedMode.Type)
if (_savedMode.Type == 2)
{
case 1:
break;
case 2:
RouteAction(Action.Delete, IPNetwork.Parse("0.0.0.0", 0), RouteType.TUNTAP, 10);
break;
RouteAction(Action.Delete, IPNetwork.Parse("0.0.0.0", 0), RouteType.TUNTAP);
}
RouteAction(Action.Delete, _directIPs, RouteType.Outbound);
@@ -333,7 +327,7 @@ namespace Netch.Controllers
Delete
}
private static void RouteAction(Action action, IEnumerable<IPNetwork> ipNetworks, RouteType routeType,
private void RouteAction(Action action, IEnumerable<IPNetwork> ipNetworks, RouteType routeType,
int metric = 0)
{
foreach (var address in ipNetworks)
@@ -342,7 +336,7 @@ namespace Netch.Controllers
}
}
private static bool RouteAction(Action action, IPNetwork ipNetwork, RouteType routeType, int metric = 0)
private bool RouteAction(Action action, IPNetwork ipNetwork, RouteType routeType, int metric = 0)
{
string gateway;
int index;
@@ -360,14 +354,30 @@ namespace Netch.Controllers
throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null);
}
var result = action switch
bool result;
switch (action)
{
Action.Create => NativeMethods.CreateRoute(ipNetwork.Network.ToString(), ipNetwork.Cidr, gateway, index,
metric),
Action.Delete => NativeMethods.DeleteRoute(ipNetwork.Network.ToString(), ipNetwork.Cidr, gateway, index,
metric),
_ => throw new ArgumentOutOfRangeException(nameof(action), action, null)
};
case Action.Create:
{
result = NativeMethods.CreateRoute(ipNetwork.Network.ToString(), ipNetwork.Cidr, gateway, index, metric);
switch (routeType)
{
case RouteType.Outbound:
_directIPs.Add(ipNetwork);
break;
case RouteType.TUNTAP:
_proxyIPs.Add(ipNetwork);
break;
}
break;
}
case Action.Delete:
result = NativeMethods.DeleteRoute(ipNetwork.Network.ToString(), ipNetwork.Cidr, gateway, index, metric);
break;
default:
throw new ArgumentOutOfRangeException(nameof(action), action, null);
}
if (!result)
{

2
modes

Submodule modes updated: 034c8583ad...3ac9f3c380