From 1d095e81d94ebe29ab086d84b6401accde2964fa Mon Sep 17 00:00:00 2001 From: travisladuke Date: Fri, 11 Aug 2023 11:06:25 -0700 Subject: [PATCH] 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. --- osdep/MacDNSHelper.mm | 5 ++- osdep/ManagedRoute.cpp | 71 +++++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/osdep/MacDNSHelper.mm b/osdep/MacDNSHelper.mm index aab244f74..5e170e172 100644 --- a/osdep/MacDNSHelper.mm +++ b/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& 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]; diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp index 1af9f6a93..a06ba11a3 100644 --- a/osdep/ManagedRoute.cpp +++ b/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) ) { - - newSystemVia = r->via; - Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device); - } - } - } - - if (!newSystemVia) { return false; } - - // Get device corresponding to route if we don't have that already - if ((newSystemVia)&&(!newSystemDevice[0])) { - rtes = _getRTEs(newSystemVia,true); + // 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->device[0]) && (strcmp(r->device,_device) != 0) && r->target.netmaskBits() != 0) { - Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device); - break; + if (r->via) { + if ( !_systemVia && r->isDefault == 1 && (strcmp(r->device,_device) != 0) ) { + + newSystemVia = r->via; + Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device); + } } } + if (newSystemVia) { _systemVia = newSystemVia; } } - if (!newSystemDevice[0]) { return false; } - // update the system via in case it changed out from under us - // while we were in default route mode + // char buf1[255], buf2[255]; + // fprintf(stderr, "_systemVia %s new %s\n", _systemVia.toString(buf1), newSystemVia.toString(buf2)); + if (!_systemVia) { return false; } - _systemVia = newSystemVia; - Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice); + 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; + } + } + } - // Do the actual default route commands + if (newSystemDevice[0]) { + Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice); + } + } + // fprintf(stderr, "_systemDevice %s new %s\n", _systemDevice, newSystemDevice); + if (!_systemDevice[0]) { return false; } + + + // 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); }