public Node(Node parent, IP4Addr address, string domain) { Parent = parent; Address = address; Domain = domain; Subdomains = new Dictionary <string, Node>(); }
/// <summary> /// Register a new subdomain for given server, assign it an arbitrary IP and return this IP. /// </summary> /// <param name="parentAddr">IP of the parent domain</param> /// <param name="subdomain">Subdomain to be registered within the parent</param> /// <returns>IP of newly associated domain.</returns> private IP4Addr RegisterNewSubdomain(IP4Addr parentAddr, string subdomain) { if (!knownDomains.ContainsKey(parentAddr.Value)) { throw new ArgumentException("Parent address does not belong to a known server."); } var parent = knownDomains[parentAddr.Value]; if (parent.Subdomains.ContainsKey(subdomain)) { // Record already exists. return(parent.Subdomains[subdomain].Address); } // Create a new node record... var newAddr = new IP4Addr(rootServers[0].Value + (uint)knownDomains.Count); Debug.Assert(!knownDomains.ContainsKey(newAddr.Value)); var fullDomain = parent.Domain == "" ? subdomain : (subdomain + "." + parent.Domain); var node = new Node(parent, newAddr, fullDomain); // Insert it into data structures... parent.Subdomains.Add(subdomain, node); knownDomains.Add(newAddr.Value, node); return(newAddr); }
public DNSClient() { var rootAddr = new IP4Addr("10.0.0.1"); var rootNode = new Node(null, rootAddr, ""); knownDomains.Add(rootAddr.Value, rootNode); rootServers = ImmutableArray.Create <IP4Addr>(rootAddr); }
public async Task <string> Reverse(IP4Addr server) { await Task.Delay(100); // simulate some async work if (!knownDomains.ContainsKey(server.Value)) { throw new DNSClientException("Server " + server.ToString() + " not found."); } return(knownDomains[server.Value].Domain); }
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; })); }
private async Task <String> AsignReverserAndReverse(IP4Addr ip) { Task <string> reverser; var hasReverser = reversers.TryGetValue(ip, out reverser); if (hasReverser) { return(reverser.Result); } else { reverser = reversers.GetOrAdd(ip, dnsClient.Reverse(ip)); return(reverser.Result); } }
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); } }
public async Task <IP4Addr> Resolve(IP4Addr server, string subDomain) { await Task.Delay(500); // simulate some async work if (!knownDomains.ContainsKey(server.Value)) { throw new DNSClientException("Server " + server.ToString() + " not found."); } var node = knownDomains[server.Value]; if (!node.Subdomains.ContainsKey(subDomain)) { throw new DNSClientException("Subdomain " + subDomain + " not found on server " + server.ToString() + "."); } return(node.Subdomains[subDomain].Address); }
public TestResult(string domain, IP4Addr address, long elapsedMilliseconds) { this.domain = domain; this.address = address; this.elapsedMilliseconds = elapsedMilliseconds; }
private IP4Addr ResolveWithCache(string domain) { IP4Addr res = dnsClient.GetRootServers()[0]; return(resolveSubDomain(domain, res)); }