Date: Thu, 6 Nov 2008 20:21:03 +0100 From: Luigi Rizzo <rizzo@iet.unipi.it> To: net@freebsd.org Subject: Two copies of resolver routines in libc ? Message-ID: <20081106192103.GA46651@onelab2.iet.unipi.it>
next in thread | raw e-mail | index | archive | help
i was recently re-looking at the problem mentioned in http://lists.freebsd.org/pipermail/freebsd-hackers/2003-August/002399.html (bogus dns servers on my ISP, telecomitalia, which takes forever to resolve AAAA queries, coupled with the absence, on the FreeBSD resolver has no way to disable AAAA queries when IPV6 is compiled in, which happens with GENERIC kernels). While looking for a workaround (attached, read later), i noticed that libc has two versions of the resolver routines: one is in /usr/src/lib/libc/resolv/res_query.c the other one is embedded into /usr/src/lib/libc/net/getaddrinfo.c which includes a slightly modified version of res_nquery, res_ndots, res_nquerydomain (all parts of the routines documented in resolver(3)). If we are lucky, this is just replicated code. But i am not even sure they are the same, e.g. in the handling of options (in resolv.conf or the environment variable RES_OPTIONS). This is really annoying, because generally you don't know if an application uses getaddrinfo() or the traditional gethost*() routines (which in turn use resolver(3)), so it is hard to tell whether applications have a consistent behaviour. If someone has time, it would be worthwhile trying to merge the two versions of the code into one (and i believe we should make getaddrinfo use the standard stuff in resolv/ --- As for a fix to my problem: --- i wanted some trick to disable, in the resolver, the generation of AAAA queries. resolver(5) mentions some options that can be put in /etc/resolv.conf or in the RES_OPTIONS environment variable, to control the behaviour of the resolver. Some more options are undocumented but implemented, e.g. looking at /usr/src/lib/libc/resolv/res_init.c you find these additional options: retrans: retry: inet6 insecure1 insecure2 rotate no-check-names edns0 dname nibble: nibble2: v6revmode: The code below (which is completely trivial) add an additional option, "noaaaa", which disables the generation of AAAA requests. Just do setenv RES_OPTIONS noaaaa and you are done. I don't know of other ways to disable these requests on normal address resolutions, other than build a kernel without INET6. As you see below (and this relates to my original complaint), i had to make the modification in two places :( because things like ssh and telnet use getaddrinfo(), whereas e.g. firefox uses res_query(). I have no idea what is used by /usr/bin/host or /usr/bin/dig , because they do not seem to use any of the library routines. Any interest to have this into the system ? cheers luigi Index: net/getaddrinfo.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/getaddrinfo.c,v retrieving revision 1.69.2.10 diff -u -r1.69.2.10 getaddrinfo.c --- net/getaddrinfo.c 28 Sep 2007 06:23:03 -0000 1.69.2.10 +++ net/getaddrinfo.c 6 Nov 2008 20:35:39 -0000 @@ -85,6 +85,7 @@ #include <errno.h> #include "res_config.h" +#include "res_private.h" #ifdef DEBUG #include <syslog.h> @@ -2257,6 +2258,8 @@ oflags = res->_flags; + if (res->options & RES_NOAAAA && type == ns_t_aaaa) + continue; /* ignore this request */ again: hp->rcode = NOERROR; /* default */ Index: resolv/res_init.c =================================================================== RCS file: /home/ncvs/src/lib/libc/resolv/res_init.c,v retrieving revision 1.2.2.3 diff -u -r1.2.2.3 res_init.c --- resolv/res_init.c 22 Dec 2006 07:33:20 -0000 1.2.2.3 +++ resolv/res_init.c 6 Nov 2008 20:34:00 -0000 @@ -636,6 +636,8 @@ !strncmp(cp, "no-tld-query", sizeof("no-tld-query") - 1)) { statp->options |= RES_NOTLDQUERY; + } else if (!strncmp(cp, "noaaaa", sizeof("noaaaa") - 1)) { + statp->options |= RES_NOAAAA; } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) { statp->options |= RES_USE_INET6; } else if (!strncmp(cp, "insecure1", sizeof("insecure1") - 1)) { Index: resolv/res_private.h =================================================================== RCS file: /home/ncvs/src/lib/libc/resolv/res_private.h,v retrieving revision 1.1.1.1.2.1 diff -u -r1.1.1.1.2.1 res_private.h --- resolv/res_private.h 17 Jul 2006 10:09:58 -0000 1.1.1.1.2.1 +++ resolv/res_private.h 6 Nov 2008 19:08:29 -0000 @@ -3,6 +3,9 @@ #ifndef res_private_h #define res_private_h +// additional debug flags to disable AAAA queries +#define RES_NOAAAA 0x00800000 + struct __res_state_ext { union res_sockaddr_union nsaddrs[MAXNS]; struct sort_list { Index: resolv/res_query.c =================================================================== RCS file: /home/ncvs/src/lib/libc/resolv/res_query.c,v retrieving revision 1.3.2.1 diff -u -r1.3.2.1 res_query.c --- resolv/res_query.c 17 Jul 2006 10:09:58 -0000 1.3.2.1 +++ resolv/res_query.c 6 Nov 2008 20:45:23 -0000 @@ -90,6 +90,7 @@ #include <string.h> #include <unistd.h> #include "port_after.h" +#include "res_private.h" /* Options. Leave them on. */ #define DEBUG @@ -126,10 +127,12 @@ again: hp->rcode = NOERROR; /* default */ + if (statp->options & RES_NOAAAA && type == ns_t_aaaa) { + return 0; /* ignore this request */ + } #ifdef DEBUG if (statp->options & RES_DEBUG) - printf(";; res_query(%s, %d, %d)\n", name, class, type); + printf(";; res_nquery(%s, %d, %d)\n", name, class, type); #endif n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20081106192103.GA46651>