Bug#836541: libc6-dev: res_query does not use external nameservers when set
Package: libc6-dev
Version: 2.19-18+deb8u4
Severity: important
Dear Maintainer,
Regarding the resolver library, when nameservers are explicitly
specified after the call to res_init and before the actual call
to res_query, the res_query code uses internal resolution first
rather than the specified nameservers.
Example code attached below.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <resolv.h>
#include <netdb.h>
#define N 4096
/* --------------------------------- */
/* CODE BEGINS */
/* --------------------------------- */
int main (int argc, char *argv[]) {
u_char nsbuf[N];
char dispbuf[N];
ns_msg msg;
ns_rr rr;
int i, l;
if (argc < 2) {
printf ("Usage: %s <domain>\n", argv[0]);
exit (1);
}
/* Initialize to use the Google nameservers */
res_init();
_res.nscount = 2;
_res.nsaddr_list[0].sin_family = AF_INET;
_res.nsaddr_list[0].sin_addr.s_addr = inet_addr("8.8.8.8");
_res.nsaddr_list[0].sin_port = htons(53);
_res.nsaddr_list[1].sin_family = AF_INET;
_res.nsaddr_list[1].sin_addr.s_addr = inet_addr("8.8.4.4");
_res.nsaddr_list[1].sin_port = htons(53);
printf("Domain: %s\n\n", argv[1]);
/* Print the A record return or the error code */
printf("A record(s):\n");
l = res_query(argv[1], ns_c_any, ns_t_a, nsbuf, sizeof(nsbuf));
if (l < 0) perror(argv[1]);
ns_initparse(nsbuf, l, &msg);
l = ns_msg_count(msg, ns_s_an);
for (i = 0; i < l; i++) {
ns_parserr(&msg, ns_s_an, i, &rr);
ns_sprintrr(&msg, &rr, NULL, NULL, dispbuf, sizeof(dispbuf));
printf("\t%s \n", dispbuf);
}
// NS RECORD
printf("\nNS record(s):\n");
l = res_query(argv[1], ns_c_any, ns_t_ns, nsbuf, sizeof(nsbuf));
if (l < 0) perror(argv[1]);
ns_initparse(nsbuf, l, &msg);
l = ns_msg_count(msg, ns_s_an);
for (i = 0; i < l; i++) {
ns_parserr(&msg, ns_s_an, 0, &rr);
ns_sprintrr(&msg, &rr, NULL, NULL, dispbuf, sizeof(dispbuf));
printf("\t%s \n", dispbuf);
}
return 0;
}
When the test program is run it incorrectly returns the LAN address
of the host from resolv.conf. It should return the internet address
of the host from the external nameservers, as seen below.
sysmgr@www:~$ ./a.out www.somewhere.com
Domain: www.somewhere.com
A record(s):
www.somewhere.com. 6H IN A 192.168.0.209
NS record(s):
www.somewhere.com. 6H IN NS localhost.
-- System Information:
Debian Release: 8.5
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: armel (armv5tel)
Kernel: Linux 4.4.0-kirkwood-tld-1 (PREEMPT)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)
Versions of packages libc6-dev depends on:
ii libc-dev-bin 2.19-18+deb8u4
ii libc6 2.19-18+deb8u4
ii linux-libc-dev 3.16.7-ckt25-2+deb8u2
libc6-dev recommends no packages.
Versions of packages libc6-dev suggests:
pn glibc-doc <none>
pn manpages-dev <none>
-- no debconf information
Reply to: