mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-12 05:55:19 +00:00
Merge pull request #1488 from zerotier/macos-ipv6-config
Convince macOS to do ipv6 dns lookups
This commit is contained in:
commit
1f99f1d5f4
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../node/InetAddress.hpp"
|
#include "../node/InetAddress.hpp"
|
||||||
|
#include "../node/MAC.hpp"
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
@ -11,6 +12,8 @@ class MacDNSHelper
|
|||||||
public:
|
public:
|
||||||
static void setDNS(uint64_t nwid, const char *domain, const std::vector<InetAddress> &servers);
|
static void setDNS(uint64_t nwid, const char *domain, const std::vector<InetAddress> &servers);
|
||||||
static void removeDNS(uint64_t nwid);
|
static void removeDNS(uint64_t nwid);
|
||||||
|
static bool addIps(uint64_t nwid, const MAC mac, const char *dev, const std::vector<InetAddress> &addrs);
|
||||||
|
static bool removeIps(uint64_t nwid);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
static void printKeys (const void* key, const void* value, void* context) {
|
||||||
|
CFShow(key);
|
||||||
|
CFShow(value);
|
||||||
|
}
|
||||||
|
|
||||||
void MacDNSHelper::setDNS(uint64_t nwid, const char *domain, const std::vector<InetAddress> &servers)
|
void MacDNSHelper::setDNS(uint64_t nwid, const char *domain, const std::vector<InetAddress> &servers)
|
||||||
{
|
{
|
||||||
SCDynamicStoreRef ds = SCDynamicStoreCreate(NULL, CFSTR("zerotier"), NULL, NULL);
|
SCDynamicStoreRef ds = SCDynamicStoreCreate(NULL, CFSTR("zerotier"), NULL, NULL);
|
||||||
@ -85,4 +90,130 @@ void MacDNSHelper::removeDNS(uint64_t nwid)
|
|||||||
CFRelease(ds);
|
CFRelease(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make macOS believe we do in fact have ipv6 connectivity and that it should resolve dns names
|
||||||
|
// over ipv6 if we ask for them.
|
||||||
|
// Originally I planned to put all the v6 ip addresses from the network into the config.
|
||||||
|
// But only the link local address is necessary and sufficient. Added other v6 addresses
|
||||||
|
// doesn't do anything.
|
||||||
|
bool MacDNSHelper::addIps(uint64_t nwid, const MAC mac, const char *dev, const std::vector<InetAddress>& addrs)
|
||||||
|
{
|
||||||
|
|
||||||
|
bool hasV6 = false;
|
||||||
|
for (unsigned int i = 0; i < addrs.size(); ++i) {
|
||||||
|
if (addrs[i].isV6()) {
|
||||||
|
hasV6 = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasV6) {
|
||||||
|
MacDNSHelper::removeIps(nwid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SCDynamicStoreRef ds = SCDynamicStoreCreate(NULL, CFSTR("zerotier"), NULL, NULL);
|
||||||
|
char buf[256] = { 0 };
|
||||||
|
sprintf(buf, "State:/Network/Service/%.16llx/IPv6", nwid);
|
||||||
|
|
||||||
|
InetAddress ll = InetAddress::makeIpv6LinkLocal(mac);
|
||||||
|
char buf2[256] = {0};
|
||||||
|
const char* llStr = ll.toIpString(buf2);
|
||||||
|
|
||||||
|
|
||||||
|
CFStringRef key = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8);
|
||||||
|
CFStringRef* cfaddrs = new CFStringRef[1];
|
||||||
|
CFStringRef* cfprefixes = new CFStringRef[1];
|
||||||
|
CFStringRef* cfdestaddrs = new CFStringRef[1];
|
||||||
|
CFStringRef* cfflags = new CFStringRef[1];
|
||||||
|
|
||||||
|
|
||||||
|
cfaddrs[0] = CFStringCreateWithCString(NULL, llStr, kCFStringEncodingUTF8);
|
||||||
|
cfprefixes[0] = CFStringCreateWithCString(NULL, "64", kCFStringEncodingUTF8);
|
||||||
|
cfdestaddrs[0] = CFStringCreateWithCString(NULL, "::ffff:ffff:ffff:ffff:0:0", kCFStringEncodingUTF8);
|
||||||
|
cfflags[0] = CFStringCreateWithCString(NULL, "0", kCFStringEncodingUTF8);
|
||||||
|
|
||||||
|
CFArrayRef addrArray = CFArrayCreate(NULL, (const void**)cfaddrs, 1, &kCFTypeArrayCallBacks);
|
||||||
|
CFArrayRef prefixArray = CFArrayCreate(NULL, (const void**)cfprefixes, 1, &kCFTypeArrayCallBacks);
|
||||||
|
CFArrayRef destArray = CFArrayCreate(NULL, (const void**)cfdestaddrs, 1, &kCFTypeArrayCallBacks);
|
||||||
|
CFArrayRef flagsArray = CFArrayCreate(NULL, (const void**)cfflags, 1, &kCFTypeArrayCallBacks);
|
||||||
|
CFStringRef cfdev = CFStringCreateWithCString(NULL, dev, kCFStringEncodingUTF8);
|
||||||
|
|
||||||
|
const int SIZE = 5;
|
||||||
|
CFStringRef keys[SIZE];
|
||||||
|
keys[0] = CFSTR("Addresses");
|
||||||
|
keys[1] = CFSTR("DestAddresses");
|
||||||
|
keys[2] = CFSTR("Flags");
|
||||||
|
keys[3] = CFSTR("InterfaceName");
|
||||||
|
keys[4] = CFSTR("PrefixLength");
|
||||||
|
|
||||||
|
CFTypeRef values[SIZE];
|
||||||
|
values[0] = addrArray;
|
||||||
|
values[1] = destArray;
|
||||||
|
values[2] = flagsArray;
|
||||||
|
// values[3] = devArray;
|
||||||
|
values[3] = cfdev;
|
||||||
|
values[4] = prefixArray;
|
||||||
|
|
||||||
|
|
||||||
|
CFDictionaryRef dict = CFDictionaryCreate(NULL,
|
||||||
|
(const void**)keys, (const void**)values, SIZE, &kCFCopyStringDictionaryKeyCallBacks,
|
||||||
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
|
|
||||||
|
// CFDictionaryApplyFunction(dict, printKeys, NULL);
|
||||||
|
|
||||||
|
CFArrayRef list = SCDynamicStoreCopyKeyList(ds, key);
|
||||||
|
CFIndex i = 0, j = CFArrayGetCount(list);
|
||||||
|
bool addrsChanged = true;
|
||||||
|
CFPropertyListRef oldAddrs = NULL;
|
||||||
|
|
||||||
|
bool ret = TRUE;
|
||||||
|
if (j > 0) {
|
||||||
|
oldAddrs = SCDynamicStoreCopyValue(ds, (CFStringRef)CFArrayGetValueAtIndex(list, i));
|
||||||
|
addrsChanged = !CFEqual(oldAddrs,dict);
|
||||||
|
}
|
||||||
|
if (addrsChanged) {
|
||||||
|
if (j <= 0) {
|
||||||
|
ret &= SCDynamicStoreAddValue(ds, key, dict);
|
||||||
|
} else {
|
||||||
|
ret &= SCDynamicStoreSetValue(ds, (CFStringRef)CFArrayGetValueAtIndex(list, i), dict);
|
||||||
|
}
|
||||||
|
if (!ret) {
|
||||||
|
fprintf(stderr, "Error writing IPv6 configuration\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(addrArray);
|
||||||
|
CFRelease(prefixArray);
|
||||||
|
CFRelease(destArray);
|
||||||
|
CFRelease(flagsArray);
|
||||||
|
CFRelease(cfdev);
|
||||||
|
|
||||||
|
CFRelease(list);
|
||||||
|
CFRelease(dict);
|
||||||
|
|
||||||
|
CFRelease(ds);
|
||||||
|
CFRelease(key);
|
||||||
|
|
||||||
|
delete[] cfaddrs;
|
||||||
|
delete[] cfprefixes;
|
||||||
|
delete[] cfdestaddrs;
|
||||||
|
delete[] cfflags;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool MacDNSHelper::removeIps(uint64_t nwid)
|
||||||
|
{
|
||||||
|
SCDynamicStoreRef ds = SCDynamicStoreCreate(NULL, CFSTR("zerotier"), NULL, NULL);
|
||||||
|
|
||||||
|
char buf[256] = {0};
|
||||||
|
sprintf(buf, "State:/Network/Service/%.16llx/IPv6", nwid);
|
||||||
|
CFStringRef key = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8);
|
||||||
|
bool res = SCDynamicStoreRemoveValue(ds, key);
|
||||||
|
CFRelease(key);
|
||||||
|
CFRelease(ds);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -244,6 +244,7 @@ MacEthernetTap::~MacEthernetTap()
|
|||||||
pid_t pid0,pid1;
|
pid_t pid0,pid1;
|
||||||
|
|
||||||
MacDNSHelper::removeDNS(_nwid);
|
MacDNSHelper::removeDNS(_nwid);
|
||||||
|
MacDNSHelper::removeIps(_nwid);
|
||||||
|
|
||||||
Mutex::Lock _gl(globalTapCreateLock);
|
Mutex::Lock _gl(globalTapCreateLock);
|
||||||
::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit
|
::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit
|
||||||
|
@ -2041,6 +2041,11 @@ public:
|
|||||||
fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString(ipbuf));
|
fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString(ipbuf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (!MacDNSHelper::addIps(n.config.nwid, n.config.mac, n.tap->deviceName().c_str(), newManagedIps))
|
||||||
|
fprintf(stderr, "ERROR: unable to add v6 addresses to system configuration" ZT_EOL_S);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
n.managedIps.swap(newManagedIps);
|
n.managedIps.swap(newManagedIps);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user