On 7/13/2011 2:39 PM, Jonathan Kamens wrote:
I agree that the order of the A/AAAA responses shouldn't matter to the
result. The whole getaddrinfo() call should fail regardless of whether
the failure is seen first or the valid response is seen first. Why?
Because getaddrinfo() should, if it isn't already, be using the RFC
3484 algorithm (and/or whatever the successor to RFC 3484 ends up
being) to sort the addresses, and for that algorithm to work, one
needs *both* the IPv4 address(es) *and* the IPv6 address(es)
available, in order to compare their scopes, prefixes, etc..
RFC 3484 tells you how to sort addresses you've got.
If you've only got one address, then bang! It's already sorted for
you. You don't need RFC 3484 to tell you how to sort it.
No, you've got one address, and one unspecified nameserver failure.
Garbage in, garbage out. To say that a nameserver failure is equivalent
to NODATA is not only technically incorrect, it leads to all sorts of
operational problems in the real world.
I have to say that some of the people on this list seem completely
detached from what real users in the real world want their computers
to do.
Really? Do you think I'm an academic? Do you think I sit and write
Internet Drafts and RFCs all day? No, I'm an implementor. I deal with
DNS operational problems and issues all day, every workday. And I can
tell you that I don't appreciate library routines making wild-ass
assumptions that, in the face of some questionable behavior by a
nameserver, maybe, possibly some quantity of addresses that I've
acquired from that dodgy nameserver are good enough for my clients to
try and connect to. No thanks. If there's a real problem I want to know
about it as clearly and unambiguously as possible. I can't deal
effectively with a problem if it's being masked by some library routine
doing something weird behind my back.
If I am trying to connect to a site on the internet, then I want my
computer to do its best to try to connect to the site. I don't want it
to throw up its hands and say, "Oh, I'm sorry, one of my address
lookups failed, so I'm not going to let you use the /other/ address
lookup, the one that succeeded, because some RFC somewhere could be
interpreted as implying that's a bad idea, if I wanted to do so."
Please, that's ridiculous.
No, what's more ridiculous is if users can't get to a site SOME OF THE
TIME, because someone's DNS is broken, a moronic library routine then
routes the traffic some unexpected way, and a whole raft of other
variables enter the picture, without anyone realizing or paying
attention to the dependencies and interconnectivity that is required to
keep the client working. There is a certain threshold of brokenness
where the infrastructure has to "throw up its hands", as you put it, and
say "nuh uh, not gonna happen", because to try to work around the
problem based on not enough information about the topology, the
environment, the dependencies, etc. you're likely to cause more harm
than good by making the failure modes way more complex than necessary.
If one of the lookups "fails", and this failure is presented to the
RFC 3484 algorithm as NODATA for a particular address family, then the
algorithm could make a bad selection of the destination address, and
this can lead to other sorts of breakage, e.g. trying to use a
tunneled connection where no tunnel exists.
If the address the client gets doesn't work, then the address doesn't
work. How is being unable to connect because the address turned out to
not be routable different from being unable to connect because the
computer refused to even try?
Because the failure modes are substantially different and it could take
significant man-hours to determine that the root cause of the problem is
actually DNS brokenness rather than something else in the network
infrastructure (routers, switches, VPN concentrators, firewalls, IPSes,
load-balancers, etc.) or in the client or server (OS, application,
middleware, etc.)
Have you ever actually troubleshot a difficult connectivity problem in a
complex networking environment? Trust me, you want clear symptoms, clear
failure modes. Not a bunch of components making dumb assumptions and/or
trying to be "helpful" outside of their defined scope of functionality.
That kind of "help" is like offering a glass of water to a drowning man.
Another possibility you're not considering is that the invoking
application itself may make independent IPv4-specific and
IPv6-specific getaddrinfo() lookups. Why would it do this? Why not?
Maybe IPv6 capability is something the user has to buy a separate
license for, so the IPv6 part is a slightly separate codepath, added
in a later version, than the base product, which is IPv4-only. When
one of the getaddrinfo() calls returns address records and the other
returns garbage, your "fix" doesn't prevent such an application from
doing something unpredictable, possibly catastrophic. So it's really
not a general solution to the problem.
I have no idea what you're talking about. If the application makes
independent IPv4 and IPv6 getaddrinfo() lookups, then the change I'm
proposing to glibc is completely irrelevant and does not impact the
existing functionality in any way. The IPv4 lookup will succeed, the
IPv6 lookup will fail, and the application is then free to decide what
to do.
I wasn't saying the glibc change would break such an application, only
that your proposed "fix" doesn't help it either, so it shouldn't be
mistaken for a general solution to the problem. Your "fix" only applies
to AF_UNSPEC and one should not assume that getaddrinfo() is *always*
called with AF_UNSPEC. That is, after all, why the ai_family member of
the "hints" parameter struct takes values other than AF_UNSPEC.
In summary, getattrinfo() with AF_UNSPEC has a very clear meaning --
"Give me whatever addresses you can." The man page says, and I am
quoting, "The value AF_UNSPEC undicates that getaddrinfo() should
return socket addresses for any address family (either IPv4 or IPv6,
for example) that can be used with node and service." I don't see how
the language could be any more clear.
Clear eh? That's because you're reading it through the tunnel vision of
your own preferences. The text you quoted says nothing about failure
modes, RFC 3484 or the full-/partial-answer distinction. Are you hanging
your hat completely on the phrase "can be used"? Really? You're reading
that much detail into such generic language? Well, as I've said before,
for RFC 3484 to work properly, one needs all available IPv4 and IPv6
addresses. If the list of addresses is short because of nameserver
brokenness, I'd say RFC 3484 couldn't do its job and the resulting
partial address list is "unusable" because it hasn't been properly
processed. That's my take on "can be used".
Since you decided to start playing the "man page semantic game", it's my
turn now.
I could just as easily point to this text from the Linux version of the
man page:
*EAI_AGAIN*
The name server returned a temporary failure indication. Try again
later.
*EAI_BADFLAGS*
/ai_flags/ contains invalid flags.
*EAI_FAIL*
The name server returned a permanent failure indication.
Notice that the descriptions of EAI_AGAIN and EAI_FAIL say "The
nameserver returned a [...] failure". Not "The nameserver returned [...]
failures for all lookups" or "The nameserver returned only failures". In
the English language, "a failure" is equivalent to "more than 0 failures".
Based on this text, slanted with my own biases and preferences, I'll say
then that *any* error return from a nameserver should cause
getaddrinfo() to fail, in order to be consistent with those error-code
descriptions. Are you going to argue differently? Shall we split hairs
over the meaning of the word "a"?
To suggest that it's reasonable and correct for it to refuse to return
a successfully fetched address is simply ludicrous.
By the same faulty reasoning, any addresses returned in a *truncated*
DNS response are still usable. We hashed that one over for years, and
finally decided it was a really stupid idea. Partial DNS results are not
reliably usable. And this is just as true for one "part" of a
getaddrinfo() lookup failing as it is for a truncated DNS response.
Unless you have all of the information which was requested, you can't
assume that the invoker is going to be able to sensibly use what you
hand back to it. If one detects a failure that materially affects the
completeness or trustworthiness of a response, one has to either a) try
to acquire the information another way (e.g. in the case of response
truncation, retry the query using TCP) or b) assume the worst and put
the onus on the invoker, or perhaps further up the responsibility chain
to the user, admin, implementor, or architect, to flag the error as an
actual error and fix what's really wrong.
- Kevin
_______________________________________________
Please visit https://lists.isc.org/mailman/listinfo/bind-users to unsubscribe
from this list
bind-users mailing list
bind-users@lists.isc.org
https://lists.isc.org/mailman/listinfo/bind-users