![](https://seccdn.libravatar.org/avatar/03f977b763487de21403593533d8ee18.jpg?s=120&d=mm&r=g)
On Thursday 15 February 2001 10:11, Nadeem Hasan wrote:
"Steven T. Hatton" wrote:
<snip>
On thing I'm still not clear on. You said "If the answer is not in cache, or in its authoritative data, then the server queries the root nameservers." Does that mean my system reaches out to the highest level name server in my root domain? I had always there there was some kind of recursive process taking place by default. Now it looks as though this type of recursion must be explicitly configured. As an example, I configure my internal network to mynet.bellatlantic.net. (Bellatlantic's DNS knows nothing about my network however - but that's a special case) If I don't set a forwarders list, my DNS will jump directly to the root server for .net? This is how I am understanding things now. That makes me think the root servers are getting an unnecessarily high level of traffic. Perhaps it's just a few lightweight hackers like me who are being this reckless, and real network admins have things configured correctly.
Is this perception correct? Do I burden the root of .net every time I get a cache miss?
If a nameserver gets a recursive query, it looks into its cache for a possible answer, if found it returns it. Otherwise, it looks for a cached referral to the authoritative nameserver for the queried domain, if found, it queries it, if not found, it queries one of the root nameservers, which will return with a referral to the autoritative nameserver for the domain, that nameserver would then be queried and it will either return an answer or a referrel to another nameserver, so on. This recursion goes on till a positive or negative answer is found.
Look at the following: (I have added my comments with //)
floyd:~ # nslookup Default Server: ns1.nadmm.com Address: 216.112.234.66
// Start with one of the root nameservers
server a.root-servers.net
Default Server: a.root-servers.net Address: 198.41.0.4
// Query for the A record of the host
floyd.nadmm.com.
Server: a.root-servers.net Address: 198.41.0.4
// Root nameserver returns a referral to all the // authoritative nameservers it knows for nadmm.com. domain Name: floyd.nadmm.com Served by: - NAMESERVER.CONCENTRIC.NET 207.155.183.72 NADMM.COM - NAMESERVER3.CONCENTRIC.NET 206.173.119.72 NADMM.COM - NS.NADMM.COM 216.112.234.68 NADMM.COM - NS1.NADMM.COM 216.112.234.66 NADMM.COM
// Use one of the referred nameservers
server nameserver.concentric.net
Default Server: nameserver.concentric.net Address: 207.155.183.72
// Now query it for an answer
floyd.nadmm.com.
Server: nameserver.concentric.net Address: 207.155.183.72
// Got a positive answer. Stop. Name: floyd.nadmm.com Address: 216.112.234.66
// Now query for a bad hostname
aa.nadmm.com.
Server: nameserver.concentric.net Address: 207.155.183.72
// Got a negative answer. Stop. *** nameserver.concentric.net can't find aa.nadmm.com.: Non-existent host/domain
Hope this helps you :)
Cheers, -- Nadeem Hasan nhasan@nadmm.com http://www.nadmm.com/
Nadeem, This does add to my understanding. Thanks. Unfortunately as my knowledge grows linearly with time (at best,) my ignorance grows exponentially :-/ I think this my be a recursive process. The key word in what you said above is *recursive*. As I read the BIND 9 Reference, *recursive* has a special meaning. It means using forwarders rather than default *iterative*. This is not clear to me. It is simply my best guess as to the intent of the author. This is my current understanding of how things work (which is changing as I write): * Client student.physics.university.edu queries local name server dns.physics.university.edu for portal.suse.com ** this is almost certainly a "recursive" query. *** The recursive nature of the query from student tells dns.physics.university.edu that student will only understand an answer containing the IP Address of portal.suse.com or a "can't find it" message. * dns.physics.university.edu checks its records and cache for the result and doesn't find it. ** It may, however, find the IP Address for a name server "closer" to the answer in its cache thus allowing it to skip the intermediate parts of the lookup process, jumping directly to the "closer" name server. We'll assume this didn't happen this time around. * dns.physics.university.edu will behave in one of the following two ways: ** dns.physics.university.edu has a forwarders list so it asks its forwarders to look up the answer on its behalf. This means dns.physics sends the same kind of query to its forwarders that student sent to dns.physics. The forwarder(s) will only return the IP Address of portal.suse.com or a "can't find it" message. They will not return a referal. *** This possible branch continues until an answer (positive or negative) is found, or a sever that does not have a forwarders list is queried. In the latter case that server acts in the same manner described in the second ** of this section. ** dns.physics.university.edu does _not_ have a forwarders list so it will query a root name server of the .com domain for the answer. (assuming no cached information.) *** The address of the root name server of .com is provided to dns.physics.university.edu by the root.hints file located on its local file system. * The root name server of .com returns either the IP Address of portal.suse.com or the address of a name server "closer" to portal.suse.com. (perhaps the address of something similar to dns.suse.com) ** if the actual IP Address is found, it is sent back to the first name server performing an iterative query (as opposed to a recursive query.) *** From that point in time the answer is simply returned down the stack of open queries until it reaches student. ** if the root sever does not have an answer in its cache nor in its zone it will return either the address of a "closer" name sever or a "don't know how to find something in that name space" message. I guess the algorithm is something like the following: /* please note that I have "over killed" many booleans in what follows. */ /* all queries start here */ handle_query(requested_name, query_type, forward, forwarders) { if (name_is_in_zone(requested_name) { return address_from_db(requested_name); // I think this could also be a "blackhole" negative } else if (name_is_in_cache(requested_name)) { if (address_found_in_cache(requested_name)) { return address_from_cache(requested_name); else { return negative; } //else } else if (query_type == recursive) { return resolve(requested_name, forward, forwarders); // the address or negative, no referal } else if (query_type == iterative) { return iterative_query(requested_name, forward, forwarders); // the IP Address, a negative or a referal } // else if } // handle_query /* must return an IP Address or a negative, no referal */ resolve(requested_name, forward, forwarders) { if (forwarders == null) { return iterative_resolve(requested_name, forward); else if (is_list_of_ip_addresses(forwarders)) { for (i = 0; i < forwarders.length; i++) { result = iterative_resolve(forwarders[i]); if (result != null) { return result; // I don't know what it would do with an explicit negative } // if } // for if (forward == only && result == null) { return negative; // didn't find it and I don't handle referals } else if (forward == first && result == null) { //default behavior return iterative_resolve(requested_name, forward, forwarders); // this is what we would have already done if forwarders == null; } // else if } // else if } // reslove /* Must return an IP Address or a negative, no referal, so keep checking till you can do this. */ iterative_resolve (requested_name, forward, forwarders) { result = iterative_query(requested_name); while (is_referal(result)) { result = iterative_query(requested_name, result); }// while retrun result; //either an address or a negative } // iterative_resolve /* returns the first good result. IP Address, a negative or a referal */ iterative_query(requested_name, start_dns=localhost) { if (name_is_in_cache(requested_name)) { if (address_found_in_cache(requested_name)) { return address_from_cache(requested_name); else { return negative; } //else } else if (start_dns==localhost) { close_dns = check_hash_for_close_dns(requested_name); if (close_dns != null) { return close_dns; else { return get_root_for_domain(requested_name) // user root.hints } // else } else if (is_dns_ip_address(start_dns) { return send_iterative_query(start_dns, requested_name); // address of requested_name || negative || referal } // else if } // iterative_query I'm sure there are holes in this. It may be way off track, but it reflects my current understanding. Steve