diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp index a06ba11a3..d51e548bb 100644 --- a/osdep/ManagedRoute.cpp +++ b/osdep/ManagedRoute.cpp @@ -484,58 +484,57 @@ bool ManagedRoute::sync() if (!hasRoute) { - if (_target && _target.netmaskBits() == 0) { + if (_target && _target.netmaskBits() == 0) { // Allow Default InetAddress newSystemVia; char newSystemDevice[128]; newSystemDevice[0] = (char)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); - } - } - } - if (newSystemVia) { _systemVia = newSystemVia; } + // if our routes got deleted + // delete the systemd via that we had added with -ifscope + if (_systemVia && !!_systemDevice[0]) { + _routeCmd("delete",_target,_systemVia,_systemDevice,(const char *)0); } + _systemVia = newSystemVia; + Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice); + // If macos has a network hiccup, it deletes what the route we set, and it's own physical routes. + // if !hasRoute (our 0.0.0.0 has been deleted), the OS has changed stuff + // So don't assume _systemX are valid anymore. Always get for _system{Via,Device} - // char buf1[255], buf2[255]; - // fprintf(stderr, "_systemVia %s new %s\n", _systemVia.toString(buf1), newSystemVia.toString(buf2)); - if (!_systemVia) { return false; } + // 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 ( r->isDefault == 1 && (strcmp(r->device,_device) != 0) ) { - 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; - } + // char buf[255]; + // fprintf(stderr, "system device1 %s %s\n", r->via.toString(buf), r->device); + + newSystemVia = r->via; + Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device); + break; } } - - if (newSystemDevice[0]) { - Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice); - } } - // fprintf(stderr, "_systemDevice %s new %s\n", _systemDevice, newSystemDevice); - if (!_systemDevice[0]) { return false; } + if (newSystemVia) { _systemVia = newSystemVia; } + if (newSystemDevice[0]) { + Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice); + } + + // if there's no newSystemVia, the OS might not have + // ipv4 or ipv6 connectivity. + // we should still add our ZeroTier ipv4 or 6 routes though + + if (!!_systemVia && !!_systemDevice[0]) { + _routeCmd("delete",_target,_systemVia,(const char *)0,(const char *)0); + } - // 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); + + if (!!_systemVia && !!_systemDevice[0]) { + _routeCmd("add",_target,_systemVia,_systemDevice,(const char *)0); + } _applied[_target] = true; @@ -595,8 +594,8 @@ void ManagedRoute::remove() for(std::map::iterator r(_applied.begin());r!=_applied.end();++r) { #ifdef __BSD__ // ------------------------------------------------------------ if (_target && _target.netmaskBits() == 0) { - if (_systemVia) { - _routeCmd("delete",_target,_via,(const char *)0,(const char *)0); + _routeCmd("delete",_target,_via,(const char *)0,(const char *)0); + if (_systemVia && _systemDevice[0]) { _routeCmd("delete",_target,_systemVia,_systemDevice,(const char *)0); _routeCmd("add",_target,_systemVia,(const char *)0,(const char *)0); diff --git a/service/OneService.cpp b/service/OneService.cpp index dfa5df056..8a0aee294 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1067,7 +1067,7 @@ public: if (_secondaryPort) { _ports[1] = _secondaryPort; } else { - _ports[1] = _secondaryPort = _getRandomPort(); + _ports[1] = _getRandomPort(); } } #ifdef ZT_USE_MINIUPNPC @@ -1129,7 +1129,6 @@ public: int64_t lastBindRefresh = 0; int64_t lastUpdateCheck = clockShouldBe; int64_t lastCleanedPeersDb = 0; - int64_t lastLocalInterfaceAddressCheck = (clockShouldBe - ZT_LOCAL_INTERFACE_CHECK_INTERVAL) + 15000; // do this in 15s to give portmapper time to configure and other things time to settle int64_t lastLocalConfFileCheck = OSUtils::now(); int64_t lastOnline = lastLocalConfFileCheck; for(;;) { @@ -1176,16 +1175,22 @@ public: // If secondary port is not configured to a constant value and we've been offline for a while, // bind a new secondary port. This is a workaround for a "coma" issue caused by buggy NATs that stop // working on one port after a while. - if (_node->online()) { - lastOnline = now; - } else if ((_secondaryPort == 0)&&((now - lastOnline) > ZT_PATH_HEARTBEAT_PERIOD)) { - _secondaryPort = _getRandomPort(); - lastBindRefresh = 0; + if (_secondaryPort == 0) { + if (_node->online()) { + lastOnline = now; + } + if ((now - lastOnline) > ZT_PATH_HEARTBEAT_PERIOD || restarted) { + _ports[1] = _getRandomPort(); +#if ZT_DEBUG==1 + fprintf(stderr, "randomized secondary port. Now it's %d\n", _ports[1]); +#endif + lastOnline = now; // don't keep spamming this branch. online() will be false for a few seconds + } } + // Refresh bindings in case device's interfaces have changed, and also sync routes to update any shadow routes (e.g. shadow default) - if (((now - lastBindRefresh) >= (_node->bondController()->inUse() ? ZT_BINDER_REFRESH_PERIOD / 4 : ZT_BINDER_REFRESH_PERIOD))||(restarted)) { - lastBindRefresh = now; + if (((now - lastBindRefresh) >= (_node->bondController()->inUse() ? ZT_BINDER_REFRESH_PERIOD / 4 : ZT_BINDER_REFRESH_PERIOD))||restarted) { unsigned int p[3]; unsigned int pc = 0; for(int i=0;i<3;++i) { @@ -1196,6 +1201,23 @@ public: // Only bother binding UDP ports if we aren't forcing TCP-relay mode _binder.refresh(_phy,p,pc,explicitBind,*this); } + + lastBindRefresh = now; + + // Sync information about physical network interfaces + _node->clearLocalInterfaceAddresses(); +#ifdef ZT_USE_MINIUPNPC + if (_portMapper) { + std::vector mappedAddresses(_portMapper->get()); + for(std::vector::const_iterator ext(mappedAddresses.begin());ext!=mappedAddresses.end();++ext) + _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext))); + } +#endif + std::vector boundAddrs(_binder.allBoundLocalInterfaceAddresses()); + for(std::vector::const_iterator i(boundAddrs.begin());i!=boundAddrs.end();++i) { + _node->addLocalInterfaceAddress(reinterpret_cast(&(*i))); + } + { Mutex::Lock _l(_nets_m); for(std::map::iterator n(_nets.begin());n!=_nets.end();++n) { @@ -1239,26 +1261,6 @@ public: } } - // Sync information about physical network interfaces - if ((now - lastLocalInterfaceAddressCheck) >= (_node->bondController()->inUse() ? ZT_LOCAL_INTERFACE_CHECK_INTERVAL / 8 : ZT_LOCAL_INTERFACE_CHECK_INTERVAL)) { - lastLocalInterfaceAddressCheck = now; - - _node->clearLocalInterfaceAddresses(); - -#ifdef ZT_USE_MINIUPNPC - if (_portMapper) { - std::vector mappedAddresses(_portMapper->get()); - for(std::vector::const_iterator ext(mappedAddresses.begin());ext!=mappedAddresses.end();++ext) - _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext))); - } -#endif - - std::vector boundAddrs(_binder.allBoundLocalInterfaceAddresses()); - for(std::vector::const_iterator i(boundAddrs.begin());i!=boundAddrs.end();++i) { - _node->addLocalInterfaceAddress(reinterpret_cast(&(*i))); - } - } - // Clean peers.d periodically if ((now - lastCleanedPeersDb) >= 3600000) { lastCleanedPeersDb = now; @@ -2037,7 +2039,7 @@ public: settings["allowTcpFallbackRelay"] = OSUtils::jsonBool(settings["allowTcpFallbackRelay"],_allowTcpFallbackRelay); settings["forceTcpRelay"] = OSUtils::jsonBool(settings["forceTcpRelay"],_forceTcpRelay); settings["primaryPort"] = OSUtils::jsonInt(settings["primaryPort"],(uint64_t)_primaryPort) & 0xffff; - settings["secondaryPort"] = OSUtils::jsonInt(settings["secondaryPort"],(uint64_t)_secondaryPort) & 0xffff; + settings["secondaryPort"] = OSUtils::jsonInt(settings["secondaryPort"],(uint64_t)_ports[1]) & 0xffff; settings["tertiaryPort"] = OSUtils::jsonInt(settings["tertiaryPort"],(uint64_t)_tertiaryPort) & 0xffff; // Enumerate all local address/port pairs that this node is listening on std::vector boundAddrs(_binder.allBoundLocalInterfaceAddresses());