Browse Source

Simplification and further concurrency improvements.

Adam Ierymenko 5 years ago
parent
commit
5aa744db84
1 changed files with 58 additions and 84 deletions
  1. 58 84
      root/root.cpp

+ 58 - 84
root/root.cpp

@@ -200,7 +200,6 @@ static std::list< SharedPtr<RootPeer> > 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< uint64_t,std::unordered_map< MulticastGroup,std::unordered_map< Address,int64_t,AddressHasher >,MulticastGroupHasher > > s_multicastSubscriptions;
 static std::unordered_map< Identity,SharedPtr<RootPeer>,IdentityHasher > s_peersByIdentity;
 static std::unordered_map< Identity,SharedPtr<RootPeer>,IdentityHasher > s_peersByIdentity;
 static std::unordered_map< Address,std::set< SharedPtr<RootPeer> >,AddressHasher > s_peersByVirtAddr;
 static std::unordered_map< Address,std::set< SharedPtr<RootPeer> >,AddressHasher > s_peersByVirtAddr;
-static std::unordered_map< InetAddress,std::set< SharedPtr<RootPeer> >,InetAddressHasher > s_peersByPhysAddr;
 static std::unordered_map< RendezvousKey,RendezvousStats,RendezvousKey::Hasher > s_rendezvousTracking;
 static std::unordered_map< RendezvousKey,RendezvousStats,RendezvousKey::Hasher > s_rendezvousTracking;
 static std::unordered_map< Address,ForwardingStats,AddressHasher > s_lastForwardedTo;
 static std::unordered_map< Address,ForwardingStats,AddressHasher > s_lastForwardedTo;
 static std::map< std::pair< uint32_t,uint32_t >,std::pair< float,float > > s_geoIp4;
 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_multicastSubscriptions_l;
 static std::mutex s_peersByIdentity_l;
 static std::mutex s_peersByIdentity_l;
 static std::mutex s_peersByVirtAddr_l;
 static std::mutex s_peersByVirtAddr_l;
-static std::mutex s_peersByPhysAddr_l;
 static std::mutex s_rendezvousTracking_l;
 static std::mutex s_rendezvousTracking_l;
 static std::mutex s_lastForwardedTo_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) {
 		if (peer) {
 			std::lock_guard<std::mutex> pl(peer->lock);
 			std::lock_guard<std::mutex> pl(peer->lock);
 
 
-			InetAddress *const peerIp = ip->isV4() ? &(peer->ip4) : &(peer->ip6);
-			if (*peerIp != ip) {
-				std::lock_guard<std::mutex> 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();
 			const int64_t now = OSUtils::now();
 			peer->lastReceive = now;
 			peer->lastReceive = now;
@@ -954,11 +942,9 @@ int main(int argc,char **argv)
 		apiServ.Get("/",[](const httplib::Request &req,httplib::Response &res) {
 		apiServ.Get("/",[](const httplib::Request &req,httplib::Response &res) {
 			std::ostringstream o;
 			std::ostringstream o;
 			std::lock_guard<std::mutex> l0(s_peersByIdentity_l);
 			std::lock_guard<std::mutex> l0(s_peersByIdentity_l);
-			std::lock_guard<std::mutex> l1(s_peersByPhysAddr_l);
 			o << "ZeroTier Root Server " << ZEROTIER_ONE_VERSION_MAJOR << '.' << ZEROTIER_ONE_VERSION_MINOR << '.' << ZEROTIER_ONE_VERSION_REVISION << ZT_EOL_S;
 			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 << "(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 << "Peers Online:       " << s_peersByIdentity.size() << ZT_EOL_S;
-			o << "Physical Addresses: " << s_peersByPhysAddr.size() << ZT_EOL_S;
 			res.set_content(o.str(),"text/plain");
 			res.set_content(o.str(),"text/plain");
 		});
 		});
 
 
@@ -1019,63 +1005,73 @@ int main(int argc,char **argv)
 			}
 			}
 			std::ostringstream o;
 			std::ostringstream o;
 			o << ZT_GEOIP_HTML_HEAD;
 			o << ZT_GEOIP_HTML_HEAD;
-			{
+			try {
 				bool firstCoord = true;
 				bool firstCoord = true;
 				std::pair< uint32_t,uint32_t > k4(0,0xffffffff);
 				std::pair< uint32_t,uint32_t > k4(0,0xffffffff);
 				std::pair< std::array< uint64_t,2 >,std::array< uint64_t,2 > > k6;
 				std::pair< std::array< uint64_t,2 >,std::array< uint64_t,2 > > k6;
 				k6.second[0] = 0xffffffffffffffffULL; k6.second[1] = 0xffffffffffffffffULL;
 				k6.second[0] = 0xffffffffffffffffULL; k6.second[1] = 0xffffffffffffffffULL;
-				std::lock_guard<std::mutex> 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<Address>,InetAddressHasher > ips;
+				{
+					std::lock_guard<std::mutex> 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 << ',';
 										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 << ',';
 										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());
 			OSUtils::ztsnprintf(tmp,sizeof(tmp),ZT_GEOIP_HTML_TAIL,s_googleMapsAPIKey.c_str());
 			o << tmp;
 			o << tmp;
@@ -1128,7 +1124,6 @@ int main(int argc,char **argv)
 					if ((now - (*p)->lastReceive) > ZT_PEER_ACTIVITY_TIMEOUT) {
 					if ((now - (*p)->lastReceive) > ZT_PEER_ACTIVITY_TIMEOUT) {
 						std::lock_guard<std::mutex> pbi_l(s_peersByIdentity_l);
 						std::lock_guard<std::mutex> pbi_l(s_peersByIdentity_l);
 						std::lock_guard<std::mutex> pbv_l(s_peersByVirtAddr_l);
 						std::lock_guard<std::mutex> pbv_l(s_peersByVirtAddr_l);
-						std::lock_guard<std::mutex> pbp_l(s_peersByPhysAddr_l);
 
 
 						s_peersByIdentity.erase((*p)->id);
 						s_peersByIdentity.erase((*p)->id);
 
 
@@ -1139,24 +1134,6 @@ int main(int argc,char **argv)
 								s_peersByVirtAddr.erase(pbv);
 								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++);
 						s_peers.erase(p++);
 					} else ++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()));
 				fprintf(sf,"Virtual Address Collisions : %llu" ZT_EOL_S,(unsigned long long)(s_peersByIdentity.size() - s_peersByVirtAddr.size()));
 				s_peersByVirtAddr_l.unlock();
 				s_peersByVirtAddr_l.unlock();
 				s_peersByIdentity_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();
 				s_rendezvousTracking_l.lock();
 				uint64_t unsuccessfulp2p = 0;
 				uint64_t unsuccessfulp2p = 0;
 				for(auto lr=s_rendezvousTracking.begin();lr!=s_rendezvousTracking.end();++lr) {
 				for(auto lr=s_rendezvousTracking.begin();lr!=s_rendezvousTracking.end();++lr) {