Example #1
0
 public Node(Node parent, IP4Addr address, string domain)
 {
     Parent     = parent;
     Address    = address;
     Domain     = domain;
     Subdomains = new Dictionary <string, Node>();
 }
Example #2
0
        /// <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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
 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;
     }));
 }
Example #7
0
        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);
            }
        }
Example #8
0
        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);
            }
        }
Example #9
0
        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);
        }
Example #10
0
 public TestResult(string domain, IP4Addr address, long elapsedMilliseconds)
 {
     this.domain              = domain;
     this.address             = address;
     this.elapsedMilliseconds = elapsedMilliseconds;
 }
Example #11
0
        private IP4Addr ResolveWithCache(string domain)
        {
            IP4Addr res = dnsClient.GetRootServers()[0];

            return(resolveSubDomain(domain, res));
        }