增加FastGithubException异常
This commit is contained in:
parent
49a18eaae9
commit
92ce30af09
43
FastGithub.Core/DomainMatch.cs
Normal file
43
FastGithub.Core/DomainMatch.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
FastGithub.Core/FastGithubException.cs
Normal file
29
FastGithub.Core/FastGithubException.cs
Normal 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 =>
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user