Beispiel #1
0
    // 正引き v4/v6 Dual Stack 対応
    public async Task <List <IPAddress> > GetIpAddressListDualStackAsync(string hostname, bool preferV6 = false, CancellationToken cancel = default, bool noCache = false)
    {
        try
        {
            ConcurrentBag <Tuple <IPAddress, int> > list = new();

            var queryTypeList = new DnsResolverQueryType[] { DnsResolverQueryType.A, DnsResolverQueryType.AAAA };

            await TaskUtil.ForEachAsync(int.MaxValue, queryTypeList, async (item, index, cancel) =>
            {
                var resultsList = await GetIpAddressListSingleStackAsync(hostname, item, null, cancel, noCache);

                if (resultsList != null)
                {
                    int i = 0;
                    foreach (var ip in resultsList.Distinct(IpComparer.Comparer))
                    {
                        list.Add(new Tuple <IPAddress, int>(ip, i));

                        i++;
                    }
                }
            }, cancel, 0);

            return(list.OrderBy(x => (int)x.Item1.AddressFamily * (preferV6 ? -1 : 1)).Select(x => x.Item1).Distinct().ToList());
        }
        catch
        {
            return(new List <IPAddress>(0));
        }
    }
Beispiel #2
0
 protected abstract Task <IEnumerable <IPAddress>?> GetIpAddressListImplAsync(string hostname, DnsResolverQueryType queryType, Ref <DnsAdditionalResults>?additional = null, CancellationToken cancel = default);
    protected override async Task <IEnumerable <IPAddress>?> GetIpAddressListImplAsync(string hostname, DnsResolverQueryType queryType, Ref <DnsAdditionalResults>?additional = null, CancellationToken cancel = default)
    {
        DnsAdditionalResults additionalData = new DnsAdditionalResults(true, false);

        QueryType qt;

        switch (queryType)
        {
        case DnsResolverQueryType.A:
            qt = QueryType.A;
            break;

        case DnsResolverQueryType.AAAA:
            qt = QueryType.AAAA;
            break;

        default:
            throw new ArgumentOutOfRangeException(nameof(queryType));
        }

        try
        {
            var res = await Client.QueryAsync(hostname, qt, queryClass : QueryClass.IN, cancel);

            if (res.Header.ResponseCode == DnsHeaderResponseCode.NotExistentDomain)
            {
                additionalData = new DnsAdditionalResults(false, true);
            }

            if (res.HasError)
            {
                additionalData = new DnsAdditionalResults(true, false);
                return(null);
            }

            if (qt == QueryType.A)
            {
                return(res.Answers?.ARecords().Where(x => x.Address.AddressFamily == AddressFamily.InterNetwork).Select(x => x.Address).ToArray() ?? null);
            }
            else
            {
                return(res.Answers?.AaaaRecords().Where(x => x.Address.AddressFamily == AddressFamily.InterNetworkV6).Select(x => x.Address).ToArray() ?? null);
            }
        }
        finally
        {
            additional?.Set(additionalData);
        }
    }