0

We are developing a client application that should be able to communicate with a service that can be either running on local host or on a different computer in the local network. We successfully use the DnsServiceRegister (Server) and DnsServiceBrowse (Client) functions in Windows 10 even if server and client are both running on localhost, as long as the network cable is plugged in. However, when the network cable is unplugged, DnsServiceBrowse refuses to work with ERROR_NO_NETWORK. Is there any way to work around this limitation without too much effort? DnsServiceRegister seems to work fine without a network cable, so maybe there is some other way to query the local DNS cache from the client side?

Code on client side:

#pragma comment(lib, "dnsapi.lib")

#include <iostream>
#include <cassert>
#include <Windows.h>
#include <windns.h>

VOID WINAPI BrowseCallback(DWORD Status, PVOID pQueryContext, PDNS_RECORD pDnsRecord)
{
    DnsRecordListFree(pDnsRecord);
}

int main()
{
    DNS_SERVICE_BROWSE_REQUEST browseRequest{};
    browseRequest.Version = DNS_QUERY_REQUEST_VERSION1;
    browseRequest.InterfaceIndex = 0;
    browseRequest.QueryName = L"_sam-balancelab._tcp.local";
    browseRequest.pBrowseCallback = BrowseCallback;
    browseRequest.pQueryContext = (PVOID)43;
    DNS_SERVICE_CANCEL cancelBrowse{};
    const DNS_STATUS result = DnsServiceBrowse(&browseRequest, &cancelBrowse);
    // PROBLEM: DnsServiceBrowse returns ERROR_NO_NETWORK(1222) if network cable is not plugged in or network adapter is disabled by user
    assert(result == DNS_REQUEST_PENDING);
    std::cin.get();
    return 0;
}

I don't believe that it is relevant, but here is the code where the service gets registered:

#pragma comment(lib, "dnsapi.lib")

#include <Windows.h>
#include <iostream>
#include <cassert>
#include <windns.h>

VOID WINAPI DnsServiceRegisterComplete(DWORD Status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance)
{
    std::cout << "DnsServiceRegisterComplete" << (int)pQueryContext << std::endl;
}

int main()
{
    const PDNS_SERVICE_INSTANCE serviceInstance = DnsServiceConstructInstance(
        L"SAM BalanceLab._sam-balancelab._tcp.local",
        L"Ryzen3950X.local",
        // for some reason, no matter what we specify here,
        // Windows only delivers nullptr for IP addresses to callers of DnsServiceResolve
        nullptr, nullptr,
        12344,
        0,
        0,
        0,
        nullptr,
        nullptr);
    assert(serviceInstance != nullptr);

    DNS_SERVICE_REGISTER_REQUEST request{};
    request.Version = DNS_QUERY_REQUEST_VERSION1;
    request.InterfaceIndex = 0;
    request.pServiceInstance = serviceInstance;
    request.pRegisterCompletionCallback = &DnsServiceRegisterComplete;
    request.pQueryContext = (void*)42;
    request.hCredentials = nullptr;
    request.unicastEnabled = FALSE;
    DWORD result = DnsServiceRegister(&request, nullptr);
    assert(result == DNS_REQUEST_PENDING);
    std::cin.get();
}
Spacy
  • 85
  • 10
  • Can you share the code of how you are calling the DnsServiceRegister to better answer the question? – Security Guard Mar 04 '21 at 19:59
  • @SecurityGuard I added the invocation code for DnsServiceRegister to my question above. – Spacy Mar 05 '21 at 20:14
  • Try replacing the second parameter from L"Ryzen3950X", to "localhost" – Security Guard Mar 06 '21 at 05:59
  • @SecurityGuard I tried it just now but DnsServiceBrowse still returns ERROR_NO_NETWORK if no network cable is attached. – Spacy Mar 08 '21 at 11:00
  • `DnsServiceBrowse` is used to initiate a DNS-SD discovery for services running on the local network. The DNS Client service is included in all client and server versions of the Windows operating system, and is running by default upon operating system installation. When you configure a TCP/IP network connection with the IP address of a DNS server,... I think the problem is that the server and the client need to establish TCP/IP communication. – Strive Sun Mar 09 '21 at 09:04
  • You can also refer: [Troubleshooting DNS clients](https://learn.microsoft.com/en-us/windows-server/networking/dns/troubleshoot/troubleshoot-dns-client#check-network-connection) – Strive Sun Mar 09 '21 at 09:04

1 Answers1

0

Did you try setting the registry key Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient\EnableMulticast to 1. I had also some issues with the error code ERROR_NO_NETWORK and for me this solved it. After setting it you may need to restart the Windows service DNS-Client or just reboot.

svanveen
  • 11
  • 1
  • I tried three states for the EnableMulticast setting: 1, 0 and deleting the key. None of it made any difference. I rebooted after each change of the setting. – Spacy May 10 '21 at 15:33
  • Just FYI, there's also EnableMDNS in HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters\ which might be equivalent. From: https://f20.be/blog/mdns – Nick Westgate Feb 23 '22 at 04:38
  • @Spacy did you use the proper type `DWORD` for the value? – svanveen Feb 23 '22 at 09:44