> It was Laurent who mentioned dnsip.

 And I did for a reason.
 (Time for a little rant.)

 The root of the problem here is that historically, there were different
mechanisms used to perform "human-readable name" -> "IP address"
resolution. DNS was one of them, and ended up being the most widely
used (for good reason: it is, by definition, distributed), but it was
not the first. Other mechanisms were, for instance, Sun's NIS and NIS+.

 I don't know who the culprit is - I want to accuse GNU as usual, but
I don't think they're the only one at fault here, because the idiocy made
it into the standard: *somebody* thought that it would be a good idea
to unify all the naming protocols under a unique interface that would
hide all the details, and include that interface into the libc.

 That interface was gethostbyname(). It was later replaced by
getaddrinfo(), which suffers from the exact same problems - although
Single Unix v4's getaddrinfo() page acknowledges that it is "often"
implemented via DNS now: see
 http://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html

 So, there is only *one* standard, libc-provided, interface, for name
resolution, and that is gethostbyname(), or now getaddrinfo(). And you
cannot be sure that it uses DNS: it all depends on your machine and
network configuration. It could use NIS on some architecture, or even
some Active Directory-based WINS resolution if the network is mostly
Microsoft-administered. On most systems, getaddrinfo() will first look
up the /etc/hosts file (which is an old legacy interface for naming,
and it is widely accepted that the naming scheme in /etc/hosts should be
compatible with DNS, but it is, strictly speaking, not DNS), and then
fall back on DNS resolution if /etc/hosts doesn't give an answer.
 GNU calls this system "NSS", Name Service Switch, and on GNU systems,
getaddrinfo()'s behaviour is configured via the /etc/nsswitch.conf file.
The usual /etc/nsswitch.conf will just contain "order hosts, bind",
which means lookup /etc/hosts first and DNS second.

 The problem with NSS is that it's useless. Everybody uses DNS now.
People who use NIS know they use NIS and use NIS tools for name resolution.
People who use WINS use Microsoft tools - and generally also use DNS.
Programmers use getaddrinfo() expecting to access DNS and nothing else.
NSS is a bloated compatibility layer that just gets in the way;
getaddrinfo() is a *horrible* API to access DNS, because it has to be
very generic (to handle every possible name service under the sun) and
can't focus on the interesting details of DNS - for instance, it is
totally synchronous by nature, with no way of specifying a timeout
except via a previous alarm() call.

 And there is *no* standard API that means "do a simple DNS query, just
bypass NSS". Every libc, even the uClibc, has to implement some minimal
NSS into getaddrinfo() - if only to allow /etc/hosts resolution. There
is no standard libc hook for DNS resolution, even if the internals of
getaddrinfo() have to perform it. So applications needing pure DNS access
have to implement DNS resolution themselves. This is obviously hard work,
so a few DNS resolution libraries exist out there. The most common is
BIND's own libresolv; good luck trying to use this in an embedded system.
Another one is djbdns' client library, which I have successfully made
work on several embedded systems, with a very small memory footprint
and disk usage. The "dnsip" utility I mentioned is based on this library,
and that is why I mentioned it: it's a small tool that performs a
full-fledged DNS query. Comparatively, the "host" command, which does
the same, needs BIND's libresolv, with a much bigger memory and disk
footprint.

 Note that "busybox nslookup" cheats, and if "busybox host" were to be
implemented, it would most likely cheat too: busybox nslookup doesn't
perform DNS resolution, it performs NSS resolution, via the only API it
has access to: getaddrinfo(). And even if it was not cheating, it would
be a very bad idea to use nslookup anyway:
 http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/nslookup-flaws.html
explains all the problems there are with BIND's original nslookup design
and implementation as far as DNS diagnostics are concerned.

 The only way for busybox not to cheat and really implement DNS tools
would be to integrate a complete DNS client library into it. I think
it would be outside the scope of busybox, though; let busybox do what
it can with NSS resolution, and use real, external DNS tools if you
need to do DNS.

 I have written a complete embeddable DNS client library (inspired by
the djbdns client library but with better APIs), and plan to release it
when it's at least a bit documented. I can send it to anyone who wants
to work with DNS, but don't be delusional: if a static 27 kB binary is
too big for you, then just don't try to do proper DNS, and stick to
your libc's NSS.

-- 
 Laurent
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to