diff --git a/osdep/LinuxEthernetTap.cpp b/osdep/LinuxEthernetTap.cpp index 8995b102b..a888db9d9 100644 --- a/osdep/LinuxEthernetTap.cpp +++ b/osdep/LinuxEthernetTap.cpp @@ -126,12 +126,14 @@ LinuxEthernetTap::LinuxEthernetTap( _mtu(mtu), _fd(0), _enabled(true), - _run(true) + _run(true), + _lastIfAddrsUpdate(0) { static std::mutex s_tapCreateLock; char procpath[128],nwids[32]; struct stat sbuf; + // Create only one tap at a time globally. std::lock_guard tapCreateLock(s_tapCreateLock); @@ -438,6 +440,14 @@ bool LinuxEthernetTap::removeIp(const InetAddress &ip) std::vector LinuxEthernetTap::ips() const { + + uint64_t now = OSUtils::now(); + + if ((now - _lastIfAddrsUpdate) <= GETIFADDRS_CACHE_TIME) { + return _ifaddrs; + } + _lastIfAddrsUpdate = now; + struct ifaddrs *ifa = (struct ifaddrs *)0; if (getifaddrs(&ifa)) return std::vector(); @@ -471,6 +481,8 @@ std::vector LinuxEthernetTap::ips() const std::sort(r.begin(),r.end()); r.erase(std::unique(r.begin(),r.end()),r.end()); + _ifaddrs = r; + return r; } diff --git a/osdep/LinuxEthernetTap.hpp b/osdep/LinuxEthernetTap.hpp index 3603740d4..424a6d37e 100644 --- a/osdep/LinuxEthernetTap.hpp +++ b/osdep/LinuxEthernetTap.hpp @@ -57,6 +57,9 @@ public: virtual void setMtu(unsigned int mtu); virtual void setDns(const char *domain, const std::vector &servers) {} + + + private: void (*_handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); void *_arg; @@ -71,6 +74,8 @@ private: std::atomic_bool _enabled; std::atomic_bool _run; std::thread _tapReaderThread; + mutable std::vector _ifaddrs; + mutable uint64_t _lastIfAddrsUpdate; }; } // namespace ZeroTier