/// <summary>
        /// Retrive the chosen DNS response endPoint.
        /// </summary>
        /// <param name="service">Dns service to call.</param>
        /// <exception cref="ArgumentNullException">Thrown when service is null.</exception>
        /// <exception cref="Exception">Thrown when service is different to the last service call.</exception>
        /// <returns>the DnsEndpoint response or null if no endPoint found.</returns>
        public async Task <DnsEndPoint> SelectHostAsync(DnsSrvServiceDescription service)
        {
            await SemaphoreKey.WaitAsync();

            try
            {
                CheckService(service);

                if (ShouldRetrieveResult)
                {
                    await RetrieveQueryResultFromDnsAsync(service);
                }

                DnsSrvResultEntry entryFound = QueryResult?.DnsEntries?.FirstOrDefault(entry => entry.IsAvailable);

                if (entryFound != null)
                {
                    Logger?.LogDebug("Entry found {entryFound}", entryFound);
                    return(entryFound.DnsEndPoint);
                }

                QueryResult?.ReduceLifeTime(ServerRecoveryUnavailableTime);
                Logger?.LogDebug("No entry found : 0 / {entryCount}", QueryResult?.DnsEntries?.Count ?? 0);
                Logger?.LogDebug("The DNS server will be recall at: {QueryResultTtlEndTime}", QueryResult?.TtlEndTime);
            }
            finally
            {
                SemaphoreKey.Release();
            }

            return(null);
        }
示例#2
0
        /// <summary>
        /// Extract the IDnsQueryResponse to build a List of DnsSrvResultEntry.
        /// </summary>
        /// <param name="result">Query response.</param>
        /// <returns>Entities List.</returns>
        protected List <DnsSrvResultEntry> ResolveServiceProcessResult(IDnsQueryResponse result)
        {
            // https://github.com/MichaCo/DnsClient.NET/blob/dev/src/DnsClient/DnsQueryExtensions.cs/#L628
            var hosts = new List <DnsSrvResultEntry>();

            if (result == null || result.HasError)
            {
                var errorMessage = result == null ? "Dns request return a null response" : result.ErrorMessage;
                Logger?.LogWarning("Dns Request fail: {errorMessage} returning empty hosts list", errorMessage);
                return(hosts);
            }

            foreach (var entry in result.Answers.SrvRecords())
            {
                var timeToLive = entry.TimeToLive;
                var hostName   = result.Additionals
                                 .OfType <CNameRecord>()
                                 .Where(p => p.DomainName.Equals(entry.Target))
                                 .Select(p => p.CanonicalName).FirstOrDefault()
                                 ?? entry.Target;

                var dnsEntry = new DnsSrvResultEntry(hostName, entry.Port, entry.Priority, entry.Weight, timeToLive);
                Logger?.LogDebug("Dns Entry create : {dnsEntry}", dnsEntry.ToString("f"));
                hosts.Add(dnsEntry);
            }

            return(hosts);
        }