MDNSService.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include <vector>
  2. #include <cassert>
  3. #include "MDNSService.h"
  4. #include "BellLogger.h"
  5. #ifdef _WIN32
  6. #include <WinSock2.h>
  7. #include <iphlpapi.h>
  8. #pragma comment(lib, "IPHLPAPI.lib")
  9. #include "mdnssvc.h"
  10. #else
  11. #include <arpa/inet.h>
  12. #include "mdns.h"
  13. #include <arpa/inet.h>
  14. #endif
  15. using namespace bell;
  16. static struct mdnsd *mdnsService;
  17. /**
  18. * Win32 implementation of MDNSService
  19. **/
  20. void* MDNSService::registerService(
  21. const std::string& serviceName,
  22. const std::string& serviceType,
  23. const std::string& serviceProto,
  24. const std::string& serviceHost,
  25. int servicePort,
  26. const std::map<std::string, std::string> txtData
  27. ) {
  28. if (!mdnsService) {
  29. char hostname[128];
  30. gethostname(hostname, sizeof(hostname));
  31. struct sockaddr_in* host = NULL;
  32. ULONG size = sizeof(IP_ADAPTER_ADDRESSES) * 64;
  33. IP_ADAPTER_ADDRESSES* adapters = (IP_ADAPTER_ADDRESSES*)malloc(size);
  34. int ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST, 0, adapters, &size);
  35. for (PIP_ADAPTER_ADDRESSES adapter = adapters; adapter && !host; adapter = adapter->Next) {
  36. if (adapter->TunnelType == TUNNEL_TYPE_TEREDO) continue;
  37. if (adapter->OperStatus != IfOperStatusUp) continue;
  38. for (IP_ADAPTER_UNICAST_ADDRESS* unicast = adapter->FirstUnicastAddress; unicast;
  39. unicast = unicast->Next) {
  40. if (adapter->FirstGatewayAddress && unicast->Address.lpSockaddr->sa_family == AF_INET) {
  41. host = (struct sockaddr_in*)unicast->Address.lpSockaddr;
  42. BELL_LOG(info, "mdns", "mDNS on interface %s", inet_ntoa(host->sin_addr));
  43. mdnsService = mdnsd_start(host->sin_addr, false);
  44. break;
  45. }
  46. }
  47. }
  48. assert(mdnsService);
  49. mdnsd_set_hostname(mdnsService, hostname, host->sin_addr);
  50. free(adapters);
  51. }
  52. std::vector<const char*> txt;
  53. std::vector<std::unique_ptr<std::string>> txtStr;
  54. for (auto& [key, value] : txtData) {
  55. auto str = make_unique<std::string>(key + "=" + value);
  56. txtStr.push_back(std::move(str));
  57. txt.push_back(txtStr.back()->c_str());
  58. }
  59. txt.push_back(NULL);
  60. std::string type(serviceType + "." + serviceProto + ".local");
  61. return mdnsd_register_svc(mdnsService, serviceName.c_str(), type.c_str(), servicePort, NULL, txt.data());
  62. }
  63. void MDNSService::unregisterService(void* service) {
  64. mdns_service_remove(mdnsService, (mdns_service*)service);
  65. }