MDNSService.cpp 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. class implMDNSService : public MDNSService {
  17. private:
  18. struct mdns_service* service;
  19. void unregisterService(void) { mdns_service_remove(implMDNSService::mdnsServer, service); };
  20. public:
  21. static struct mdnsd* mdnsServer;
  22. implMDNSService(struct mdns_service* service) : service(service) { };
  23. };
  24. /**
  25. * Win32 implementation of MDNSService
  26. **/
  27. struct mdnsd* implMDNSService::mdnsServer = NULL;
  28. std::unique_ptr<MDNSService> MDNSService::registerService(
  29. const std::string& serviceName,
  30. const std::string& serviceType,
  31. const std::string& serviceProto,
  32. const std::string& serviceHost,
  33. int servicePort,
  34. const std::map<std::string, std::string> txtData
  35. ) {
  36. if (!implMDNSService::mdnsServer) {
  37. char hostname[128];
  38. gethostname(hostname, sizeof(hostname));
  39. struct sockaddr_in* host = NULL;
  40. ULONG size = sizeof(IP_ADAPTER_ADDRESSES) * 64;
  41. IP_ADAPTER_ADDRESSES* adapters = (IP_ADAPTER_ADDRESSES*)malloc(size);
  42. int ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST, 0, adapters, &size);
  43. for (PIP_ADAPTER_ADDRESSES adapter = adapters; adapter && !host; adapter = adapter->Next) {
  44. if (adapter->TunnelType == TUNNEL_TYPE_TEREDO) continue;
  45. if (adapter->OperStatus != IfOperStatusUp) continue;
  46. for (IP_ADAPTER_UNICAST_ADDRESS* unicast = adapter->FirstUnicastAddress; unicast;
  47. unicast = unicast->Next) {
  48. if (adapter->FirstGatewayAddress && unicast->Address.lpSockaddr->sa_family == AF_INET) {
  49. host = (struct sockaddr_in*)unicast->Address.lpSockaddr;
  50. BELL_LOG(info, "mdns", "mDNS on interface %s", inet_ntoa(host->sin_addr));
  51. implMDNSService::mdnsServer = mdnsd_start(host->sin_addr, false);
  52. break;
  53. }
  54. }
  55. }
  56. assert(implMDNSService::mdnsServer);
  57. mdnsd_set_hostname(implMDNSService::mdnsServer, hostname, host->sin_addr);
  58. free(adapters);
  59. }
  60. std::vector<const char*> txt;
  61. std::vector<std::unique_ptr<std::string>> txtStr;
  62. for (auto& [key, value] : txtData) {
  63. auto str = make_unique<std::string>(key + "=" + value);
  64. txtStr.push_back(std::move(str));
  65. txt.push_back(txtStr.back()->c_str());
  66. }
  67. txt.push_back(NULL);
  68. std::string type(serviceType + "." + serviceProto + ".local");
  69. auto service = mdnsd_register_svc(implMDNSService::mdnsServer, serviceName.c_str(),
  70. type.c_str(), servicePort, NULL, txt.data());
  71. return std::make_unique<implMDNSService>(service);
  72. }