Use multicast DNS when network cable is unplugged

879 Views Asked by At

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();
}
1

There are 1 best solutions below

3
svanveen On

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.