There's no way that I know of to find out which name server returned the result just by looking at the results of a call to res_search()
. That information is only in the higher-level UDP packet header and is no longer available by the time the packet has been unpacked by libresolv
.
However, depending on the version of libresolv
it appears to be possible to do it by registering a "response hook" with the resolver using:
res_send_setrhook()
or
_res.rhook = &funcptr;
The first parameter supplied to the hook callback will be a struct sockaddr *
of the server that sent the response. The code below works on MacOS X 10.5.6:
#include <stdlib.h>
#include <stdio.h>
#include <resolv.h>
#include <netinet/in.h>
res_sendhookact hook(const struct sockaddr *ns,
const u_char *query,
int querylen,
u_char *ans,
int anssiz,
int *resplen)
{
fprintf(stderr, "answer returned from %s\n",
inet_ntoa(((struct sockaddr_in *)ns)->sin_addr));
return res_goahead;
}
main() {
res_init();
_res.rhook = hook;
res_search(...);
}
BTW it is (mostly) possible to ask a server what it thinks its called:
dig @server hostname.bind ch txt
which will return a TXT
record containing the server's hostname (so long as the functionality exists in the DNS server software and hasn't been disabled).
This can be useful to identify which server out of any particular "DNS Anycast Cloud" is serving you at the moment.