如何使用 DnsQuery 指定要查询的特定 DNS 服务器?

Posted

技术标签:

【中文标题】如何使用 DnsQuery 指定要查询的特定 DNS 服务器?【英文标题】:How does one specify a specific DNS server to query using DnsQuery? 【发布时间】:2012-01-19 19:10:00 【问题描述】:

DnsQuery 没有参数来指定要查询的服务器。另一方面,我看到this sample,它似乎在MSDN文档中标记为“保留且必须为0”的参数中传递了一个IP。

有什么方法可以查询特定的服务器(就像 nslookup 一样?)还是我必须编写自己的 DNS 客户端(或者当然是找一个库)?

【问题讨论】:

它已正式记录在 DnsQueryEx 中。查看 DNS_QUERY_REQUEST 参数。它允许您传递 DNS 服务器列表。嗯....看起来这仅适用于 Windows 8 和 Win8-sever。无赖:(msdn.microsoft.com/en-us/library/windows/desktop/…[2]:msdn.microsoft.com/en-us/library/windows/desktop/… 我会在调用 DnsQuery 之前尝试使用 DnsValidateServerStatus。有可能它会将必要的 DNS 记录从传递给 DnsValidateServerStatus 的服务器加载到您的本地 DNS 缓存中,然后 DnsQuery 将简单地重用它们。这是一个 hack,不过我从未尝试过。 【参考方案1】:

DnsQuery PVOID pExtra 的第 4 个参数接受包含要查询的特定 DNS 服务器的 PIP4_ARRAY。这与 DNS_QUERY_BYPASS_CACHE 的第三个参数 DWORD Options 结合使用,以绕过解析器缓存。

这从 Windows 2000 开始有效,在 Windows XP DnsQuery 调用该函数 称为 privateNarrowToWideQuery(在 dnsapi.dll 中)并采用 pExtra 参数作为 PIP4_ARRAY。

MSDN 在这方面不准确,导致这是一个未记录的功能。 在旧版本的 DnsQuery API 中,调用 pExtra 以前称为 aipServers

关于IPV6 AAAA记录的DNS,可以试试第二个参数的函数 WORD wType 作为DNS_TYPE_AAAA 和第五个参数PDNS_RECORD *ppQueryResultsSet 作为指向DNS_AAAA_DATA 的指针。虽然这仍然会强制您传入 IPV4 IP 地址数组而不是 IPV6。

关于 IPV6 查询的 Windows 版本支持,请参阅以下参考资料

Domain Name Service (DNS) Domain Name System Client Behavior in Windows Vista Changes to IPv6 in Windows Vista and Windows Server 2008

在未来的 Windows 版本中,我相信为 IPV6 执行此操作的正确方法是使用 DnsQueryEx ,其第一个参数为 PDNS_QUERY_REQUEST pQueryRequest ,其中包含 成员PDNS_ADDR_ARRAY pDnsServerList;,其中包含成员WORD Family;,指定DNS 服务器的IP 地址类型。

DnsQuery 是否已经支持指向 PDNS_ADDR_ARRAY 的指针作为PVOID pExtra 的参数,或者将在未来的 Windows 版本中进行修改,我不确定,但欢迎您尝试看看。

请参阅How to use the DnsQuery function to resolve host names and host addresses with Visual C++ .NET 以获取示例代码,正如您已经发现的那样。

另请参阅以下similar SO Question。

【讨论】:

可能还没有开始更新文档,Windows CE 的 MSDN 文档和一些 Windows 移动设备仍然提到 aipServers【参考方案2】:

它有一个功能:

        PCSTR       pszName = machine.c_str(); 

        DWORD       Options = NULL; 

        PVOID       pExtra = NULL; 

        PDNS_RECORD ppQueryResults; 

        PVOID       *pReserved = NULL; 



DNS_STATUS DNS_stat = DnsQuery_A(
                pszName,
                DNS_TYPE_A,
                Options,
                pExtra,
                &ppQueryResults,
                pReserved
            );

其中 pszName 是服务器名称。

【讨论】:

以上是关于如何使用 DnsQuery 指定要查询的特定 DNS 服务器?的主要内容,如果未能解决你的问题,请参考以下文章

dnsquery - 使用解析程序查询域名服务器

DDoS攻击与防御

基于分子中特定条件的平均值

检索Solr查询中的特定字段?

用户如何在ldap服务器中创建用户后登录?

oracle 学习笔记