@ -44,11 +44,10 @@
# include "CertificateOfMembership.hpp"
# include "Salsa20.hpp"
# include "Poly1305.hpp"
# include "Packet.hpp"
# include "Identity.hpp"
# include "Peer.hpp"
# include "Topology.hpp"
# include "Packet.hpp"
# include "Switch.hpp"
# include "Node.hpp"
namespace ZeroTier {
@ -566,17 +565,17 @@ void Cluster::removeMember(uint16_t memberId)
_memberIds = newMemberIds ;
}
bool Cluster : : redirectPeer ( const SharedPtr < Peer > & peer , const Inet Address & local Address, const InetAddress & peerPhysicalAddress , bool offload )
InetAddress Cluster : : findBetterEndpoint ( const Address & peer Address, const InetAddress & peerPhysicalAddress , bool offload )
{
if ( ! peerPhysicalAddress ) // sanity check
return false ;
return InetAddress ( ) ;
if ( _addressToLocationFunction ) {
// Pick based on location if it can be determined
int px = 0 , py = 0 , pz = 0 ;
if ( _addressToLocationFunction ( _addressToLocationFunctionArg , reinterpret_cast < const struct sockaddr_storage * > ( & peerPhysicalAddress ) , & px , & py , & pz ) = = 0 ) {
TRACE ( " NO GEOLOCATION available for %s " , peerPhysicalAddress . toIpString ( ) . c_str ( ) ) ;
return false ;
TRACE ( " no geolocation data for %s (geo-lookup is lazy/async so it may work next time) " , peerPhysicalAddress . toIpString ( ) . c_str ( ) ) ;
return InetAddress ( ) ;
}
// Find member closest to this peer
@ -585,7 +584,6 @@ bool Cluster::redirectPeer(const SharedPtr<Peer> &peer,const InetAddress &localA
const double currentDistance = _dist3d ( _x , _y , _z , px , py , pz ) ;
double bestDistance = ( offload ? 2147483648.0 : currentDistance ) ;
unsigned int bestMember = _id ;
TRACE ( " %s is at %d,%d,%d -- looking for anyone closer than %d,%d,%d (%fkm) " , peerPhysicalAddress . toString ( ) . c_str ( ) , px , py , pz , _x , _y , _z , bestDistance ) ;
{
Mutex : : Lock _l ( _memberIds_m ) ;
for ( std : : vector < uint16_t > : : const_iterator mid ( _memberIds . begin ( ) ) ; mid ! = _memberIds . end ( ) ; + + mid ) {
@ -604,41 +602,17 @@ bool Cluster::redirectPeer(const SharedPtr<Peer> &peer,const InetAddress &localA
}
}
if ( best . size ( ) > 0 ) {
TRACE ( " %s seems closer to %u at %fkm, suggesting redirect... " , peer - > address ( ) . toString ( ) . c_str ( ) , bestMember , bestDistance ) ;
/* if (peer->remoteVersionProtocol() >= 5) {
// If it's a newer peer send VERB_PUSH_DIRECT_PATHS which is more idiomatic
} else { */
// Otherwise send VERB_RENDEZVOUS for ourselves, which will trick peers into trying other endpoints for us even if they're too old for PUSH_DIRECT_PATHS
for ( std : : vector < InetAddress > : : const_iterator a ( best . begin ( ) ) ; a ! = best . end ( ) ; + + a ) {
if ( a - > ss_family = = peerPhysicalAddress . ss_family ) {
Packet outp ( peer - > address ( ) , RR - > identity . address ( ) , Packet : : VERB_RENDEZVOUS ) ;
outp . append ( ( uint8_t ) 0 ) ; // no flags
RR - > identity . address ( ) . appendTo ( outp ) ; // HACK: rendezvous with ourselves! with really old peers this will only work if I'm a root server!
outp . append ( ( uint16_t ) a - > port ( ) ) ;
if ( a - > ss_family = = AF_INET ) {
outp . append ( ( uint8_t ) 4 ) ;
outp . append ( a - > rawIpData ( ) , 4 ) ;
} else {
outp . append ( ( uint8_t ) 16 ) ;
outp . append ( a - > rawIpData ( ) , 16 ) ;
}
outp . armor ( peer - > key ( ) , true ) ;
RR - > antiRec - > logOutgoingZT ( outp . data ( ) , outp . size ( ) ) ;
RR - > node - > putPacket ( localAddress , peerPhysicalAddress , outp . data ( ) , outp . size ( ) ) ;
}
}
//}
return true ;
} else {
//TRACE("peer %s is at [%d,%d,%d], distance to us is %f and this seems to be the best",peer->address().toString().c_str(),px,py,pz,currentDistance);
return false ;
for ( std : : vector < InetAddress > : : const_iterator a ( best . begin ( ) ) ; a ! = best . end ( ) ; + + a ) {
if ( a - > ss_family = = peerPhysicalAddress . ss_family ) {
TRACE ( " %s at [%d,%d,%d] is %f from us but %f from %u, can redirect to %s " , peerAddress . toString ( ) . c_str ( ) , px , py , pz , currentDistance , bestDistance , bestMember , a - > toString ( ) . c_str ( ) ) ;
return * a ;
}
}
TRACE ( " %s at [%d,%d,%d] is %f from us, no better endpoints found " , peerAddress . toString ( ) . c_str ( ) , px , py , pz , currentDistance ) ;
return InetAddress ( ) ;
} else {
// TODO: pick based on load if no location info?
return false ;
return InetAddress ( ) ;
}
}