2
0
Adam Ierymenko 8 жил өмнө
parent
commit
9e7c778cc8
3 өөрчлөгдсөн 44 нэмэгдсэн , 39 устгасан
  1. 9 4
      node/Node.cpp
  2. 18 13
      node/Topology.cpp
  3. 17 22
      node/Topology.hpp

+ 9 - 4
node/Node.cpp

@@ -159,7 +159,8 @@ public:
 	_PingPeersThatNeedPing(const RuntimeEnvironment *renv,uint64_t now) :
 	_PingPeersThatNeedPing(const RuntimeEnvironment *renv,uint64_t now) :
 		lastReceiveFromUpstream(0),
 		lastReceiveFromUpstream(0),
 		RR(renv),
 		RR(renv),
-		_now(now)
+		_now(now),
+		_bestCurrentUpstream(RR->topology->getUpstreamPeer())
 	{
 	{
 		RR->topology->getUpstreamStableEndpoints(_upstreams);
 		RR->topology->getUpstreamStableEndpoints(_upstreams);
 	}
 	}
@@ -194,8 +195,11 @@ public:
 				}
 				}
 			} else contacted = true;
 			} else contacted = true;
 
 
-			if (!contacted)
-				p->sendHELLO(InetAddress(),InetAddress(),_now);
+			if ((!contacted)&&(_bestCurrentUpstream)) {
+				const SharedPtr<Path> up(_bestCurrentUpstream->getBestPath(_now,true));
+				if (up)
+					p->sendHELLO(up->localAddress(),up->address(),_now);
+			}
 
 
 			lastReceiveFromUpstream = std::max(p->lastReceive(),lastReceiveFromUpstream);
 			lastReceiveFromUpstream = std::max(p->lastReceive(),lastReceiveFromUpstream);
 		} else if (p->isActive(_now)) {
 		} else if (p->isActive(_now)) {
@@ -205,7 +209,8 @@ public:
 
 
 private:
 private:
 	const RuntimeEnvironment *RR;
 	const RuntimeEnvironment *RR;
-	uint64_t _now;
+	const uint64_t _now;
+	const SharedPtr<Peer> _bestCurrentUpstream;
 	Hashtable< Address,std::vector<InetAddress> > _upstreams;
 	Hashtable< Address,std::vector<InetAddress> > _upstreams;
 };
 };
 
 

+ 18 - 13
node/Topology.cpp

@@ -79,7 +79,7 @@ SharedPtr<Peer> Topology::addPeer(const SharedPtr<Peer> &peer)
 
 
 	SharedPtr<Peer> np;
 	SharedPtr<Peer> np;
 	{
 	{
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_peers_m);
 		SharedPtr<Peer> &hp = _peers[peer->address()];
 		SharedPtr<Peer> &hp = _peers[peer->address()];
 		if (!hp)
 		if (!hp)
 			hp = peer;
 			hp = peer;
@@ -99,7 +99,7 @@ SharedPtr<Peer> Topology::getPeer(const Address &zta)
 	}
 	}
 
 
 	{
 	{
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_peers_m);
 		const SharedPtr<Peer> *const ap = _peers.get(zta);
 		const SharedPtr<Peer> *const ap = _peers.get(zta);
 		if (ap)
 		if (ap)
 			return *ap;
 			return *ap;
@@ -110,7 +110,7 @@ SharedPtr<Peer> Topology::getPeer(const Address &zta)
 		if (id) {
 		if (id) {
 			SharedPtr<Peer> np(new Peer(RR,RR->identity,id));
 			SharedPtr<Peer> np(new Peer(RR,RR->identity,id));
 			{
 			{
-				Mutex::Lock _l(_lock);
+				Mutex::Lock _l(_peers_m);
 				SharedPtr<Peer> &ap = _peers[zta];
 				SharedPtr<Peer> &ap = _peers[zta];
 				if (!ap)
 				if (!ap)
 					ap.swap(np);
 					ap.swap(np);
@@ -127,7 +127,7 @@ Identity Topology::getIdentity(const Address &zta)
 	if (zta == RR->identity.address()) {
 	if (zta == RR->identity.address()) {
 		return RR->identity;
 		return RR->identity;
 	} else {
 	} else {
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_peers_m);
 		const SharedPtr<Peer> *const ap = _peers.get(zta);
 		const SharedPtr<Peer> *const ap = _peers.get(zta);
 		if (ap)
 		if (ap)
 			return (*ap)->identity();
 			return (*ap)->identity();
@@ -147,7 +147,8 @@ void Topology::saveIdentity(const Identity &id)
 SharedPtr<Peer> Topology::getUpstreamPeer(const Address *avoid,unsigned int avoidCount,bool strictAvoid)
 SharedPtr<Peer> Topology::getUpstreamPeer(const Address *avoid,unsigned int avoidCount,bool strictAvoid)
 {
 {
 	const uint64_t now = RR->node->now();
 	const uint64_t now = RR->node->now();
-	Mutex::Lock _l(_lock);
+	Mutex::Lock _l1(_peers_m);
+	Mutex::Lock _l2(_upstreams_m);
 
 
 	if (_amRoot) {
 	if (_amRoot) {
 		/* If I am a root, pick another root that isn't mine and that
 		/* If I am a root, pick another root that isn't mine and that
@@ -208,13 +209,13 @@ SharedPtr<Peer> Topology::getUpstreamPeer(const Address *avoid,unsigned int avoi
 
 
 bool Topology::isUpstream(const Identity &id) const
 bool Topology::isUpstream(const Identity &id) const
 {
 {
-	Mutex::Lock _l(_lock);
+	Mutex::Lock _l(_upstreams_m);
 	return (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),id.address()) != _upstreamAddresses.end());
 	return (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),id.address()) != _upstreamAddresses.end());
 }
 }
 
 
 ZT_PeerRole Topology::role(const Address &ztaddr) const
 ZT_PeerRole Topology::role(const Address &ztaddr) const
 {
 {
-	Mutex::Lock _l(_lock);
+	Mutex::Lock _l(_upstreams_m);
 	if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),ztaddr) != _upstreamAddresses.end()) {
 	if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),ztaddr) != _upstreamAddresses.end()) {
 		for(std::vector<World::Root>::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) {
 		for(std::vector<World::Root>::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) {
 			if (i->identity.address() == ztaddr)
 			if (i->identity.address() == ztaddr)
@@ -227,7 +228,7 @@ ZT_PeerRole Topology::role(const Address &ztaddr) const
 
 
 bool Topology::isProhibitedEndpoint(const Address &ztaddr,const InetAddress &ipaddr) const
 bool Topology::isProhibitedEndpoint(const Address &ztaddr,const InetAddress &ipaddr) const
 {
 {
-	Mutex::Lock _l(_lock);
+	Mutex::Lock _l(_upstreams_m);
 
 
 	// For roots the only permitted addresses are those defined. This adds just a little
 	// For roots the only permitted addresses are those defined. This adds just a little
 	// bit of extra security against spoofing, replaying, etc.
 	// bit of extra security against spoofing, replaying, etc.
@@ -257,7 +258,8 @@ bool Topology::addWorld(const World &newWorld)
 	if ((newWorld.type() != World::TYPE_PLANET)&&(newWorld.type() != World::TYPE_MOON))
 	if ((newWorld.type() != World::TYPE_PLANET)&&(newWorld.type() != World::TYPE_MOON))
 		return false;
 		return false;
 
 
-	Mutex::Lock _l(_lock);
+	Mutex::Lock _l1(_upstreams_m);
+	Mutex::Lock _l2(_peers_m);
 
 
 	World *existing = (World *)0;
 	World *existing = (World *)0;
 	switch(newWorld.type()) {
 	switch(newWorld.type()) {
@@ -313,7 +315,7 @@ void Topology::addMoon(const uint64_t id)
 {
 {
 	{
 	{
 		const Address a(id >> 24);
 		const Address a(id >> 24);
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_upstreams_m);
 		if (std::find(_contactingMoons.begin(),_contactingMoons.end(),a) == _contactingMoons.end())
 		if (std::find(_contactingMoons.begin(),_contactingMoons.end(),a) == _contactingMoons.end())
 			_contactingMoons.push_back(a);
 			_contactingMoons.push_back(a);
 	}
 	}
@@ -339,7 +341,8 @@ void Topology::addMoon(const uint64_t id)
 
 
 void Topology::removeMoon(const uint64_t id)
 void Topology::removeMoon(const uint64_t id)
 {
 {
-	Mutex::Lock _l(_lock);
+	Mutex::Lock _l1(_upstreams_m);
+	Mutex::Lock _l2(_peers_m);
 
 
 	std::vector<World> nm;
 	std::vector<World> nm;
 	for(std::vector<World>::const_iterator m(_moons.begin());m!=_moons.end();++m) {
 	for(std::vector<World>::const_iterator m(_moons.begin());m!=_moons.end();++m) {
@@ -365,8 +368,9 @@ void Topology::removeMoon(const uint64_t id)
 
 
 void Topology::clean(uint64_t now)
 void Topology::clean(uint64_t now)
 {
 {
-	Mutex::Lock _l(_lock);
 	{
 	{
+		Mutex::Lock _l1(_peers_m);
+		Mutex::Lock _l2(_upstreams_m);
 		Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
 		Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
 		Address *a = (Address *)0;
 		Address *a = (Address *)0;
 		SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
 		SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
@@ -376,6 +380,7 @@ void Topology::clean(uint64_t now)
 		}
 		}
 	}
 	}
 	{
 	{
+		Mutex::Lock _l(_paths_m);
 		Hashtable< Path::HashKey,SharedPtr<Path> >::Iterator i(_paths);
 		Hashtable< Path::HashKey,SharedPtr<Path> >::Iterator i(_paths);
 		Path::HashKey *k = (Path::HashKey *)0;
 		Path::HashKey *k = (Path::HashKey *)0;
 		SharedPtr<Path> *p = (SharedPtr<Path> *)0;
 		SharedPtr<Path> *p = (SharedPtr<Path> *)0;
@@ -401,7 +406,7 @@ Identity Topology::_getIdentity(const Address &zta)
 
 
 void Topology::_memoizeUpstreams()
 void Topology::_memoizeUpstreams()
 {
 {
-	// assumes _lock is locked
+	// assumes _upstreams_m and _peers_m are locked
 	_upstreamAddresses.clear();
 	_upstreamAddresses.clear();
 	_amRoot = false;
 	_amRoot = false;
 	for(std::vector<World::Root>::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) {
 	for(std::vector<World::Root>::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) {

+ 17 - 22
node/Topology.hpp

@@ -82,7 +82,7 @@ public:
 	 */
 	 */
 	inline SharedPtr<Peer> getPeerNoCache(const Address &zta)
 	inline SharedPtr<Peer> getPeerNoCache(const Address &zta)
 	{
 	{
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_peers_m);
 		const SharedPtr<Peer> *const ap = _peers.get(zta);
 		const SharedPtr<Peer> *const ap = _peers.get(zta);
 		if (ap)
 		if (ap)
 			return *ap;
 			return *ap;
@@ -98,7 +98,7 @@ public:
 	 */
 	 */
 	inline SharedPtr<Path> getPath(const InetAddress &l,const InetAddress &r)
 	inline SharedPtr<Path> getPath(const InetAddress &l,const InetAddress &r)
 	{
 	{
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_paths_m);
 		SharedPtr<Path> &p = _paths[Path::HashKey(l,r)];
 		SharedPtr<Path> &p = _paths[Path::HashKey(l,r)];
 		if (!p)
 		if (!p)
 			p.setToUnsafe(new Path(l,r));
 			p.setToUnsafe(new Path(l,r));
@@ -178,7 +178,7 @@ public:
 	 */
 	 */
 	inline void getUpstreamStableEndpoints(Hashtable< Address,std::vector<InetAddress> > &eps) const
 	inline void getUpstreamStableEndpoints(Hashtable< Address,std::vector<InetAddress> > &eps) const
 	{
 	{
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_upstreams_m);
 		for(std::vector<World::Root>::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) {
 		for(std::vector<World::Root>::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) {
 			std::vector<InetAddress> &ips = eps[i->identity.address()];
 			std::vector<InetAddress> &ips = eps[i->identity.address()];
 			for(std::vector<InetAddress>::const_iterator j(i->stableEndpoints.begin());j!=i->stableEndpoints.end();++j) {
 			for(std::vector<InetAddress>::const_iterator j(i->stableEndpoints.begin());j!=i->stableEndpoints.end();++j) {
@@ -204,7 +204,7 @@ public:
 	 */
 	 */
 	inline std::vector<Address> upstreamAddresses() const
 	inline std::vector<Address> upstreamAddresses() const
 	{
 	{
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_upstreams_m);
 		std::vector<Address> u(_upstreamAddresses);
 		std::vector<Address> u(_upstreamAddresses);
 		for(std::vector<Address>::const_iterator m(_contactingMoons.begin());m!=_contactingMoons.end();++m) {
 		for(std::vector<Address>::const_iterator m(_contactingMoons.begin());m!=_contactingMoons.end();++m) {
 			if (std::find(u.begin(),u.end(),*m) == u.end())
 			if (std::find(u.begin(),u.end(),*m) == u.end())
@@ -218,7 +218,7 @@ public:
 	 */
 	 */
 	inline std::vector<World> moons() const
 	inline std::vector<World> moons() const
 	{
 	{
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_upstreams_m);
 		return _moons;
 		return _moons;
 	}
 	}
 
 
@@ -227,7 +227,7 @@ public:
 	 */
 	 */
 	inline World planet() const
 	inline World planet() const
 	{
 	{
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_upstreams_m);
 		return _planet;
 		return _planet;
 	}
 	}
 
 
@@ -286,7 +286,7 @@ public:
 	inline unsigned long countActive(uint64_t now) const
 	inline unsigned long countActive(uint64_t now) const
 	{
 	{
 		unsigned long cnt = 0;
 		unsigned long cnt = 0;
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_peers_m);
 		Hashtable< Address,SharedPtr<Peer> >::Iterator i(const_cast<Topology *>(this)->_peers);
 		Hashtable< Address,SharedPtr<Peer> >::Iterator i(const_cast<Topology *>(this)->_peers);
 		Address *a = (Address *)0;
 		Address *a = (Address *)0;
 		SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
 		SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
@@ -299,20 +299,13 @@ public:
 	/**
 	/**
 	 * Apply a function or function object to all peers
 	 * Apply a function or function object to all peers
 	 *
 	 *
-	 * Note: explicitly template this by reference if you want the object
-	 * passed by reference instead of copied.
-	 *
-	 * Warning: be careful not to use features in these that call any other
-	 * methods of Topology that may lock _lock, otherwise a recursive lock
-	 * and deadlock or lock corruption may occur.
-	 *
 	 * @param f Function to apply
 	 * @param f Function to apply
 	 * @tparam F Function or function object type
 	 * @tparam F Function or function object type
 	 */
 	 */
 	template<typename F>
 	template<typename F>
 	inline void eachPeer(F f)
 	inline void eachPeer(F f)
 	{
 	{
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_peers_m);
 		Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
 		Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
 		Address *a = (Address *)0;
 		Address *a = (Address *)0;
 		SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
 		SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
@@ -332,7 +325,7 @@ public:
 	 */
 	 */
 	inline std::vector< std::pair< Address,SharedPtr<Peer> > > allPeers() const
 	inline std::vector< std::pair< Address,SharedPtr<Peer> > > allPeers() const
 	{
 	{
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_peers_m);
 		return _peers.entries();
 		return _peers.entries();
 	}
 	}
 
 
@@ -382,7 +375,7 @@ public:
 	{
 	{
 		if (count > ZT_MAX_TRUSTED_PATHS)
 		if (count > ZT_MAX_TRUSTED_PATHS)
 			count = ZT_MAX_TRUSTED_PATHS;
 			count = ZT_MAX_TRUSTED_PATHS;
-		Mutex::Lock _l(_lock);
+		Mutex::Lock _l(_trustedPaths_m);
 		for(unsigned int i=0;i<count;++i) {
 		for(unsigned int i=0;i<count;++i) {
 			_trustedPathIds[i] = ids[i];
 			_trustedPathIds[i] = ids[i];
 			_trustedPathNetworks[i] = networks[i];
 			_trustedPathNetworks[i] = networks[i];
@@ -399,18 +392,20 @@ private:
 	uint64_t _trustedPathIds[ZT_MAX_TRUSTED_PATHS];
 	uint64_t _trustedPathIds[ZT_MAX_TRUSTED_PATHS];
 	InetAddress _trustedPathNetworks[ZT_MAX_TRUSTED_PATHS];
 	InetAddress _trustedPathNetworks[ZT_MAX_TRUSTED_PATHS];
 	unsigned int _trustedPathCount;
 	unsigned int _trustedPathCount;
-
-	World _planet;
-	std::vector< World > _moons;
+	Mutex _trustedPaths_m;
 
 
 	Hashtable< Address,SharedPtr<Peer> > _peers;
 	Hashtable< Address,SharedPtr<Peer> > _peers;
+	Mutex _peers_m;
+
 	Hashtable< Path::HashKey,SharedPtr<Path> > _paths;
 	Hashtable< Path::HashKey,SharedPtr<Path> > _paths;
+	Mutex _paths_m;
 
 
+	World _planet;
+	std::vector<World> _moons;
 	std::vector<Address> _contactingMoons;
 	std::vector<Address> _contactingMoons;
 	std::vector<Address> _upstreamAddresses;
 	std::vector<Address> _upstreamAddresses;
 	bool _amRoot;
 	bool _amRoot;
-
-	Mutex _lock;
+	Mutex _upstreams_m; // locks worlds, upstream info, moon info, etc.
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier