mirror of
https://github.com/fergalmoran/DnsServer.git
synced 2025-12-28 12:30:18 +00:00
GeoDistanceApp: updated implementation to support EDNS Client Subnet.
This commit is contained in:
@@ -28,6 +28,7 @@ using System.Net.Sockets;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TechnitiumLibrary;
|
using TechnitiumLibrary;
|
||||||
using TechnitiumLibrary.Net.Dns;
|
using TechnitiumLibrary.Net.Dns;
|
||||||
|
using TechnitiumLibrary.Net.Dns.EDnsOptions;
|
||||||
using TechnitiumLibrary.Net.Dns.ResourceRecords;
|
using TechnitiumLibrary.Net.Dns.ResourceRecords;
|
||||||
|
|
||||||
namespace GeoDistance
|
namespace GeoDistance
|
||||||
@@ -36,6 +37,7 @@ namespace GeoDistance
|
|||||||
{
|
{
|
||||||
#region variables
|
#region variables
|
||||||
|
|
||||||
|
IDnsServer _dnsServer;
|
||||||
MaxMind _maxMind;
|
MaxMind _maxMind;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -84,6 +86,7 @@ namespace GeoDistance
|
|||||||
|
|
||||||
public Task InitializeAsync(IDnsServer dnsServer, string config)
|
public Task InitializeAsync(IDnsServer dnsServer, string config)
|
||||||
{
|
{
|
||||||
|
_dnsServer = dnsServer;
|
||||||
_maxMind = MaxMind.Create(dnsServer);
|
_maxMind = MaxMind.Create(dnsServer);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@@ -98,13 +101,34 @@ namespace GeoDistance
|
|||||||
case DnsResourceRecordType.AAAA:
|
case DnsResourceRecordType.AAAA:
|
||||||
Location location = null;
|
Location location = null;
|
||||||
|
|
||||||
if (_maxMind.DatabaseReader.TryCity(remoteEP.Address, out CityResponse response))
|
EDnsClientSubnetOptionData clientSubnet = null;
|
||||||
|
|
||||||
|
if (request.EDNS is not null)
|
||||||
|
{
|
||||||
|
foreach (EDnsOption option in request.EDNS.Options)
|
||||||
|
{
|
||||||
|
if (option.Code == EDnsOptionCode.EDNS_CLIENT_SUBNET)
|
||||||
|
{
|
||||||
|
EDnsClientSubnetOptionData cs = option.Data as EDnsClientSubnetOptionData;
|
||||||
|
|
||||||
|
if (_maxMind.DatabaseReader.TryCity(cs.Address, out CityResponse csResponse) && csResponse.Location.HasCoordinates)
|
||||||
|
{
|
||||||
|
location = csResponse.Location;
|
||||||
|
clientSubnet = cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((location is null) && _maxMind.DatabaseReader.TryCity(remoteEP.Address, out CityResponse response) && response.Location.HasCoordinates)
|
||||||
location = response.Location;
|
location = response.Location;
|
||||||
|
|
||||||
dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
|
dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
|
||||||
dynamic jsonClosestServer = null;
|
dynamic jsonClosestServer = null;
|
||||||
|
|
||||||
if ((location == null) || !location.HasCoordinates)
|
if (location is null)
|
||||||
{
|
{
|
||||||
jsonClosestServer = jsonAppRecordData[0];
|
jsonClosestServer = jsonAppRecordData[0];
|
||||||
}
|
}
|
||||||
@@ -127,7 +151,7 @@ namespace GeoDistance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jsonClosestServer == null)
|
if (jsonClosestServer is null)
|
||||||
return Task.FromResult<DnsDatagram>(null);
|
return Task.FromResult<DnsDatagram>(null);
|
||||||
|
|
||||||
List<DnsResourceRecord> answers = new List<DnsResourceRecord>();
|
List<DnsResourceRecord> answers = new List<DnsResourceRecord>();
|
||||||
@@ -161,7 +185,17 @@ namespace GeoDistance
|
|||||||
if (answers.Count > 1)
|
if (answers.Count > 1)
|
||||||
answers.Shuffle();
|
answers.Shuffle();
|
||||||
|
|
||||||
return Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers));
|
EDnsOption[] options = null;
|
||||||
|
|
||||||
|
if (clientSubnet is not null)
|
||||||
|
{
|
||||||
|
options = new EDnsOption[]
|
||||||
|
{
|
||||||
|
new EDnsOption(EDnsOptionCode.EDNS_CLIENT_SUBNET, new EDnsClientSubnetOptionData(clientSubnet.SourcePrefixLength, clientSubnet.SourcePrefixLength, clientSubnet.Address))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers, null, null, _dnsServer.UdpPayloadSize, EDnsHeaderFlags.None, options));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Task.FromResult<DnsDatagram>(null);
|
return Task.FromResult<DnsDatagram>(null);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ using System.Collections.Generic;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TechnitiumLibrary.Net.Dns;
|
using TechnitiumLibrary.Net.Dns;
|
||||||
|
using TechnitiumLibrary.Net.Dns.EDnsOptions;
|
||||||
using TechnitiumLibrary.Net.Dns.ResourceRecords;
|
using TechnitiumLibrary.Net.Dns.ResourceRecords;
|
||||||
|
|
||||||
namespace GeoDistance
|
namespace GeoDistance
|
||||||
@@ -34,6 +35,7 @@ namespace GeoDistance
|
|||||||
{
|
{
|
||||||
#region variables
|
#region variables
|
||||||
|
|
||||||
|
IDnsServer _dnsServer;
|
||||||
MaxMind _maxMind;
|
MaxMind _maxMind;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -82,6 +84,7 @@ namespace GeoDistance
|
|||||||
|
|
||||||
public Task InitializeAsync(IDnsServer dnsServer, string config)
|
public Task InitializeAsync(IDnsServer dnsServer, string config)
|
||||||
{
|
{
|
||||||
|
_dnsServer = dnsServer;
|
||||||
_maxMind = MaxMind.Create(dnsServer);
|
_maxMind = MaxMind.Create(dnsServer);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@@ -91,13 +94,34 @@ namespace GeoDistance
|
|||||||
{
|
{
|
||||||
Location location = null;
|
Location location = null;
|
||||||
|
|
||||||
if (_maxMind.DatabaseReader.TryCity(remoteEP.Address, out CityResponse response))
|
EDnsClientSubnetOptionData clientSubnet = null;
|
||||||
|
|
||||||
|
if (request.EDNS is not null)
|
||||||
|
{
|
||||||
|
foreach (EDnsOption option in request.EDNS.Options)
|
||||||
|
{
|
||||||
|
if (option.Code == EDnsOptionCode.EDNS_CLIENT_SUBNET)
|
||||||
|
{
|
||||||
|
EDnsClientSubnetOptionData cs = option.Data as EDnsClientSubnetOptionData;
|
||||||
|
|
||||||
|
if (_maxMind.DatabaseReader.TryCity(cs.Address, out CityResponse csResponse) && csResponse.Location.HasCoordinates)
|
||||||
|
{
|
||||||
|
location = csResponse.Location;
|
||||||
|
clientSubnet = cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((location is null) && _maxMind.DatabaseReader.TryCity(remoteEP.Address, out CityResponse response) && response.Location.HasCoordinates)
|
||||||
location = response.Location;
|
location = response.Location;
|
||||||
|
|
||||||
dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
|
dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
|
||||||
dynamic jsonClosestServer = null;
|
dynamic jsonClosestServer = null;
|
||||||
|
|
||||||
if ((location == null) || !location.HasCoordinates)
|
if (location is null)
|
||||||
{
|
{
|
||||||
jsonClosestServer = jsonAppRecordData[0];
|
jsonClosestServer = jsonAppRecordData[0];
|
||||||
}
|
}
|
||||||
@@ -120,11 +144,11 @@ namespace GeoDistance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jsonClosestServer == null)
|
if (jsonClosestServer is null)
|
||||||
return Task.FromResult<DnsDatagram>(null);
|
return Task.FromResult<DnsDatagram>(null);
|
||||||
|
|
||||||
dynamic jsonCname = jsonClosestServer.cname;
|
dynamic jsonCname = jsonClosestServer.cname;
|
||||||
if (jsonCname == null)
|
if (jsonCname is null)
|
||||||
return Task.FromResult<DnsDatagram>(null);
|
return Task.FromResult<DnsDatagram>(null);
|
||||||
|
|
||||||
string cname = jsonCname.Value;
|
string cname = jsonCname.Value;
|
||||||
@@ -138,7 +162,17 @@ namespace GeoDistance
|
|||||||
else
|
else
|
||||||
answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecordData(cname)) };
|
answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecordData(cname)) };
|
||||||
|
|
||||||
return Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers));
|
EDnsOption[] options = null;
|
||||||
|
|
||||||
|
if (clientSubnet is not null)
|
||||||
|
{
|
||||||
|
options = new EDnsOption[]
|
||||||
|
{
|
||||||
|
new EDnsOption(EDnsOptionCode.EDNS_CLIENT_SUBNET, new EDnsClientSubnetOptionData(clientSubnet.SourcePrefixLength, clientSubnet.SourcePrefixLength, clientSubnet.Address))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers, null, null, _dnsServer.UdpPayloadSize, EDnsHeaderFlags.None, options));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
Reference in New Issue
Block a user