Simplification and further concurrency improvements.

This commit is contained in:
Adam Ierymenko 2019-09-12 08:41:34 -07:00
parent 0ad82dad80
commit 5aa744db84
No known key found for this signature in database
GPG Key ID: C8877CF2D7A5D7F3

View File

@ -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< Identity,SharedPtr<RootPeer>,IdentityHasher > s_peersByIdentity;
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< 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<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();
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<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 << "(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<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 << ',';
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<std::mutex> pbi_l(s_peersByIdentity_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);
@ -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) {