|
@@ -81,47 +81,49 @@ void Peer::received(
|
|
Packet::Verb inReVerb)
|
|
Packet::Verb inReVerb)
|
|
{
|
|
{
|
|
#ifdef ZT_ENABLE_CLUSTER
|
|
#ifdef ZT_ENABLE_CLUSTER
|
|
- bool redirected = false;
|
|
|
|
- if ((RR->cluster)&&(hops == 0)&&(verb != Packet::VERB_OK)&&(verb != Packet::VERB_ERROR)&&(verb != Packet::VERB_RENDEZVOUS)&&(verb != Packet::VERB_PUSH_DIRECT_PATHS)) {
|
|
|
|
- InetAddress redirectTo(RR->cluster->findBetterEndpoint(_id.address(),remoteAddr,false));
|
|
|
|
- if ((redirectTo.ss_family == AF_INET)||(redirectTo.ss_family == AF_INET6)) {
|
|
|
|
- if (_vProto >= 5) {
|
|
|
|
- // For newer peers we can send a more idiomatic verb: PUSH_DIRECT_PATHS.
|
|
|
|
- Packet outp(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS);
|
|
|
|
- outp.append((uint16_t)1); // count == 1
|
|
|
|
- outp.append((uint8_t)0); // no flags
|
|
|
|
- outp.append((uint16_t)0); // no extensions
|
|
|
|
- if (redirectTo.ss_family == AF_INET) {
|
|
|
|
- outp.append((uint8_t)4);
|
|
|
|
- outp.append((uint8_t)6);
|
|
|
|
- outp.append(redirectTo.rawIpData(),4);
|
|
|
|
- } else {
|
|
|
|
- outp.append((uint8_t)6);
|
|
|
|
- outp.append((uint8_t)18);
|
|
|
|
- outp.append(redirectTo.rawIpData(),16);
|
|
|
|
- }
|
|
|
|
- outp.append((uint16_t)redirectTo.port());
|
|
|
|
- outp.armor(_key,true);
|
|
|
|
- RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
|
|
- RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size());
|
|
|
|
- } else {
|
|
|
|
- // For older peers we use RENDEZVOUS to coax them into contacting us elsewhere.
|
|
|
|
- Packet outp(_id.address(),RR->identity.address(),Packet::VERB_RENDEZVOUS);
|
|
|
|
- outp.append((uint8_t)0); // no flags
|
|
|
|
- RR->identity.address().appendTo(outp);
|
|
|
|
- outp.append((uint16_t)redirectTo.port());
|
|
|
|
- if (redirectTo.ss_family == AF_INET) {
|
|
|
|
- outp.append((uint8_t)4);
|
|
|
|
- outp.append(redirectTo.rawIpData(),4);
|
|
|
|
|
|
+ InetAddress redirectTo;
|
|
|
|
+ if ((RR->cluster)&&(hops == 0)) {
|
|
|
|
+ // Note: findBetterEndpoint() is first since we still want to check
|
|
|
|
+ // for a better endpoint even if we don't actually send a redirect.
|
|
|
|
+ if ( (RR->cluster->findBetterEndpoint(redirectTo,_id.address(),remoteAddr,false)) && (verb != Packet::VERB_OK)&&(verb != Packet::VERB_ERROR)&&(verb != Packet::VERB_RENDEZVOUS)&&(verb != Packet::VERB_PUSH_DIRECT_PATHS) ) {
|
|
|
|
+ if ((redirectTo.ss_family == AF_INET)||(redirectTo.ss_family == AF_INET6)) {
|
|
|
|
+ if (_vProto >= 5) {
|
|
|
|
+ // For newer peers we can send a more idiomatic verb: PUSH_DIRECT_PATHS.
|
|
|
|
+ Packet outp(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS);
|
|
|
|
+ outp.append((uint16_t)1); // count == 1
|
|
|
|
+ outp.append((uint8_t)0); // no flags
|
|
|
|
+ outp.append((uint16_t)0); // no extensions
|
|
|
|
+ if (redirectTo.ss_family == AF_INET) {
|
|
|
|
+ outp.append((uint8_t)4);
|
|
|
|
+ outp.append((uint8_t)6);
|
|
|
|
+ outp.append(redirectTo.rawIpData(),4);
|
|
|
|
+ } else {
|
|
|
|
+ outp.append((uint8_t)6);
|
|
|
|
+ outp.append((uint8_t)18);
|
|
|
|
+ outp.append(redirectTo.rawIpData(),16);
|
|
|
|
+ }
|
|
|
|
+ outp.append((uint16_t)redirectTo.port());
|
|
|
|
+ outp.armor(_key,true);
|
|
|
|
+ RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
|
|
+ RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size());
|
|
} else {
|
|
} else {
|
|
- outp.append((uint8_t)16);
|
|
|
|
- outp.append(redirectTo.rawIpData(),16);
|
|
|
|
|
|
+ // For older peers we use RENDEZVOUS to coax them into contacting us elsewhere.
|
|
|
|
+ Packet outp(_id.address(),RR->identity.address(),Packet::VERB_RENDEZVOUS);
|
|
|
|
+ outp.append((uint8_t)0); // no flags
|
|
|
|
+ RR->identity.address().appendTo(outp);
|
|
|
|
+ outp.append((uint16_t)redirectTo.port());
|
|
|
|
+ if (redirectTo.ss_family == AF_INET) {
|
|
|
|
+ outp.append((uint8_t)4);
|
|
|
|
+ outp.append(redirectTo.rawIpData(),4);
|
|
|
|
+ } else {
|
|
|
|
+ outp.append((uint8_t)16);
|
|
|
|
+ outp.append(redirectTo.rawIpData(),16);
|
|
|
|
+ }
|
|
|
|
+ outp.armor(_key,true);
|
|
|
|
+ RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
|
|
+ RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size());
|
|
}
|
|
}
|
|
- outp.armor(_key,true);
|
|
|
|
- RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
|
|
- RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size());
|
|
|
|
}
|
|
}
|
|
- redirected = true;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
@@ -140,11 +142,13 @@ void Peer::received(
|
|
_lastMulticastFrame = now;
|
|
_lastMulticastFrame = now;
|
|
|
|
|
|
#ifdef ZT_ENABLE_CLUSTER
|
|
#ifdef ZT_ENABLE_CLUSTER
|
|
- // If we're in cluster mode and have sent the peer a better endpoint, stop
|
|
|
|
- // here and don't confirm paths, replicate multicast info, etc. The new
|
|
|
|
- // endpoint should do that.
|
|
|
|
- if (redirected)
|
|
|
|
|
|
+ // If we're in cluster mode and there's a better endpoint, stop here and don't
|
|
|
|
+ // learn or confirm paths. Also reset any existing paths, since they should
|
|
|
|
+ // go there and no longer talk to us here.
|
|
|
|
+ if (redirectTo) {
|
|
|
|
+ _numPaths = 0;
|
|
return;
|
|
return;
|
|
|
|
+ }
|
|
#endif
|
|
#endif
|
|
|
|
|
|
if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
|
|
if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
|