From 92ce30af09e3ed36d1180a533b7970a00e9f4361 Mon Sep 17 00:00:00 2001 From: xljiulang <366193849@qq.com> Date: Sat, 17 Jul 2021 21:34:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0FastGithubException=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FastGithub.Core/DomainMatch.cs | 43 ++++++++++ FastGithub.Core/FastGithubException.cs | 29 +++++++ FastGithub.Core/FastGithubOptions.cs | 80 +++++++++---------- ...{DnsIPEndPoint.cs => IPEndPointOptions.cs} | 19 ++--- FastGithub.ReverseProxy/DomainResolver.cs | 10 ++- .../ReverseProxyException.cs | 20 ----- FastGithub/Program.cs | 2 +- 7 files changed, 121 insertions(+), 82 deletions(-) create mode 100644 FastGithub.Core/DomainMatch.cs create mode 100644 FastGithub.Core/FastGithubException.cs rename FastGithub.Core/{DnsIPEndPoint.cs => IPEndPointOptions.cs} (77%) delete mode 100644 FastGithub.ReverseProxy/ReverseProxyException.cs diff --git a/FastGithub.Core/DomainMatch.cs b/FastGithub.Core/DomainMatch.cs new file mode 100644 index 0000000..c5215e1 --- /dev/null +++ b/FastGithub.Core/DomainMatch.cs @@ -0,0 +1,43 @@ +using System.Text.RegularExpressions; + +namespace FastGithub +{ + /// + /// 域名匹配 + /// + sealed class DomainMatch + { + private readonly Regex regex; + private readonly string pattern; + + /// + /// 域名匹配 + /// + /// 域名表达式 + public DomainMatch(string pattern) + { + this.pattern = pattern; + var regexPattern = Regex.Escape(pattern).Replace(@"\*", ".*"); + this.regex = new Regex($"^{regexPattern}$", RegexOptions.IgnoreCase); + } + + /// + /// 是否与指定域名匹配 + /// + /// + /// + public bool IsMatch(string domain) + { + return this.regex.IsMatch(domain); + } + + /// + /// 转换为文本 + /// + /// + public override string ToString() + { + return this.pattern; + } + } +} diff --git a/FastGithub.Core/FastGithubException.cs b/FastGithub.Core/FastGithubException.cs new file mode 100644 index 0000000..d601770 --- /dev/null +++ b/FastGithub.Core/FastGithubException.cs @@ -0,0 +1,29 @@ +using System; + +namespace FastGithub +{ + /// + /// 表示FastGithub异常 + /// + public class FastGithubException : Exception + { + /// + /// FastGithub异常 + /// + /// + public FastGithubException(string message) + : base(message) + { + } + + /// + /// FastGithub异常 + /// + /// + /// + public FastGithubException(string message, Exception? innerException) + : base(message, innerException) + { + } + } +} diff --git a/FastGithub.Core/FastGithubOptions.cs b/FastGithub.Core/FastGithubOptions.cs index a57918a..db884a1 100644 --- a/FastGithub.Core/FastGithubOptions.cs +++ b/FastGithub.Core/FastGithubOptions.cs @@ -1,6 +1,7 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; -using System.Text.RegularExpressions; +using System.Net; namespace FastGithub { @@ -13,22 +14,52 @@ namespace FastGithub /// 域名 /// private DomainMatch[]? domainMatches; + private IPEndPoint? trustedDnsEndPoint; + private IPEndPoint? unTrustedDnsEndPoint; /// /// 受信任的dns服务 /// - public DnsIPEndPoint TrustedDns { get; set; } = new DnsIPEndPoint { IPAddress = "127.0.0.1", Port = 5533 }; + public IPEndPointOptions TrustedDns { get; set; } = new IPEndPointOptions { IPAddress = "127.0.0.1", Port = 5533 }; /// /// 不受信任的dns服务 /// - public DnsIPEndPoint UntrustedDns { get; set; } = new DnsIPEndPoint { IPAddress = "114.114.114.114", Port = 53 }; + public IPEndPointOptions UntrustedDns { get; set; } = new IPEndPointOptions { IPAddress = "114.114.114.114", Port = 53 }; /// /// 代理的域名匹配 /// public HashSet DomainMatches { get; set; } = new(); + /// + /// 验证选项值 + /// + /// + public void Validate() + { + this.trustedDnsEndPoint = this.TrustedDns.ToIPEndPoint(); + this.unTrustedDnsEndPoint = this.UntrustedDns.ToIPEndPoint(); + this.domainMatches = this.DomainMatches.Select(item => new DomainMatch(item)).ToArray(); + } + + + /// + /// 受信任的dns服务节点 + /// + public IPEndPoint GetTrustedDns() + { + return this.trustedDnsEndPoint ?? throw new InvalidOperationException(); + } + + /// + /// 不受信任的dns服务节点 + /// + public IPEndPoint GetUnTrustedDns() + { + return this.unTrustedDnsEndPoint ?? throw new InvalidOperationException(); + } + /// /// 是否匹配指定的域名 /// @@ -38,48 +69,9 @@ namespace FastGithub { if (this.domainMatches == null) { - this.domainMatches = this.DomainMatches.Select(item => new DomainMatch(item)).ToArray(); + throw new InvalidOperationException(); } return this.domainMatches.Any(item => item.IsMatch(domain)); } - - /// - /// 域名匹配 - /// - private class DomainMatch - { - private readonly Regex regex; - private readonly string pattern; - - /// - /// 域名匹配 - /// - /// 域名表达式 - public DomainMatch(string pattern) - { - this.pattern = pattern; - var regexPattern = Regex.Escape(pattern).Replace(@"\*", ".*"); - this.regex = new Regex($"^{regexPattern}$", RegexOptions.IgnoreCase); - } - - /// - /// 是否与指定域名匹配 - /// - /// - /// - public bool IsMatch(string domain) - { - return this.regex.IsMatch(domain); - } - - /// - /// 转换为文本 - /// - /// - public override string ToString() - { - return this.pattern; - } - } } } diff --git a/FastGithub.Core/DnsIPEndPoint.cs b/FastGithub.Core/IPEndPointOptions.cs similarity index 77% rename from FastGithub.Core/DnsIPEndPoint.cs rename to FastGithub.Core/IPEndPointOptions.cs index aa70b35..3a523be 100644 --- a/FastGithub.Core/DnsIPEndPoint.cs +++ b/FastGithub.Core/IPEndPointOptions.cs @@ -7,7 +7,7 @@ namespace FastGithub /// /// dns的终节点 /// - public class DnsIPEndPoint + public class IPEndPointOptions { /// /// IP地址 @@ -24,29 +24,20 @@ namespace FastGithub /// 转换为IPEndPoint /// /// + /// public IPEndPoint ToIPEndPoint() - { - return new IPEndPoint(System.Net.IPAddress.Parse(this.IPAddress), this.Port); - } - - /// - /// 验证dns - /// 防止使用自己使用自己来解析域名造成死循环 - /// - /// - public bool Validate() { if (System.Net.IPAddress.TryParse(this.IPAddress, out var address) == false) { - return false; + throw new FastGithubException($"无效的ip:{this.IPAddress}"); } if (this.Port == 53 && IsLocalMachineIPAddress(address)) { - return false; + throw new FastGithubException($"配置的dns值不能指向{nameof(FastGithub)}自身:{this.IPAddress}:{this.Port}"); } - return true; + return new IPEndPoint(address, this.Port); } /// diff --git a/FastGithub.ReverseProxy/DomainResolver.cs b/FastGithub.ReverseProxy/DomainResolver.cs index 04886b2..e8908e9 100644 --- a/FastGithub.ReverseProxy/DomainResolver.cs +++ b/FastGithub.ReverseProxy/DomainResolver.cs @@ -63,20 +63,24 @@ namespace FastGithub.ReverseProxy var address = addresses?.FirstOrDefault(); if (address == null) { - throw new Exception($"解析不到{domain}的ip"); + throw new FastGithubException($"dns({endpoint}):解析不到{domain}的ip"); } // 受干扰的dns,常常返回127.0.0.1来阻断请求 // 如果解析到的ip为本机ip,会产生反向代理请求死循环 if (address.Equals(IPAddress.Loopback)) { - throw new Exception($"dns受干扰,解析{domain}的ip为{address}"); + throw new FastGithubException($"dns({endpoint}):解析{domain}被干扰为{address}"); } return address; } + catch (FastGithubException) + { + throw; + } catch (Exception ex) { - throw new ReverseProxyException($"dns({endpoint}):{ex.Message}", ex); + throw new FastGithubException($"dns({endpoint}):{ex.Message}", ex); } } } diff --git a/FastGithub.ReverseProxy/ReverseProxyException.cs b/FastGithub.ReverseProxy/ReverseProxyException.cs deleted file mode 100644 index 16aa1b7..0000000 --- a/FastGithub.ReverseProxy/ReverseProxyException.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; - -namespace FastGithub.ReverseProxy -{ - /// - /// 反向代理异常 - /// - sealed class ReverseProxyException : Exception - { - /// - /// 反向代理异常 - /// - /// - /// - public ReverseProxyException(string message, Exception? inner) - : base(message, inner) - { - } - } -} diff --git a/FastGithub/Program.cs b/FastGithub/Program.cs index 222b653..3b77699 100644 --- a/FastGithub/Program.cs +++ b/FastGithub/Program.cs @@ -39,7 +39,7 @@ namespace FastGithub .AddDnscryptProxy() .AddOptions() .Bind(ctx.Configuration.GetSection(nameof(FastGithub))) - .Validate(opt => opt.TrustedDns.Validate() && opt.UntrustedDns.Validate(), "无效的Dns配置"); + .PostConfigure(opt => opt.Validate()); }) .ConfigureWebHostDefaults(web => {