More threading improvements in root, more DNS TXT and multicast work (in progress)

This commit is contained in:
Adam Ierymenko 2019-09-16 10:33:59 -07:00
parent 9f9032ae36
commit e08fc81397
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
10 changed files with 317 additions and 95 deletions

View file

@ -21,6 +21,7 @@
#include <stdexcept>
#include <algorithm>
#include <utility>
#include <set>
#include "Constants.hpp"
#include "../include/ZeroTierOne.h"
@ -32,8 +33,9 @@
#include "Mutex.hpp"
#include "InetAddress.hpp"
#include "Hashtable.hpp"
#include "Root.hpp"
#include "Locator.hpp"
#include "SharedPtr.hpp"
#include "ScopedPtr.hpp"
namespace ZeroTier {
@ -65,7 +67,7 @@ public:
{
SharedPtr<Peer> np;
{
Mutex::Lock _l(_peers_m);
Mutex::Lock _l(_peers_l);
SharedPtr<Peer> &hp = _peers[peer->address()];
if (!hp)
hp = peer;
@ -86,11 +88,12 @@ public:
if (zta == _myIdentity.address())
return SharedPtr<Peer>();
Mutex::Lock l1(_peers_m);
Mutex::Lock l1(_peers_l);
const SharedPtr<Peer> *const ap = _peers.get(zta);
if (ap)
return *ap;
#if 0
Mutex::Lock l2(_roots_m);
for(std::vector<Root>::const_iterator r(_roots.begin());r!=_roots.end();++r) {
if (r->address() == zta) {
@ -101,6 +104,7 @@ public:
} catch ( ... ) {}
}
}
#endif
return SharedPtr<Peer>();
}
@ -115,7 +119,7 @@ public:
if (zta == _myIdentity.address()) {
return _myIdentity;
} else {
Mutex::Lock _l(_peers_m);
Mutex::Lock _l(_peers_l);
const SharedPtr<Peer> *const ap = _peers.get(zta);
if (ap)
return (*ap)->identity();
@ -132,7 +136,7 @@ public:
*/
ZT_ALWAYS_INLINE SharedPtr<Path> getPath(const int64_t l,const InetAddress &r)
{
Mutex::Lock _l(_paths_m);
Mutex::Lock _l(_paths_l);
SharedPtr<Path> &p = _paths[Path::HashKey(l,r)];
if (!p)
p.set(new Path(l,r));
@ -145,11 +149,13 @@ public:
*/
ZT_ALWAYS_INLINE bool isRoot(const Identity &id) const
{
#if 0
Mutex::Lock l(_roots_m);
for(std::vector<Root>::const_iterator r(_roots.begin());r!=_roots.end();++r) {
if (r->is(id))
return true;
}
#endif
return false;
}
@ -159,7 +165,7 @@ public:
ZT_ALWAYS_INLINE void doPeriodicTasks(int64_t now)
{
{
Mutex::Lock _l1(_peers_m);
Mutex::Lock _l1(_peers_l);
Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
Address *a = (Address *)0;
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
@ -170,7 +176,7 @@ public:
}
}
{
Mutex::Lock _l(_paths_m);
Mutex::Lock _l(_paths_l);
Hashtable< Path::HashKey,SharedPtr<Path> >::Iterator i(_paths);
Path::HashKey *k = (Path::HashKey *)0;
SharedPtr<Path> *p = (SharedPtr<Path> *)0;
@ -188,7 +194,7 @@ public:
ZT_ALWAYS_INLINE unsigned long countActive(int64_t now) const
{
unsigned long cnt = 0;
Mutex::Lock _l(_peers_m);
Mutex::Lock _l(_peers_l);
Hashtable< Address,SharedPtr<Peer> >::Iterator i(const_cast<Topology *>(this)->_peers);
Address *a = (Address *)0;
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
@ -212,7 +218,7 @@ public:
template<typename F>
ZT_ALWAYS_INLINE void eachPeer(F f)
{
Mutex::Lock l(_peers_m);
Mutex::Lock l(_peers_l);
Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
Address *a = (Address *)0;
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
@ -221,6 +227,7 @@ public:
}
}
#if 0
/**
* Apply a function or function object to all roots
*
@ -237,7 +244,7 @@ public:
SharedPtr<Peer> rp;
for(std::vector<Root>::const_iterator i(_roots.begin());i!=_roots.end();++i) {
{
Mutex::Lock l2(_peers_m);
Mutex::Lock l2(_peers_l);
const SharedPtr<Peer> *const ap = _peers.get(i->address());
if (ap) {
rp = *ap;
@ -256,7 +263,7 @@ public:
* @param now Current time
* @return Best/fastest currently connected root or NULL if none
*/
ZT_ALWAYS_INLINE SharedPtr<Peer> root(const int64_t now)
inline SharedPtr<Peer> root(const int64_t now)
{
Mutex::Lock l(_bestRoot_m);
if ((!_bestRoot)||((now - _lastRankedBestRoot) >= ZT_FIND_BEST_ROOT_PERIOD)) {
@ -266,7 +273,7 @@ public:
long bestQuality = 2147483647;
for(std::vector<Root>::const_iterator i(_roots.begin());i!=_roots.end();++i) {
{
Mutex::Lock l2(_peers_m);
Mutex::Lock l2(_peers_l);
const SharedPtr<Peer> *const ap = _peers.get(i->address());
if (ap) {
rp = *ap;
@ -287,6 +294,54 @@ public:
}
return _bestRoot;
}
#endif
ZT_ALWAYS_INLINE SharedPtr<Peer> root(const int64_t now)
{
return SharedPtr<Peer>();
}
/**
* @return Names of dynamic roots currently known by the system
*/
ZT_ALWAYS_INLINE std::vector<Str> dynamicRootNames() const
{
Mutex::Lock l(_dynamicRoots_l);
return _dynamicRoots.keys();
}
/**
* Set or update a static root entry
*
* @param id Static root's identity
* @param addrs Static root's IP address(es)
*/
ZT_ALWAYS_INLINE void setStaticRoot(const Identity &id,const std::vector<InetAddress> &addrs)
{
Mutex::Lock l(_staticRoots_l);
_staticRoots[id] = addrs;
}
/**
* Set or update dynamic root if new locator is newer and valid
*
* This checks internal validity of the new locator including its internal self-signature.
* It does not check any DNS signatures.
*
* @param dnsName DNS name used to retrive root
* @param latestLocator Latest locator
* @return True if latest locator is internally valid and newer
*/
ZT_ALWAYS_INLINE bool setDynamicRoot(const Str &dnsName,const Locator &latestLocator)
{
Mutex::Lock l(_dynamicRoots_l);
Locator &ll = _dynamicRoots[dnsName];
if (ll.timestamp() < latestLocator.timestamp()) {
ll = latestLocator;
return true;
}
return false;
}
/**
* Get the best relay to a given address, which may or may not be a root
@ -298,15 +353,15 @@ public:
ZT_ALWAYS_INLINE SharedPtr<Peer> findRelayTo(const int64_t now,const Address &toAddr)
{
// TODO: in the future this will check 'mesh-like' relays and if enabled consult LF for other roots (for if this is a root)
return root(now);
//return root(now);
}
/**
* @param allPeers vector to fill with all current peers
*/
ZT_ALWAYS_INLINE void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const
inline void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const
{
Mutex::Lock l(_peers_m);
Mutex::Lock l(_peers_l);
allPeers.clear();
allPeers.reserve(_peers.size());
Hashtable< Address,SharedPtr<Peer> >::Iterator i(*(const_cast<Hashtable< Address,SharedPtr<Peer> > *>(&_peers)));
@ -385,7 +440,7 @@ public:
/**
* Set or clear physical path configuration (called via Node::setPhysicalPathConfiguration)
*/
ZT_ALWAYS_INLINE void setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig)
inline void setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig)
{
if (!pathNetwork) {
_numConfiguredPhysicalPaths = 0;
@ -422,17 +477,26 @@ public:
private:
const RuntimeEnvironment *const RR;
const Identity _myIdentity;
std::pair<InetAddress,ZT_PhysicalPathConfiguration> _physicalPathConfig[ZT_MAX_CONFIGURABLE_PATHS];
unsigned int _numConfiguredPhysicalPaths;
std::vector<Root> _roots;
SharedPtr<Peer> _bestRoot;
int64_t _lastRankedBestRoot;
Hashtable< Address,SharedPtr<Peer> > _peers;
Hashtable< Path::HashKey,SharedPtr<Path> > _paths;
Mutex _roots_m;
Mutex _bestRoot_m;
Mutex _peers_m;
Mutex _paths_m;
Hashtable< Identity,std::vector<InetAddress> > _staticRoots;
Hashtable< Str,Locator > _dynamicRoots;
//std::vector<Root> _roots;
//SharedPtr<Peer> _bestRoot;
//int64_t _lastRankedBestRoot;
//Mutex _roots_m;
//Mutex _bestRoot_m;
Mutex _peers_l;
Mutex _paths_l;
Mutex _staticRoots_l;
Mutex _dynamicRoots_l;
};
} // namespace ZeroTier