DnsServiceRegister API 问题

问题描述 投票:0回答:2

我正在尝试使用 Windows 10+ API DnsServiceRegister 来注册可发现的 Web 服务器。

       DNS_SERVICE_REGISTER_REQUEST rd = {};           
       DNS_SERVICE_INSTANCE di = {};
       rd.pServiceInstance = &di;
       rd.unicastEnabled =  0;
       di.pszInstanceName = L"Remote Control._http._tcp.local";
       di.pszHostName = L"192.168.10.6";
       IP4_ADDRESS i4 = {};
       InetPton(AF_INET, L"192.168.10.6", (void*)&i4);
       di.ip4Address = &i4;

       di.wPort = (WORD)12345;
       rd.Version = DNS_QUERY_REQUEST_VERSION1;
       rd.pRegisterCompletionCallback = [](DWORD Status,
           PVOID pQueryContext,
           PDNS_SERVICE_INSTANCE pInstance)
       {
           nop();
       };
       DnsServiceRegister(&rd, 0);

调用成功(根据文档返回值 DNS_REQUEST_PENDING),过了一会儿,我的回调被调用,状态 = 0(成功?)。但是,没有 UPnP 工具检测到我的服务。 当我将单播设置为 1 时,状态为 9002(错误)。

使用此 API 时我缺少什么?

编辑:调用回调时,pInstance 参数指向带有 ip4Address 和 ip6Address 空指针的 DNS_SERVICE_INSTANCE。为什么?

编辑:可以使用 DnsServiceBrowse() 发现它。但 UPnP 扫描工具无法发现它。

winapi dns
2个回答
0
投票

di.pszHostName = L"192.168.10.6";

不是有效的主机名。它必须是一个字符串并以 .local 结尾。

我遇到了同样的问题,我复制了您的代码片段进行测试。如果主机名是以 .local 结尾的普通名称,则它可以工作。


0
投票

我复制了您的代码并做了一些小的修改,在调用 DnsServiceRegister() 和我的回调函数中获得了正确的返回值以指示事物已注册,但我从未在运行 mdns-scan 或的 linux 机器上看到结果avahi-发现。

我是否需要在这些调用之前启用 Windows 服务,或者拥有凭据句柄?

void DnsServiceRegisterComplete(
    DWORD Status,
    PVOID pQueryContext,
    PDNS_SERVICE_INSTANCE pInstance
)
{
    if (bConsoleExists)
        std::cout << "[" << getTimeISO8601() << "] DnsServiceRegisterComplete(" << Status << ") DNS_ERROR_RCODE_SERVER_FAILURE=" << DNS_ERROR_RCODE_SERVER_FAILURE << std::endl;
    return;
}

void TiVomDNSRegister(bool enable = true)
{
    IP4_ADDRESS i4 = { 0 };
    InetPton(AF_INET, L"192.168.50.32", (void*)&i4);
    DNS_SERVICE_INSTANCE di = { 0 };
    di.ip4Address = &i4;
    di.pszInstanceName = L"WimSurface9._tivo-videos._tcp.local";
    di.pszHostName = L"WimSurface9.local";
    di.wPort = (WORD)80;
    DNS_SERVICE_REGISTER_REQUEST rd = { 0 };
    rd.Version = DNS_QUERY_REQUEST_VERSION1;
    rd.InterfaceIndex = 0;
    rd.pServiceInstance = &di;
    rd.pRegisterCompletionCallback = &DnsServiceRegisterComplete;
    rd.pQueryContext = nullptr;
    rd.hCredentials = 0;
    rd.unicastEnabled = FALSE; // true if the DNS protocol should be used to advertise the service; false if the mDNS protocol should be used.
    if (enable)
    {
        auto mDNSReturn = DnsServiceRegister(&rd, nullptr);
        if (bConsoleExists)
            std::cout << " DnsServiceRegister(" << mDNSReturn << ") DNS_REQUEST_PENDING=" << DNS_REQUEST_PENDING << std::endl;
    }
    else
    {
        auto mDNSReturn = DnsServiceDeRegister(&rd, nullptr);
        if (bConsoleExists)
            std::cout << " DnsServiceRegister(" << mDNSReturn << ") DNS_REQUEST_PENDING=" << DNS_REQUEST_PENDING << std::endl;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.