diff --git a/Netch/Controllers/MainController.cs b/Netch/Controllers/MainController.cs index 50edfffa..6d1d974b 100644 --- a/Netch/Controllers/MainController.cs +++ b/Netch/Controllers/MainController.cs @@ -2,8 +2,11 @@ using System; using System.IO; using System.Threading.Tasks; using Microsoft.VisualStudio.Threading; +using Netch.Enums; using Netch.Interfaces; using Netch.Models; +using Netch.Servers; +using Netch.Servers.Shadowsocks; using Netch.Utils; using Serilog; using Serilog.Events; @@ -20,6 +23,8 @@ namespace Netch.Controllers public static IModeController? ModeController { get; private set; } + public static ModeFeature ModeFeatures { get; private set; } + public static async Task StartAsync(Server server, Mode mode) { Log.Information("Start MainController: {Server} {Mode}", $"{server.Type}", $"[{(int)mode.Type}]{mode.Remark}"); @@ -44,10 +49,24 @@ namespace Netch.Controllers try { - if (!ModeHelper.SkipServerController(server, mode)) - server = await StartServerAsync(server); + (ModeController, ModeFeatures) = ModeHelper.GetModeControllerByType(mode.Type, out var modePort, out var portName); - await StartModeAsync(server, mode); + if (modePort != null) + TryReleaseTcpPort((ushort)modePort, portName); + + switch (server) + { + case Socks5 socks5 when !socks5.Auth() || socks5.Auth() && ModeFeatures.HasFlag(ModeFeature.SupportSocks5Auth): + case Shadowsocks shadowsocks when !shadowsocks.HasPlugin() && ModeFeatures.HasFlag(ModeFeature.SupportShadowsocks) && + Global.Settings.Redirector.RedirectorSS: + break; + default: + server = await StartServerAsync(server); + break; + } + + Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", ModeController.Name)); + await ModeController.StartAsync(server, mode); } catch (Exception e) { @@ -77,24 +96,12 @@ namespace Netch.Controllers Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", ServerController.Name)); Log.Debug("Server Information: {Data}", $"{server.Type} {server.MaskedData()}"); - var socks5 = await ServerController.StartAsync(server); + var socks5Bridge = await ServerController.StartAsync(server); - StatusPortInfoText.Socks5Port = socks5.Port; + StatusPortInfoText.Socks5Port = socks5Bridge.Port; StatusPortInfoText.UpdateShareLan(); - return socks5; - } - - private static async Task StartModeAsync(Server server, Mode mode) - { - ModeController = ModeHelper.GetModeControllerByType(mode.Type, out var port, out var portName); - - if (port != null) - TryReleaseTcpPort((ushort)port, portName); - - Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", ModeController.Name)); - - await ModeController.StartAsync(server, mode); + return socks5Bridge; } public static async Task StopAsync() @@ -122,8 +129,9 @@ namespace Netch.Controllers Log.Error(e, "MainController Stop Error"); } - ModeController = null; ServerController = null; + ModeController = null; + ModeFeatures = 0; } public static void PortCheck(ushort port, string portName, PortType portType = PortType.Both) diff --git a/Netch/Enums/ModeFeature.cs b/Netch/Enums/ModeFeature.cs new file mode 100644 index 00000000..bdc655c2 --- /dev/null +++ b/Netch/Enums/ModeFeature.cs @@ -0,0 +1,16 @@ +using System; + +namespace Netch.Enums +{ + [Flags] + public enum ModeFeature + { + SupportSocks5 = 0, + SupportIPv4 = 0, + SupportSocks5Auth = 0b_0001, + [Obsolete] + SupportShadowsocks = 0b_0010, + SupportIPv6 = 0b_0100, + RequireTestNat = 0b_1000 + } +} \ No newline at end of file diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs index d4b2346e..0dc20b58 100644 --- a/Netch/Forms/MainForm.cs +++ b/Netch/Forms/MainForm.cs @@ -1158,7 +1158,7 @@ namespace Netch.Forms /// private async Task NatTestAsync() { - if (!MainController.Mode!.TestNatRequired()) + if (!MainController.ModeFeatures.HasFlag(ModeFeature.RequireTestNat)) return; if (NatTestLock.CurrentCount == 0) diff --git a/Netch/Models/Mode.cs b/Netch/Models/Mode.cs index d8979970..fbe2730a 100644 --- a/Netch/Models/Mode.cs +++ b/Netch/Models/Mode.cs @@ -120,14 +120,4 @@ namespace Netch.Models return $"[{(int)Type + 1}] {i18N.Translate(Remark)}"; } } - - public static class ModeExtension - { - /// 是否会转发 UDP - public static bool TestNatRequired(this Mode mode) - { - return mode.Type is ModeType.Process && Global.Settings.Redirector.FilterProtocol.HasFlag(PortType.UDP) || - mode.Type is ModeType.BypassRuleIPs; - } - } } \ No newline at end of file diff --git a/Netch/Servers/Socks5/S5Controller.cs b/Netch/Servers/Socks5/S5Controller.cs index d4156c2b..cb31900d 100644 --- a/Netch/Servers/Socks5/S5Controller.cs +++ b/Netch/Servers/Socks5/S5Controller.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Netch.Models; @@ -10,10 +11,10 @@ namespace Netch.Servers public override async Task StartAsync(Server s) { var server = (Socks5)s; - if (server.Auth()) - await base.StartAsync(s); + if (!server.Auth()) + throw new ArgumentException(); - return server; + return await base.StartAsync(s); } } } \ No newline at end of file diff --git a/Netch/Utils/ModeHelper.cs b/Netch/Utils/ModeHelper.cs index 3faeff46..777fd385 100644 --- a/Netch/Utils/ModeHelper.cs +++ b/Netch/Utils/ModeHelper.cs @@ -6,8 +6,6 @@ using Netch.Controllers; using Netch.Enums; using Netch.Interfaces; using Netch.Models; -using Netch.Servers; -using Netch.Servers.Shadowsocks; using Serilog; namespace Netch.Utils @@ -126,38 +124,20 @@ namespace Netch.Utils File.Delete(mode.FullName); } - public static bool SkipServerController(Server server, Mode mode) - { - switch (mode.Type) - { - case ModeType.Process: - return server switch - { - Socks5 => true, - Shadowsocks shadowsocks when !shadowsocks.HasPlugin() && Global.Settings.Redirector.RedirectorSS => true, - _ => false - }; - case ModeType.ProxyRuleIPs: - case ModeType.BypassRuleIPs: - return server is Socks5; - default: - return false; - } - } - - public static IModeController GetModeControllerByType(ModeType type, out ushort? port, out string portName) + public static (IModeController, ModeFeature) GetModeControllerByType(ModeType type, out ushort? port, out string portName) { port = null; portName = string.Empty; switch (type) { case ModeType.Process: - return new NFController(); + return (new NFController(), ModeFeature.SupportIPv6 | ModeFeature.SupportSocks5Auth | ModeFeature.RequireTestNat); case ModeType.ProxyRuleIPs: + return (new TUNController(), ModeFeature.SupportSocks5Auth); case ModeType.BypassRuleIPs: - return new TUNController(); + return (new TUNController(), ModeFeature.SupportSocks5Auth | ModeFeature.RequireTestNat); case ModeType.Pcap2Socks: - return new PcapController(); + return (new PcapController(), 0); default: Log.Error("未知模式类型"); throw new MessageException("未知模式类型"); diff --git a/Netch/Utils/PortHelper.cs b/Netch/Utils/PortHelper.cs index d062775e..f47704d3 100644 --- a/Netch/Utils/PortHelper.cs +++ b/Netch/Utils/PortHelper.cs @@ -195,8 +195,8 @@ namespace Netch.Utils [Flags] public enum PortType { - TCP = 0x01, - UDP = 0x10, + TCP = 0b_01, + UDP = 0b_10, Both = TCP | UDP }