diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp index dca772e8f..30b1ff2ef 100644 --- a/node/InetAddress.cpp +++ b/node/InetAddress.cpp @@ -279,6 +279,8 @@ bool InetAddress::containsAddress(const InetAddress &addr) const switch(ss_family) { case AF_INET: { const unsigned int bits = netmaskBits(); + if (bits == 0) + return true; return ( (Utils::ntoh((uint32_t)reinterpret_cast(&addr)->sin_addr.s_addr) >> (32 - bits)) == (Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr) >> (32 - bits)) ); } case AF_INET6: { diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp index 118fc7d56..62597a005 100644 --- a/osdep/ManagedRoute.cpp +++ b/osdep/ManagedRoute.cpp @@ -234,8 +234,8 @@ static void _routeCmd(const char *op,const InetAddress &target,const InetAddress int exitcode = -1; ::waitpid(p,&exitcode,0); } else if (p == 0) { - //::close(STDOUT_FILENO); - //::close(STDERR_FILENO); + ::close(STDOUT_FILENO); + ::close(STDERR_FILENO); if (via) { if ((ifscope)&&(ifscope[0])) { ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,"-ifscope",ifscope,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString().c_str(),via.toIpString().c_str(),(const char *)0); diff --git a/osdep/ManagedRoute.hpp b/osdep/ManagedRoute.hpp index ca71b18bb..7000e3a42 100644 --- a/osdep/ManagedRoute.hpp +++ b/osdep/ManagedRoute.hpp @@ -57,7 +57,7 @@ public: */ inline bool set(const InetAddress &target,const InetAddress &via,const char *device) { - if ((!_via)&&(!_device[0])) + if ((!via)&&(!device[0])) return false; this->remove(); _target = target; diff --git a/service/OneService.cpp b/service/OneService.cpp index 29916896b..45f4234eb 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1327,6 +1327,18 @@ public: const InetAddress *const via = reinterpret_cast(&(nwc->routes[i].via)); bool haveRoute = false; + + // We don't need to bother applying local routes to local managed IPs since these are implied by setting the IP + for(std::vector::iterator ip(n.managedIps.begin());ip!=n.managedIps.end();++ip) { + if ((target->netmaskBits() == ip->netmaskBits())&&(target->containsAddress(*ip))) { + haveRoute = true; + break; + } + } + + if (haveRoute) + continue; + for(std::list::iterator mr(n.managedRoutes.begin());mr!=n.managedRoutes.end();++mr) { if (mr->target() == *target) { if ((via->ss_family == target->ss_family)&&(mr->via() == *via)) { @@ -1338,11 +1350,11 @@ public: } } } + if (haveRoute) continue; n.managedRoutes.push_back(ManagedRoute()); - if ((target->isDefaultRoute())&&(n.allowDefault)) { if (!n.managedRoutes.back().set(*target,*via,tapdev.c_str())) n.managedRoutes.pop_back();