diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp index 83de36d43..91bfbed6c 100644 --- a/node/InetAddress.cpp +++ b/node/InetAddress.cpp @@ -91,7 +91,13 @@ InetAddress::IpScope InetAddress::ipScope() const const unsigned char *ip = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); if ((ip[0] & 0xf0) == 0xf0) { if (ip[0] == 0xff) return IP_SCOPE_MULTICAST; // ff00::/8 - if ((ip[0] == 0xfe)&&((ip[1] & 0xc0) == 0x80)) return IP_SCOPE_LINK_LOCAL; // fe80::/10 + if ((ip[0] == 0xfe)&&((ip[1] & 0xc0) == 0x80)) { + unsigned int k = 2; + while ((!ip[k])&&(k < 15)) ++k; + if ((k == 15)&&(ip[15] == 0x01)) + return IP_SCOPE_LOOPBACK; // fe80::1/128 + else return IP_SCOPE_LINK_LOCAL; // fe80::/10 + } if ((ip[0] & 0xfe) == 0xfc) return IP_SCOPE_PRIVATE; // fc00::/7 } unsigned int k = 0; diff --git a/node/Peer.cpp b/node/Peer.cpp index 225fbdef3..f5fdf7dd8 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -214,7 +214,6 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,const std::vector _lastDirectPathPush = now; TRACE("pushing %u direct paths to %s",(unsigned int)dps.size(),_id.address().toString().c_str()); - printf("pushing %u direct paths to %s",(unsigned int)dps.size(),_id.address().toString().c_str()); std::vector::const_iterator p(dps.begin()); while (p != dps.end()) { diff --git a/service/OneService.cpp b/service/OneService.cpp index 7532bf750..109050bff 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -78,8 +78,10 @@ class SqliteNetworkController; #include #else #include +#include #include #include +#include #endif // Include the right tap device driver for this platform -- add new platforms here @@ -123,6 +125,9 @@ namespace ZeroTier { typedef BSDEthernetTap EthernetTap; } // Attempt to engage TCP fallback after this many ms of no reply to packets sent to global-scope IPs #define ZT1_TCP_FALLBACK_AFTER 60000 +// How often to check for local interface addresses +#define ZT1_LOCAL_INTERFACE_CHECK_INTERVAL 300000 + namespace ZeroTier { namespace { @@ -405,6 +410,7 @@ public: _nextBackgroundTaskDeadline(0), _tcpFallbackTunnel((TcpConnection *)0), _termReason(ONE_STILL_RUNNING), + _port(port), _run(true) { struct sockaddr_in in4; @@ -501,6 +507,7 @@ public: _lastRestart = clockShouldBe; uint64_t lastTapMulticastGroupCheck = 0; uint64_t lastTcpFallbackResolve = 0; + uint64_t lastLocalInterfaceAddressCheck = 0; #ifdef ZT_AUTO_UPDATE uint64_t lastSoftwareUpdateCheck = 0; #endif // ZT_AUTO_UPDATE @@ -554,6 +561,66 @@ public: } } + if ((now - lastLocalInterfaceAddressCheck) >= ZT1_LOCAL_INTERFACE_CHECK_INTERVAL) { + lastLocalInterfaceAddressCheck = now; + +#ifdef __UNIX_LIKE__ + std::vector ztDevices; + { + Mutex::Lock _l(_taps_m); + for(std::map< uint64_t,EthernetTap *>::const_iterator t(_taps.begin());t!=_taps.end();++t) + ztDevices.push_back(t->second->deviceName()); + } + + struct ifaddrs *ifatbl = (struct ifaddrs *)0; + if ((getifaddrs(&ifatbl) == 0)&&(ifatbl)) { + _node->clearLocalInterfaceAddresses(); + struct ifaddrs *ifa = ifatbl; + while (ifa) { + if ((ifa->ifa_name)&&(ifa->ifa_addr)) { + bool isZT = false; + for(std::vector::const_iterator d(ztDevices.begin());d!=ztDevices.end();++d) { + if (*d == ifa->ifa_name) { + isZT = true; + break; + } + } + if (!isZT) { + InetAddress ip(ifa->ifa_addr); + if ((ip.ss_family == AF_INET)||(ip.ss_family == AF_INET6)) { + switch(ip.ipScope()) { + case InetAddress::IP_SCOPE_LINK_LOCAL: + case InetAddress::IP_SCOPE_PRIVATE: + case InetAddress::IP_SCOPE_PSEUDOPRIVATE: + case InetAddress::IP_SCOPE_SHARED: + case InetAddress::IP_SCOPE_GLOBAL: + ip.setPort(_port); + _node->addLocalInterfaceAddress(reinterpret_cast(&ip),0,ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL,0); + break; + default: + break; + } + } + } + } + ifa = ifa->ifa_next; + } + freeifaddrs(ifatbl); + } +#endif // __UNIX_LIKE__ + +#ifdef __WINDOWS__ + std::vector ztDevices; + { + Mutex::Lock _l(_taps_m); + for(std::map< uint64_t,EthernetTap *>::const_iterator t(_taps.begin());t!=_taps.end();++t) + ztDevices.push_back(t->second->deviceName()); + } + + // TODO +#endif // __WINDOWS__ + } + const unsigned long delay = (dl > now) ? (unsigned long)(dl - now) : 100; clockShouldBe = now + (uint64_t)delay; _phy.poll(delay); @@ -1158,6 +1225,8 @@ private: std::string _fatalErrorMessage; Mutex _termReason_m; + unsigned int _port; + bool _run; Mutex _run_m; };