diff --git a/Netch/Controllers/Mode/TUNTAPController.cs b/Netch/Controllers/Mode/TUNTAPController.cs index 4e35e3c4..9eaae7aa 100644 --- a/Netch/Controllers/Mode/TUNTAPController.cs +++ b/Netch/Controllers/Mode/TUNTAPController.cs @@ -208,12 +208,17 @@ namespace Netch.Controllers var adapterName = TUNTAP.GetName(Global.TUNTAP.ComponentID); string dns; - //V2ray使用Unbound本地DNS会导致查询异常缓慢故此V2ray不启动unbound而是使用自定义DNS - //if (Global.Settings.TUNTAP.UseCustomDNS || server.Type.Equals("VMess")) if (Global.Settings.TUNTAP.UseCustomDNS) { - dns = Global.Settings.TUNTAP.DNS.Aggregate(string.Empty, (current, value) => current + (value + ',')).Trim(); - dns = dns.Substring(0, dns.Length - 1); + if (Global.Settings.TUNTAP.DNS.Any()) + { + dns = Global.Settings.TUNTAP.DNS.Aggregate((current, ip) => $"{current},{ip}"); + } + else + { + Global.Settings.TUNTAP.DNS.Add("1.1.1.1"); + dns = "1.1.1.1"; + } } else { @@ -221,17 +226,17 @@ namespace Netch.Controllers dns = "127.0.0.1"; } - if (Global.Settings.TUNTAP.UseFakeDNS) dns += " -fakeDns"; - var argument = new StringBuilder(); if (server.Type == "Socks5") argument.Append($"-proxyServer {server.Hostname}:{server.Port} "); else argument.Append($"-proxyServer 127.0.0.1:{Global.Settings.Socks5LocalPort} "); - argument.Append($"-tunAddr {Global.Settings.TUNTAP.Address} -tunMask {Global.Settings.TUNTAP.Netmask} -tunGw {Global.Settings.TUNTAP.Gateway} -tunDns {dns} -tunName \"{adapterName}\""); + argument.Append($"-tunAddr {Global.Settings.TUNTAP.Address} -tunMask {Global.Settings.TUNTAP.Netmask} -tunGw {Global.Settings.TUNTAP.Gateway} -tunDns {dns} -tunName \"{adapterName}\" "); + + if (Global.Settings.TUNTAP.UseFakeDNS) + argument.Append("-fakeDns "); - State = State.Starting; return StartInstanceAuto(argument.ToString(), ProcessPriorityClass.RealTime); } diff --git a/Netch/Forms/SettingForm.cs b/Netch/Forms/SettingForm.cs index 71cbbb31..fe7d1504 100644 --- a/Netch/Forms/SettingForm.cs +++ b/Netch/Forms/SettingForm.cs @@ -17,87 +17,27 @@ namespace Netch.Forms InitializeComponent(); } - private void TUNTAPUseCustomDNSCheckBox_CheckedChanged(object sender, EventArgs e) - { - if (!UseCustomDNSCheckBox.Checked) - { - TUNTAPDNSTextBox.Enabled = false; - } - else - { - TUNTAPDNSTextBox.Enabled = true; - } - - if (Global.Settings.TUNTAP.DNS.Count > 0) - { - var dns = ""; - foreach (var ip in Global.Settings.TUNTAP.DNS) - { - dns += ip; - dns += ','; - } - - dns = dns.Trim(); - TUNTAPDNSTextBox.Text = dns.Substring(0, dns.Length - 1); - } - // 如果 DNS 为空,设置为默认 DNS 1.1.1.1 - else - { - Global.Settings.TUNTAP.DNS.Add("1.1.1.1"); - TUNTAPDNSTextBox.Text = "1.1.1.1"; - } - } - private void InitValue() { // Local Port Socks5PortTextBox.Text = Global.Settings.Socks5LocalPort.ToString(); HTTPPortTextBox.Text = Global.Settings.HTTPLocalPort.ToString(); RedirectorTextBox.Text = Global.Settings.RedirectorTCPPort.ToString(); - switch (Global.Settings.LocalAddress) + AllowDevicesCheckBox.Checked = Global.Settings.LocalAddress switch { - case "127.0.0.1": - AllowDevicesCheckBox.Checked = false; - break; - case "0.0.0.0": - AllowDevicesCheckBox.Checked = true; - break; - default: - Global.Settings.LocalAddress = "127.0.0.1"; - AllowDevicesCheckBox.Checked = false; - break; - } + "127.0.0.1" => false, + "0.0.0.0" => true, + _ => false + }; // TUN/TAP TUNTAPAddressTextBox.Text = Global.Settings.TUNTAP.Address; TUNTAPNetmaskTextBox.Text = Global.Settings.TUNTAP.Netmask; TUNTAPGatewayTextBox.Text = Global.Settings.TUNTAP.Gateway; UseCustomDNSCheckBox.Checked = Global.Settings.TUNTAP.UseCustomDNS; + TUNTAPUseCustomDNSCheckBox_CheckedChanged(null, null); ProxyDNSCheckBox.Checked = Global.Settings.TUNTAP.ProxyDNS; UseFakeDNSCheckBox.Checked = Global.Settings.TUNTAP.UseFakeDNS; - if (Global.Settings.TUNTAP.DNS.Count > 0) - { - var dns = ""; - foreach (var ip in Global.Settings.TUNTAP.DNS) - { - dns += ip; - dns += ','; - } - - dns = dns.Trim(); - TUNTAPDNSTextBox.Text = dns.Substring(0, dns.Length - 1); - } - else - { - // 如果 DNS 为空,设置为默认 DNS 1.1.1.1 - Global.Settings.TUNTAP.DNS.Add("1.1.1.1"); - TUNTAPDNSTextBox.Text = "1.1.1.1"; - } - - if (!UseCustomDNSCheckBox.Checked) - { - TUNTAPDNSTextBox.Enabled = false; - } // Behavior ExitWhenClosedCheckBox.Checked = Global.Settings.ExitWhenClosed; @@ -107,17 +47,31 @@ namespace Netch.Forms RunAtStartupCheckBox.Checked = Global.Settings.RunAtStartup; CheckUpdateWhenOpenedCheckBox.Checked = Global.Settings.CheckUpdateWhenOpened; BootShadowsocksFromDLLCheckBox.Checked = Global.Settings.BootShadowsocksFromDLL; - ModifySystemDNSCheckBox.Checked = Global.Settings.ModifySystemDNS; CheckBetaUpdateCheckBox.Checked = Global.Settings.CheckBetaUpdate; + ModifySystemDNSCheckBox.Checked = Global.Settings.ModifySystemDNS; UpdateSubscribeatWhenOpenedCheckBox.Checked = Global.Settings.UpdateSubscribeatWhenOpened; ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString(); TcpingAtStartedCheckBox.Checked = Global.Settings.StartedTcping; DetectionIntervalTextBox.Text = Global.Settings.StartedTcping_Interval.ToString(); + InitSTUN(); AclAddrTextBox.Text = Global.Settings.ACL; LanguageComboBox.Items.AddRange(i18N.GetTranslateList().ToArray()); LanguageComboBox.SelectedItem = Global.Settings.Language; - InitSTUN(); + } + + private void TUNTAPUseCustomDNSCheckBox_CheckedChanged(object sender, EventArgs e) + { + TUNTAPDNSTextBox.Enabled = UseCustomDNSCheckBox.Checked; + + if (UseCustomDNSCheckBox.Checked) + { + TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.DNS.Any() ? Global.Settings.TUNTAP.DNS.Aggregate((current, ip) => $"{current},{ip}") : "1.1.1.1"; + } + else + { + TUNTAPDNSTextBox.Text = "Unbound local DNS"; + } } private void InitText() @@ -183,25 +137,228 @@ namespace Netch.Forms private void ControlButton_Click(object sender, EventArgs e) { + #region Check + + #region Port + + int socks5LocalPort; + int httpLocalPort; + int redirectorTCPPort; + try + { + socks5LocalPort = int.Parse(Socks5PortTextBox.Text); + httpLocalPort = int.Parse(HTTPPortTextBox.Text); + redirectorTCPPort = int.Parse(RedirectorTextBox.Text); + + static void CheckPort(string portName, int port, int originPort, PortType portType = PortType.Both) + { + if (port <= 0 || port >= 65536) + throw new FormatException(); + + if (port == originPort) + return; + + if (PortHelper.PortInUse(port, portType)) + { + MessageBoxX.Show(i18N.TranslateFormat("The {0} port is in use.", portName)); + throw new PortInUseException(); + } + } + + CheckPort("Socks5", socks5LocalPort, Global.Settings.Socks5LocalPort); + CheckPort("HTTP", httpLocalPort, Global.Settings.HTTPLocalPort); + CheckPort("RedirectorTCP", redirectorTCPPort, Global.Settings.RedirectorTCPPort); + } + catch (Exception exception) + { + switch (exception) + { + case FormatException _: + MessageBoxX.Show(i18N.Translate("Port value illegal. Try again.")); + break; + case PortInUseException _: + break; + } + + return; + } + + #endregion + + #region TUNTAP + + var dns = new string[0]; + try + { + IPAddress.Parse(TUNTAPAddressTextBox.Text); + IPAddress.Parse(TUNTAPNetmaskTextBox.Text); + IPAddress.Parse(TUNTAPGatewayTextBox.Text); + + if (UseCustomDNSCheckBox.Checked) + { + dns = TUNTAPDNSTextBox.Text.Split(',').Where(s => !string.IsNullOrEmpty(s)).Select(s => s.Trim()).ToArray(); + if (dns.Any()) + { + foreach (var ip in dns) + IPAddress.Parse(ip); + } + else + { + MessageBoxX.Show("DNS can not be empty"); + return; + } + } + } + catch (Exception exception) + { + if (exception is FormatException) + MessageBoxX.Show(i18N.Translate("IP address format illegal. Try again.")); + + TUNTAPAddressTextBox.Text = Global.Settings.TUNTAP.Address; + TUNTAPNetmaskTextBox.Text = Global.Settings.TUNTAP.Netmask; + TUNTAPGatewayTextBox.Text = Global.Settings.TUNTAP.Gateway; + UseCustomDNSCheckBox.Checked = Global.Settings.TUNTAP.UseCustomDNS; + + if (UseCustomDNSCheckBox.Checked) + { + TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.DNS.Aggregate((current, ip) => $"{current},{ip}"); + } + + return; + } + + #endregion + + #region Behavior + + // Profile + int profileCount; + try + { + profileCount = int.Parse(ProfileCountTextBox.Text); + + if (profileCount <= -1) + { + throw new FormatException(); + } + } + catch (FormatException) + { + ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString(); + MessageBoxX.Show(i18N.Translate("ProfileCount value illegal. Try again.")); + + return; + } + + // Started TCPing Interval + int detectionInterval; + try + { + detectionInterval = int.Parse(DetectionIntervalTextBox.Text); + + if (detectionInterval <= 0) + { + throw new FormatException(); + } + } + catch (FormatException) + { + ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString(); + MessageBoxX.Show(i18N.Translate("Detection interval value illegal. Try again.")); + + return; + } + + // STUN + string stunServer; + int stunServerPort; + try + { + var stun = STUN_ServerComboBox.Text.Split(':'); + stunServer = stun[0]; + + stunServerPort = 3478; + if (stun.Length > 1) + stunServerPort = int.Parse(stun[1]); + + if (stunServerPort <= 0) + { + throw new FormatException(); + } + } + catch (FormatException) + { + ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString(); + MessageBoxX.Show(i18N.Translate("STUN_ServerPort value illegal. Try again.")); + + return; + } + + #endregion + + #endregion + + #region Save + + #region Port + + Global.Settings.Socks5LocalPort = socks5LocalPort; + Global.Settings.HTTPLocalPort = httpLocalPort; + Global.Settings.RedirectorTCPPort = redirectorTCPPort; + Global.Settings.LocalAddress = AllowDevicesCheckBox.Checked ? "0.0.0.0" : "127.0.0.1"; + + #endregion + + #region TUNTAP + + Global.Settings.TUNTAP.Address = TUNTAPAddressTextBox.Text; + Global.Settings.TUNTAP.Netmask = TUNTAPNetmaskTextBox.Text; + Global.Settings.TUNTAP.Gateway = TUNTAPGatewayTextBox.Text; + Global.Settings.TUNTAP.UseCustomDNS = UseCustomDNSCheckBox.Checked; + if (Global.Settings.TUNTAP.UseCustomDNS) + { + Global.Settings.TUNTAP.DNS.Clear(); + Global.Settings.TUNTAP.DNS.AddRange(dns); + } + + Global.Settings.TUNTAP.ProxyDNS = ProxyDNSCheckBox.Checked; + Global.Settings.TUNTAP.UseFakeDNS = UseFakeDNSCheckBox.Checked; + + #endregion + + #region Behavior + Global.Settings.ExitWhenClosed = ExitWhenClosedCheckBox.Checked; Global.Settings.StopWhenExited = StopWhenExitedCheckBox.Checked; Global.Settings.StartWhenOpened = StartWhenOpenedCheckBox.Checked; - Global.Settings.CheckUpdateWhenOpened = CheckUpdateWhenOpenedCheckBox.Checked; - Global.Settings.CheckBetaUpdate = CheckBetaUpdateCheckBox.Checked; - Global.Settings.UpdateSubscribeatWhenOpened = UpdateSubscribeatWhenOpenedCheckBox.Checked; Global.Settings.MinimizeWhenStarted = MinimizeWhenStartedCheckBox.Checked; Global.Settings.RunAtStartup = RunAtStartupCheckBox.Checked; + Global.Settings.CheckUpdateWhenOpened = CheckUpdateWhenOpenedCheckBox.Checked; Global.Settings.BootShadowsocksFromDLL = BootShadowsocksFromDLLCheckBox.Checked; + Global.Settings.CheckBetaUpdate = CheckBetaUpdateCheckBox.Checked; + Global.Settings.ModifySystemDNS = ModifySystemDNSCheckBox.Checked; + Global.Settings.UpdateSubscribeatWhenOpened = UpdateSubscribeatWhenOpenedCheckBox.Checked; + + Global.Settings.ProfileCount = profileCount; + Global.Settings.StartedTcping = TcpingAtStartedCheckBox.Checked; + Global.Settings.StartedTcping_Interval = detectionInterval; + Global.Settings.STUN_Server = stunServer; + Global.Settings.STUN_Server_Port = stunServerPort; + Global.Settings.ACL = AclAddrTextBox.Text; Global.Settings.Language = LanguageComboBox.SelectedItem.ToString(); - // 开机自启判断 + #endregion + + #endregion + + #region Register Startup Item + var scheduler = new TaskSchedulerClass(); scheduler.Connect(); var folder = scheduler.GetFolder("\\"); var taskIsExists = false; try - { folder.GetTask("Netch Startup"); taskIsExists = true; @@ -211,7 +368,7 @@ namespace Netch.Forms // ignored } - if (RunAtStartupCheckBox.Checked) + if (Global.Settings.RunAtStartup) { if (taskIsExists) folder.DeleteTask("Netch Startup", 0); @@ -233,185 +390,17 @@ namespace Netch.Forms folder.RegisterTaskDefinition("Netch Startup", task, (int) _TASK_CREATION.TASK_CREATE, null, null, _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, ""); } - else { if (taskIsExists) folder.DeleteTask("Netch Startup", 0); } - // 端口检查 - if (!CheckPortText("Socks5", ref Socks5PortTextBox, ref Global.Settings.Socks5LocalPort)) - return; - if (!CheckPortText("HTTP", ref HTTPPortTextBox, ref Global.Settings.HTTPLocalPort)) - return; - if (!CheckPortText("RedirectorTCP", ref RedirectorTextBox, ref Global.Settings.RedirectorTCPPort, PortType.TCP)) - return; - Global.Settings.LocalAddress = AllowDevicesCheckBox.Checked ? "0.0.0.0" : "127.0.0.1"; - try - { - var Address = IPAddress.Parse(TUNTAPAddressTextBox.Text); - var Netmask = IPAddress.Parse(TUNTAPNetmaskTextBox.Text); - var Gateway = IPAddress.Parse(TUNTAPGatewayTextBox.Text); + #endregion - var DNS = new List(); - foreach (var ip in TUNTAPDNSTextBox.Text.Split(',')) - { - DNS.Add(IPAddress.Parse(ip)); - } - } - catch (FormatException) - { - MessageBoxX.Show(i18N.Translate("IP address format illegal. Try again.")); - - TUNTAPAddressTextBox.Text = Global.Settings.TUNTAP.Address; - TUNTAPNetmaskTextBox.Text = Global.Settings.TUNTAP.Netmask; - TUNTAPGatewayTextBox.Text = Global.Settings.TUNTAP.Gateway; - - var DNS = ""; - foreach (var ip in Global.Settings.TUNTAP.DNS) - { - DNS += ip; - DNS += ','; - } - - DNS = DNS.Trim(); - TUNTAPDNSTextBox.Text = DNS.Substring(0, DNS.Length - 1); - UseCustomDNSCheckBox.Checked = Global.Settings.TUNTAP.UseCustomDNS; - - return; - } - - try - { - var ProfileCount = int.Parse(ProfileCountTextBox.Text); - - if (ProfileCount > -1) - { - Global.Settings.ProfileCount = ProfileCount; - } - else - { - throw new FormatException(); - } - } - catch (FormatException) - { - ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString(); - MessageBoxX.Show(i18N.Translate("ProfileCount value illegal. Try again.")); - - return; - } - - try - { - var stun = STUN_ServerComboBox.Text.Split(':'); - var STUN_Server = stun[0]; - Global.Settings.STUN_Server = STUN_Server; - - var STUN_ServerPort = 3478; - if (stun.Length > 1) - STUN_ServerPort = int.Parse(stun[1]); - - if (STUN_ServerPort > 0) - { - Global.Settings.STUN_Server_Port = STUN_ServerPort; - } - else - { - throw new FormatException(); - } - } - catch (FormatException) - { - ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString(); - MessageBoxX.Show(i18N.Translate("STUN_ServerPort value illegal. Try again.")); - - return; - } - - try - { - Global.Settings.StartedTcping = TcpingAtStartedCheckBox.Checked; - - var DetectionInterval = int.Parse(DetectionIntervalTextBox.Text); - - if (DetectionInterval > 0) - { - Global.Settings.StartedTcping_Interval = DetectionInterval; - } - else - { - throw new FormatException(); - } - } - catch (FormatException) - { - ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString(); - MessageBoxX.Show(i18N.Translate("Detection interval value illegal. Try again.")); - - return; - } - - Global.Settings.ACL = AclAddrTextBox.Text; - Global.Settings.TUNTAP.Address = TUNTAPAddressTextBox.Text; - Global.Settings.TUNTAP.Netmask = TUNTAPNetmaskTextBox.Text; - Global.Settings.TUNTAP.Gateway = TUNTAPGatewayTextBox.Text; - Global.Settings.TUNTAP.DNS.Clear(); - foreach (var ip in TUNTAPDNSTextBox.Text.Split(',')) - { - Global.Settings.TUNTAP.DNS.Add(ip); - } - - Global.Settings.TUNTAP.UseCustomDNS = UseCustomDNSCheckBox.Checked; - Global.Settings.TUNTAP.ProxyDNS = ProxyDNSCheckBox.Checked; - Global.Settings.TUNTAP.UseFakeDNS = UseFakeDNSCheckBox.Checked; - Global.Settings.ModifySystemDNS = ModifySystemDNSCheckBox.Checked; Configuration.Save(); MessageBoxX.Show(i18N.Translate("Saved")); Close(); } - - /// - /// - /// - /// - /// - /// - /// - /// - private bool CheckPortText(string portName, ref TextBox portTextBox, ref int originPort, PortType portType = PortType.Both) - { - // 端口检查 - try - { - var port = int.Parse(portTextBox.Text); - - if (port <= 0 || port >= 65536) - { - throw new FormatException(); - } - - if (port == originPort) - { - return true; - } - - if (PortHelper.PortInUse(port, portType)) - { - MessageBoxX.Show(i18N.TranslateFormat("The {0} port is in use.", portName)); - return false; - } - - originPort = port; - } - catch (FormatException) - { - MessageBoxX.Show(i18N.Translate("Port value illegal. Try again.")); - return false; - } - - return true; - } } } \ No newline at end of file diff --git a/Netch/Utils/PortHelper.cs b/Netch/Utils/PortHelper.cs index b480c6c1..bfd7e6bc 100644 --- a/Netch/Utils/PortHelper.cs +++ b/Netch/Utils/PortHelper.cs @@ -136,4 +136,10 @@ namespace Netch.Utils UDP, Both } + + public class PortInUseException : Exception + { + + } + } \ No newline at end of file