@ -240,70 +240,83 @@ bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily)
return false ;
}
void Peer : : pushDirectPaths ( Path * path , uint64_t now , bool force )
bool Peer : : pushDirectPaths ( const InetAddress & localAddr , const InetAddress & toAddress , uint64_t now , bool force )
{
# ifdef ZT_ENABLE_CLUSTER
// Cluster mode disables normal PUSH_DIRECT_PATHS in favor of cluster-based peer redirection
if ( RR - > cluster )
return ;
return false ;
# endif
if ( ( ( now - _lastDirectPathPushSent ) > = ZT_DIRECT_PATH_PUSH_INTERVAL ) | | ( force ) ) {
_lastDirectPathPushSent = now ;
if ( ! force ) {
if ( ( now - _lastDirectPathPushSent ) < ZT_DIRECT_PATH_PUSH_INTERVAL )
return false ;
else _lastDirectPathPushSent = now ;
}
std : : vector < InetAddress > dps ( RR - > node - > directPaths ( ) ) ;
if ( dps . empty ( ) )
return ;
std : : vector < InetAddress > dps ( RR - > node - > directPaths ( ) ) ;
std : : vector < InetAddress > sym ( RR - > sa - > getSymmetricNatPredictions ( ) ) ;
for ( unsigned long i = 0 , added = 0 ; i < sym . size ( ) ; + + i ) {
InetAddress tmp ( sym [ ( unsigned long ) RR - > node - > prng ( ) % sym . size ( ) ] ) ;
if ( std : : find ( dps . begin ( ) , dps . end ( ) , tmp ) = = dps . end ( ) ) {
dps . push_back ( tmp ) ;
if ( + + added > = ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY )
break ;
}
}
if ( dps . empty ( ) )
return false ;
# ifdef ZT_TRACE
{
std : : string ps ;
for ( std : : vector < InetAddress > : : const_iterator p ( dps . begin ( ) ) ; p ! = dps . end ( ) ; + + p ) {
if ( ps . length ( ) > 0 )
ps . push_back ( ' , ' ) ;
ps . append ( p - > toString ( ) ) ;
}
TRACE ( " pushing %u direct paths to %s: %s " , ( unsigned int ) dps . size ( ) , _id . address ( ) . toString ( ) . c_str ( ) , ps . c_str ( ) ) ;
{
std : : string ps ;
for ( std : : vector < InetAddress > : : const_iterator p ( dps . begin ( ) ) ; p ! = dps . end ( ) ; + + p ) {
if ( ps . length ( ) > 0 )
ps . push_back ( ' , ' ) ;
ps . append ( p - > toString ( ) ) ;
}
TRACE ( " pushing %u direct paths to %s: %s " , ( unsigned int ) dps . size ( ) , _id . address ( ) . toString ( ) . c_str ( ) , ps . c_str ( ) ) ;
}
# endif
std : : vector < InetAddress > : : const_iterator p ( dps . begin ( ) ) ;
while ( p ! = dps . end ( ) ) {
Packet outp ( _id . address ( ) , RR - > identity . address ( ) , Packet : : VERB_PUSH_DIRECT_PATHS ) ;
outp . addSize ( 2 ) ; // leave room for count
unsigned int count = 0 ;
while ( ( p ! = dps . end ( ) ) & & ( ( outp . size ( ) + 24 ) < ZT_PROTO_MAX_PACKET_LENGTH ) ) {
uint8_t addressType = 4 ;
switch ( p - > ss_family ) {
case AF_INET :
break ;
case AF_INET6 :
addressType = 6 ;
break ;
default : // we currently only push IP addresses
+ + p ;
continue ;
}
std : : vector < InetAddress > : : const_iterator p ( dps . begin ( ) ) ;
while ( p ! = dps . end ( ) ) {
Packet outp ( _id . address ( ) , RR - > identity . address ( ) , Packet : : VERB_PUSH_DIRECT_PATHS ) ;
outp . addSize ( 2 ) ; // leave room for count
unsigned int count = 0 ;
while ( ( p ! = dps . end ( ) ) & & ( ( outp . size ( ) + 24 ) < 1200 ) ) {
uint8_t addressType = 4 ;
switch ( p - > ss_family ) {
case AF_INET :
break ;
case AF_INET6 :
addressType = 6 ;
break ;
default : // we currently only push IP addresses
+ + p ;
continue ;
}
outp . append ( ( uint8_t ) 0 ) ; // no flags
outp . append ( ( uint16_t ) 0 ) ; // no extensions
outp . append ( addressType ) ;
outp . append ( ( uint8_t ) ( ( addressType = = 4 ) ? 6 : 18 ) ) ;
outp . append ( p - > rawIpData ( ) , ( ( addressType = = 4 ) ? 4 : 16 ) ) ;
outp . append ( ( uint16_t ) p - > port ( ) ) ;
outp . append ( ( uint8_t ) 0 ) ; // no flags
outp . append ( ( uint16_t ) 0 ) ; // no extensions
outp . append ( addressType ) ;
outp . append ( ( uint8_t ) ( ( addressType = = 4 ) ? 6 : 18 ) ) ;
outp . append ( p - > rawIpData ( ) , ( ( addressType = = 4 ) ? 4 : 16 ) ) ;
outp . append ( ( uint16_t ) p - > port ( ) ) ;
+ + count ;
+ + p ;
}
+ + count ;
+ + p ;
}
if ( count ) {
outp . setAt ( ZT_PACKET_IDX_PAYLOAD , ( uint16_t ) count ) ;
outp . armor ( _key , true ) ;
path - > send ( RR , outp . data ( ) , outp . size ( ) , now ) ;
}
if ( count ) {
outp . setAt ( ZT_PACKET_IDX_PAYLOAD , ( uint16_t ) count ) ;
outp . armor ( _key , true ) ;
RR - > node - > putPacket ( localAddr , toAddress , outp . data ( ) , outp . size ( ) , 0 ) ;
}
}
return true ;
}
bool Peer : : resetWithinScope ( InetAddress : : IpScope scope , uint64_t now )