diff options
Diffstat (limited to 'node/Peer.cpp')
-rw-r--r-- | node/Peer.cpp | 115 |
1 files changed, 64 insertions, 51 deletions
diff --git a/node/Peer.cpp b/node/Peer.cpp index 17f9b2ef..87ca94e1 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -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) @@ -373,7 +386,7 @@ bool Peer::validateAndSetNetworkMembershipCertificate(uint64_t nwid,const Certif // Check signature, log and return if cert is invalid if (com.signedBy() != Network::controllerFor(nwid)) { - TRACE("rejected network membership certificate for %.16llx signed by %s: signer not a controller of this network",(unsigned long long)_id,com.signedBy().toString().c_str()); + TRACE("rejected network membership certificate for %.16llx signed by %s: signer not a controller of this network",(unsigned long long)nwid,com.signedBy().toString().c_str()); return false; // invalid signer } @@ -382,7 +395,7 @@ bool Peer::validateAndSetNetworkMembershipCertificate(uint64_t nwid,const Certif // We are the controller: RR->identity.address() == controller() == cert.signedBy() // So, verify that we signed th cert ourself if (!com.verify(RR->identity)) { - TRACE("rejected network membership certificate for %.16llx self signed by %s: signature check failed",(unsigned long long)_id,com.signedBy().toString().c_str()); + TRACE("rejected network membership certificate for %.16llx self signed by %s: signature check failed",(unsigned long long)nwid,com.signedBy().toString().c_str()); return false; // invalid signature } @@ -398,7 +411,7 @@ bool Peer::validateAndSetNetworkMembershipCertificate(uint64_t nwid,const Certif } if (!com.verify(signer->identity())) { - TRACE("rejected network membership certificate for %.16llx signed by %s: signature check failed",(unsigned long long)_id,com.signedBy().toString().c_str()); + TRACE("rejected network membership certificate for %.16llx signed by %s: signature check failed",(unsigned long long)nwid,com.signedBy().toString().c_str()); return false; // invalid signature } } @@ -419,7 +432,7 @@ bool Peer::needsOurNetworkMembershipCertificate(uint64_t nwid,uint64_t now,bool const uint64_t tmp = lastPushed; if (updateLastPushedTime) lastPushed = now; - return ((now - tmp) >= (ZT_NETWORK_AUTOCONF_DELAY / 2)); + return ((now - tmp) >= (ZT_NETWORK_AUTOCONF_DELAY / 3)); } void Peer::clean(uint64_t now) |