Browse Source

Clean dead paths from peers.

Adam Ierymenko 11 years ago
parent
commit
8e587ae481
5 changed files with 41 additions and 1 deletions
  1. 2 0
      node/InetAddress.hpp
  2. 18 0
      node/Path.hpp
  3. 12 0
      node/Peer.cpp
  4. 5 0
      node/Peer.hpp
  5. 4 1
      node/Topology.cpp

+ 2 - 0
node/InetAddress.hpp

@@ -51,6 +51,8 @@ namespace ZeroTier {
 
 
 /**
 /**
  * Wrapper for sockaddr structures for IPV4 and IPV6
  * Wrapper for sockaddr structures for IPV4 and IPV6
+ *
+ * Note: this class is raw memcpy'able, which is used in a couple places.
  */
  */
 class InetAddress
 class InetAddress
 {
 {

+ 18 - 0
node/Path.hpp

@@ -29,6 +29,7 @@
 #define ZT_PATH_HPP
 #define ZT_PATH_HPP
 
 
 #include <stdint.h>
 #include <stdint.h>
+#include <string.h>
 
 
 #include <stdexcept>
 #include <stdexcept>
 #include <string>
 #include <string>
@@ -57,6 +58,12 @@ public:
 		_tcp(false),
 		_tcp(false),
 		_fixed(false) {}
 		_fixed(false) {}
 
 
+	Path(const Path &p)
+	{
+		// InetAddress is memcpy'able
+		memcpy(this,&p,sizeof(Path));
+	}
+
 	Path(const InetAddress &addr,bool tcp,bool fixed = false) :
 	Path(const InetAddress &addr,bool tcp,bool fixed = false) :
 		_lastSend(0),
 		_lastSend(0),
 		_lastReceived(0),
 		_lastReceived(0),
@@ -66,6 +73,13 @@ public:
 		_tcp(tcp),
 		_tcp(tcp),
 		_fixed(fixed) {}
 		_fixed(fixed) {}
 
 
+	inline Path &operator=(const Path &p)
+	{
+		if (this != &p)
+			memcpy(this,&p,sizeof(Path));
+		return *this;
+	}
+
 	inline const InetAddress &address() const throw() { return _addr; }
 	inline const InetAddress &address() const throw() { return _addr; }
 	inline bool tcp() const throw() { return _tcp; }
 	inline bool tcp() const throw() { return _tcp; }
 	inline uint64_t lastSend() const throw() { return _lastSend; }
 	inline uint64_t lastSend() const throw() { return _lastSend; }
@@ -81,6 +95,10 @@ public:
 	inline void firewallOpenerSent(uint64_t t) throw() { _lastFirewallOpener = t; }
 	inline void firewallOpenerSent(uint64_t t) throw() { _lastFirewallOpener = t; }
 	inline void pinged(uint64_t t) throw() { _lastPing = t; }
 	inline void pinged(uint64_t t) throw() { _lastPing = t; }
 
 
+	/**
+	 * @param now Current time
+	 * @return True if this path is fixed or has received data in last ACTIVITY_TIMEOUT ms
+	 */
 	inline bool active(uint64_t now) const
 	inline bool active(uint64_t now) const
 		throw()
 		throw()
 	{
 	{

+ 12 - 0
node/Peer.cpp

@@ -187,4 +187,16 @@ bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now,bool firstSinceRes
 	return sent;
 	return sent;
 }
 }
 
 
+void Peer::clean(uint64_t now)
+{
+	Mutex::Lock _l(_lock);
+	unsigned long i = 0,o = 0,l = _paths.size();
+	while (i != l) {
+		if (_paths[i].active(now))
+			_paths[o++] = _paths[i];
+		++i;
+	}
+	_paths.resize(o);
+}
+
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 5 - 0
node/Peer.hpp

@@ -165,6 +165,11 @@ public:
 	 */
 	 */
 	bool sendPing(const RuntimeEnvironment *_r,uint64_t now,bool firstSinceReset);
 	bool sendPing(const RuntimeEnvironment *_r,uint64_t now,bool firstSinceReset);
 
 
+	/**
+	 * Called periodically by Topology::clean() to remove stale paths and do other cleanup
+	 */
+	void clean(uint64_t now);
+
 	/**
 	/**
 	 * @return All known direct paths to this peer
 	 * @return All known direct paths to this peer
 	 */
 	 */

+ 4 - 1
node/Topology.cpp

@@ -210,7 +210,10 @@ void Topology::clean()
 	for(std::map< Address,SharedPtr<Peer> >::iterator p(_activePeers.begin());p!=_activePeers.end();) {
 	for(std::map< Address,SharedPtr<Peer> >::iterator p(_activePeers.begin());p!=_activePeers.end();) {
 		if (((now - p->second->lastUsed()) >= ZT_PEER_IN_MEMORY_EXPIRATION)&&(!_supernodeAddresses.count(p->second->address())))
 		if (((now - p->second->lastUsed()) >= ZT_PEER_IN_MEMORY_EXPIRATION)&&(!_supernodeAddresses.count(p->second->address())))
 			_activePeers.erase(p++);
 			_activePeers.erase(p++);
-		else ++p;
+		else {
+			p->second->clean(now);
+			++p;
+		}
 	}
 	}
 }
 }