/// <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);
        }
        private async Task RetrieveQueryResultFromDnsAsync(DnsSrvServiceDescription service)
        {
            Logger?.LogDebug("Retrieve DnsService values {service}", service);
            QueryResult = await DnsQuerier.QueryServiceAsync(service);

            DnsSortResult.Sort(QueryResult);
            LastService = service;
        }
예제 #3
0
        /// <summary>
        /// Create a Dns url string from the DnsSrvServiceDescription.
        /// </summary>
        /// <param name="service">The dns info.</param>
        /// <returns>Dns url create.</returns>
        protected string CreateDnsQueryString(DnsSrvServiceDescription service)
        {
            service = service ?? throw new ArgumentNullException(nameof(service), "The service should not be null.");
            string dnsQueryString = $"_{service.ServiceName}._{service.Protocol}.{service.Domain}.";

            Logger?.LogDebug("Dns query string build : {dnsQueryString}" + dnsQueryString);
            return(dnsQueryString);
        }
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DnsServiceBalancingMessageHandler"/> class.
 /// </summary>
 /// <param name="serviceDescription">The server description.</param>
 /// <param name="targetSelector">The api caller and selector.</param>
 /// <param name="quarantinePolicy">The respose quarantine policy to blacklist an host and retrieve the request.</param>
 /// <param name="logger">The logger.</param>
 public DnsServiceBalancingMessageHandler(
     DnsSrvServiceDescription serviceDescription,
     IDnsServiceTargetSelector targetSelector,
     ITargetQuarantinePolicy quarantinePolicy,
     ILogger logger = null)
 {
     ServiceDescription = serviceDescription;
     TargetSelector     = targetSelector;
     QuarantinePolicy   = quarantinePolicy;
     Logger             = logger;
 }
예제 #5
0
 /// <summary>
 /// Are this object equal to an other DnsSrvServiceDescription.
 /// </summary>
 /// <param name="obj">an other DnsSrvServiceDescription.</param>
 /// <returns>Is equal or not.</returns>
 public override bool Equals(object obj)
 {
     if ((obj == null) || !this.GetType().Equals(obj.GetType()))
     {
         return(false);
     }
     else
     {
         DnsSrvServiceDescription service = (DnsSrvServiceDescription)obj;
         return(GetHashCode() == service.GetHashCode());
     }
 }
        internal void CheckService(DnsSrvServiceDescription service)
        {
            if (service == null)
            {
                Logger?.LogError("DnsSrvServiceDescription service null found");
                throw new ArgumentNullException(nameof(service));
            }

            if (LastService != null && !service.Equals(LastService))
            {
                Logger?.LogError("Cannot change the resolved service");
                throw new Exception("Cannot change the resolved service");
            }
        }
        /// <summary>
        /// Reset all the DnsSrvServiceDescription values.
        /// </summary>
        /// <returns>The Task return.</returns>
        public async Task ResetAsync()
        {
            await SemaphoreKey.WaitAsync();

            try
            {
                Logger?.LogDebug("Reset of DnsServiceTargetSelectorReal");
                QueryResult = null;
                LastService = null;
            }
            finally
            {
                SemaphoreKey.Release();
            }
        }
예제 #8
0
        /// <summary>
        /// Ask a new srv call.
        /// </summary>
        /// <param name="service">Address to be call.</param>
        /// <returns>Call Response with HostName, Port, Priority, Weight and Ttl.</returns>
        public async Task <DnsSrvQueryResult> QueryServiceAsync(DnsSrvServiceDescription service)
        {
            if (service == null)
            {
                Logger?.LogError("DnsSrvServiceDescription cannot be null.");
                throw new ArgumentNullException(nameof(service));
            }

            string queryString = CreateDnsQueryString(service);
            var    result      = await LookupClient.QueryAsync(queryString, QueryType.SRV).ConfigureAwait(false);

            var queryResult = ResolveServiceProcessResult(result);

            return(new DnsSrvQueryResult(queryResult));
        }
        /// <summary>
        /// Extract a service and a domain from an Uri.
        /// </summary>
        /// <param name="uri">Uri to be extract.</param>
        /// <returns>DnsSrvServiceDescription object.</returns>
        public DnsSrvServiceDescription FromUri(Uri uri)
        {
            uri = uri ?? throw new ArgumentNullException(nameof(uri), "The uri should not be null.");

            var splitIndex  = uri.DnsSafeHost.IndexOf(".");
            var serviceName = uri.DnsSafeHost.Substring(0, splitIndex);
            var domain      = uri.DnsSafeHost.Substring(splitIndex + 1);

            if ((ServiceWhiteList != null && !ServiceWhiteList.Contains(serviceName)) ||
                (DomainWhiteList != null &&
                 ((AllowSubDomains && !DomainWhiteList.Any(dom => domain.EndsWith(dom))) ||
                  (!AllowSubDomains && !DomainWhiteList.Contains(domain)))))
            {
                return(null);
            }

            var dnsSrvServiceDescription = new DnsSrvServiceDescription(
                serviceName: serviceName,
                protocol: Protocol,
                domain: domain);

            return(dnsSrvServiceDescription);
        }