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.
This commit is contained in:
travisladuke 2023-08-11 11:06:25 -07:00 committed by Travis LaDuke
parent d976a9f5a0
commit 1d095e81d9
2 changed files with 45 additions and 31 deletions

View File

@ -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) bool MacDNSHelper::addIps4(uint64_t nwid, const MAC mac, const char *dev, const std::vector<InetAddress>& addrs)
{ {
const char* ipStr = {0}; const char* ipStr = {0};
const char* ipStr2 = {0};
char buf2[256] = {0}; char buf2[256] = {0};
bool hasV4 = false; bool hasV4 = false;
@ -116,7 +115,6 @@ bool MacDNSHelper::addIps4(uint64_t nwid, const MAC mac, const char *dev, const
hasV4 = true; hasV4 = true;
ipStr = addrs[i].toIpString(buf2); ipStr = addrs[i].toIpString(buf2);
ipStr2 = addrs[i].toIpString(buf2);
break; 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 cfdev = CFStringCreateWithCString(NULL, dev, kCFStringEncodingUTF8);
CFStringRef cfserver = CFStringCreateWithCString(NULL, "127.0.0.1", 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; const int SIZE = 4;
CFStringRef keys[SIZE]; CFStringRef keys[SIZE];

View File

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