增加FastGithubException异常

This commit is contained in:
xljiulang 2021-07-17 21:34:04 +08:00
parent 49a18eaae9
commit 92ce30af09
7 changed files with 121 additions and 82 deletions

View File

@ -0,0 +1,43 @@
using System.Text.RegularExpressions;
namespace FastGithub
{
/// <summary>
/// 域名匹配
/// </summary>
sealed class DomainMatch
{
private readonly Regex regex;
private readonly string pattern;
/// <summary>
/// 域名匹配
/// </summary>
/// <param name="pattern">域名表达式</param>
public DomainMatch(string pattern)
{
this.pattern = pattern;
var regexPattern = Regex.Escape(pattern).Replace(@"\*", ".*");
this.regex = new Regex($"^{regexPattern}$", RegexOptions.IgnoreCase);
}
/// <summary>
/// 是否与指定域名匹配
/// </summary>
/// <param name="domain"></param>
/// <returns></returns>
public bool IsMatch(string domain)
{
return this.regex.IsMatch(domain);
}
/// <summary>
/// 转换为文本
/// </summary>
/// <returns></returns>
public override string ToString()
{
return this.pattern;
}
}
}

View File

@ -0,0 +1,29 @@
using System;
namespace FastGithub
{
/// <summary>
/// 表示FastGithub异常
/// </summary>
public class FastGithubException : Exception
{
/// <summary>
/// FastGithub异常
/// </summary>
/// <param name="message"></param>
public FastGithubException(string message)
: base(message)
{
}
/// <summary>
/// FastGithub异常
/// </summary>
/// <param name="message"></param>
/// <param name="innerException"></param>
public FastGithubException(string message, Exception? innerException)
: base(message, innerException)
{
}
}
}

View File

@ -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
/// 域名
/// </summary>
private DomainMatch[]? domainMatches;
private IPEndPoint? trustedDnsEndPoint;
private IPEndPoint? unTrustedDnsEndPoint;
/// <summary>
/// 受信任的dns服务
/// </summary>
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 };
/// <summary>
/// 不受信任的dns服务
/// </summary>
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 };
/// <summary>
/// 代理的域名匹配
/// </summary>
public HashSet<string> DomainMatches { get; set; } = new();
/// <summary>
/// 验证选项值
/// </summary>
/// <exception cref="FastGithubException"></exception>
public void Validate()
{
this.trustedDnsEndPoint = this.TrustedDns.ToIPEndPoint();
this.unTrustedDnsEndPoint = this.UntrustedDns.ToIPEndPoint();
this.domainMatches = this.DomainMatches.Select(item => new DomainMatch(item)).ToArray();
}
/// <summary>
/// 受信任的dns服务节点
/// </summary>
public IPEndPoint GetTrustedDns()
{
return this.trustedDnsEndPoint ?? throw new InvalidOperationException();
}
/// <summary>
/// 不受信任的dns服务节点
/// </summary>
public IPEndPoint GetUnTrustedDns()
{
return this.unTrustedDnsEndPoint ?? throw new InvalidOperationException();
}
/// <summary>
/// 是否匹配指定的域名
/// </summary>
@ -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));
}
/// <summary>
/// 域名匹配
/// </summary>
private class DomainMatch
{
private readonly Regex regex;
private readonly string pattern;
/// <summary>
/// 域名匹配
/// </summary>
/// <param name="pattern">域名表达式</param>
public DomainMatch(string pattern)
{
this.pattern = pattern;
var regexPattern = Regex.Escape(pattern).Replace(@"\*", ".*");
this.regex = new Regex($"^{regexPattern}$", RegexOptions.IgnoreCase);
}
/// <summary>
/// 是否与指定域名匹配
/// </summary>
/// <param name="domain"></param>
/// <returns></returns>
public bool IsMatch(string domain)
{
return this.regex.IsMatch(domain);
}
/// <summary>
/// 转换为文本
/// </summary>
/// <returns></returns>
public override string ToString()
{
return this.pattern;
}
}
}
}

View File

@ -7,7 +7,7 @@ namespace FastGithub
/// <summary>
/// dns的终节点
/// </summary>
public class DnsIPEndPoint
public class IPEndPointOptions
{
/// <summary>
/// IP地址
@ -24,29 +24,20 @@ namespace FastGithub
/// 转换为IPEndPoint
/// </summary>
/// <returns></returns>
/// <exception cref="FastGithubException"></exception>
public IPEndPoint ToIPEndPoint()
{
return new IPEndPoint(System.Net.IPAddress.Parse(this.IPAddress), this.Port);
}
/// <summary>
/// 验证dns
/// 防止使用自己使用自己来解析域名造成死循环
/// </summary>
/// <returns></returns>
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);
}
/// <summary>

View File

@ -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);
}
}
}

View File

@ -1,20 +0,0 @@
using System;
namespace FastGithub.ReverseProxy
{
/// <summary>
/// 反向代理异常
/// </summary>
sealed class ReverseProxyException : Exception
{
/// <summary>
/// 反向代理异常
/// </summary>
/// <param name="message"></param>
/// <param name="inner"></param>
public ReverseProxyException(string message, Exception? inner)
: base(message, inner)
{
}
}
}

View File

@ -39,7 +39,7 @@ namespace FastGithub
.AddDnscryptProxy()
.AddOptions<FastGithubOptions>()
.Bind(ctx.Configuration.GetSection(nameof(FastGithub)))
.Validate(opt => opt.TrustedDns.Validate() && opt.UntrustedDns.Validate(), "无效的Dns配置");
.PostConfigure(opt => opt.Validate());
})
.ConfigureWebHostDefaults(web =>
{