【问题标题】:Use res_nmkquery() to connect to an ipv6-only DNS server使用 res_nmkquery() 连接到仅支持 ipv6 的 DNS 服务器
【发布时间】:2017-08-04 00:57:41
【问题描述】:

我一直在使用linux resolver functions,如res_ninit()、res_nmkquery()等来执行DNS请求。

现在大部分时间都可以简单地使用系统的默认解析器,但有时我需要手动对特定主机或 IP 地址执行实时 DNS 请求。

这就是问题所在 - 我希望能够连接到在仅接受 IPv6 流量的主机上运行的 DNS 服务器,但我用于连接特定名称服务器的代码通常涉及以下内容:

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

这段代码显然只需要 ipv4 地址(将 uint32_t 值复制到 {__res_state}.ns_addr_list 结构,这是一个 struct sockaddr_in 变量,它也只处理 ipv4 值。

查看 /usr/include/resolv.h,我可以看到 __res_state 结构还具有变量 u_int16_t nscount6;struct sockaddr_in6 *nsaddrs[MAXNS];,这显然是为了支持 ipv6。但是,我似乎在互联网上找不到任何关于在 res_nmkquery() 调用中使用这些值来连接到仅限 ipv6 主机上的 DNS 服务器的 cmets。

那么,如何使用 res_nmkquery() 和/或 struct __res_state 连接到仅支持 ipv6 的主机上的 DNS 服务器

我已经尝试直接编辑 nsaddrs 和 nscount6 变量,但是 res_nmkquery() 的代码返回错误,并且似乎看不到我放在那里的名称服务器。我需要做什么才能完成这项工作?

如果有影响,我只关心 ubuntu(即,仅 gcc 解决方案或仅 gnu 解决方案都可以接受)。

【问题讨论】:

    标签: c dns ipv6


    【解决方案1】:

    我真的很讨厌回答我自己的问题,但是在六个月之后连一条评论都没有,看来我自己的问题的答案是: 你不能

    res_nmkquery() 之类的函数已经过时了。从我研究过的执行 DNS 查询的库中,它们倾向于 (a) 加载系统的解析器状态并手动连接到 DNS 服务器,或者 (b) 利用诸如 gethostbyname() 之类的函数来让系统执行请求。

    res_nmkquery() 之类的函数似乎已经过时,很少在野外使用。这并不是说它们不好。只是如果您尝试使用它们,可能会有更好的方法来完成您想要完成的工作。

    【讨论】:

    • 这个东西主要用于移植旧的 *BSD 应用程序,在 Linux 上已经过时了;这些天你应该使用getaddrinfo() 和朋友。
    • @MichaelHampton:如果您愿意详细说明,请输入答案,我会选择它
    • 手册页(您链接到的)声明这些函数来自 4.3BSD。这个特殊的古老 BSD 于 1986 年 6 月发布,比第一个 IPv6 RFC 早了将近十年。 BSD 是what it was,这些功能永远不会被更新以支持 IPv6。因此我们有了新的 API……这可能不值得一个完整的答案……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    相关资源
    最近更新 更多