mirror of
https://github.com/netchx/netch.git
synced 2026-05-07 22:44:03 +08:00
基本完成重构 Controller
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Netch.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
@@ -9,9 +8,10 @@ namespace Netch.Controllers
|
||||
{
|
||||
public DNSController()
|
||||
{
|
||||
MainName = "unbound";
|
||||
AkaName = "dns Service";
|
||||
MainFile = "unbound";
|
||||
ExtFiles = new[] {"unbound-service.conf", "forward-zone.conf"};
|
||||
ready = BeforeStartProgress();
|
||||
InitCheck();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -20,33 +20,36 @@ namespace Netch.Controllers
|
||||
/// <returns></returns>
|
||||
public bool Start()
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting dns Service"));
|
||||
if (!Ready) return false;
|
||||
|
||||
Instance = GetProcess("bin\\unbound.exe");
|
||||
Instance.StartInfo.Arguments = "-c unbound-service.conf -v";
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
try
|
||||
{
|
||||
Instance = MainController.GetProcess("bin\\unbound.exe");
|
||||
|
||||
Instance.StartInfo.Arguments = "-c unbound-service.conf -v";
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
Logging.Info("dns-unbound 启动完毕");
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info("dns-unbound 进程出错");
|
||||
Stop();
|
||||
Logging.Error("dns-unbound 进程出错:\n" + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
WriteLog(e);
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,12 @@ using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class SSController : ServerClient
|
||||
public class SSController : EncryptedProxy
|
||||
{
|
||||
public SSController()
|
||||
{
|
||||
MainName = "Shadowsocks";
|
||||
ready = BeforeStartProgress();
|
||||
MainFile = "Shadowsocks";
|
||||
InitCheck();
|
||||
}
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
@@ -27,7 +27,7 @@ namespace Netch.Controllers
|
||||
if (!NativeMethods.Shadowsocks.Info(client, remote, passwd, method))
|
||||
{
|
||||
State = State.Stopped;
|
||||
Logging.Info("DLL SS INFO 设置失败!");
|
||||
Logging.Error("DLL SS INFO 设置失败!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Netch.Controllers
|
||||
if (!NativeMethods.Shadowsocks.Start())
|
||||
{
|
||||
State = State.Stopped;
|
||||
Logging.Info("DLL SS 启动失败!");
|
||||
Logging.Error("DLL SS 启动失败!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -45,18 +45,13 @@ namespace Netch.Controllers
|
||||
return true;
|
||||
}
|
||||
|
||||
Instance = MainController.GetProcess("bin\\Shadowsocks.exe");
|
||||
|
||||
#region Instance.Arguments
|
||||
if (!Ready) return false;
|
||||
Instance = GetProcess("bin\\Shadowsocks.exe");
|
||||
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -m {server.EncryptMethod} -k \"{server.Password}\" -u";
|
||||
if (!string.IsNullOrWhiteSpace(server.Plugin) && !string.IsNullOrWhiteSpace(server.PluginOption))
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -m {server.EncryptMethod} -k \"{server.Password}\" -u --plugin {server.Plugin} --plugin-opts \"{server.PluginOption}\"";
|
||||
else
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -m {server.EncryptMethod} -k \"{server.Password}\" -u";
|
||||
Instance.StartInfo.Arguments += $" --plugin {server.Plugin} --plugin-opts \"{server.PluginOption}\"";
|
||||
if (mode.BypassChina) Instance.StartInfo.Arguments += " --acl default.acl";
|
||||
|
||||
#endregion
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
@@ -64,6 +59,7 @@ namespace Netch.Controllers
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
@@ -72,14 +68,14 @@ namespace Netch.Controllers
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
Logging.Info("SS 进程启动失败");
|
||||
Logging.Error("SS 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Info("SS 进程启动超时");
|
||||
Logging.Error("SS 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
@@ -87,10 +83,11 @@ namespace Netch.Controllers
|
||||
/// <summary>
|
||||
/// SSController 停止
|
||||
/// </summary>
|
||||
public new void Stop()
|
||||
public override void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
if (Global.Settings.BootShadowsocksFromDLL) NativeMethods.Shadowsocks.Stop();
|
||||
else
|
||||
StopInstance();
|
||||
}
|
||||
|
||||
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
@@ -5,23 +5,23 @@ using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class SSRController : ServerClient
|
||||
public class SSRController : EncryptedProxy
|
||||
{
|
||||
public SSRController()
|
||||
{
|
||||
MainName = "ShadowsocksR";
|
||||
ready = BeforeStartProgress();
|
||||
MainFile = "ShadowsocksR";
|
||||
InitCheck();
|
||||
}
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
Instance = MainController.GetProcess("bin\\ShadowsocksR.exe");
|
||||
if (!Ready) return false;
|
||||
|
||||
Instance = GetProcess("bin\\ShadowsocksR.exe");
|
||||
Instance.StartInfo.FileName = "bin\\ShadowsocksR.exe";
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
#region Instance.Arguments
|
||||
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -k \"{server.Password}\" -m {server.EncryptMethod} -t 120";
|
||||
|
||||
if (!string.IsNullOrEmpty(server.Protocol))
|
||||
@@ -42,8 +42,6 @@ namespace Netch.Controllers
|
||||
|
||||
if (mode.BypassChina) Instance.StartInfo.Arguments += " --acl default.acl";
|
||||
|
||||
#endregion
|
||||
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
@@ -57,14 +55,14 @@ namespace Netch.Controllers
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
Logging.Info("SSR 进程启动失败");
|
||||
Logging.Error("SSR 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Info("SSR 进程启动超时");
|
||||
Logging.Error("SSR 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
@@ -81,5 +79,10 @@ namespace Netch.Controllers
|
||||
else if (e.Data.Contains("Invalid config path") || e.Data.Contains("usage")) State = State.Stopped;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,24 +2,23 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Netch.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TrojanController : ServerClient
|
||||
public class TrojanController : EncryptedProxy
|
||||
{
|
||||
public TrojanController()
|
||||
{
|
||||
MainName = "Trojan";
|
||||
ready = BeforeStartProgress();
|
||||
MainFile = "Trojan";
|
||||
InitCheck();
|
||||
}
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting Trojan"));
|
||||
if (!Ready) return false;
|
||||
|
||||
File.WriteAllText("data\\last.json", JsonConvert.SerializeObject(new Trojan
|
||||
{
|
||||
@@ -33,7 +32,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
}));
|
||||
|
||||
Instance = MainController.GetProcess("bin\\Trojan.exe");
|
||||
Instance = GetProcess("bin\\Trojan.exe");
|
||||
Instance.StartInfo.Arguments = "-c ..\\data\\last.json";
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
@@ -50,14 +49,14 @@ namespace Netch.Controllers
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
Logging.Info("Trojan 进程启动失败");
|
||||
Logging.Error("Trojan 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Info("Trojan 进程启动超时");
|
||||
Logging.Error("Trojan 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
@@ -74,5 +73,10 @@ namespace Netch.Controllers
|
||||
else if (e.Data.Contains("exiting")) State = State.Stopped;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,16 +9,17 @@ using VMess = Netch.Models.Information.VMess;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class VMessController : ServerClient
|
||||
public class VMessController : EncryptedProxy
|
||||
{
|
||||
public VMessController()
|
||||
{
|
||||
MainName = "v2ray";
|
||||
ready = BeforeStartProgress();
|
||||
MainFile = "v2ray";
|
||||
InitCheck();
|
||||
}
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
if (!Ready) return false;
|
||||
File.WriteAllText("data\\last.json", JsonConvert.SerializeObject(new VMess.Config
|
||||
{
|
||||
inbounds = new List<VMess.Inbounds>
|
||||
@@ -167,7 +168,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
}));
|
||||
|
||||
Instance = MainController.GetProcess("bin\\v2ray.exe");
|
||||
Instance = GetProcess("bin\\v2ray.exe");
|
||||
Instance.StartInfo.Arguments = "-config ..\\data\\last.json";
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
@@ -190,14 +191,14 @@ namespace Netch.Controllers
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
Logging.Info("V2Ray 进程启动失败");
|
||||
Logging.Error("V2Ray 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Info("V2Ray 进程启动超时");
|
||||
Logging.Error("V2Ray 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
@@ -214,5 +215,10 @@ namespace Netch.Controllers
|
||||
else if (e.Data.Contains("config file not readable") || e.Data.Contains("failed to")) State = State.Stopped;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,18 @@ using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class Controller
|
||||
public abstract class Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 控制器名
|
||||
/// <param />
|
||||
/// 未赋值会在 <see cref="InitCheck" /> 赋值为 <see cref="MainFile" />
|
||||
/// </summary>
|
||||
public string AkaName;
|
||||
|
||||
/// <summary>
|
||||
/// 其他需要文件
|
||||
/// </summary>
|
||||
protected string[] ExtFiles;
|
||||
|
||||
/// <summary>
|
||||
@@ -16,21 +26,26 @@ namespace Netch.Controllers
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 程序名
|
||||
/// 主程序名(不含扩展名)
|
||||
/// </summary>
|
||||
public string MainName;
|
||||
public string MainFile;
|
||||
|
||||
public bool ready;
|
||||
/// <summary>
|
||||
/// 运行检查, 由 <see cref="InitCheck()" /> 赋值
|
||||
/// </summary>
|
||||
public bool Ready;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
protected State State = State.Waiting;
|
||||
|
||||
public abstract void Stop();
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
protected void StopInstance()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -40,7 +55,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
Logging.Error($"停止 {MainFile}.exe 错误:\n" + e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,53 +64,87 @@ namespace Netch.Controllers
|
||||
/// 杀残留进程,清除日志,检查文件
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected bool BeforeStartProgress()
|
||||
protected void InitCheck()
|
||||
{
|
||||
if (string.IsNullOrEmpty(AkaName)) AkaName = MainFile;
|
||||
|
||||
var result = false;
|
||||
// 杀残留
|
||||
MainController.KillProcessByName(MainName);
|
||||
MainController.KillProcessByName(MainFile);
|
||||
// 清日志
|
||||
try
|
||||
{
|
||||
if (File.Exists($"logging\\{MainName}.log")) File.Delete($"logging\\{MainName}.log");
|
||||
if (File.Exists($"logging\\{AkaName}.log")) File.Delete($"logging\\{AkaName}.log");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore
|
||||
// ignored
|
||||
}
|
||||
|
||||
// 检查文件
|
||||
if (!File.Exists($"bin\\{MainName}.exe")) Logging.Info($"bin\\{MainName}.exe 文件不存在");
|
||||
var mainResult = true;
|
||||
var extResult = true;
|
||||
if (!string.IsNullOrEmpty(MainFile) && !File.Exists($"bin\\{MainFile}.exe"))
|
||||
{
|
||||
mainResult = false;
|
||||
Logging.Error($"主程序 bin\\{MainFile}.exe 不存在");
|
||||
}
|
||||
|
||||
if (ExtFiles == null)
|
||||
result = true;
|
||||
extResult = true;
|
||||
else
|
||||
foreach (var f in ExtFiles)
|
||||
if (!File.Exists($"bin\\{f}"))
|
||||
Logging.Info($"bin\\{f}.exe 文件不存在");
|
||||
{
|
||||
extResult = false;
|
||||
Logging.Error($"附加文件 bin\\{f} 不存在");
|
||||
}
|
||||
|
||||
if (!ready) Logging.Info(MainName + "未能就绪");
|
||||
return result;
|
||||
result = extResult && mainResult;
|
||||
if (!result)
|
||||
Logging.Error(AkaName + " 未就绪");
|
||||
Ready = result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写日志
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns>e是否为空</returns>
|
||||
public bool WriteLog(DataReceivedEventArgs e)
|
||||
/// <param name="std"></param>
|
||||
/// <returns><see cref="std" />是否为空</returns>
|
||||
protected bool WriteLog(DataReceivedEventArgs std)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.Data)) return false;
|
||||
if (string.IsNullOrWhiteSpace(std.Data)) return false;
|
||||
try
|
||||
|
||||
{
|
||||
File.AppendAllText($"logging\\{MainName}.log", $@"{e.Data}{Global.EOF}");
|
||||
File.AppendAllText($"logging\\{AkaName}.log", $@"{std.Data}{Global.EOF}");
|
||||
}
|
||||
catch (Exception exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info($"写入{MainName}日志失败" + exception);
|
||||
Logging.Error($"写入{AkaName}日志错误:\n" + e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Process GetProcess(string path = null, bool redirectStd = true)
|
||||
{
|
||||
var p = new Process
|
||||
{
|
||||
StartInfo =
|
||||
{
|
||||
Arguments = "",
|
||||
WorkingDirectory = $"{Global.NetchDir}\\bin",
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardError = redirectStd,
|
||||
RedirectStandardInput = redirectStd,
|
||||
RedirectStandardOutput = redirectStd,
|
||||
UseShellExecute = false
|
||||
},
|
||||
EnableRaisingEvents = true
|
||||
};
|
||||
if (path != null) p.StartInfo.FileName = Path.GetFullPath(path);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Netch/Controllers/Interface/EncryptedProxy.cs
Normal file
18
Netch/Controllers/Interface/EncryptedProxy.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Diagnostics;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public abstract class EncryptedProxy : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public abstract bool Start(Server server, Mode mode);
|
||||
|
||||
public abstract void OnOutputDataReceived(object sender, DataReceivedEventArgs e);
|
||||
}
|
||||
}
|
||||
15
Netch/Controllers/Interface/ModeController.cs
Normal file
15
Netch/Controllers/Interface/ModeController.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public abstract class ModeController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否成功</returns>
|
||||
public abstract bool Start(Server server, Mode mode);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public abstract class ServerClient : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public abstract bool Start(Server server, Mode mode);
|
||||
|
||||
/// <summary>
|
||||
/// ServerClient 停止
|
||||
/// <param />
|
||||
/// 注意 对象类型 以调用子类 Stop() 方法
|
||||
/// </summary>
|
||||
public new void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
|
||||
// SSController Stop()
|
||||
// 不能自动转换对象类型的兼容代码 :(
|
||||
if (Global.Settings.BootShadowsocksFromDLL) NativeMethods.Shadowsocks.Stop();
|
||||
}
|
||||
|
||||
public abstract void OnOutputDataReceived(object sender, DataReceivedEventArgs e);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Forms;
|
||||
@@ -12,29 +11,15 @@ namespace Netch.Controllers
|
||||
{
|
||||
public class MainController
|
||||
{
|
||||
/// <summary>
|
||||
/// HTTP 控制器
|
||||
/// </summary>
|
||||
public HTTPController pHTTPController;
|
||||
public EncryptedProxy pEncryptedProxyController;
|
||||
|
||||
/// <summary>
|
||||
/// NF 控制器
|
||||
/// </summary>
|
||||
public NFController pNFController;
|
||||
public ModeController pModeController;
|
||||
|
||||
/// <summary>
|
||||
/// NTT 控制器
|
||||
/// </summary>
|
||||
public NTTController pNTTController;
|
||||
|
||||
public ServerClient pServerClientController;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// TUN/TAP 控制器
|
||||
/// </summary>
|
||||
public TUNTAPController pTUNTAPController;
|
||||
|
||||
[DllImport("dnsapi", EntryPoint = "DnsFlushResolverCache")]
|
||||
public static extern uint FlushDNSResolverCache();
|
||||
|
||||
@@ -46,6 +31,7 @@ namespace Netch.Controllers
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Server server, Mode mode)
|
||||
{
|
||||
pNTTController ??= new NTTController();
|
||||
FlushDNSResolverCache();
|
||||
|
||||
var result = false;
|
||||
@@ -58,61 +44,60 @@ namespace Netch.Controllers
|
||||
switch (server.Type)
|
||||
{
|
||||
case "SS":
|
||||
pServerClientController = new SSController();
|
||||
pEncryptedProxyController = new SSController();
|
||||
break;
|
||||
case "SSR":
|
||||
pServerClientController = new SSRController();
|
||||
pEncryptedProxyController = new SSRController();
|
||||
break;
|
||||
case "VMess":
|
||||
pServerClientController = new VMessController();
|
||||
pEncryptedProxyController = new VMessController();
|
||||
break;
|
||||
case "Trojan":
|
||||
pServerClientController = new TrojanController();
|
||||
pEncryptedProxyController = new TrojanController();
|
||||
break;
|
||||
}
|
||||
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting ", pServerClientController.MainName));
|
||||
if (pServerClientController.ready) result = pServerClientController.Start(server, mode);
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting ", pEncryptedProxyController.AkaName));
|
||||
if (pEncryptedProxyController.Ready) result = pEncryptedProxyController.Start(server, mode);
|
||||
}
|
||||
|
||||
if (result) // If server runs,then run mode
|
||||
if (result)
|
||||
{
|
||||
// 加密代理已启动
|
||||
switch (mode.Type)
|
||||
{
|
||||
case 0: // 进程代理模式
|
||||
pNFController ??= new NFController();
|
||||
pNTTController ??= new NTTController();
|
||||
if (pNFController.ready) result = pNFController.Start(server, mode, false);
|
||||
|
||||
if (!result && pNFController.ready)
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Restarting Redirector"));
|
||||
Logging.Info("正常启动失败后尝试停止驱动服务再重新启动");
|
||||
//正常启动失败后尝试停止驱动服务再重新启动
|
||||
result = pNFController.Start(server, mode, true);
|
||||
}
|
||||
|
||||
if (result)
|
||||
Task.Run(() => pNTTController.Start());
|
||||
pModeController = new NFController();
|
||||
break;
|
||||
case 1: // TUN/TAP 黑名单代理模式
|
||||
case 2: // TUN/TAP 白名单代理模式
|
||||
pTUNTAPController ??= new TUNTAPController();
|
||||
pNTTController ??= new NTTController();
|
||||
result = pTUNTAPController.Start(server, mode);
|
||||
pModeController = new TUNTAPController();
|
||||
break;
|
||||
case 3:
|
||||
case 5:
|
||||
pModeController = new HTTPController();
|
||||
break;
|
||||
case 4: // Socks5 代理模式,不需要启动额外的Server
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pModeController != null && pModeController.Ready)
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting ", pModeController.AkaName));
|
||||
result = pModeController.Start(server, mode);
|
||||
}
|
||||
|
||||
switch (mode.Type)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
if (result)
|
||||
Task.Run(() => pNTTController.Start());
|
||||
break;
|
||||
case 3: // HTTP 系统代理和 Socks5 和 HTTP 代理模式
|
||||
case 5:
|
||||
pHTTPController ??= new HTTPController();
|
||||
result = pHTTPController.Start(server, mode);
|
||||
break;
|
||||
case 4: // Socks5 代理模式,不需要启动额外的Server
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) Stop();
|
||||
|
||||
@@ -124,36 +109,8 @@ namespace Netch.Controllers
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
pServerClientController?.Stop();
|
||||
|
||||
if (pNFController != null)
|
||||
pNFController.Stop();
|
||||
else if (pTUNTAPController != null)
|
||||
pTUNTAPController.Stop();
|
||||
else
|
||||
pHTTPController?.Stop();
|
||||
|
||||
pNTTController?.Stop();
|
||||
}
|
||||
|
||||
public static Process GetProcess(string path = null)
|
||||
{
|
||||
var p = new Process
|
||||
{
|
||||
StartInfo =
|
||||
{
|
||||
Arguments = "",
|
||||
WorkingDirectory = $"{Global.NetchDir}\\bin",
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardError = true,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false
|
||||
},
|
||||
EnableRaisingEvents = true
|
||||
};
|
||||
if (path != null) p.StartInfo.FileName = Path.GetFullPath(path);
|
||||
return p;
|
||||
pEncryptedProxyController?.Stop();
|
||||
pModeController?.Stop();
|
||||
}
|
||||
|
||||
public static void KillProcessByName(string name)
|
||||
@@ -166,11 +123,11 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
Logging.Info($"结束进程 {name} 错误: " + e.Message);
|
||||
Logging.Error($"结束进程 {name} 错误:\n" + e);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class HTTPController
|
||||
public class HTTPController : ModeController
|
||||
{
|
||||
/// <summary>
|
||||
/// 实例
|
||||
@@ -17,14 +17,22 @@ namespace Netch.Controllers
|
||||
private string prevBypass, prevHTTP, prevPAC;
|
||||
private bool prevEnabled;
|
||||
|
||||
public HTTPController()
|
||||
{
|
||||
AkaName = "HTTP";
|
||||
Ready = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Server server, Mode mode)
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
if (!Ready) return false;
|
||||
|
||||
RecordPrevious();
|
||||
try
|
||||
{
|
||||
@@ -45,7 +53,7 @@ namespace Netch.Controllers
|
||||
{
|
||||
if (MessageBoxX.Show(i18N.Translate("Failed to set the system proxy, it may be caused by the lack of dependent programs. Do you want to jump to Netch's official website to download dependent programs?"), confirm: true) == DialogResult.OK) Process.Start("https://netch.org/#/?id=%e4%be%9d%e8%b5%96");
|
||||
|
||||
Logging.Info("设置系统代理失败" + e);
|
||||
Logging.Error("设置系统代理失败" + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -72,18 +80,11 @@ namespace Netch.Controllers
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
public override void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
pPrivoxyController.Stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
}
|
||||
pPrivoxyController.Stop();
|
||||
|
||||
NativeMethods.SetGlobal(prevHTTP, prevBypass);
|
||||
if (prevPAC != "")
|
||||
@@ -94,7 +95,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
Logging.Error("停止HTTP控制器错误:\n" + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
269
Netch/Controllers/Mode/NFController.cs
Normal file
269
Netch/Controllers/Mode/NFController.cs
Normal file
@@ -0,0 +1,269 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using nfapinet;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class NFController : ModeController
|
||||
{
|
||||
/// <summary>
|
||||
/// 流量变动处理器
|
||||
/// </summary>
|
||||
/// <param name="upload">上传</param>
|
||||
/// <param name="download">下载</param>
|
||||
public delegate void BandwidthUpdateHandler(long upload, long download);
|
||||
|
||||
private readonly string _binDriverPath;
|
||||
|
||||
private readonly string _driverPath = $"{Environment.SystemDirectory}\\drivers\\netfilter2.sys";
|
||||
private readonly ServiceController _service = new ServiceController("netfilter2");
|
||||
private string _systemDriverVersion;
|
||||
|
||||
public NFController()
|
||||
{
|
||||
MainFile = "Redirector";
|
||||
InitCheck();
|
||||
|
||||
// 驱动版本
|
||||
_systemDriverVersion = FileVersionInfo.GetVersionInfo(_driverPath).FileVersion;
|
||||
// 生成系统版本
|
||||
var winNTver = $"{Environment.OSVersion.Version.Major.ToString()}.{Environment.OSVersion.Version.Minor.ToString()}";
|
||||
var driverName = "";
|
||||
switch (winNTver)
|
||||
{
|
||||
case "10.0":
|
||||
driverName = "Win-10.sys";
|
||||
break;
|
||||
case "6.3":
|
||||
case "6.2":
|
||||
driverName = "Win-8.sys";
|
||||
break;
|
||||
case "6.1":
|
||||
case "6.0":
|
||||
driverName = "Win-7.sys";
|
||||
break;
|
||||
default:
|
||||
Logging.Error($"不支持的系统版本:{winNTver}");
|
||||
Ready = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_binDriverPath = "bin\\" + driverName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 流量变动事件
|
||||
/// </summary>
|
||||
public event BandwidthUpdateHandler OnBandwidthUpdated;
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
if (!CheckDriverReady())
|
||||
{
|
||||
if (File.Exists(_driverPath))
|
||||
UninstallDriver();
|
||||
if (!InstallDriver())
|
||||
return false;
|
||||
}
|
||||
|
||||
var processList = "";
|
||||
foreach (var proc in mode.Rule)
|
||||
processList += proc + ",";
|
||||
processList += "NTT.exe";
|
||||
|
||||
Instance = GetProcess("bin\\Redirector.exe");
|
||||
if (server.Type != "Socks5")
|
||||
{
|
||||
Instance.StartInfo.Arguments += $"-r 127.0.0.1:{Global.Settings.Socks5LocalPort} -p \"{processList}\"";
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
var result = DNS.Lookup(server.Hostname);
|
||||
if (result == null)
|
||||
{
|
||||
Logging.Info("无法解析服务器 IP 地址");
|
||||
return false;
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $"-r {result}:{server.Port} -p \"{processList}\"";
|
||||
if (!string.IsNullOrWhiteSpace(server.Username) && !string.IsNullOrWhiteSpace(server.Password)) Instance.StartInfo.Arguments += $" -username \"{server.Username}\" -password \"{server.Password}\"";
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $" -t {Global.Settings.RedirectorTCPPort}";
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
|
||||
for (var j = 0; j < 40; j++)
|
||||
{
|
||||
Thread.Sleep(250);
|
||||
|
||||
if (State == State.Started) return true;
|
||||
}
|
||||
|
||||
Logging.Error("NF 进程启动超时");
|
||||
Stop();
|
||||
if (!RestartService()) return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool RestartService()
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (_service.Status)
|
||||
{
|
||||
// 启动驱动服务
|
||||
case ServiceControllerStatus.Running:
|
||||
// 防止其他程序占用 重置 NF 百万连接数限制
|
||||
_service.Stop();
|
||||
_service.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting netfilter2 Service"));
|
||||
_service.Start();
|
||||
break;
|
||||
case ServiceControllerStatus.Stopped:
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting netfilter2 Service"));
|
||||
_service.Start();
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error("启动驱动服务失败:\n" + e);
|
||||
|
||||
var result = NFAPI.nf_registerDriver("netfilter2");
|
||||
if (result != NF_STATUS.NF_STATUS_SUCCESS)
|
||||
{
|
||||
Logging.Error($"注册驱动失败,返回值:{result}");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info("注册驱动成功");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CheckDriverReady()
|
||||
{
|
||||
// 检查驱动是否存在
|
||||
if (!File.Exists(_driverPath)) return false;
|
||||
|
||||
// 检查驱动版本号
|
||||
var binVersion = FileVersionInfo.GetVersionInfo(_binDriverPath).FileVersion;
|
||||
return _systemDriverVersion.Equals(binVersion);
|
||||
}
|
||||
|
||||
public bool UninstallDriver()
|
||||
{
|
||||
try
|
||||
{
|
||||
var service = new ServiceController("netfilter2");
|
||||
if (service.Status == ServiceControllerStatus.Running)
|
||||
{
|
||||
service.Stop();
|
||||
service.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (!File.Exists(_driverPath)) return true;
|
||||
try
|
||||
{
|
||||
NFAPI.nf_unRegisterDriver("netfilter2");
|
||||
|
||||
File.Delete(_driverPath);
|
||||
_systemDriverVersion = "";
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public bool InstallDriver()
|
||||
{
|
||||
if (!Ready) return false;
|
||||
Logging.Info("安装驱动中");
|
||||
try
|
||||
{
|
||||
File.Copy(_binDriverPath, _driverPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error("驱动复制失败\n" + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
MainForm.Instance.StatusText(i18N.Translate("Register driver"));
|
||||
// 注册驱动文件
|
||||
var result = NFAPI.nf_registerDriver("netfilter2");
|
||||
if (result == NF_STATUS.NF_STATUS_SUCCESS)
|
||||
{
|
||||
_systemDriverVersion = FileVersionInfo.GetVersionInfo(_driverPath).FileVersion;
|
||||
Logging.Info($"驱动安装成功,当前驱动版本:{_systemDriverVersion}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Error($"注册驱动失败,返回值:{result}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!WriteLog(e)) return;
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
State = State.Stopped;
|
||||
else if (e.Data.Contains("Started"))
|
||||
State = State.Started;
|
||||
else if (e.Data.Contains("Failed") || e.Data.Contains("Unable")) State = State.Stopped;
|
||||
}
|
||||
else if (State == State.Started)
|
||||
{
|
||||
if (e.Data.StartsWith("[APP][Bandwidth]"))
|
||||
{
|
||||
var splited = e.Data.Replace("[APP][Bandwidth]", "").Trim().Split(',');
|
||||
if (splited.Length == 2)
|
||||
{
|
||||
var uploadSplited = splited[0].Split(':');
|
||||
var downloadSplited = splited[1].Split(':');
|
||||
|
||||
if (uploadSplited.Length == 2 && downloadSplited.Length == 2)
|
||||
if (long.TryParse(uploadSplited[1], out var upload) && long.TryParse(downloadSplited[1], out var download))
|
||||
Task.Run(() => OnBandwidthUpdated(upload, download));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
@@ -11,32 +15,28 @@ using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TUNTAPController : Controller
|
||||
public class TUNTAPController : ModeController
|
||||
{
|
||||
// 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 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();
|
||||
|
||||
/// <summary>
|
||||
/// 服务器 IP 地址
|
||||
/// </summary>
|
||||
private IPAddress[] _serverAddresses = new IPAddress[0];
|
||||
|
||||
/// <summary>
|
||||
/// 本地 DNS 服务控制器
|
||||
/// </summary>
|
||||
public DNSController pDNSController = new DNSController();
|
||||
|
||||
public Mode SavedMode = new Mode();
|
||||
|
||||
/// <summary>
|
||||
/// 保存传入的规则
|
||||
/// </summary>
|
||||
public Server SavedServer = new Server();
|
||||
|
||||
/// <summary>
|
||||
/// 服务器 IP 地址
|
||||
/// </summary>
|
||||
public IPAddress[] ServerAddresses = new IPAddress[0];
|
||||
|
||||
public TUNTAPController()
|
||||
{
|
||||
MainName = "tun2socks";
|
||||
ready = BeforeStartProgress();
|
||||
MainFile = "tun2socks";
|
||||
InitCheck();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -45,16 +45,16 @@ namespace Netch.Controllers
|
||||
public bool Configure()
|
||||
{
|
||||
// 查询服务器 IP 地址
|
||||
var destination = Dns.GetHostAddressesAsync(SavedServer.Hostname);
|
||||
var destination = Dns.GetHostAddressesAsync(_savedServer.Hostname);
|
||||
if (destination.Wait(1000))
|
||||
{
|
||||
if (destination.Result.Length == 0) return false;
|
||||
|
||||
ServerAddresses = destination.Result;
|
||||
_serverAddresses = destination.Result;
|
||||
}
|
||||
|
||||
// 搜索出口
|
||||
return Configuration.SearchOutbounds();
|
||||
return SearchOutbounds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -65,12 +65,12 @@ namespace Netch.Controllers
|
||||
MainForm.Instance.StatusText(i18N.Translate("SetupBypass"));
|
||||
Logging.Info("设置绕行规则 → 设置让服务器 IP 走直连");
|
||||
// 让服务器 IP 走直连
|
||||
foreach (var address in ServerAddresses)
|
||||
foreach (var address in _serverAddresses)
|
||||
if (!IPAddress.IsLoopback(address))
|
||||
NativeMethods.CreateRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
|
||||
// 处理模式的绕过中国
|
||||
if (SavedMode.BypassChina)
|
||||
if (_savedMode.BypassChina)
|
||||
{
|
||||
Logging.Info("设置绕行规则 → 处理模式的绕过中国");
|
||||
using (var sr = new StringReader(Encoding.UTF8.GetString(Resources.CNIP)))
|
||||
@@ -98,7 +98,7 @@ namespace Netch.Controllers
|
||||
|
||||
Logging.Info("设置绕行规则 → 处理绕过局域网 IP");
|
||||
// 处理绕过局域网 IP
|
||||
foreach (var ip in BypassLanIPs)
|
||||
foreach (var ip in _bypassLanIPs)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
var address = IPAddress.Parse(info[0]);
|
||||
@@ -106,7 +106,7 @@ namespace Netch.Controllers
|
||||
if (!IPAddress.IsLoopback(address)) NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
|
||||
if (SavedMode.Type == 2) // 处理仅规则内走直连
|
||||
if (_savedMode.Type == 2) // 处理仅规则内走直连
|
||||
{
|
||||
Logging.Info("设置绕行规则 → 处理仅规则内走直连");
|
||||
// 将 TUN/TAP 网卡权重放到最高
|
||||
@@ -129,14 +129,14 @@ namespace Netch.Controllers
|
||||
{
|
||||
State = State.Stopped;
|
||||
|
||||
foreach (var address in ServerAddresses) NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
foreach (var address in _serverAddresses) NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info("设置绕行规则 → 创建规则路由");
|
||||
// 创建规则路由
|
||||
foreach (var ip in SavedMode.Rule)
|
||||
foreach (var ip in _savedMode.Rule)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
|
||||
@@ -145,10 +145,10 @@ namespace Netch.Controllers
|
||||
NativeMethods.CreateRoute(info[0], prefix, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
}
|
||||
else if (SavedMode.Type == 1) // 处理仅规则内走代理
|
||||
else if (_savedMode.Type == 1) // 处理仅规则内走代理
|
||||
{
|
||||
Logging.Info("设置绕行规则->处理仅规则内走代理");
|
||||
foreach (var ip in SavedMode.Rule)
|
||||
foreach (var ip in _savedMode.Rule)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
|
||||
@@ -211,11 +211,11 @@ namespace Netch.Controllers
|
||||
/// </summary>
|
||||
public bool ClearBypass()
|
||||
{
|
||||
if (SavedMode.Type == 2)
|
||||
if (_savedMode.Type == 2)
|
||||
{
|
||||
NativeMethods.DeleteRoute("0.0.0.0", 0, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index, 10);
|
||||
|
||||
foreach (var ip in SavedMode.Rule)
|
||||
foreach (var ip in _savedMode.Rule)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
|
||||
@@ -224,9 +224,9 @@ namespace Netch.Controllers
|
||||
NativeMethods.DeleteRoute(info[0], prefix, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
}
|
||||
else if (SavedMode.Type == 1)
|
||||
else if (_savedMode.Type == 1)
|
||||
{
|
||||
foreach (var ip in SavedMode.Rule)
|
||||
foreach (var ip in _savedMode.Rule)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
|
||||
@@ -278,7 +278,7 @@ namespace Netch.Controllers
|
||||
if (!IPAddress.IsLoopback(address)) NativeMethods.DeleteRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
|
||||
foreach (var ip in BypassLanIPs)
|
||||
foreach (var ip in _bypassLanIPs)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
var address = IPAddress.Parse(info[0]);
|
||||
@@ -286,7 +286,7 @@ namespace Netch.Controllers
|
||||
if (!IPAddress.IsLoopback(address)) NativeMethods.DeleteRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
|
||||
if (SavedMode.BypassChina)
|
||||
if (_savedMode.BypassChina)
|
||||
using (var sr = new StringReader(Encoding.UTF8.GetString(Resources.CNIP)))
|
||||
{
|
||||
string text;
|
||||
@@ -299,24 +299,21 @@ namespace Netch.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var address in ServerAddresses)
|
||||
foreach (var address in _serverAddresses)
|
||||
if (!IPAddress.IsLoopback(address))
|
||||
NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">配置</param>
|
||||
/// <returns>是否成功</returns>
|
||||
public bool Start(Server server, Mode mode)
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
if (!Ready) return false;
|
||||
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting Tap"));
|
||||
|
||||
SavedMode = mode;
|
||||
SavedServer = server;
|
||||
_savedMode = mode;
|
||||
_savedServer = server;
|
||||
|
||||
if (!Configure()) return false;
|
||||
|
||||
@@ -324,7 +321,7 @@ namespace Netch.Controllers
|
||||
SetupBypass();
|
||||
Logging.Info("设置绕行规则完毕");
|
||||
|
||||
Instance = MainController.GetProcess("bin\\tun2socks.exe");
|
||||
Instance = GetProcess("bin\\tun2socks.exe");
|
||||
|
||||
var adapterName = TUNTAP.GetName(Global.TUNTAP.ComponentID);
|
||||
Logging.Info($"tun2sock使用适配器:{adapterName}");
|
||||
@@ -353,15 +350,13 @@ namespace Netch.Controllers
|
||||
if (Global.Settings.TUNTAP.UseFakeDNS) dns += " -fakeDns";
|
||||
|
||||
if (server.Type == "Socks5")
|
||||
Instance.StartInfo.Arguments = string.Format("-proxyServer {0}:{1} -tunAddr {2} -tunMask {3} -tunGw {4} -tunDns {5} -tunName \"{6}\"", server.Hostname, server.Port, Global.Settings.TUNTAP.Address, Global.Settings.TUNTAP.Netmask, Global.Settings.TUNTAP.Gateway, dns, adapterName);
|
||||
Instance.StartInfo.Arguments = $"-proxyServer {server.Hostname}:{server.Port} -tunAddr {Global.Settings.TUNTAP.Address} -tunMask {Global.Settings.TUNTAP.Netmask} -tunGw {Global.Settings.TUNTAP.Gateway} -tunDns {dns} -tunName \"{adapterName}\"";
|
||||
else
|
||||
Instance.StartInfo.Arguments = string.Format("-proxyServer 127.0.0.1:{0} -tunAddr {1} -tunMask {2} -tunGw {3} -tunDns {4} -tunName \"{5}\"", Global.Settings.Socks5LocalPort, Global.Settings.TUNTAP.Address, Global.Settings.TUNTAP.Netmask, Global.Settings.TUNTAP.Gateway, dns, adapterName);
|
||||
Instance.StartInfo.Arguments = $"-proxyServer 127.0.0.1:{Global.Settings.Socks5LocalPort} -tunAddr {Global.Settings.TUNTAP.Address} -tunMask {Global.Settings.TUNTAP.Netmask} -tunGw {Global.Settings.TUNTAP.Gateway} -tunDns {dns} -tunName \"{adapterName}\"";
|
||||
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
|
||||
Logging.Info(Instance.StartInfo.Arguments);
|
||||
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginErrorReadLine();
|
||||
@@ -387,14 +382,14 @@ namespace Netch.Controllers
|
||||
/// <summary>
|
||||
/// TUN/TAP停止
|
||||
/// </summary>
|
||||
public new void Stop()
|
||||
public override void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
StopInstance();
|
||||
ClearBypass();
|
||||
pDNSController.Stop();
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!WriteLog(e)) return;
|
||||
if (State == State.Starting)
|
||||
@@ -404,5 +399,113 @@ namespace Netch.Controllers
|
||||
else if (e.Data.Contains("failed") || e.Data.Contains("invalid vconfig file")) State = State.Stopped;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 搜索出口
|
||||
/// </summary>
|
||||
public static bool SearchOutbounds()
|
||||
{
|
||||
Logging.Info("正在搜索出口中");
|
||||
|
||||
if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0)
|
||||
{
|
||||
Global.Adapter.Index = pRoute.dwForwardIfIndex;
|
||||
Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop);
|
||||
Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Error("GetBestRoute 搜索失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info($"搜索适配器index:{Global.Adapter.Index}");
|
||||
var AddressGot = false;
|
||||
foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
|
||||
try
|
||||
{
|
||||
var adapterProperties = adapter.GetIPProperties();
|
||||
var p = adapterProperties.GetIPv4Properties();
|
||||
Logging.Info($"检测适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {p.Index}");
|
||||
|
||||
// 通过索引查找对应适配器的 IPv4 地址
|
||||
if (p.Index == Global.Adapter.Index)
|
||||
{
|
||||
var AdapterIPs = "";
|
||||
|
||||
foreach (var ip in adapterProperties.UnicastAddresses)
|
||||
{
|
||||
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
AddressGot = true;
|
||||
Global.Adapter.Address = ip.Address;
|
||||
Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}");
|
||||
break;
|
||||
}
|
||||
|
||||
AdapterIPs = $"{ip.Address} | ";
|
||||
}
|
||||
|
||||
if (!AddressGot)
|
||||
{
|
||||
if (AdapterIPs.Length > 3)
|
||||
{
|
||||
AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3);
|
||||
Logging.Info($"所有出口地址:{AdapterIPs}");
|
||||
}
|
||||
|
||||
Logging.Error("出口无 IPv4 地址,当前只支持 IPv4 地址");
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (!AddressGot)
|
||||
{
|
||||
Logging.Error("无法找到当前使用适配器");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 搜索 TUN/TAP 适配器的索引
|
||||
Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
|
||||
if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID))
|
||||
{
|
||||
Logging.Error("未找到可用 TUN/TAP 适配器");
|
||||
if (MessageBoxX.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), confirm: true) == DialogResult.OK)
|
||||
{
|
||||
Configuration.addtap();
|
||||
//给点时间,不然立马安装完毕就查找适配器可能会导致找不到适配器ID
|
||||
Thread.Sleep(1000);
|
||||
Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//MessageBoxX.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually"));
|
||||
// return false;
|
||||
}
|
||||
|
||||
foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
|
||||
if (adapter.Id == Global.TUNTAP.ComponentID)
|
||||
{
|
||||
Global.TUNTAP.Adapter = adapter;
|
||||
Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index;
|
||||
|
||||
Logging.Info($"找到适配器TUN/TAP:{adapter.Id}");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Logging.Error("无法找到出口");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,269 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using nfapinet;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class NFController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 流量变动处理器
|
||||
/// </summary>
|
||||
/// <param name="upload">上传</param>
|
||||
/// <param name="download">下载</param>
|
||||
public delegate void BandwidthUpdateHandler(long upload, long download);
|
||||
|
||||
/// 驱动文件路径
|
||||
private readonly string _driverPath = $"{Environment.SystemDirectory}\\drivers\\netfilter2.sys";
|
||||
|
||||
public NFController()
|
||||
{
|
||||
MainName = "Redirector";
|
||||
ready = BeforeStartProgress();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 流量变动事件
|
||||
/// </summary>
|
||||
public event BandwidthUpdateHandler OnBandwidthUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <param name="StopServiceAndRestart">先停止驱动服务再重新启动</param>
|
||||
/// <returns>是否成功</returns>
|
||||
public bool Start(Server server, Mode mode, bool StopServiceAndRestart)
|
||||
{
|
||||
if (!StopServiceAndRestart)
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting Redirector"));
|
||||
|
||||
// 检查驱动是否存在
|
||||
if (File.Exists(_driverPath))
|
||||
{
|
||||
// 生成系统版本
|
||||
var version = $"{Environment.OSVersion.Version.Major.ToString()}.{Environment.OSVersion.Version.Minor.ToString()}";
|
||||
var driverName = "";
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case "10.0":
|
||||
driverName = "Win-10.sys";
|
||||
break;
|
||||
case "6.3":
|
||||
case "6.2":
|
||||
driverName = "Win-8.sys";
|
||||
break;
|
||||
case "6.1":
|
||||
case "6.0":
|
||||
driverName = "Win-7.sys";
|
||||
break;
|
||||
default:
|
||||
Logging.Info($"不支持的系统版本:{version}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查驱动版本号
|
||||
var SystemfileVerInfo = FileVersionInfo.GetVersionInfo(_driverPath);
|
||||
var BinFileVerInfo = FileVersionInfo.GetVersionInfo(string.Format("bin\\{0}", driverName));
|
||||
|
||||
if (!SystemfileVerInfo.FileVersion.Equals(BinFileVerInfo.FileVersion))
|
||||
{
|
||||
Logging.Info("开始更新驱动");
|
||||
// 需要更新驱动
|
||||
try
|
||||
{
|
||||
var service = new ServiceController("netfilter2");
|
||||
if (service.Status == ServiceControllerStatus.Running)
|
||||
{
|
||||
service.Stop();
|
||||
service.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
}
|
||||
|
||||
NFAPI.nf_unRegisterDriver("netfilter2");
|
||||
|
||||
//删除老驱动
|
||||
File.Delete(_driverPath);
|
||||
if (!InstallDriver())
|
||||
return false;
|
||||
|
||||
Logging.Info($"驱动更新完毕,当前驱动版本:{BinFileVerInfo.FileVersion}");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Logging.Info("更新驱动出错");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!InstallDriver()) return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 启动驱动服务
|
||||
var service = new ServiceController("netfilter2");
|
||||
if (service.Status == ServiceControllerStatus.Running && StopServiceAndRestart)
|
||||
{
|
||||
// 防止其他程序占用 重置 NF 百万连接数限制
|
||||
service.Stop();
|
||||
service.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting netfilter2 Service"));
|
||||
service.Start();
|
||||
}
|
||||
else if (service.Status == ServiceControllerStatus.Stopped)
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting netfilter2 Service"));
|
||||
service.Start();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
|
||||
var result = NFAPI.nf_registerDriver("netfilter2");
|
||||
if (result != NF_STATUS.NF_STATUS_SUCCESS)
|
||||
{
|
||||
Logging.Info($"注册驱动失败,返回值:{result}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var processes = "";
|
||||
foreach (var proc in mode.Rule)
|
||||
{
|
||||
processes += proc;
|
||||
processes += ",";
|
||||
}
|
||||
|
||||
processes += "NTT.exe";
|
||||
|
||||
Instance = MainController.GetProcess("bin\\Redirector.exe");
|
||||
|
||||
if (server.Type != "Socks5")
|
||||
{
|
||||
Instance.StartInfo.Arguments += $"-r 127.0.0.1:{Global.Settings.Socks5LocalPort} -p \"{processes}\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = DNS.Lookup(server.Hostname);
|
||||
if (result == null)
|
||||
{
|
||||
Logging.Info("无法解析服务器 IP 地址");
|
||||
return false;
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $"-r {result}:{server.Port} -p \"{processes}\"";
|
||||
if (!string.IsNullOrWhiteSpace(server.Username) && !string.IsNullOrWhiteSpace(server.Password)) Instance.StartInfo.Arguments += $" -username \"{server.Username}\" -password \"{server.Password}\"";
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $" -t {Global.Settings.RedirectorTCPPort}";
|
||||
Logging.Info(Instance.StartInfo.Arguments);
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
|
||||
if (State == State.Started) return true;
|
||||
}
|
||||
|
||||
Logging.Info("NF 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool InstallDriver()
|
||||
{
|
||||
Logging.Info("安装驱动中");
|
||||
// 生成系统版本
|
||||
var version = $"{Environment.OSVersion.Version.Major.ToString()}.{Environment.OSVersion.Version.Minor.ToString()}";
|
||||
|
||||
// 检查系统版本并复制对应驱动
|
||||
try
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case "10.0":
|
||||
File.Copy("bin\\Win-10.sys", _driverPath);
|
||||
Logging.Info("已复制 Win10 驱动");
|
||||
break;
|
||||
case "6.3":
|
||||
case "6.2":
|
||||
File.Copy("bin\\Win-8.sys", _driverPath);
|
||||
Logging.Info("已复制 Win8 驱动");
|
||||
break;
|
||||
case "6.1":
|
||||
case "6.0":
|
||||
File.Copy("bin\\Win-7.sys", _driverPath);
|
||||
Logging.Info("已复制 Win7 驱动");
|
||||
break;
|
||||
default:
|
||||
Logging.Info($"不支持的系统版本:{version}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info("复制驱动文件失败");
|
||||
Logging.Info(e.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
MainForm.Instance.StatusText(i18N.Translate("Register driver"));
|
||||
// 注册驱动文件
|
||||
var result = NFAPI.nf_registerDriver("netfilter2");
|
||||
if (result != NF_STATUS.NF_STATUS_SUCCESS)
|
||||
{
|
||||
Logging.Info($"注册驱动失败,返回值:{result}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!WriteLog(e)) return;
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
State = State.Stopped;
|
||||
else if (e.Data.Contains("Started"))
|
||||
State = State.Started;
|
||||
else if (e.Data.Contains("Failed") || e.Data.Contains("Unable")) State = State.Stopped;
|
||||
}
|
||||
else if (State == State.Started)
|
||||
{
|
||||
if (e.Data.StartsWith("[APP][Bandwidth]"))
|
||||
{
|
||||
var splited = e.Data.Replace("[APP][Bandwidth]", "").Trim().Split(',');
|
||||
if (splited.Length == 2)
|
||||
{
|
||||
var uploadSplited = splited[0].Split(':');
|
||||
var downloadSplited = splited[1].Split(':');
|
||||
|
||||
if (uploadSplited.Length == 2 && downloadSplited.Length == 2)
|
||||
if (long.TryParse(uploadSplited[1], out var upload) && long.TryParse(downloadSplited[1], out var download))
|
||||
Task.Run(() => OnBandwidthUpdated(upload, download));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,21 +12,22 @@ namespace Netch.Controllers
|
||||
{
|
||||
public NTTController()
|
||||
{
|
||||
MainName = "NTT";
|
||||
ready = BeforeStartProgress();
|
||||
MainFile = "NTT";
|
||||
InitCheck();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动NatTypeTester
|
||||
/// 启动 NatTypeTester
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public (bool, string, string, string) Start()
|
||||
{
|
||||
if (!Ready) return (false, null, null, null);
|
||||
Thread.Sleep(1000);
|
||||
MainForm.Instance.NatTypeStatusText(i18N.Translate("Starting NatTester"));
|
||||
try
|
||||
{
|
||||
Instance = MainController.GetProcess("bin\\NTT.exe");
|
||||
Instance = GetProcess("bin\\NTT.exe");
|
||||
|
||||
Instance.StartInfo.Arguments = $" {Global.Settings.STUN_Server} {Global.Settings.STUN_Server_Port}";
|
||||
|
||||
@@ -39,7 +40,7 @@ namespace Netch.Controllers
|
||||
Instance.BeginErrorReadLine();
|
||||
Instance.WaitForExit();
|
||||
|
||||
var result = File.ReadAllText($"logging\\{MainName}.log").Split('#');
|
||||
var result = File.ReadAllText($"logging\\{MainFile}.log").Split('#');
|
||||
var natType = result[0];
|
||||
var localEnd = result[1];
|
||||
var publicEnd = result[2];
|
||||
@@ -49,15 +50,22 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Logging.Info("NTT 进程出错");
|
||||
Logging.Error("NTT 进程出错");
|
||||
Stop();
|
||||
return (false, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
WriteLog(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 无用
|
||||
/// </summary>
|
||||
public override void Stop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Netch.Models;
|
||||
|
||||
@@ -8,34 +9,44 @@ namespace Netch.Controllers
|
||||
{
|
||||
public PrivoxyController()
|
||||
{
|
||||
MainName = "Privoxy";
|
||||
MainFile = "Privoxy";
|
||||
ExtFiles = new[] {"default.conf"};
|
||||
ready = BeforeStartProgress();
|
||||
InitCheck();
|
||||
}
|
||||
|
||||
public bool Start(Server server, Mode mode)
|
||||
{
|
||||
if (server.Type != "Socks5")
|
||||
File.WriteAllText("data\\privoxy.conf", File.ReadAllText("bin\\default.conf").Replace("_BIND_PORT_", Global.Settings.HTTPLocalPort.ToString()).Replace("_DEST_PORT_", Global.Settings.Socks5LocalPort.ToString()).Replace("0.0.0.0", Global.Settings.LocalAddress));
|
||||
else
|
||||
File.WriteAllText("data\\privoxy.conf", File.ReadAllText("bin\\default.conf").Replace("_BIND_PORT_", Global.Settings.HTTPLocalPort.ToString()).Replace("_DEST_PORT_", server.Port.ToString()).Replace("s 0.0.0.0", $"s {Global.Settings.LocalAddress}").Replace("/ 127.0.0.1", $"/ {server.Hostname}"));
|
||||
if (!Ready) return false;
|
||||
|
||||
var isSocks5 = server.Type == "Socks5";
|
||||
var socks5Port = isSocks5 ? server.Port : Global.Settings.Socks5LocalPort;
|
||||
var text = File.ReadAllText("bin\\default.conf")
|
||||
.Replace("_BIND_PORT_", Global.Settings.HTTPLocalPort.ToString())
|
||||
.Replace("_DEST_PORT_", socks5Port.ToString())
|
||||
.Replace("0.0.0.0", Global.Settings.LocalAddress);
|
||||
if (isSocks5)
|
||||
text = text.Replace("/ 127.0.0.1", $"/ {server.Hostname}");
|
||||
File.WriteAllText("data\\privoxy.conf", text);
|
||||
|
||||
Instance = new Process
|
||||
Instance = GetProcess("bin\\Privoxy.exe", false);
|
||||
Instance.StartInfo.Arguments = "..\\data\\privoxy.conf";
|
||||
Instance.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
Instance.StartInfo.UseShellExecute = true;
|
||||
try
|
||||
{
|
||||
StartInfo =
|
||||
{
|
||||
FileName = $"{Global.NetchDir}\\bin\\Privoxy.exe",
|
||||
Arguments = "..\\data\\privoxy.conf",
|
||||
WorkingDirectory = $"{Global.NetchDir}\\bin",
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
UseShellExecute = true,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
Instance.Start();
|
||||
Instance.Start();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ namespace Netch.Forms
|
||||
//MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false;
|
||||
|
||||
UpdateStatus(State.Starting);
|
||||
|
||||
|
||||
Firewall.AddNetchFwRules();
|
||||
|
||||
Task.Run(() =>
|
||||
@@ -44,7 +44,7 @@ namespace Netch.Forms
|
||||
var server = ServerComboBox.SelectedItem as Models.Server;
|
||||
var mode = ModeComboBox.SelectedItem as Models.Mode;
|
||||
|
||||
MainController = new MainController();
|
||||
MainController ??= new MainController();
|
||||
|
||||
var startResult = MainController.Start(server, mode);
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace Netch.Forms
|
||||
if (server.Type == "Socks5")
|
||||
{
|
||||
// 不可控Socks5
|
||||
if (mode.Type == 3 && mode.Type == 5)
|
||||
if (mode.Type == 3 || mode.Type == 5)
|
||||
{
|
||||
// 可控HTTP
|
||||
text.Append(
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.ServiceProcess;
|
||||
@@ -18,7 +17,9 @@ using WebClient = Netch.Override.WebClient;
|
||||
namespace Netch.Forms
|
||||
{
|
||||
partial class Dummy
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
partial class MainForm
|
||||
{
|
||||
#region MenuStrip
|
||||
@@ -160,7 +161,7 @@ namespace Netch.Forms
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 跳过
|
||||
// ignored
|
||||
}
|
||||
|
||||
Global.Settings.Server = Global.Settings.Server.Where(server => server.Group != item.Remark).ToList();
|
||||
@@ -261,39 +262,18 @@ namespace Netch.Forms
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
var driver = $"{Environment.SystemDirectory}\\drivers\\netfilter2.sys";
|
||||
if (File.Exists(driver))
|
||||
try
|
||||
{
|
||||
try
|
||||
if (new NFController().UninstallDriver())
|
||||
{
|
||||
var service = new ServiceController("netfilter2");
|
||||
if (service.Status == ServiceControllerStatus.Running)
|
||||
{
|
||||
service.Stop();
|
||||
service.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 跳过
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
NFAPI.nf_unRegisterDriver("netfilter2");
|
||||
|
||||
File.Delete(driver);
|
||||
|
||||
MessageBoxX.Show(i18N.Translate("Service has been uninstalled"), owner: this);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Error") + i18N.Translate(": ") + ex, info: false, owner: this);
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Service has been uninstalled"), owner: this);
|
||||
MessageBox.Show(i18N.Translate("Error", e.Message));
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
|
||||
Enabled = true;
|
||||
@@ -398,8 +378,8 @@ namespace Netch.Forms
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info("使用代理更新 ACL 失败!" + e.Message);
|
||||
MessageBoxX.Show(i18N.Translate("ACL update failed") + "\n" + e.Message);
|
||||
Logging.Error("使用代理更新 ACL 失败!" + e);
|
||||
MessageBoxX.Show(i18N.Translate("ACL update failed") + "\n" + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -414,17 +394,7 @@ namespace Netch.Forms
|
||||
|
||||
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (State != State.Waiting && State != State.Stopped)
|
||||
{
|
||||
ControlButton_Click(sender, e);
|
||||
}
|
||||
SaveConfigs();
|
||||
|
||||
UpdateStatus(State.Terminating);
|
||||
NotifyIcon.Visible = false;
|
||||
Close();
|
||||
Dispose();
|
||||
Environment.Exit(Environment.ExitCode);
|
||||
Exit(true);
|
||||
}
|
||||
|
||||
private void RelyToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
@@ -461,7 +431,7 @@ namespace Netch.Forms
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Info("ACL 更新失败!" + args.Error);
|
||||
Logging.Error("ACL 更新失败!" + args.Error);
|
||||
MessageBoxX.Show(i18N.Translate("ACL update failed") + "\n" + args.Error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Netch.Forms
|
||||
partial class MainForm
|
||||
{
|
||||
|
||||
// init at MainFrom_Load()
|
||||
/// init at <see cref="MainForm_Load"/>
|
||||
private int _sizeHeight;
|
||||
private int _controlHeight;
|
||||
private int _profileBoxHeight;
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace Netch.Forms
|
||||
// 如果勾选了关闭时退出,自动点击退出按钮
|
||||
else
|
||||
{
|
||||
ExitToolStripButton.PerformClick();
|
||||
Exit(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -414,35 +414,52 @@ namespace Netch.Forms
|
||||
Activate();
|
||||
}
|
||||
|
||||
private void ExitToolStripButton_Click(object sender, EventArgs e)
|
||||
private void Exit(bool forceExit = false)
|
||||
{
|
||||
// 已启动
|
||||
if (State != State.Waiting && State != State.Stopped)
|
||||
{
|
||||
// 未开启自动停止
|
||||
if (!Global.Settings.StopWhenExited)
|
||||
if (forceExit)
|
||||
ControlFun();
|
||||
else
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please press Stop button first"));
|
||||
if (!Global.Settings.StopWhenExited)
|
||||
{
|
||||
// 未开启自动停止
|
||||
MessageBoxX.Show(i18N.Translate("Please press Stop button first"));
|
||||
|
||||
Visible = true;
|
||||
ShowInTaskbar = true; // 显示在系统任务栏
|
||||
WindowState = FormWindowState.Normal; // 还原窗体
|
||||
NotifyIcon.Visible = true; // 托盘图标隐藏
|
||||
Visible = true;
|
||||
ShowInTaskbar = true; // 显示在系统任务栏
|
||||
WindowState = FormWindowState.Normal; // 还原窗体
|
||||
NotifyIcon.Visible = true; // 托盘图标隐藏
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 自动停止
|
||||
|
||||
ControlButton_Click(sender, e);
|
||||
}
|
||||
|
||||
SaveConfigs();
|
||||
|
||||
UpdateStatus(State.Terminating);
|
||||
NotifyIcon.Visible = false;
|
||||
Close();
|
||||
Dispose();
|
||||
Environment.Exit(Environment.ExitCode);
|
||||
Hide();
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
for (var i = 0; i < 16; i++)
|
||||
{
|
||||
if (State == State.Waiting || State == State.Stopped)
|
||||
break;
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
|
||||
SaveConfigs();
|
||||
UpdateStatus(State.Terminating);
|
||||
Dispose();
|
||||
Environment.Exit(Environment.ExitCode);
|
||||
});
|
||||
}
|
||||
|
||||
private void ExitToolStripButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
|
||||
private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{
|
||||
protected override void OnRenderToolStripBorder(System.Windows.Forms.ToolStripRenderEventArgs e)
|
||||
{
|
||||
// 跳过
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ namespace Netch.Utils
|
||||
public static int received;
|
||||
|
||||
/// <summary>
|
||||
/// 计算流量
|
||||
/// </summary>
|
||||
/// <param name="bandwidth">流量</param>
|
||||
/// <returns>带单位的流量字符串</returns>
|
||||
public static string Compute(long bandwidth)
|
||||
/// 计算流量
|
||||
/// </summary>
|
||||
/// <param name="bandwidth">流量</param>
|
||||
/// <returns>带单位的流量字符串</returns>
|
||||
public static string Compute(long bandwidth)
|
||||
{
|
||||
string[] units = { "KB", "MB", "GB", "TB", "PB" };
|
||||
string[] units = {"KB", "MB", "GB", "TB", "PB"};
|
||||
double result = bandwidth;
|
||||
var i = -1;
|
||||
|
||||
@@ -50,27 +50,24 @@ namespace Netch.Utils
|
||||
//var processList = Process.GetProcessesByName(ProcessName).Select(p => p.Id).ToHashSet();
|
||||
var processList = new List<int>();
|
||||
|
||||
if (server.Type.Equals("Socks5") && mainController.pHTTPController != null)
|
||||
if (server.Type.Equals("Socks5") && mainController.pModeController.AkaName == "HTTP")
|
||||
{
|
||||
processList.Add(mainController.pHTTPController.pPrivoxyController.Instance.Id);
|
||||
processList.Add(((HTTPController) mainController.pModeController).pPrivoxyController.Instance.Id);
|
||||
}
|
||||
else if (server.Type.Equals("SS") && Global.Settings.BootShadowsocksFromDLL)
|
||||
{
|
||||
processList.Add(Process.GetCurrentProcess().Id);
|
||||
}
|
||||
else if (mainController.pServerClientController != null)
|
||||
else if (mainController.pEncryptedProxyController != null)
|
||||
{
|
||||
// mainController.pServerClientController.Instance
|
||||
processList.Add(mainController.pServerClientController.Instance.Id);
|
||||
processList.Add(mainController.pEncryptedProxyController.Instance.Id);
|
||||
}
|
||||
else if (mainController.pTUNTAPController != null)
|
||||
else if (mainController.pModeController != null)
|
||||
{
|
||||
processList.Add(mainController.pTUNTAPController.Instance.Id);
|
||||
}
|
||||
else if (mainController.pNFController != null)
|
||||
{
|
||||
processList.Add(mainController.pNFController.Instance.Id);
|
||||
processList.Add(mainController.pModeController.Instance.Id);
|
||||
}
|
||||
|
||||
Logging.Info("启动流量统计 PID:" + string.Join(",", processList.ToArray()));
|
||||
|
||||
Task.Run(() =>
|
||||
@@ -109,6 +106,7 @@ namespace Netch.Utils
|
||||
MainForm.Instance.OnBandwidthUpdated(0);
|
||||
received = 0;
|
||||
}
|
||||
|
||||
while (MainForm.Instance.State != State.Stopped)
|
||||
{
|
||||
Task.Delay(1000).Wait();
|
||||
@@ -117,7 +115,6 @@ namespace Netch.Utils
|
||||
MainForm.Instance.OnBandwidthUpdated(Convert.ToInt64(received));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,112 +89,6 @@ namespace Netch.Utils
|
||||
File.WriteAllText(SETTINGS_JSON, JsonConvert.SerializeObject(Global.Settings, Formatting.Indented));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 搜索出口
|
||||
/// </summary>
|
||||
public static bool SearchOutbounds()
|
||||
{
|
||||
Logging.Info("正在搜索出口中");
|
||||
|
||||
if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0)
|
||||
{
|
||||
Global.Adapter.Index = pRoute.dwForwardIfIndex;
|
||||
Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop);
|
||||
Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Info("GetBestRoute 搜索失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info($"搜索适配器index:{Global.Adapter.Index}");
|
||||
var AddressGot = false;
|
||||
foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
try
|
||||
{
|
||||
var adapterProperties = adapter.GetIPProperties();
|
||||
var p = adapterProperties.GetIPv4Properties();
|
||||
Logging.Info($"检测适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {p.Index}");
|
||||
|
||||
// 通过索引查找对应适配器的 IPv4 地址
|
||||
if (p.Index == Global.Adapter.Index)
|
||||
{
|
||||
var AdapterIPs = "";
|
||||
|
||||
foreach (var ip in adapterProperties.UnicastAddresses)
|
||||
{
|
||||
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
AddressGot = true;
|
||||
Global.Adapter.Address = ip.Address;
|
||||
Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}");
|
||||
break;
|
||||
}
|
||||
AdapterIPs = $"{ip.Address} | ";
|
||||
}
|
||||
|
||||
if (!AddressGot)
|
||||
{
|
||||
if (AdapterIPs.Length > 3)
|
||||
{
|
||||
AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3);
|
||||
Logging.Info($"所有出口地址:{AdapterIPs}");
|
||||
}
|
||||
Logging.Info("出口无 IPv4 地址,当前只支持 IPv4 地址");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
}
|
||||
|
||||
if (!AddressGot)
|
||||
{
|
||||
Logging.Info("无法找到当前使用适配器");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 搜索 TUN/TAP 适配器的索引
|
||||
Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
|
||||
if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID))
|
||||
{
|
||||
Logging.Info("未找到可用 TUN/TAP 适配器");
|
||||
if (MessageBoxX.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"),confirm:true) == DialogResult.OK)
|
||||
{
|
||||
addtap();
|
||||
//给点时间,不然立马安装完毕就查找适配器可能会导致找不到适配器ID
|
||||
Thread.Sleep(1000);
|
||||
Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//MessageBoxX.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually"));
|
||||
// return false;
|
||||
}
|
||||
|
||||
foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
if (adapter.Id == Global.TUNTAP.ComponentID)
|
||||
{
|
||||
Global.TUNTAP.Adapter = adapter;
|
||||
Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index;
|
||||
|
||||
Logging.Info($"找到适配器:{adapter.Id}");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Info("无法找到出口");
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// 安装tap网卡
|
||||
/// </summary>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NetFwTypeLib;
|
||||
|
||||
namespace Netch.Utils
|
||||
@@ -24,8 +20,8 @@ namespace Netch.Utils
|
||||
"Netch.exe"
|
||||
};
|
||||
|
||||
private const string _netch = "Netch";
|
||||
private const string _netchAutoRule = "NetchAutoRule";
|
||||
private const string Netch = "Netch";
|
||||
private const string NetchAutoRule = "NetchAutoRule";
|
||||
|
||||
/// <summary>
|
||||
/// 添加防火墙规则 (非 Netch 自带程序)
|
||||
@@ -33,7 +29,7 @@ namespace Netch.Utils
|
||||
/// <param name="exeFullPath"></param>
|
||||
public static void AddFwRule(string exeFullPath)
|
||||
{
|
||||
AddFwRule(_netchAutoRule, exeFullPath);
|
||||
AddFwRule(NetchAutoRule, exeFullPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -41,7 +37,7 @@ namespace Netch.Utils
|
||||
/// </summary>
|
||||
public static void RemoveFwRules()
|
||||
{
|
||||
RemoveFwRules(_netchAutoRule);
|
||||
RemoveFwRules(NetchAutoRule);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -49,7 +45,7 @@ namespace Netch.Utils
|
||||
/// </summary>
|
||||
public static void AddNetchFwRules()
|
||||
{
|
||||
if (GetFwRulePath(_netch).StartsWith(Global.NetchDir) && GetFwRulesNumber(_netch) >= ProgramPath.Length) return;
|
||||
if (GetFwRulePath(Netch).StartsWith(Global.NetchDir) && GetFwRulesNumber(Netch) >= ProgramPath.Length) return;
|
||||
RemoveNetchFwRules();
|
||||
foreach (var p in ProgramPath)
|
||||
{
|
||||
@@ -64,9 +60,9 @@ namespace Netch.Utils
|
||||
/// <summary>
|
||||
/// 清除防火墙规则 (Netch 自带程序)
|
||||
/// </summary>
|
||||
public static void RemoveNetchFwRules()
|
||||
private static void RemoveNetchFwRules()
|
||||
{
|
||||
RemoveFwRules(_netch);
|
||||
RemoveFwRules(Netch);
|
||||
}
|
||||
|
||||
#region 封装
|
||||
@@ -111,7 +107,7 @@ namespace Netch.Utils
|
||||
var rule = (INetFwRule2)FwPolicy.Rules.Item(ruleName);
|
||||
return rule.ApplicationName;
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Exception)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
@@ -120,7 +116,13 @@ namespace Netch.Utils
|
||||
private static int GetFwRulesNumber(string ruleName)
|
||||
{
|
||||
// https://stackoverflow.com/a/53601691
|
||||
return FwPolicy.Rules.Cast<INetFwRule>().Count(rule => rule.Name == ruleName);
|
||||
var i = 0;
|
||||
foreach (INetFwRule2 rule in FwPolicy.Rules)
|
||||
{
|
||||
if (rule.Name == ruleName)
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -12,7 +12,16 @@ namespace Netch.Utils
|
||||
/// <param name="text">内容</param>
|
||||
public static void Info(string text)
|
||||
{
|
||||
File.AppendAllText("logging\\application.log", $@"[{DateTime.Now}] {text}{Global.EOF}");
|
||||
File.AppendAllText("logging\\application.log", $@"[{DateTime.Now}][INFO] {text}{Global.EOF}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误
|
||||
/// </summary>
|
||||
/// <param name="text">内容</param>
|
||||
public static void Error(string text)
|
||||
{
|
||||
File.AppendAllText("logging\\application.log", $@"[{DateTime.Now}][ERROR] {text}{Global.EOF}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace Netch.Utils
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
Logging.Error(e.ToString());
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ namespace Netch.Utils
|
||||
|
||||
if (!Global.EncryptMethods.SS.Contains(data.EncryptMethod))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 SS 加密方式:{0}", data.EncryptMethod));
|
||||
Logging.Error($"不支持的 SS 加密方式:{data.EncryptMethod}");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -313,14 +313,14 @@ namespace Netch.Utils
|
||||
data.TransferProtocol = vmess.net;
|
||||
if (!Global.TransferProtocols.Contains(data.TransferProtocol))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 VMess 传输协议:{0}", data.TransferProtocol));
|
||||
Logging.Error($"不支持的 VMess 传输协议:{data.TransferProtocol}");
|
||||
return null;
|
||||
}
|
||||
|
||||
data.FakeType = vmess.type;
|
||||
if (data.FakeType.Length != 0 && !Global.FakeTypes.Contains(data.FakeType))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 VMess 伪装类型:{0}", data.FakeType));
|
||||
Logging.Error($"不支持的 VMess 伪装类型:{data.FakeType}");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ namespace Netch.Utils
|
||||
{
|
||||
if (!Global.EncryptMethods.VMessQUIC.Contains(vmess.host))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 VMess QUIC 加密方式:{0}", vmess.host));
|
||||
Logging.Error($"不支持的 VMess QUIC 加密方式:{vmess.host}");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -393,43 +393,43 @@ namespace Netch.Utils
|
||||
case "SS":
|
||||
if (!Global.EncryptMethods.SS.Contains(NetchLink.EncryptMethod))
|
||||
{
|
||||
Logging.Info($"不支持的 SS 加密方式:{NetchLink.EncryptMethod}");
|
||||
Logging.Error($"不支持的 SS 加密方式:{NetchLink.EncryptMethod}");
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case "SSR":
|
||||
if (!Global.EncryptMethods.SSR.Contains(NetchLink.EncryptMethod))
|
||||
{
|
||||
Logging.Info($"不支持的 SSR 加密方式:{NetchLink.EncryptMethod}");
|
||||
Logging.Error($"不支持的 SSR 加密方式:{NetchLink.EncryptMethod}");
|
||||
return null;
|
||||
}
|
||||
if (!Global.Protocols.Contains(NetchLink.Protocol))
|
||||
{
|
||||
Logging.Info($"不支持的 SSR 协议:{NetchLink.Protocol}");
|
||||
Logging.Error($"不支持的 SSR 协议:{NetchLink.Protocol}");
|
||||
return null;
|
||||
}
|
||||
if (!Global.OBFSs.Contains(NetchLink.OBFS))
|
||||
{
|
||||
Logging.Info($"不支持的 SSR 混淆:{NetchLink.OBFS}");
|
||||
Logging.Error($"不支持的 SSR 混淆:{NetchLink.OBFS}");
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case "VMess":
|
||||
if (!Global.TransferProtocols.Contains(NetchLink.TransferProtocol))
|
||||
{
|
||||
Logging.Info($"不支持的 VMess 传输协议:{NetchLink.TransferProtocol}");
|
||||
Logging.Error($"不支持的 VMess 传输协议:{NetchLink.TransferProtocol}");
|
||||
return null;
|
||||
}
|
||||
if (!Global.FakeTypes.Contains(NetchLink.FakeType))
|
||||
{
|
||||
Logging.Info($"不支持的 VMess 伪装类型:{NetchLink.FakeType}");
|
||||
Logging.Error($"不支持的 VMess 伪装类型:{NetchLink.FakeType}");
|
||||
return null;
|
||||
}
|
||||
if (NetchLink.TransferProtocol == "quic")
|
||||
{
|
||||
if (!Global.EncryptMethods.VMessQUIC.Contains(NetchLink.QUICSecure))
|
||||
{
|
||||
Logging.Info($"不支持的 VMess QUIC 加密方式:{NetchLink.QUICSecure}");
|
||||
Logging.Error($"不支持的 VMess QUIC 加密方式:{NetchLink.QUICSecure}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -492,7 +492,7 @@ namespace Netch.Utils
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
Logging.Error(e.ToString());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ namespace Netch
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 跳过
|
||||
// ignored
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user