Browse Source

fix macos default route again

see commit fb6af1971 * Fix network DNS on macOS
adding that stuff to System Config causes this extra route to be added
which breaks ipv4 default route.
We figured out a weird System Coniguration setting
that works.

--- old
couldn't figure out how to fix it in SystemConfiguration
so here we are# Please enter the commit message for your changes. Lines starting

We also moved the dns setter to before the syncIps stuff
to help with a race condition. It didn't always work when
you re-joined a network with default route enabled.
travisladuke 2 years ago
parent
commit
1d095e81d9
2 changed files with 42 additions and 28 deletions
  1. 2 3
      osdep/MacDNSHelper.mm
  2. 40 25
      osdep/ManagedRoute.cpp

+ 2 - 3
osdep/MacDNSHelper.mm

@@ -107,7 +107,6 @@ void MacDNSHelper::removeDNS(uint64_t nwid)
 bool MacDNSHelper::addIps4(uint64_t nwid, const MAC mac, const char *dev, const std::vector<InetAddress>& addrs)
 {
     const char* ipStr = {0};
-    const char* ipStr2 = {0};
     char buf2[256] = {0};
 
     bool hasV4 = false;
@@ -116,7 +115,6 @@ bool MacDNSHelper::addIps4(uint64_t nwid, const MAC mac, const char *dev, const
             hasV4 = true;
 
             ipStr = addrs[i].toIpString(buf2);
-            ipStr2 = addrs[i].toIpString(buf2);
 
             break;
         }
@@ -141,7 +139,8 @@ bool MacDNSHelper::addIps4(uint64_t nwid, const MAC mac, const char *dev, const
     CFStringRef cfdev = CFStringCreateWithCString(NULL, dev, kCFStringEncodingUTF8);
 
     CFStringRef cfserver = CFStringCreateWithCString(NULL, "127.0.0.1", kCFStringEncodingUTF8);
-    CFStringRef cfrouter = CFStringCreateWithCString(NULL, ipStr2, kCFStringEncodingUTF8);
+    // using the ip from the zerotier network breaks routing on the mac
+    CFStringRef cfrouter = CFStringCreateWithCString(NULL, "127.0.0.1", kCFStringEncodingUTF8);
 
     const int SIZE = 4;
     CFStringRef keys[SIZE];

+ 40 - 25
osdep/ManagedRoute.cpp

@@ -252,7 +252,7 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
 
 static void _routeCmd(const char *op,const InetAddress &target,const InetAddress &via,const char *ifscope,const char *localInterface)
 {
-	//char f1[1024],f2[1024]; printf("%s %s %s %s %s\n",op,target.toString(f1),via.toString(f2),ifscope,localInterface);
+	// char f1[1024],f2[1024]; printf("cmd %s %s %s %s %s\n",op,target.toString(f1),via.toString(f2),ifscope,localInterface);
 	long p = (long)fork();
 	if (p > 0) {
 		int exitcode = -1;
@@ -479,6 +479,9 @@ bool ManagedRoute::sync()
 		if (hasRoute) { break; }
 	}
 
+	// char buf[255];
+	// fprintf(stderr, "hasRoute %d %s\n", !!hasRoute, _target.toString(buf));
+
 
 	if (!hasRoute) {
 		if (_target && _target.netmaskBits() == 0) {
@@ -486,46 +489,58 @@ bool ManagedRoute::sync()
 			char newSystemDevice[128];
 			newSystemDevice[0] = (char)0;
 
-			// Find system default route that this route should override
-			// We need to put it back when default route is turned off
-			for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) {
-				if (r->via) {
-					if ( !_systemVia && r->isDefault == 1 && (strcmp(r->device,_device) != 0) ) {
+			// If macos has a network hiccup, it deletes what _systemVia we had set.
+			// Then we don't know how to set the default route again.
+			// So use the one we had set previously. Don't overwrite it.
+			if (!_systemVia) {
+				// Find system default route that this route should override
+				// We need to put it back when default route is turned off
+				for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) {
+					if (r->via) {
+						if ( !_systemVia && r->isDefault == 1 && (strcmp(r->device,_device) != 0) ) {
 
-						newSystemVia = r->via;
-						Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device);
+							newSystemVia = r->via;
+							Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device);
+						}
 					}
 				}
+				if (newSystemVia) { _systemVia = newSystemVia; }
 			}
 
-			if (!newSystemVia) { return false; }
 
-			// Get device corresponding to route if we don't have that already
-			if ((newSystemVia)&&(!newSystemDevice[0])) {
-				rtes = _getRTEs(newSystemVia,true);
-				for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) {
-					if ( (r->device[0]) && (strcmp(r->device,_device) != 0) && r->target.netmaskBits() != 0) {
-						Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device);
-						break;
+			// char buf1[255], buf2[255];
+			// fprintf(stderr, "_systemVia %s new %s\n", _systemVia.toString(buf1), newSystemVia.toString(buf2));
+			if (!_systemVia) { return false; }
+
+			if (!_systemDevice[0]) {
+				// Get device corresponding to route if we don't have that already
+				if ((newSystemVia)&&(!newSystemDevice[0])) {
+					rtes = _getRTEs(newSystemVia,true);
+					for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) {
+						if ( (r->device[0]) && (strcmp(r->device,_device) != 0) && r->target.netmaskBits() != 0) {
+							Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device);
+							break;
+						}
 					}
 				}
-			}
-			if (!newSystemDevice[0]) { return false; }
-
 
-			// update the system via in case it changed out from under us
-			// while we were in default route mode
+				if (newSystemDevice[0]) {
+					Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice);
+				}
+			}
+			// fprintf(stderr, "_systemDevice %s new %s\n", _systemDevice, newSystemDevice);
+			if (!_systemDevice[0]) { return false; }
 
-			_systemVia = newSystemVia;
-			Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice);
 
-			// Do the actual default route commands
+			// Do Default Route route commands
 			_routeCmd("delete",_target,_systemVia,(const char *)0,(const char *)0);
 			_routeCmd("add",_target,_via,(const char *)0,(const char *)0);
 			_routeCmd("add",_target,_systemVia,_systemDevice,(const char *)0);
+
 			_applied[_target] = true;
+
 		} else {
-			// Do the actual route commands
+			// Do Non-Default route commands
 			_applied[_target] = true;
 			_routeCmd("add",leftt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
 		}