Search code examples
cdnsipv6

Use res_nmkquery() to connect to an ipv6-only DNS server


I have been using the linux resolver functions, such as res_ninit(), res_nmkquery(), etc, to perform DNS requests.

Now most of the time it's okay to simply use the system's default resolvers, but there are times where I need to perform a live DNS request on a specific host or IP address manually.

This is where the problem comes in - I'd like to be able to connect to a DNS server running on a host which only accepts IPv6 traffic, yet my code for connecting to specific name servers usually involves something like:

int i, c;
uint32_t ip;
struct __res_state state;
// a bunch of other stuff
res_ninit(&state);
// more stuff
memcpy((void *)&state.nsaddr_list[0].sin_addr, &ip, sizeof(ip));
// more stuff with state
res_nmkquery(&state, /* ... blah blah */);
// and so on... you get the idea

This code clearly only takes ipv4 addresses (the copying of a uint32_t value into a {__res_state}.ns_addr_list structure, which is a struct sockaddr_in variable, which also only handles ipv4 values.

Looking at /usr/include/resolv.h, I can see that the __res_state struct also has the variables u_int16_t nscount6; and struct sockaddr_in6 *nsaddrs[MAXNS];, which are clearly there for ipv6 support. However, I cannot seem to find any comments on the interwebs about using these values in a res_nmkquery() call to connect to a DNS server on an ipv6-only host.

So then, how do I use res_nmkquery() and/or struct __res_state to connect to a DNS server on an ipv6-only host?

I have already tried editing the nsaddrs and nscount6 variables directly, however the code to res_nmkquery() returns an error, and appears to not see the name servers I put there. What do I need to do to make this work?

If it makes a difference, I only care about ubuntu (ie, gcc-only solutions or gnu-only solutions are acceptable).


Solution

  • I really hate answering my own questions, but after six months with not so much as a single comment, it would appear the answer to my own question is: you cant.

    Functions like res_nmkquery() are rather outdated. From the libraries I've researched which perform DNS queries, they tend to either (a) load the system's resolver state and connect to the DNS servers manually, or (b) utilize functions like gethostbyname() to let the system perform the request.

    Functions like res_nmkquery() seem to be outdated and rarely used in the wild. This is not to say they are bad; only that if you are trying to use them, there's probably a better way to do what you're trying to accomplish.