Browse Source

Stop duplciate IPv6 addresses due to privacy mode IPs.

Adam Ierymenko 7 years ago
parent
commit
fac7dc9c91
2 changed files with 22 additions and 2 deletions
  1. 20 0
      node/InetAddress.hpp
  2. 2 2
      node/Peer.cpp

+ 20 - 0
node/InetAddress.hpp

@@ -405,6 +405,26 @@ struct InetAddress : public sockaddr_storage
 		return false;
 	}
 
+	/**
+	 * Performs an IP-only comparison or, if that is impossible, a memcmp()
+	 *
+	 * This version compares only the first 64 bits of IPv6 addresses.
+	 *
+	 * @param a InetAddress to compare again
+	 * @return True if only IP portions are equal (false for non-IP or null addresses)
+	 */
+	inline bool ipsEqual2(const InetAddress &a) const
+	{
+		if (ss_family == a.ss_family) {
+			if (ss_family == AF_INET)
+				return (reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const struct sockaddr_in *>(&a)->sin_addr.s_addr);
+			if (ss_family == AF_INET6)
+				return (memcmp(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_addr.s6_addr,8) == 0);
+			return (memcmp(this,&a,sizeof(InetAddress)) == 0);
+		}
+		return false;
+	}
+
 	inline unsigned long hashCode() const
 	{
 		if (ss_family == AF_INET) {

+ 2 - 2
node/Peer.cpp

@@ -171,7 +171,7 @@ void Peer::received(
 			bool redundant = false;
 			for(unsigned int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
 				if (_paths[i].p) {
-					if ( (_paths[i].p->alive(now)) && ( ((_paths[i].p->localSocket() == path->localSocket())&&(_paths[i].p->address().ss_family == path->address().ss_family)) || (_paths[i].p->address().ipsEqual(path->address())) ) )  {
+					if ( (_paths[i].p->alive(now)) && ( ((_paths[i].p->localSocket() == path->localSocket())&&(_paths[i].p->address().ss_family == path->address().ss_family)) || (_paths[i].p->address().ipsEqual2(path->address())) ) )  {
 						redundant = true;
 						break;
 					}
@@ -560,7 +560,7 @@ void Peer::clusterRedirect(void *tPtr,const SharedPtr<Path> &originatingPath,con
 		unsigned int j = 0;
 		for(unsigned int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
 			if (_paths[i].p) {
-				if ((_paths[i].priority >= newPriority)&&(!_paths[i].p->address().ipsEqual(remoteAddress))) {
+				if ((_paths[i].priority >= newPriority)&&(!_paths[i].p->address().ipsEqual2(remoteAddress))) {
 					if (i != j)
 						_paths[j] = _paths[i];
 					++j;