/// <summary> /// Get cached list of authoritative name server ip addresses /// </summary> /// <param name="domainName"></param> /// <param name="round"></param> /// <returns></returns> public async Task <DnsLookupResult> GetAuthority(string domainName, int round = 0, bool followCnames = true, DnsLookupResult?from = null) { var key = domainName.ToLower().TrimEnd('.'); try { // Example: _acme-challenge.sub.example.co.uk domainName = domainName.TrimEnd('.'); // First domain we should try to ask is the tld (e.g. co.uk) var rootDomain = _domainParser.GetTLD(domainName); var testZone = rootDomain; var client = GetDefaultClient(round); // Other sub domains we should ask: // 1. example // 1. sub // 2. _acme-challenge var remainingParts = domainName.Substring(0, domainName.LastIndexOf(rootDomain)) .Trim('.').Split('.').Where(x => !string.IsNullOrEmpty(x)) .Reverse().ToArray(); var digDeeper = true; IEnumerable <IPAddress>?ipSet = null; do { // Partial result cachign if (!_authoritativeNs.ContainsKey(testZone)) { _log.Verbose("Querying server {server} about {part}", client.IpAddress, testZone); using (LogContext.PushProperty("Domain", testZone)) { var tempResult = await client.GetNameServers(testZone, round); _authoritativeNs.TryAdd(testZone, tempResult?.ToList() ?? ipSet ?? _defaultNs); } } ipSet = _authoritativeNs[testZone]; client = Produce(ipSet.OrderBy(x => Guid.NewGuid()).First()); // CNAME only valid for full domain. Subdomains may be // regular records again if (followCnames && testZone == key) { var cname = default(string?); if (!_cnames.ContainsKey(key)) { _cnames.TryAdd(key, await client.GetCname(testZone)); } cname = _cnames[key]; if (cname != null) { return(await GetAuthority(cname, round, true, Produce(key, from))); } } if (remainingParts.Any()) { testZone = $"{remainingParts[0]}.{testZone}"; remainingParts = remainingParts[1..];
private string?GetTldCache(string domain) { if (_tldCache.TryGetValue(domain, out var value)) { return(value); } value = _domainParser.GetTLD(domain); _tldCache.Add(domain, value); return(value); }
private string?GetTldCache(string domain) { if (_tldCache.TryGetValue(domain, out var value)) { return(value); } try { value = _domainParser.GetTLD(domain); _tldCache.Add(domain, value); } catch { value = ".error"; _tldCache.Add(domain, value); } return(value); }
public string GetRootDomain(string domainName) => _domainParser.GetTLD(domainName.TrimEnd('.'));
/// <summary> /// Get cached list of authoritative name server ip addresses /// </summary> /// <param name="domainName"></param> /// <param name="round"></param> /// <returns></returns> public async Task <DnsLookupResult> GetAuthority(string domainName, int round = 0, bool followCnames = true) { var key = domainName.ToLower().TrimEnd('.'); if (!_authoritativeNs.ContainsKey(key)) { try { // Example: _acme-challenge.sub.example.co.uk domainName = domainName.TrimEnd('.'); // First domain we should try to ask is the tld (e.g. co.uk) var rootDomain = _domainParser.GetTLD(domainName); var testZone = rootDomain; var client = GetDefaultClient(round); // Other sub domains we should ask: // 1. example // 1. sub // 2. _acme-challenge var remainingParts = domainName.Substring(0, domainName.LastIndexOf(rootDomain)) .Trim('.').Split('.') .Where(x => !string.IsNullOrEmpty(x)); remainingParts = remainingParts.Reverse(); var digDeeper = true; IEnumerable <IPAddress>?ipSet = null; do { // Partial result cachign if (!_authoritativeNs.ContainsKey(testZone)) { _log.Verbose("Querying server {server} about {part}", client.IpAddress, testZone); using (LogContext.PushProperty("Domain", testZone)) { var tempResult = await client.GetNameServers(testZone, round); _authoritativeNs.Add(testZone, tempResult?.ToList() ?? ipSet ?? _defaultNs); } } ipSet = _authoritativeNs[testZone]; client = Produce(ipSet.OrderBy(x => Guid.NewGuid()).First()); // CNAME only valid for full domain. Subdomains may be // regular records again if (followCnames && testZone == key) { var cname = await client.GetCname(testZone); if (cname != null) { return(await GetAuthority(cname, round)); } } if (remainingParts.Any()) { testZone = $"{remainingParts.First()}.{testZone}"; remainingParts = remainingParts.Skip(1).ToArray(); } else { digDeeper = false; } }while (digDeeper); if (ipSet == null) { throw new Exception("No results"); } } catch (Exception ex) { _log.Warning("Unable to find or contact authoritative name servers for {domainName}: {message}", domainName, ex.Message); _authoritativeNs.Add(key, _defaultNs); } } return(new DnsLookupResult(key, _authoritativeNs[key].Select(ip => Produce(ip)))); }
/// <summary> /// Get cached list of authoritative name server ip addresses /// </summary> /// <param name="domainName"></param> /// <param name="round"></param> /// <returns></returns> private async Task <IEnumerable <IPAddress> > GetAuthoritativeNameServersForDomain(string domainName, int round) { var key = domainName.ToLower().TrimEnd('.'); if (!_authoritativeNs.ContainsKey(key)) { try { // _acme-challenge.sub.example.co.uk domainName = domainName.TrimEnd('.'); // First domain we should try to ask var rootDomain = _domainParser.GetTLD(domainName); var testZone = rootDomain; var client = GetDefaultClient(round); // Other sub domains we should try asking: // 1. sub // 2. _acme-challenge var remainingParts = domainName.Substring(0, domainName.LastIndexOf(rootDomain)) .Trim('.').Split('.') .Where(x => !string.IsNullOrEmpty(x)); remainingParts = remainingParts.Reverse(); var digDeeper = true; IEnumerable <IPAddress>?ipSet = null; do { // Partial result cachign if (!_authoritativeNs.ContainsKey(testZone)) { _log.Verbose("Querying server {server} about {part}", client.IpAddress, testZone); using (LogContext.PushProperty("Domain", testZone)) { var tempResult = await client.GetAuthoritativeNameServers(testZone, round); _authoritativeNs.Add(testZone, tempResult?.ToList() ?? ipSet ?? _defaultNs); } } ipSet = _authoritativeNs[testZone]; client = Produce(ipSet.OrderBy(x => Guid.NewGuid()).First()); if (remainingParts.Any()) { testZone = $"{remainingParts.First()}.{testZone}"; remainingParts = remainingParts.Skip(1).ToArray(); } else { digDeeper = false; } }while (digDeeper); if (ipSet == null) { throw new Exception("No results"); } } catch (Exception ex) { _log.Warning("Unable to find or contact authoritative name servers for {domainName}: {message}", domainName, ex.Message); _authoritativeNs.Add(key, _defaultNs); } } return(_authoritativeNs[key]); }