自动侦测本机ip做为dns响应值
This commit is contained in:
parent
4ce79fa5d6
commit
2bacf5a4fc
@ -40,7 +40,9 @@ namespace FastGithub.Dns
|
|||||||
{
|
{
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.requestResolver = new CompositeRequestResolver(IPAddress.Parse(options.Value.UpStream), githubRequestResolver);
|
|
||||||
|
var upStream = IPAddress.Parse(options.Value.UpStream);
|
||||||
|
this.requestResolver = new CompositeRequestResolver(upStream, githubRequestResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -57,7 +59,8 @@ namespace FastGithub.Dns
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.LogInformation("dns服务启动成功");
|
this.logger.LogInformation("dns服务启动成功");
|
||||||
this.dnsAddresses = this.SetNameServers(IPAddress.Loopback, IPAddress.Parse(this.options.Value.UpStream));
|
var upStream = IPAddress.Parse(options.Value.UpStream);
|
||||||
|
this.dnsAddresses = this.SetNameServers(IPAddress.Loopback, upStream);
|
||||||
return base.StartAsync(cancellationToken);
|
return base.StartAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +77,7 @@ namespace FastGithub.Dns
|
|||||||
var result = await this.socket.ReceiveFromAsync(this.buffer, SocketFlags.None, remoteEndPoint);
|
var result = await this.socket.ReceiveFromAsync(this.buffer, SocketFlags.None, remoteEndPoint);
|
||||||
var datas = new byte[result.ReceivedBytes];
|
var datas = new byte[result.ReceivedBytes];
|
||||||
this.buffer.AsSpan(0, datas.Length).CopyTo(datas);
|
this.buffer.AsSpan(0, datas.Length).CopyTo(datas);
|
||||||
this.HandleRequestAsync(datas, result.RemoteEndPoint, stoppingToken);
|
this.HandleRequestAsync(datas, (IPEndPoint)result.RemoteEndPoint, stoppingToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,12 +87,13 @@ namespace FastGithub.Dns
|
|||||||
/// <param name="datas"></param>
|
/// <param name="datas"></param>
|
||||||
/// <param name="remoteEndPoint"></param>
|
/// <param name="remoteEndPoint"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
private async void HandleRequestAsync(byte[] datas, EndPoint remoteEndPoint, CancellationToken cancellationToken)
|
private async void HandleRequestAsync(byte[] datas, IPEndPoint remoteEndPoint, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var request = Request.FromArray(datas);
|
var request = Request.FromArray(datas);
|
||||||
var response = await this.requestResolver.Resolve(request, cancellationToken);
|
var remoteRequest = new RemoteRequest(request, remoteEndPoint.Address);
|
||||||
|
var response = await this.requestResolver.Resolve(remoteRequest, cancellationToken);
|
||||||
await this.socket.SendToAsync(response.ToArray(), SocketFlags.None, remoteEndPoint);
|
await this.socket.SendToAsync(response.ToArray(), SocketFlags.None, remoteEndPoint);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Net;
|
|
||||||
|
|
||||||
namespace FastGithub.Dns
|
namespace FastGithub.Dns
|
||||||
{
|
{
|
||||||
@ -28,10 +27,5 @@ namespace FastGithub.Dns
|
|||||||
/// 是否使用反向代理访问github
|
/// 是否使用反向代理访问github
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool UseGithubReverseProxy { get; set; } = true;
|
public bool UseGithubReverseProxy { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// dns响应的反向代理服务的ip
|
|
||||||
/// </summary>
|
|
||||||
public string GithubReverseProxyIPAddress { get; set; } = IPAddress.Loopback.ToString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,38 +48,55 @@ namespace FastGithub.Dns
|
|||||||
public Task<IResponse> Resolve(IRequest request, CancellationToken cancellationToken = default)
|
public Task<IResponse> Resolve(IRequest request, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
IResponse response = Response.FromRequest(request);
|
IResponse response = Response.FromRequest(request);
|
||||||
var question = request.Questions.FirstOrDefault();
|
if (request is not RemoteRequest remoteRequest)
|
||||||
|
{
|
||||||
|
return Task.FromResult(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
var question = request.Questions.FirstOrDefault();
|
||||||
if (question == null || question.Type != RecordType.A)
|
if (question == null || question.Type != RecordType.A)
|
||||||
{
|
{
|
||||||
return Task.FromResult(response);
|
return Task.FromResult(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
var domain = question.Name.ToString();
|
var domain = question.Name;
|
||||||
if (this.githubResolver.IsSupported(domain) == false)
|
if (this.githubResolver.IsSupported(domain.ToString()) == false)
|
||||||
{
|
{
|
||||||
return Task.FromResult(response);
|
return Task.FromResult(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.CurrentValue.UseGithubReverseProxy == false)
|
var record = this.GetAnswerRecord(remoteRequest, domain);
|
||||||
|
if (record != null)
|
||||||
{
|
{
|
||||||
var address = this.githubResolver.Resolve(domain);
|
this.logger.LogInformation($"[{domain}->{record.IPAddress}]");
|
||||||
if (address != null)
|
|
||||||
{
|
|
||||||
var ttl = this.options.CurrentValue.GithubTTL;
|
|
||||||
var record = new IPAddressResourceRecord(question.Name, address, ttl);
|
|
||||||
response.AnswerRecords.Add(record);
|
|
||||||
this.logger.LogInformation($"[{domain}->{address}]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var address = IPAddress.Parse(this.options.CurrentValue.GithubReverseProxyIPAddress);
|
|
||||||
var record = new IPAddressResourceRecord(question.Name, address, TimeSpan.FromMinutes(1));
|
|
||||||
response.AnswerRecords.Add(record);
|
response.AnswerRecords.Add(record);
|
||||||
this.logger.LogInformation($"[{domain}->{address}]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(response);
|
return Task.FromResult(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取答案
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="domain"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private IPAddressResourceRecord? GetAnswerRecord(RemoteRequest request, Domain domain)
|
||||||
|
{
|
||||||
|
if (this.options.CurrentValue.UseGithubReverseProxy == true)
|
||||||
|
{
|
||||||
|
var localAddress = request.GetLocalAddress() ?? IPAddress.Loopback;
|
||||||
|
return new IPAddressResourceRecord(domain, localAddress, TimeSpan.FromMinutes(1d));
|
||||||
|
}
|
||||||
|
|
||||||
|
var githubAddress = this.githubResolver.Resolve(domain.ToString());
|
||||||
|
if (githubAddress == null)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ttl = this.options.CurrentValue.GithubTTL;
|
||||||
|
return new IPAddressResourceRecord(domain, githubAddress, ttl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
77
FastGithub.Dns/RemoteRequest.cs
Normal file
77
FastGithub.Dns/RemoteRequest.cs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
using DNS.Protocol;
|
||||||
|
using System.Buffers.Binary;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
|
||||||
|
namespace FastGithub.Dns
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 远程请求
|
||||||
|
/// </summary>
|
||||||
|
sealed class RemoteRequest : Request
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取远程地址
|
||||||
|
/// </summary>
|
||||||
|
public IPAddress RemoteAddress { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 远程请求
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="remoteAddress"></param>
|
||||||
|
public RemoteRequest(Request request, IPAddress remoteAddress)
|
||||||
|
: base(request)
|
||||||
|
{
|
||||||
|
this.RemoteAddress = remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取对应的本机地址
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public IPAddress? GetLocalAddress()
|
||||||
|
{
|
||||||
|
foreach (var @interface in NetworkInterface.GetAllNetworkInterfaces())
|
||||||
|
{
|
||||||
|
var addresses = @interface.GetIPProperties().UnicastAddresses;
|
||||||
|
foreach (var item in addresses)
|
||||||
|
{
|
||||||
|
if (IsInSubNet(item.IPv4Mask, item.Address, this.RemoteAddress))
|
||||||
|
{
|
||||||
|
return item.Address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否在相同的子网里
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mask"></param>
|
||||||
|
/// <param name="local"></param>
|
||||||
|
/// <param name="remote"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static bool IsInSubNet(IPAddress mask, IPAddress local, IPAddress remote)
|
||||||
|
{
|
||||||
|
if (local.AddressFamily != remote.AddressFamily)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var maskValue = GetValue(mask);
|
||||||
|
var localValue = GetValue(local);
|
||||||
|
var remoteValue = GetValue(remote);
|
||||||
|
return (maskValue & localValue) == (maskValue & remoteValue);
|
||||||
|
|
||||||
|
static long GetValue(IPAddress address)
|
||||||
|
{
|
||||||
|
var bytes = address.GetAddressBytes();
|
||||||
|
return bytes.Length == sizeof(int)
|
||||||
|
? BinaryPrimitives.ReadInt32BigEndian(bytes)
|
||||||
|
: BinaryPrimitives.ReadInt64BigEndian(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,8 +3,7 @@
|
|||||||
"UpStream": "114.114.114.114", // 上游dns
|
"UpStream": "114.114.114.114", // 上游dns
|
||||||
"GithubTTL": "00:10:00", // github相关域名解析结果的存活时长
|
"GithubTTL": "00:10:00", // github相关域名解析结果的存活时长
|
||||||
"SetToLocalMachine": true, // 是否设置本机使用此dns(仅支持windows)
|
"SetToLocalMachine": true, // 是否设置本机使用此dns(仅支持windows)
|
||||||
"UseGithubReverseProxy": true, // 是否使用反向代理访问github以解决连接被重复的问题
|
"UseGithubReverseProxy": true // 是否使用反向代理访问github以解决连接被重复的问题
|
||||||
"GithubReverseProxyIPAddress": "127.0.0.1" // dns响应的反向代理服务ip,局域网部署时要填写局域网ip
|
|
||||||
},
|
},
|
||||||
"Lookup": { // ip查找
|
"Lookup": { // ip查找
|
||||||
"IPAddressComProvider": {
|
"IPAddressComProvider": {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user