/// <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; }
/// <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); }
/// <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; }
/// <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(); } }
/// <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); }