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