| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 | #include <cassert>#include <vector>#include "BellLogger.h"#include "MDNSService.h"#ifdef _WIN32#include <WinSock2.h>#include <iphlpapi.h>#pragma comment(lib, "IPHLPAPI.lib")#include "mdnssvc.h"#else#include <arpa/inet.h>#include "mdns.h"#endifusing namespace bell;class implMDNSService : public MDNSService { private:  struct mdns_service* service;  void unregisterService(void) {    mdns_service_remove(implMDNSService::mdnsServer, service);  }; public:  static struct mdnsd* mdnsServer;  implMDNSService(struct mdns_service* service) : service(service){};};/** * Win32 implementation of MDNSService **/struct mdnsd* implMDNSService::mdnsServer = NULL;static std::mutex registerMutex;std::unique_ptr<MDNSService> MDNSService::registerService(    const std::string& serviceName, const std::string& serviceType,    const std::string& serviceProto, const std::string& serviceHost,    int servicePort, const std::map<std::string, std::string> txtData) {  std::lock_guard lock(registerMutex);  if (!implMDNSService::mdnsServer) {    char hostname[128];    gethostname(hostname, sizeof(hostname));    struct sockaddr_in* host = NULL;    ULONG size = sizeof(IP_ADAPTER_ADDRESSES) * 64;    IP_ADAPTER_ADDRESSES* adapters = (IP_ADAPTER_ADDRESSES*)malloc(size);    int ret = GetAdaptersAddresses(AF_UNSPEC,                                   GAA_FLAG_INCLUDE_GATEWAYS |                                       GAA_FLAG_SKIP_MULTICAST |                                       GAA_FLAG_SKIP_ANYCAST,                                   0, adapters, &size);    for (PIP_ADAPTER_ADDRESSES adapter = adapters; adapter && !host;         adapter = adapter->Next) {      if (adapter->TunnelType == TUNNEL_TYPE_TEREDO)        continue;      if (adapter->OperStatus != IfOperStatusUp)        continue;      for (IP_ADAPTER_UNICAST_ADDRESS* unicast = adapter->FirstUnicastAddress;           unicast; unicast = unicast->Next) {        if (adapter->FirstGatewayAddress &&            unicast->Address.lpSockaddr->sa_family == AF_INET) {          host = (struct sockaddr_in*)unicast->Address.lpSockaddr;          BELL_LOG(info, "mdns", "mDNS on interface %s",                   inet_ntoa(host->sin_addr));          implMDNSService::mdnsServer = mdnsd_start(host->sin_addr, false);          break;        }      }    }    assert(implMDNSService::mdnsServer);    mdnsd_set_hostname(implMDNSService::mdnsServer, hostname, host->sin_addr);    free(adapters);  }  std::vector<const char*> txt;  std::vector<std::unique_ptr<std::string>> txtStr;  for (auto& [key, value] : txtData) {    auto str = make_unique<std::string>(key + "=" + value);    txtStr.push_back(std::move(str));    txt.push_back(txtStr.back()->c_str());  }  txt.push_back(NULL);  std::string type(serviceType + "." + serviceProto + ".local");  auto service =      mdnsd_register_svc(implMDNSService::mdnsServer, serviceName.c_str(),                         type.c_str(), servicePort, NULL, txt.data());  return std::make_unique<implMDNSService>(service);}
 |