diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index 79bf76adc..c1ea6c13b 100644 --- a/node/InetAddress.hpp +++ b/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(this)->sin_addr.s_addr == reinterpret_cast(&a)->sin_addr.s_addr); + if (ss_family == AF_INET6) + return (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr,reinterpret_cast(&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) { diff --git a/node/Peer.cpp b/node/Peer.cpp index d68e0df32..a3682a97f 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -171,7 +171,7 @@ void Peer::received( bool redundant = false; for(unsigned int i=0;ialive(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 &originatingPath,con unsigned int j = 0; for(unsigned int i=0;i= 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;