MacDNSHelper.mm 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "MacDNSHelper.hpp"
  2. #include <stdio.h>
  3. #include <SystemConfiguration/SystemConfiguration.h>
  4. namespace ZeroTier {
  5. void MacDNSHelper::setDNS(uint64_t nwid, const char *domain, const std::vector<InetAddress> &servers)
  6. {
  7. SCDynamicStoreRef ds = SCDynamicStoreCreate(NULL, CFSTR("zerotier"), NULL, NULL);
  8. CFStringRef *s = new CFStringRef[4];
  9. for (unsigned int i = 0; i < servers.size(); ++i) {
  10. char buf[64];
  11. ZeroTier::InetAddress a = servers[i];
  12. const char *ipStr = a.toIpString(buf);
  13. s[i] = CFStringCreateWithCString(NULL, ipStr, kCFStringEncodingUTF8);
  14. }
  15. CFArrayRef serverArray = CFArrayCreate(NULL, (const void**)s, servers.size(), &kCFTypeArrayCallBacks);
  16. CFStringRef keys[2];
  17. keys[0] = CFSTR("SupplementalMatchDomains");
  18. keys[1] = CFSTR("ServerAddresses");
  19. CFStringRef cfdomain = CFStringCreateWithCString(NULL, domain, kCFStringEncodingUTF8);
  20. CFArrayRef domainArray = CFArrayCreate(NULL, (const void**)&cfdomain, 1, &kCFTypeArrayCallBacks);
  21. CFTypeRef values[2];
  22. values[0] = domainArray;
  23. values[1] = serverArray;
  24. CFDictionaryRef dict = CFDictionaryCreate(NULL,
  25. (const void**)keys, (const void**)values, 2, &kCFCopyStringDictionaryKeyCallBacks,
  26. &kCFTypeDictionaryValueCallBacks);
  27. char buf[256] = {0};
  28. sprintf(buf, "State:/Network/Service/%.16llx/DNS", nwid);
  29. CFStringRef key = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8);
  30. CFArrayRef list = SCDynamicStoreCopyKeyList(ds, key);
  31. CFIndex i = 0, j = CFArrayGetCount(list);
  32. bool dnsServersChanged = true;
  33. CFPropertyListRef oldDNSServers = NULL;
  34. if (j > 0) {
  35. oldDNSServers = SCDynamicStoreCopyValue(ds, (CFStringRef)CFArrayGetValueAtIndex(list, i));
  36. dnsServersChanged = !CFEqual(oldDNSServers,dict);
  37. }
  38. if (dnsServersChanged) {
  39. bool ret = TRUE;
  40. if (j <= 0) {
  41. ret &= SCDynamicStoreAddValue(ds, key, dict);
  42. } else {
  43. ret &= SCDynamicStoreSetValue(ds, (CFStringRef)CFArrayGetValueAtIndex(list, i), dict);
  44. }
  45. if (!ret) {
  46. fprintf(stderr, "Error writing DNS configuration\n");
  47. }
  48. }
  49. if (oldDNSServers != NULL) {
  50. CFRelease(oldDNSServers);
  51. }
  52. CFRelease(list);
  53. CFRelease(key);
  54. CFRelease(dict);
  55. CFRelease(domainArray);
  56. CFRelease(cfdomain);
  57. CFRelease(serverArray);
  58. for (int i = 0; i < servers.size(); ++i) {
  59. CFRelease(s[i]);
  60. }
  61. delete[] s;
  62. CFRelease(ds);
  63. }
  64. void MacDNSHelper::removeDNS(uint64_t nwid)
  65. {
  66. SCDynamicStoreRef ds = SCDynamicStoreCreate(NULL, CFSTR("zerotier"), NULL, NULL);
  67. char buf[256] = {0};
  68. sprintf(buf, "State:/Network/Service/%.16llx/DNS", nwid);
  69. CFStringRef key = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8);
  70. SCDynamicStoreRemoveValue(ds, key);
  71. CFRelease(key);
  72. CFRelease(ds);
  73. }
  74. }