From 5aa744db84ab132ca209da4e953a9106c3c1c834 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 12 Sep 2019 08:41:34 -0700 Subject: [PATCH] Simplification and further concurrency improvements. --- root/root.cpp | 142 +++++++++++++++++++++----------------------------- 1 file changed, 58 insertions(+), 84 deletions(-) diff --git a/root/root.cpp b/root/root.cpp index 6928af893..5cd4b9cd4 100644 --- a/root/root.cpp +++ b/root/root.cpp @@ -200,7 +200,6 @@ static std::list< SharedPtr > s_peers; static std::unordered_map< uint64_t,std::unordered_map< MulticastGroup,std::unordered_map< Address,int64_t,AddressHasher >,MulticastGroupHasher > > s_multicastSubscriptions; static std::unordered_map< Identity,SharedPtr,IdentityHasher > s_peersByIdentity; static std::unordered_map< Address,std::set< SharedPtr >,AddressHasher > s_peersByVirtAddr; -static std::unordered_map< InetAddress,std::set< SharedPtr >,InetAddressHasher > s_peersByPhysAddr; static std::unordered_map< RendezvousKey,RendezvousStats,RendezvousKey::Hasher > s_rendezvousTracking; static std::unordered_map< Address,ForwardingStats,AddressHasher > s_lastForwardedTo; static std::map< std::pair< uint32_t,uint32_t >,std::pair< float,float > > s_geoIp4; @@ -211,7 +210,6 @@ static std::mutex s_peers_l; static std::mutex s_multicastSubscriptions_l; static std::mutex s_peersByIdentity_l; static std::mutex s_peersByVirtAddr_l; -static std::mutex s_peersByPhysAddr_l; static std::mutex s_rendezvousTracking_l; static std::mutex s_lastForwardedTo_l; @@ -318,20 +316,10 @@ static void handlePacket(const int v4s,const int v6s,const InetAddress *const ip if (peer) { std::lock_guard pl(peer->lock); - InetAddress *const peerIp = ip->isV4() ? &(peer->ip4) : &(peer->ip6); - if (*peerIp != ip) { - std::lock_guard pbp_l(s_peersByPhysAddr_l); - if (*peerIp) { - auto prev = s_peersByPhysAddr.find(*peerIp); - if (prev != s_peersByPhysAddr.end()) { - prev->second.erase(peer); - if (prev->second.empty()) - s_peersByPhysAddr.erase(prev); - } - } - *peerIp = ip; - s_peersByPhysAddr[ip].emplace(peer); - } + if (ip->isV4()) + peer->ip4 = ip; + else if (ip->isV6()) + peer->ip6 = ip; const int64_t now = OSUtils::now(); peer->lastReceive = now; @@ -954,11 +942,9 @@ int main(int argc,char **argv) apiServ.Get("/",[](const httplib::Request &req,httplib::Response &res) { std::ostringstream o; std::lock_guard l0(s_peersByIdentity_l); - std::lock_guard l1(s_peersByPhysAddr_l); o << "ZeroTier Root Server " << ZEROTIER_ONE_VERSION_MAJOR << '.' << ZEROTIER_ONE_VERSION_MINOR << '.' << ZEROTIER_ONE_VERSION_REVISION << ZT_EOL_S; o << "(c)2019 ZeroTier, Inc." ZT_EOL_S "Licensed under the ZeroTier BSL 1.1" ZT_EOL_S ZT_EOL_S; o << "Peers Online: " << s_peersByIdentity.size() << ZT_EOL_S; - o << "Physical Addresses: " << s_peersByPhysAddr.size() << ZT_EOL_S; res.set_content(o.str(),"text/plain"); }); @@ -1019,63 +1005,73 @@ int main(int argc,char **argv) } std::ostringstream o; o << ZT_GEOIP_HTML_HEAD; - { + try { bool firstCoord = true; std::pair< uint32_t,uint32_t > k4(0,0xffffffff); std::pair< std::array< uint64_t,2 >,std::array< uint64_t,2 > > k6; k6.second[0] = 0xffffffffffffffffULL; k6.second[1] = 0xffffffffffffffffULL; - std::lock_guard l(s_peersByPhysAddr_l); - for(auto p=s_peersByPhysAddr.begin();p!=s_peersByPhysAddr.end();++p) { - if (!p->second.empty()) { - if (p->first.isV4()) { - k4.first = ip4ToH32(p->first); - auto geo = std::map< std::pair< uint32_t,uint32_t >,std::pair< float,float > >::reverse_iterator(s_geoIp4.upper_bound(k4)); - while (geo != s_geoIp4.rend()) { - if ((geo->first.first <= k4.first)&&(geo->first.second >= k4.first)) { - if (!firstCoord) + std::unordered_map< InetAddress,std::set
,InetAddressHasher > ips; + { + std::lock_guard l(s_peers_l); + for(auto p=s_peers.begin();p!=s_peers.end();++p) { + if ((*p)->ip4) + ips[(*p)->ip4].insert((*p)->id.address()); + if ((*p)->ip6) + ips[(*p)->ip6].insert((*p)->id.address()); + } + } + for(auto p=ips.begin();p!=ips.end();++p) { + if (p->first.isV4()) { + k4.first = ip4ToH32(p->first); + auto geo = std::map< std::pair< uint32_t,uint32_t >,std::pair< float,float > >::reverse_iterator(s_geoIp4.upper_bound(k4)); + while (geo != s_geoIp4.rend()) { + if ((geo->first.first <= k4.first)&&(geo->first.second >= k4.first)) { + if (!firstCoord) + o << ','; + firstCoord = false; + o << "{lat:" << geo->second.first << ",lng:" << geo->second.second << ",_l:\""; + bool firstAddr = true; + for(auto a=p->second.begin();a!=p->second.end();++a) { + if (!firstAddr) o << ','; - firstCoord = false; - o << "{lat:" << geo->second.first << ",lng:" << geo->second.second << ",_l:\""; - bool firstAddr = true; - for(auto a=p->second.begin();a!=p->second.end();++a) { - if (!firstAddr) - o << ','; - o << (*a)->id.address().toString(tmp); - firstAddr = false; - } - o << "\"}"; - break; - } else if ((geo->first.first < k4.first)&&(geo->first.second < k4.first)) { - break; + o << a->toString(tmp); + firstAddr = false; } - ++geo; + o << "\"}"; + break; + } else if ((geo->first.first < k4.first)&&(geo->first.second < k4.first)) { + break; } - } else if (p->first.isV6()) { - k6.first = ip6ToH128(p->first); - auto geo = std::map< std::pair< std::array< uint64_t,2 >,std::array< uint64_t,2 > >,std::pair< float,float > >::reverse_iterator(s_geoIp6.upper_bound(k6)); - while (geo != s_geoIp6.rend()) { - if ((geo->first.first <= k6.first)&&(geo->first.second >= k6.first)) { - if (!firstCoord) + ++geo; + } + } else if (p->first.isV6()) { + k6.first = ip6ToH128(p->first); + auto geo = std::map< std::pair< std::array< uint64_t,2 >,std::array< uint64_t,2 > >,std::pair< float,float > >::reverse_iterator(s_geoIp6.upper_bound(k6)); + while (geo != s_geoIp6.rend()) { + if ((geo->first.first <= k6.first)&&(geo->first.second >= k6.first)) { + if (!firstCoord) + o << ','; + firstCoord = false; + o << "{lat:" << geo->second.first << ",lng:" << geo->second.second << ",_l:\""; + bool firstAddr = true; + for(auto a=p->second.begin();a!=p->second.end();++a) { + if (!firstAddr) o << ','; - firstCoord = false; - o << "{lat:" << geo->second.first << ",lng:" << geo->second.second << ",_l:\""; - bool firstAddr = true; - for(auto a=p->second.begin();a!=p->second.end();++a) { - if (!firstAddr) - o << ','; - o << (*a)->id.address().toString(tmp); - firstAddr = false; - } - o << "\"}"; - break; - } else if ((geo->first.first < k6.first)&&(geo->first.second < k6.first)) { - break; + o << a->toString(tmp); + firstAddr = false; } - ++geo; + o << "\"}"; + break; + } else if ((geo->first.first < k6.first)&&(geo->first.second < k6.first)) { + break; } + ++geo; } } } + } catch ( ... ) { + res.set_content("Internal error: unexpected exception resolving GeoIP locations","text/plain"); + return; } OSUtils::ztsnprintf(tmp,sizeof(tmp),ZT_GEOIP_HTML_TAIL,s_googleMapsAPIKey.c_str()); o << tmp; @@ -1128,7 +1124,6 @@ int main(int argc,char **argv) if ((now - (*p)->lastReceive) > ZT_PEER_ACTIVITY_TIMEOUT) { std::lock_guard pbi_l(s_peersByIdentity_l); std::lock_guard pbv_l(s_peersByVirtAddr_l); - std::lock_guard pbp_l(s_peersByPhysAddr_l); s_peersByIdentity.erase((*p)->id); @@ -1139,24 +1134,6 @@ int main(int argc,char **argv) s_peersByVirtAddr.erase(pbv); } - if ((*p)->ip4) { - auto pbp = s_peersByPhysAddr.find((*p)->ip4); - if (pbp != s_peersByPhysAddr.end()) { - pbp->second.erase((*p)); - if (pbp->second.empty()) - s_peersByPhysAddr.erase(pbp); - } - } - - if ((*p)->ip6) { - auto pbp = s_peersByPhysAddr.find((*p)->ip6); - if (pbp != s_peersByPhysAddr.end()) { - pbp->second.erase((*p)); - if (pbp->second.empty()) - s_peersByPhysAddr.erase(pbp); - } - } - s_peers.erase(p++); } else ++p; } @@ -1264,9 +1241,6 @@ int main(int argc,char **argv) fprintf(sf,"Virtual Address Collisions : %llu" ZT_EOL_S,(unsigned long long)(s_peersByIdentity.size() - s_peersByVirtAddr.size())); s_peersByVirtAddr_l.unlock(); s_peersByIdentity_l.unlock(); - s_peersByPhysAddr_l.lock(); - fprintf(sf,"Physical Endpoints : %llu" ZT_EOL_S,(unsigned long long)s_peersByPhysAddr.size()); - s_peersByPhysAddr_l.unlock(); s_rendezvousTracking_l.lock(); uint64_t unsuccessfulp2p = 0; for(auto lr=s_rendezvousTracking.begin();lr!=s_rendezvousTracking.end();++lr) {