Trying to get full domain info in nslookup

Mark Andrews wrote:

Mark Andrews wrote:

QTYPE=* (otherwise known as "any") queries are treated by BIND as
non-recursive-when-something-is-cached-for-the-name-recursive-otherw
ise because of a misreading of RFC 1034 that has never been
corrected.

In your opinion. Please re-read Section 6.2.2. It clearly
show the caching servers returning subsets of records.

In response to a *non-recursive* query, sure. All of the example
queries in Section 6.2.2 are RD=0 unless otherwise noted (see the
intro paragraph at 6.2). Nowhere in 1034/1035 is it permitted to treat
an RD=1 query as RD=0 and yet return the response as RA=1, which is
what BIND does. That's just fibbing. Of course, BIND or any DNS
implementation for that matter, can decline to recurse a query but a)
this decision should IMO be policy-driven, not hardcoded for QTYPE=*
queries, and b) the responding server shouldn't *lie* about whether it
is honoring recursion or not. Don't you think it kind of defeats the
whole purpose of the RA bit if responders can set it any way they want, for any arbitrary reason?


The nameserver is not required to recurse if it can answer
from the cache. "*" is clearly NOT required to return all
possible records.

3.7.1. Standard queries

* matches all RR types.

"*" matches NOT returns all RR types. When you have a incomplete
cache "*" matches all records there.

That's highly arguable. * "matches" all RR types, but what does it "return"? You say, "all records there" (i.e. in the cache), I say "all records available", which could, in addition to cached records, mean records obtainable via recursion, if recursion is requested and honored.
This section of the RFC is not clear on this point; it only talks about "matching", it doesn't say anything about "returning". In contrast, in the section describing recursive service generally (4.3.1), it says

If recursive service is requested and available, the recursive response
to a query will be one of the following:

- The answer to the query, possibly preface by one or more CNAME
RRs that specify aliases encountered on the way to an answer.

- A name error indicating that the name does not exist. This
may include CNAME RRs that indicate that the original query
name was an alias for a name which does not exist.

- A temporary error indication.

Note: "the answer to the query". Not "as much of the answer as I feel like returning from my cache, if and only if I have a partial answer in my cache, otherwise the answer as I obtained it via recursion". Can you in good conscience say that when recursion is in effect and a resolver returns a *partial* answer to a query, even though the full answer is available via recursion, and even though the full answer *would* have been returned if the cache contents were slightly different, that it has really fulfilled its duty and returned "the answer to the query"? I would certainly dispute that interpretation. The obvious intent is that when recursion is in effect, the resolver attempts, within _reasonable_ limits, to get a proper answer back to the client. Those _reasonable_ limits should be both reasonably low (can't go on retrying and retransmitting forever), but they should also be reasonably high (which may mean recursing sometimes, even if we don't feel like doing so). I don't see returning "whatever I happen to have available without recursing" as sufficiently diligent. If that's what the client wanted and/or expected, it would have made a non-recursive query. What you're basically saying is that the client wasted its time setting the RD bit, and I can't accept that.


5.3.3. Algorithm

The top level algorithm has four steps:

1. See if the answer is in local information, and if so return
it to the client.

....

Step 1 searches the cache for the desired data. If the data is in the
cache, it is assumed to be good enough for normal use.

Again, the pertinent inquiry is: what is "the answer" to a QTYPE=* query? To be sure, BIND's current behavior gives *an* answer to the query, which violates no fundamental rules of DNS (such a violation of fundamental rules would be, e.g. if it answered a question that wasn't asked, or something like that), but is that type of answer *the* answer to the query, when it's only a partial answer, and the full answer is available, and recursion is in effect? I say no.

One could argue that named shouldn't even recurse in a
attempt to get some sort of a answer but then you would not
be able to determine if NXDOMAIN should be returned or not.

So if
something happens to be cached for the name you're querying in the
nameserver which is responding to the query, you get the cached
data, otherwise it goes out and fetches a new set of Resource
Records. To run a proper test, you'd need to clear the cache (i.e.
restart the nameserver process) between each set of queries. Then
you'd see that each response to a QTYPE=* query consists of only
those RRs with the name immunetolerance.org that were cached from
the responses to the previous immunetolerance.org queries (assuming
that the cache wasn't being populated with immunetolerance.org
Resource Records by anything else)

.

Bottom line, BIND has made QTYPE=* a lot less useful than it could
be or was originally intended to be. I think there isn't a lot of
incentive to fix this, though, because to fix it raises the
possibility that apps could start using QTYPE=* inappropriately,
thus causing wasted resources. That's a FUD argument, though, and
should not IMO stand in the way of a proper implementation.

To turn "*" into ALL the cache the cache would have to make
a "*" query for every query it made or remember it had made
a "*" query and clear that state whenever it expired a RRset.

The former option is probably preferable rom a code-simplicity
standpoint, the latter from a performance/resource-consumption
standpoint. Note that if only *one* RRset has expired from the cache,
it should only be necessary to recurse for a fresh version of just
that one RRset, not necessarily the full nameset (of course, this is
subject to local and/or adaptive Optimisation; it might make sense to
do the
QTYPE=* query anyway, because the additional overhead is relatively
low compared to the benefits of "freshening" all of the other cached
RRsets under the name).

You then also have to deal with the fact that "*" queries are
more likely to exceed the various DNS buffer sizes causing
fallover to TCP initially and then truncated TCP responses
(authoritative servers) or failures from caches as they can't
get a non truncated response.

1. We're dealing with the buffer-size/truncation/TCP-retry issue
anyway for DNSSEC 2. If the app can make do with an non-deterministic
subset of the data, it always has the option of issuing a
non-recursive query (like the ones exemplified in Section 6.2.2). If
it absolutely *must* have a full set of data, and can't get it because
it's too big, and doesn't have a fallback option of issuing multiple
type-specific queries, then that's the fault of the app and/or the
respetive domain owner(s). We shouldn't be trying to save those folks
from themselves. They'll eventually learn the error of their ways and
either change the app and/or trim down the namesets to a reasonable
size.


I've yet to see a application (other than a zone/dns maintenance
application) that needs to see all the record types at a node.

Self-fulfilling prophecy. BIND -- and the other DNS implementations that have followed BIND's lead in this regard -- has made QTYPE=* so useless that most apps stay away from it. Doesn't mean that it wouldn't or couldn't be a useful and efficient (relative to multiple type-specific
queries) querying mechanism.

P.S. I'm surprised you didn't bring up the negative-caching implications.


What negative cache implications? Either there node is empty,
does not exist or has data. It takes as much space to store that
a node is empty as it takes to remember that a not doesn't exist
or that is doesn't have a particuler RR type.

What I'm getting at is, if a resolver caches the results of a QTYPE=* query, and, before any of those RRsets have expired, is queried for an RRset under that name which *wasn't* in the response, should it be entitled to answer NODATA on its own initiative? After all, it has a "full" nameset cached, so it "knows" that the RRset doesn't exist, right? Or, does it *always* have to go back to an authoritative server in order to send back the NODATA? If the resolver can answer NODATA based purely on cached data, must it then insulate the RRsets of that "atomic" QTYPE=* response from being "freshened" by the results of subsequent type-specific queries? Without such insulation, the RRsets could get freshened indefinitely, and the resolver will still keep on returning NODATA for any other RRset under the name, even though new RRsets may have popped up on the authoritative servers ages ago.

In previous discussions, I've proposed that authoritative servers include a "generic" negative caching record in all responses to QTYPE=* queries, which would be the minimized aggregate of all NODATA responses to all queries of the name. A caching resolver can then answer with NODATA confidently as long as that "generic" negative caching record is in effect. Once that negative caching record expires, then the caching resolver will need to once again talk to the authoritative servers if it gets a query for one of the RRsets outside of those it already has cached. Upon reflection, I think the inclusion of such a "generic"
negative caching record, to a response with an otherwise-complete Answer Section, would probably be too dangerous to the installed codebase, so it's something that should only be used by mutual agreement (e.g.
through EDNS options). I haven't completely given up on the idea though.


- Kevin



  Latest articles

Slave bind skips delegation record in master zone

Slave zones not updating

SPF RRType

ipv6 and dnssec

Ze Network © 2007 Free Space Australia Inc. All rights reserved.

   Wallpaper World   Tran Community