Skip to content

Commit fb6af19

Browse files
committed
Fix network DNS on macOS
It stopped working for ipv4 only networks in Monterey. See zerotier#1696 We add some config like so to System Configuration ``` scutil show State:/Network/Service/9bee8941b5xxxxxx/IPv4 <dictionary> { Addresses : <array> { 0 : 10.2.1.36 } InterfaceName : feth4823 Router : 10.2.1.36 ServerAddress : 127.0.0.1 } ```
1 parent 41f9bdc commit fb6af19

File tree

4 files changed

+136
-7
lines changed

4 files changed

+136
-7
lines changed

osdep/MacDNSHelper.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ class MacDNSHelper
1212
public:
1313
static void setDNS(uint64_t nwid, const char *domain, const std::vector<InetAddress> &servers);
1414
static void removeDNS(uint64_t nwid);
15-
static bool addIps(uint64_t nwid, const MAC mac, const char *dev, const std::vector<InetAddress> &addrs);
16-
static bool removeIps(uint64_t nwid);
15+
static bool addIps4(uint64_t nwid, const MAC mac, const char *dev, const std::vector<InetAddress> &addrs);
16+
static bool addIps6(uint64_t nwid, const MAC mac, const char *dev, const std::vector<InetAddress> &addrs);
17+
static bool removeIps4(uint64_t nwid);
18+
static bool removeIps6(uint64_t nwid);
1719
};
1820

1921
}

osdep/MacDNSHelper.mm

+124-3
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,114 @@ static void printKeys (const void* key, const void* value, void* context) {
9595
// Originally I planned to put all the v6 ip addresses from the network into the config.
9696
// But only the link local address is necessary and sufficient. Added other v6 addresses
9797
// doesn't do anything.
98-
bool MacDNSHelper::addIps(uint64_t nwid, const MAC mac, const char *dev, const std::vector<InetAddress>& addrs)
98+
//
99+
// As of Monterey we need IPv4 set up too.
100+
101+
bool MacDNSHelper::addIps4(uint64_t nwid, const MAC mac, const char *dev, const std::vector<InetAddress>& addrs)
99102
{
103+
const char* ipStr = {0};
104+
const char* ipStr2 = {0};
105+
char buf2[256] = {0};
106+
107+
bool hasV4 = false;
108+
for (unsigned int i = 0; i < addrs.size(); ++i) {
109+
if (addrs[i].isV4()) {
110+
hasV4 = true;
111+
112+
ipStr = addrs[i].toIpString(buf2);
113+
ipStr2 = addrs[i].toIpString(buf2);
114+
115+
break;
116+
}
117+
}
118+
119+
if (!hasV4) {
120+
MacDNSHelper::removeIps4(nwid);
121+
return true;
122+
}
123+
124+
125+
SCDynamicStoreRef ds = SCDynamicStoreCreate(NULL, CFSTR("zerotier"), NULL, NULL);
126+
char buf[256] = { 0 };
127+
sprintf(buf, "State:/Network/Service/%.16llx/IPv4", nwid);
128+
129+
130+
CFStringRef key = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8);
131+
132+
CFStringRef cfaddr = CFStringCreateWithCString(NULL, ipStr, kCFStringEncodingUTF8);
133+
CFArrayRef addrArray = CFArrayCreate(NULL, (const void**)&cfaddr, 1, &kCFTypeArrayCallBacks);
134+
135+
CFStringRef cfdev = CFStringCreateWithCString(NULL, dev, kCFStringEncodingUTF8);
136+
137+
CFStringRef cfserver = CFStringCreateWithCString(NULL, "127.0.0.1", kCFStringEncodingUTF8);
138+
CFStringRef cfrouter = CFStringCreateWithCString(NULL, ipStr2, kCFStringEncodingUTF8);
139+
140+
const int SIZE = 4;
141+
CFStringRef keys[SIZE];
142+
keys[0] = CFSTR("Addresses");
143+
keys[1] = CFSTR("InterfaceName");
144+
keys[2] = CFSTR("ServerAddress");
145+
keys[3] = CFSTR("Router");
146+
147+
CFTypeRef values[SIZE];
148+
values[0] = addrArray;
149+
values[1] = cfdev;
150+
values[2] = cfserver;
151+
values[3] = cfrouter;
152+
153+
154+
CFDictionaryRef dict = CFDictionaryCreate(NULL,
155+
(const void**)keys, (const void**)values, SIZE, &kCFCopyStringDictionaryKeyCallBacks,
156+
&kCFTypeDictionaryValueCallBacks);
157+
158+
// CFDictionaryApplyFunction(dict, printKeys, NULL);
159+
160+
CFArrayRef list = SCDynamicStoreCopyKeyList(ds, key);
161+
CFIndex i = 0, j = CFArrayGetCount(list);
162+
bool addrsChanged = true;
163+
CFPropertyListRef oldAddrs = NULL;
164+
165+
bool ret = TRUE;
166+
if (j > 0) {
167+
oldAddrs = SCDynamicStoreCopyValue(ds, (CFStringRef)CFArrayGetValueAtIndex(list, i));
168+
addrsChanged = !CFEqual(oldAddrs,dict);
169+
}
170+
if (addrsChanged) {
171+
if (j <= 0) {
172+
ret &= SCDynamicStoreAddValue(ds, key, dict);
173+
} else {
174+
ret &= SCDynamicStoreSetValue(ds, (CFStringRef)CFArrayGetValueAtIndex(list, i), dict);
175+
}
176+
if (!ret) {
177+
fprintf(stderr, "Error writing IPv6 configuration\n");
178+
}
179+
}
180+
if (oldAddrs != NULL) {
181+
CFRelease(oldAddrs);
182+
}
183+
184+
CFRelease(cfaddr);
185+
186+
CFRelease(addrArray);
187+
CFRelease(cfdev);
188+
CFRelease(cfserver);
189+
CFRelease(cfrouter);
190+
191+
CFRelease(ds);
192+
CFRelease(key);
100193

194+
// for (unsigned int i = 0; i < SIZE; ++i) {
195+
// values[i] = NULL;
196+
// }
197+
198+
CFRelease(list);
199+
CFRelease(dict);
200+
201+
return ret;
202+
203+
}
204+
bool MacDNSHelper::addIps6(uint64_t nwid, const MAC mac, const char *dev, const std::vector<InetAddress>& addrs)
205+
{
101206
bool hasV6 = false;
102207
for (unsigned int i = 0; i < addrs.size(); ++i) {
103208
if (addrs[i].isV6()) {
@@ -107,7 +212,7 @@ static void printKeys (const void* key, const void* value, void* context) {
107212
}
108213

109214
if (!hasV6) {
110-
MacDNSHelper::removeIps(nwid);
215+
MacDNSHelper::removeIps6(nwid);
111216
return true;
112217
}
113218

@@ -204,7 +309,7 @@ static void printKeys (const void* key, const void* value, void* context) {
204309

205310
return ret;
206311
}
207-
bool MacDNSHelper::removeIps(uint64_t nwid)
312+
bool MacDNSHelper::removeIps6(uint64_t nwid)
208313
{
209314
SCDynamicStoreRef ds = SCDynamicStoreCreate(NULL, CFSTR("zerotier"), NULL, NULL);
210315

@@ -218,4 +323,20 @@ static void printKeys (const void* key, const void* value, void* context) {
218323
return res;
219324
}
220325

326+
327+
bool MacDNSHelper::removeIps4(uint64_t nwid)
328+
{
329+
SCDynamicStoreRef ds = SCDynamicStoreCreate(NULL, CFSTR("zerotier"), NULL, NULL);
330+
331+
char buf[256] = {0};
332+
sprintf(buf, "State:/Network/Service/%.16llx/IPv4", nwid);
333+
CFStringRef key = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8);
334+
bool res = SCDynamicStoreRemoveValue(ds, key);
335+
CFRelease(key);
336+
CFRelease(ds);
337+
338+
return res;
339+
}
340+
341+
221342
}

osdep/MacEthernetTap.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ MacEthernetTap::~MacEthernetTap()
245245
pid_t pid0,pid1;
246246

247247
MacDNSHelper::removeDNS(_nwid);
248-
MacDNSHelper::removeIps(_nwid);
248+
MacDNSHelper::removeIps4(_nwid);
249+
MacDNSHelper::removeIps6(_nwid);
249250

250251
Mutex::Lock _gl(globalTapCreateLock);
251252
::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit

service/OneService.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -2531,8 +2531,13 @@ class OneServiceImpl : public OneService
25312531
}
25322532

25332533
#ifdef __APPLE__
2534-
if (!MacDNSHelper::addIps(n.config().nwid, n.config().mac, n.tap()->deviceName().c_str(), newManagedIps))
2534+
if (!MacDNSHelper::addIps6(n.config().nwid, n.config().mac, n.tap()->deviceName().c_str(), newManagedIps)) {
25352535
fprintf(stderr, "ERROR: unable to add v6 addresses to system configuration" ZT_EOL_S);
2536+
}
2537+
2538+
if (!MacDNSHelper::addIps4(n.config().nwid, n.config().mac, n.tap()->deviceName().c_str(), newManagedIps)) {
2539+
fprintf(stderr, "ERROR: unable to add v4 addresses to system configuration" ZT_EOL_S);
2540+
}
25362541
#endif
25372542
n.setManagedIps(newManagedIps);
25382543
}

0 commit comments

Comments
 (0)