private static async Task <IPHostEntry> GetHostEntryFromNameAsync(IDnsQuery query, string hostName)
        {
            if (string.IsNullOrWhiteSpace(hostName))
            {
                throw new ArgumentNullException(nameof(hostName));
            }

            var hostString = DnsString.FromResponseQueryString(hostName);
            var ipv4Result = query.QueryAsync(hostString, QueryType.A);
            var ipv6Result = query.QueryAsync(hostString, QueryType.AAAA);

            await Task.WhenAll(ipv4Result, ipv6Result).ConfigureAwait(false);

            var allRecords = ipv4Result.Result
                             .Answers.Concat(ipv6Result.Result.Answers)
                             .ToArray();

            return(GetHostEntryProcessResult(hostString, allRecords));
        }
Exemplo n.º 2
0
        public static async Task <ServiceHostEntry[]> ResolveServiceAsync(this IDnsQuery query, string baseDomain, string serviceName, string tag = null)
        {
            if (baseDomain == null)
            {
                throw new ArgumentNullException(nameof(baseDomain));
            }
            if (string.IsNullOrWhiteSpace(serviceName))
            {
                throw new ArgumentNullException(nameof(serviceName));
            }

            string queryString;

            if (string.IsNullOrWhiteSpace(tag))
            {
                queryString = $"{serviceName}.{baseDomain}.";
            }
            else
            {
                queryString = $"_{serviceName}._{tag}.{baseDomain}.";
            }

            var hosts  = new List <ServiceHostEntry>();
            var result = await query.QueryAsync(queryString, QueryType.SRV);

            if (result.HasError)
            {
                return(hosts.ToArray());
            }

            foreach (var entry in result.Answers.SrvRecords())
            {
                var addresses = result.Additionals
                                .OfType <AddressRecord>()
                                .Where(p => p.DomainName.Equals(entry.Target))
                                .Select(p => p.Address);

                hosts.Add(new ServiceHostEntry()
                {
                    AddressList = addresses.ToArray(),
                    HostName    = entry.Target.Value,
                    Port        = entry.Port
                });
            }

            return(hosts.ToArray());
        }
        /// <summary>
        /// The <c>ResolveServiceAsync</c> method does a <see cref="QueryType.SRV"/> lookup for <c>_{<paramref name="serviceName"/>}[._{<paramref name="tag"/>}].{<paramref name="baseDomain"/>}</c>
        /// and aggregates the result (hostname, port and list of <see cref="IPAddress"/>s) to a <see cref="ServiceHostEntry"/>.
        /// <para>
        /// This method expects matching A or AAAA records to populate the <see cref="IPHostEntry.AddressList"/>,
        /// and/or a <see cref="ResourceRecordType.CNAME"/> record to populate the <see cref="IPHostEntry.HostName"/> property of the result.
        /// </para>
        /// </summary>
        /// <remarks>
        /// The returned list of <see cref="IPAddress"/>s and/or the hostname can be empty if no matching additional records are found.
        /// </remarks>
        /// <param name="query">The <see cref="IDnsQuery"/> instance.</param>
        /// <param name="baseDomain">The base domain, which will be appended to the end of the query string.</param>
        /// <param name="serviceName">The name of the service to look for. Must not have any <c>_</c> prefix.</param>
        /// <param name="tag">An optional tag. Must not have any <c>_</c> prefix.</param>
        /// <returns>A collection of <see cref="ServiceHostEntry"/>s.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="baseDomain"/> or <paramref name="serviceName"/> are null.</exception>
        /// <seealso href="https://tools.ietf.org/html/rfc2782">RFC 2782</seealso>
        public static async Task <ServiceHostEntry[]> ResolveServiceAsync(this IDnsQuery query, string baseDomain, string serviceName, string tag = null)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }
            if (baseDomain == null)
            {
                throw new ArgumentNullException(nameof(baseDomain));
            }
            if (string.IsNullOrWhiteSpace(serviceName))
            {
                throw new ArgumentNullException(nameof(serviceName));
            }

            var queryString = ConcatResolveServiceName(baseDomain, serviceName, tag);

            var result = await query.QueryAsync(queryString, QueryType.SRV).ConfigureAwait(false);

            return(ResolveServiceProcessResult(result));
        }