mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-18 02:40:13 +00:00
Almost done... very few std::map<>s remaining in any spot that matters.
This commit is contained in:
parent
db0369e9b8
commit
3dba016a93
@ -39,8 +39,9 @@ namespace ZeroTier {
|
||||
* A minimal hash table implementation for the ZeroTier core
|
||||
*
|
||||
* This is not a drop-in replacement for STL containers, and has several
|
||||
* limitations. It's designed to be small and fast for use in the
|
||||
* ZeroTier core.
|
||||
* limitations. Keys can be uint64_t or an object, and if the latter they
|
||||
* must implement a method called hashCode() that returns an unsigned long
|
||||
* value that is evenly distributed.
|
||||
*/
|
||||
template<typename K,typename V>
|
||||
class Hashtable
|
||||
|
@ -309,31 +309,18 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force)
|
||||
|
||||
const uint64_t now = RR->node->now();
|
||||
|
||||
std::pair<InetAddress,InetAddress> cg(Peer::findCommonGround(*p1p,*p2p,now));
|
||||
if (!(cg.first))
|
||||
return false;
|
||||
|
||||
if (cg.first.ipScope() != cg.second.ipScope())
|
||||
return false;
|
||||
|
||||
// Addresses are sorted in key for last unite attempt map for order
|
||||
// invariant lookup: (p1,p2) == (p2,p1)
|
||||
Array<Address,2> uniteKey;
|
||||
if (p1 >= p2) {
|
||||
uniteKey[0] = p2;
|
||||
uniteKey[1] = p1;
|
||||
} else {
|
||||
uniteKey[0] = p1;
|
||||
uniteKey[1] = p2;
|
||||
}
|
||||
{
|
||||
Mutex::Lock _l(_lastUniteAttempt_m);
|
||||
std::map< Array< Address,2 >,uint64_t >::const_iterator e(_lastUniteAttempt.find(uniteKey));
|
||||
if ((!force)&&(e != _lastUniteAttempt.end())&&((now - e->second) < ZT_MIN_UNITE_INTERVAL))
|
||||
uint64_t &luts = _lastUniteAttempt[_LastUniteKey(p1,p2)];
|
||||
if (((now - luts) < ZT_MIN_UNITE_INTERVAL)&&(!force))
|
||||
return false;
|
||||
else _lastUniteAttempt[uniteKey] = now;
|
||||
luts = now;
|
||||
}
|
||||
|
||||
std::pair<InetAddress,InetAddress> cg(Peer::findCommonGround(*p1p,*p2p,now));
|
||||
if ((!(cg.first))||(cg.first.ipScope() != cg.second.ipScope()))
|
||||
return false;
|
||||
|
||||
TRACE("unite: %s(%s) <> %s(%s)",p1.toString().c_str(),cg.second.toString().c_str(),p2.toString().c_str(),cg.first.toString().c_str());
|
||||
|
||||
/* Tell P1 where to find P2 and vice versa, sending the packets to P1 and
|
||||
@ -543,6 +530,17 @@ unsigned long Switch::doTimerTasks(uint64_t now)
|
||||
}
|
||||
}
|
||||
|
||||
{ // Remove really old last unite attempt entries to keep table size controlled
|
||||
Mutex::Lock _l(_lastUniteAttempt_m);
|
||||
Hashtable< _LastUniteKey,uint64_t >::Iterator i(_lastUniteAttempt);
|
||||
_LastUniteKey *k = (_LastUniteKey *)0;
|
||||
uint64_t *v = (uint64_t *)0;
|
||||
while (i.next(k,v)) {
|
||||
if ((now - *v) >= (ZT_MIN_UNITE_INTERVAL * 16))
|
||||
_lastUniteAttempt.erase(*k);
|
||||
}
|
||||
}
|
||||
|
||||
return nextDelay;
|
||||
}
|
||||
|
||||
|
@ -235,7 +235,24 @@ private:
|
||||
Mutex _txQueue_m;
|
||||
|
||||
// Tracks sending of VERB_RENDEZVOUS to relaying peers
|
||||
std::map< Array< Address,2 >,uint64_t > _lastUniteAttempt; // key is always sorted in ascending order, for set-like behavior
|
||||
struct _LastUniteKey
|
||||
{
|
||||
_LastUniteKey() : x(0),y(0) {}
|
||||
_LastUniteKey(const Address &a1,const Address &a2)
|
||||
{
|
||||
if (a1 > a2) {
|
||||
x = a2.toInt();
|
||||
y = a1.toInt();
|
||||
} else {
|
||||
x = a1.toInt();
|
||||
y = a2.toInt();
|
||||
}
|
||||
}
|
||||
inline unsigned long hashCode() const throw() { return ((unsigned long)x ^ (unsigned long)y); }
|
||||
inline bool operator==(const _LastUniteKey &k) const throw() { return ((x == k.x)&&(y == k.y)); }
|
||||
uint64_t x,y;
|
||||
};
|
||||
Hashtable< _LastUniteKey,uint64_t > _lastUniteAttempt; // key is always sorted in ascending order, for set-like behavior
|
||||
Mutex _lastUniteAttempt_m;
|
||||
|
||||
// Active attempts to contact remote peers, including state of multi-phase NAT traversal
|
||||
|
Loading…
Reference in New Issue
Block a user