using DNS.Protocol;
using System.Buffers.Binary;
using System.Net;
using System.Net.NetworkInformation;
namespace FastGithub.Dns
{
///
/// 远程请求
///
sealed class RemoteRequest : Request
{
///
/// 获取远程地址
///
public IPAddress RemoteAddress { get; }
///
/// 远程请求
///
///
///
public RemoteRequest(Request request, IPAddress remoteAddress)
: base(request)
{
this.RemoteAddress = remoteAddress;
}
///
/// 获取对应的本机地址
///
///
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;
}
///
/// 是否在相同的子网里
///
///
///
///
///
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);
}
}
}
}