Article View: demon.ip.developers
Article #918Re: DNS caching; is it *truly* possible to flush locally?
From: Brian {Hamilton Kelly}
Date: Fri, 26 Jul 1996 00:00
Date: Fri, 26 Jul 1996 00:00
106 lines
5942 bytes
5942 bytes
[Supplemental info: that's why I'm following up my own posting.]
In article <838400731snz@dsl.co.uk>
bhk@dsl.co.uk "Brian {Hamilton Kelly}" writes:
> In article <838306928snz.4895@grempc.demon.co.uk>
> Graham@grempc.demon.co.uk "Graham E Kinns" writes:
>
> > KA9Q uses signed 32 bits to store TTLs, I've placed values >> 2^31 in
> > my domain.txt as a test and they've actually remained +ve OK although
> > reduced somewhat smaller. I can't make -942919 into anything that
> > would suggest where it came from, I can only think your cache has been
> > corrupted in memory or on writing to the file and subsequently read
> > back incorrectly - a check to silently discard -ve TTLs would go amiss
> > somewhere, I can't see a use for them (although 0x80000000 is used to
> > mark entries with no TTL) RFC1035 sec 6.1.3 does mention using -ve
> > TTLs but I don't see any relevance to the resolver side of KA9Q.
>
> On the basis that there were almost 120 times as many expired items as
> those that weren't, and that there was no other "corruption" of the file,
> I'm beginning to think that the perennial bleat of "delete DOMAIN.TXT,
> it's been corrupted somehow" is a rather esoteric way of saying "that's
> not a bug, it's a feature". Everything that's now left in DOMAIN.TXT has
> positive TTLs, none of them larger than 86400 (apart from one anomalous
> one for univ-lille.fr, which is 97 million; that I'm prepared to believe
> may be a corruption!)
>
> It definitely seems to me that somewhere a signed 32-bit integer is being
> treated as unsigned: perhaps there's a parameter mismatch somewhere (oh
> for a proper language that enforces strict type checking for separate
> compilation [like Ada or Modula-2], as opposed to independent
> compilation [which is an area in which C is more akin to Fortran]!)
I've been looking at the code for KA9Q, and think I've solved the mystery
(or rather, located it: it cannot be solved without a *lot* of
cross-checking).
The definition of the structure used internally to hold RRs is (from
DOMAIN.H):
struct rr
{
struct rr *last;
struct rr *next;
char source;
char *comment; /* optional comment */
char *name; /* Domain name, ascii form */
char *suffix; /* Suffix name */
int32 ttl; /* Time-to-live */
int16 class; /* IN, etc */
int16 type; /* A, MX, etc */
int16 rdlength; /* Length of data field */
union
{
int32 addr; /* Used for type == A */
struct soa soa; /* Used for type == SOA */
struct mx mx; /* Used for type == MX */
struct hinfo hinfo; /* Used for type == HINFO */
struct minfo minfo; /* Used for type == MINFO */
struct wks wks; /* Used for type == WKS */
char *name; /* for domain names */
char *data; /* for anything else */
} rdata;
};
(I've deleted a lot of #defines that provide symbolic constants.)
The TTL field is certainly *used* as if it were, as Graham, says, a
signed 32-bit integer (from DOMAIN.C):
if(test_rrp->ttl > 0L
&& (test_rrp->ttl -= elapsed) <= 0L)
test_rrp->ttl = 0L;
(Similar code appears in other routines too). On this basis, if
decrementing the TTL makes it -ve, it gets replaced by zero. So why are
there negative values in the cache and the DOMAIN.TXT file?
Well, let's look at the definition of int32 (from GLOBAL.H):
typedef unsigned long int32; /* 32-bit signed integer */
Note that *carefully*: the comment says that it's a signed integer (which
it needs to be for the code fragment above to work). But the actual C
declares it to be an UNsigned integer. Whoops. Watta mistaka to maka!
With the TTL field being an unsigned integer, a negative value can never
be detected by the code fragment above, and that accounts for the wrong
values in the cache and the file. They get saved in the file as negative
values because the printf format expects them to be signed, although the
code actually treats them as huge positive integers.
Goodness only knows when the error first occurred; presumably the author
of the test on the ttl expected it to be a signed integer, as did the
person writing the comment in the typedef. Perhaps it was even correct
at one stage, and someone has at some time obtruded the unwanted
"unsigned" into the typedef. The reason why I say it will be difficult
to fix is that there are literally hundreds of variables declared as
int32s: some of these may be meant to be signed, and some unsigned, and
the code involving each will have to be examined to determine which is
which. I've counted 429 lines in the sources which mention int32, and
that's without looking at the OS/2 specific files!
I'm cc'ing by e-mail to Niel (who maintains KA9Q/2) and to Robert (who
seems to be working on the original DOS version). I'd be interested in
your comments.
--
Brian {Hamilton Kelly} bhk@dsl.co.uk
Tony Blair's New Labour: The Windows'95 of Political Parties
(c/w Plug'n'Pray and a pretence of offering object-orientation)
Technical Details
Message-ID:
<838411052snz@dsl.co.uk>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<838060435snz@dsl.co.uk> <838306928snz.4895@grempc.demon.co.uk> <838400731snz@dsl.co.uk>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10bb05,467f920bc280412f
X-Google-Attributes: gid10bb05,public
From: Brian {Hamilton Kelly} <bhk@dsl.co.uk>
Subject: Re: DNS caching; is it *truly* possible to flush locally?
Date: 1996/07/26
Message-ID: <838411052snz@dsl.co.uk>
X-Deja-AN: 170595275
x-mail2news-path: dragnhll.demon.co.uk
x-nntp-posting-host: dragnhll.demon.co.uk
references: <838060435snz@dsl.co.uk> <838306928snz.4895@grempc.demon.co.uk> <838400731snz@dsl.co.uk>
organization: Dragonhill Systems Ltd
newsgroups: demon.ip.developers