private async Task <IP4Addr> Resolve(ParsedDomain domain) { if (domain.IsTopLevelDomain()) { int rootServerIndex = Interlocked.Increment(ref rootServerCounter) % dnsClient.GetRootServers().Count; IP4Addr rootServerIP = dnsClient.GetRootServers()[rootServerIndex]; return(dnsClient.Resolve(rootServerIP, domain.GetThisLevelSubdomain()).Result); } else { var upperLevelIP = await AssignResolverAndResolve(domain.GetUpperLevel()); return(dnsClient.Resolve(upperLevelIP, domain.GetThisLevelSubdomain()).Result); } }
private IP4Addr resolveSubDomain(string domain, IP4Addr start) { string[] domains = domain.Split('.'); Array.Reverse(domains); IP4Addr res = start; for (var i = 0; i < domains.Length; i++) { var sub = domains[i]; string cacheKey = ""; for (var j = i; j >= 0; j--) { cacheKey += domains[j] + (j == 0 ? "" : "."); } Task <IP4Addr> t; mut.WaitOne(); if (IpCache.ContainsKey(cacheKey)) { t = IpCache[cacheKey]; dbg("Cache hit " + cacheKey); } else { dbg("Setting cache for " + cacheKey); t = dnsClient.Resolve(res, sub); IpCache[cacheKey] = t; } mut.ReleaseMutex(); if (t.IsCompleted) { dbg("Cache needs verifying"); // task has already been finished, verify cache Task <String> reverse = dnsClient.Reverse(t.Result); reverse.Wait(); if (reverse.Result != cacheKey) { dbg("Cache verification failed. " + reverse.Result); IpCache.Remove(cacheKey, out Task <IP4Addr> v); // go level back i = Math.Max(-1, i - 2); continue; } } t.Wait(); res = t.Result; } return(res); }
public Task <IP4Addr> ResolveRecursive(string domain) { return(Task <IP4Addr> .Run(() => { string[] domains = domain.Split('.'); Array.Reverse(domains); IP4Addr res = dnsClient.GetRootServers()[0]; foreach (var sub in domains) { var t = dnsClient.Resolve(res, sub); t.Wait(); res = t.Result; } return res; })); }