From 11ff96ba1ddc07c3414590aa31a35e6353176213 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 30 Sep 2015 15:20:08 -0700 Subject: Consider IPv6 paths reliable (no constant keepalives needed) --- node/Path.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'node/Path.hpp') diff --git a/node/Path.hpp b/node/Path.hpp index 3fa06b58..9d97d2df 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -114,7 +114,7 @@ public: */ inline bool reliable() const throw() { - return ((_ipScope != InetAddress::IP_SCOPE_GLOBAL)&&(_ipScope != InetAddress::IP_SCOPE_PSEUDOPRIVATE)); + return ( (_addr.ss_family == AF_INET6) || ((_ipScope != InetAddress::IP_SCOPE_GLOBAL)&&(_ipScope != InetAddress::IP_SCOPE_PSEUDOPRIVATE)) ); } /** -- cgit v1.2.3 From a3db7d0728c1bc5181b8a70e8c379632125ee376 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 1 Oct 2015 11:11:52 -0700 Subject: Refactor: move network COMs out of Network and into Peer in prep for tightening up multicast lookup and other things. --- node/Constants.hpp | 7 ++ node/IncomingPacket.cpp | 25 ++---- node/Network.cpp | 132 ++---------------------------- node/Network.hpp | 45 +++------- node/Node.hpp | 10 +++ node/OutboundMulticast.cpp | 6 +- node/Path.hpp | 8 -- node/Peer.cpp | 199 +++++++++++++++++++++++++++++++++++++++++---- node/Peer.hpp | 57 ++++++++++++- node/Switch.cpp | 8 +- node/Topology.cpp | 7 +- 11 files changed, 289 insertions(+), 215 deletions(-) (limited to 'node/Path.hpp') diff --git a/node/Constants.hpp b/node/Constants.hpp index 4f783550..27c43aa7 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -324,6 +324,13 @@ */ #define ZT_DIRECT_PATH_PUSH_INTERVAL 300000 +/** + * How long (max) to remember network certificates of membership? + * + * This only applies to networks we don't belong to. + */ +#define ZT_PEER_NETWORK_COM_EXPIRATION 3600000 + /** * Sanity limit on maximum bridge routes * diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 3866abf1..e892edc2 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -421,9 +421,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p // OK(MULTICAST_FRAME) includes certificate of membership update CertificateOfMembership com; offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS); - SharedPtr network(RR->node->network(nwid)); - if ((network)&&(com.hasRequiredFields())) - network->validateAndAddMembershipCertificate(com); + peer->validateAndSetNetworkMembershipCertificate(RR,nwid,com); } if ((flags & 0x02) != 0) { @@ -511,7 +509,7 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,const SharedPtr const SharedPtr network(RR->node->network(at(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID))); if (network) { if (size() > ZT_PROTO_VERB_FRAME_IDX_PAYLOAD) { - if (!network->isAllowed(peer->address())) { + if (!network->isAllowed(peer)) { TRACE("dropped FRAME from %s(%s): not a member of private network %.16llx",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),(unsigned long long)network->id()); _sendErrorNeedCertificate(RR,peer,network->id()); return true; @@ -552,13 +550,11 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr

validateAndAddMembershipCertificate(com)) - comFailed = true; // technically this check is redundant to isAllowed(), but do it anyway for thoroughness - } + if (!peer->validateAndSetNetworkMembershipCertificate(RR,network->id(),com)) + comFailed = true; } - if ((comFailed)||(!network->isAllowed(peer->address()))) { + if ((comFailed)||(!network->isAllowed(peer))) { TRACE("dropped EXT_FRAME from %s(%s): not a member of private network %.16llx",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),network->id()); _sendErrorNeedCertificate(RR,peer,network->id()); return true; @@ -642,11 +638,7 @@ bool IncomingPacket::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment unsigned int ptr = ZT_PACKET_IDX_PAYLOAD; while (ptr < size()) { ptr += com.deserialize(*this,ptr); - if (com.hasRequiredFields()) { - SharedPtr network(RR->node->network(com.networkId())); - if (network) - network->validateAndAddMembershipCertificate(com); - } + peer->validateAndSetNetworkMembershipCertificate(RR,com.networkId(),com); } peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP); @@ -809,13 +801,12 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share if ((flags & 0x01) != 0) { CertificateOfMembership com; offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM); - if (com.hasRequiredFields()) - network->validateAndAddMembershipCertificate(com); + peer->validateAndSetNetworkMembershipCertificate(RR,nwid,com); } // Check membership after we've read any included COM, since // that cert might be what we needed. - if (!network->isAllowed(peer->address())) { + if (!network->isAllowed(peer)) { TRACE("dropped MULTICAST_FRAME from %s(%s): not a member of private network %.16llx",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),(unsigned long long)network->id()); _sendErrorNeedCertificate(RR,peer,network->id()); return true; diff --git a/node/Network.cpp b/node/Network.cpp index 2b24d5f9..9c8aabfa 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -59,6 +59,9 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : Utils::snprintf(confn,sizeof(confn),"networks.d/%.16llx.conf",_id); Utils::snprintf(mcdbn,sizeof(mcdbn),"networks.d/%.16llx.mcerts",_id); + // These files are no longer used, so clean them. + RR->node->dataStoreDelete(mcdbn); + if (_id == ZT_TEST_NETWORK_ID) { applyConfiguration(NetworkConfig::createTestNetworkConfig(RR->identity.address())); @@ -79,24 +82,6 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : // Save a one-byte CR to persist membership while we request a real netconf RR->node->dataStorePut(confn,"\n",1,false); } - - try { - std::string mcdb(RR->node->dataStoreGet(mcdbn)); - if (mcdb.length() > 6) { - const char *p = mcdb.data(); - const char *e = p + mcdb.length(); - if (!memcmp("ZTMCD0",p,6)) { - p += 6; - while (p != e) { - CertificateOfMembership com; - com.deserialize2(p,e); - if (!com) - break; - _certInfo[com.issuedTo()].com = com; - } - } - } - } catch ( ... ) {} // ignore invalid MCDB, we'll re-learn from peers } if (!_portInitialized) { @@ -115,32 +100,10 @@ Network::~Network() char n[128]; if (_destroyed) { RR->node->configureVirtualNetworkPort(_id,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); - Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id); RR->node->dataStoreDelete(n); - Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.mcerts",_id); - RR->node->dataStoreDelete(n); } else { RR->node->configureVirtualNetworkPort(_id,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp); - - clean(); - - Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.mcerts",_id); - - Mutex::Lock _l(_lock); - if ((!_config)||(_config->isPublic())||(_certInfo.empty())) { - RR->node->dataStoreDelete(n); - } else { - std::string buf("ZTMCD0"); - Hashtable< Address,_RemoteMemberCertificateInfo >::Iterator i(_certInfo); - Address *a = (Address *)0; - _RemoteMemberCertificateInfo *ci = (_RemoteMemberCertificateInfo *)0; - while (i.next(a,ci)) { - if (ci->com) - ci->com.serialize2(buf); - } - RR->node->dataStorePut(n,buf,true); - } } } @@ -281,70 +244,6 @@ void Network::requestConfiguration() RR->sw->send(outp,true,0); } -bool Network::validateAndAddMembershipCertificate(const CertificateOfMembership &cert) -{ - if (!cert) // sanity check - return false; - - Mutex::Lock _l(_lock); - - { - const _RemoteMemberCertificateInfo *ci = _certInfo.get(cert.issuedTo()); - if ((ci)&&(ci->com == cert)) - return true; // we already have it - } - - // Check signature, log and return if cert is invalid - if (cert.signedBy() != controller()) { - TRACE("rejected network membership certificate for %.16llx signed by %s: signer not a controller of this network",(unsigned long long)_id,cert.signedBy().toString().c_str()); - return false; // invalid signer - } - - if (cert.signedBy() == RR->identity.address()) { - - // We are the controller: RR->identity.address() == controller() == cert.signedBy() - // So, verify that we signed th cert ourself - if (!cert.verify(RR->identity)) { - TRACE("rejected network membership certificate for %.16llx self signed by %s: signature check failed",(unsigned long long)_id,cert.signedBy().toString().c_str()); - return false; // invalid signature - } - - } else { - - SharedPtr signer(RR->topology->getPeer(cert.signedBy())); - - if (!signer) { - // This would be rather odd, since this is our controller... could happen - // if we get packets before we've gotten config. - RR->sw->requestWhois(cert.signedBy()); - return false; // signer unknown - } - - if (!cert.verify(signer->identity())) { - TRACE("rejected network membership certificate for %.16llx signed by %s: signature check failed",(unsigned long long)_id,cert.signedBy().toString().c_str()); - return false; // invalid signature - } - } - - // If we made it past authentication, add or update cert in our cert info store - _certInfo[cert.issuedTo()].com = cert; - - return true; -} - -bool Network::peerNeedsOurMembershipCertificate(const Address &to,uint64_t now) -{ - Mutex::Lock _l(_lock); - if ((_config)&&(!_config->isPublic())&&(_config->com())) { - _RemoteMemberCertificateInfo &ci = _certInfo[to]; - if ((now - ci.lastPushed) > (ZT_NETWORK_AUTOCONF_DELAY / 2)) { - ci.lastPushed = now; - return true; - } - } - return false; -} - void Network::clean() { const uint64_t now = RR->node->now(); @@ -353,22 +252,6 @@ void Network::clean() if (_destroyed) return; - if ((_config)&&(_config->isPublic())) { - // Open (public) networks do not track certs or cert pushes at all. - _certInfo.clear(); - } else if (_config) { - // Clean obsolete entries from private network cert info table - Hashtable< Address,_RemoteMemberCertificateInfo >::Iterator i(_certInfo); - Address *a = (Address *)0; - _RemoteMemberCertificateInfo *ci = (_RemoteMemberCertificateInfo *)0; - const uint64_t forgetIfBefore = now - (ZT_PEER_ACTIVITY_TIMEOUT * 16); // arbitrary reasonable cutoff - while (i.next(a,ci)) { - if ((ci->lastPushed < forgetIfBefore)&&(!ci->com.agreesWith(_config->com()))) - _certInfo.erase(*a); - } - } - - // Clean learned multicast groups if we haven't heard from them in a while { Hashtable< MulticastGroup,uint64_t >::Iterator i(_multicastGroupsBehindMe); MulticastGroup *mg = (MulticastGroup *)0; @@ -494,7 +377,7 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const } else ec->assignedAddressCount = 0; } -bool Network::_isAllowed(const Address &peer) const +bool Network::_isAllowed(const SharedPtr &peer) const { // Assumes _lock is locked try { @@ -502,10 +385,7 @@ bool Network::_isAllowed(const Address &peer) const return false; if (_config->isPublic()) return true; - const _RemoteMemberCertificateInfo *ci = _certInfo.get(peer); - if (!ci) - return false; - return _config->com().agreesWith(ci->com); + return ((_config->com())&&(peer->networkMembershipCertificatesAgree(_id,_config->com()))); } catch (std::exception &exc) { TRACE("isAllowed() check failed for peer %s: unexpected exception: %s",peer.toString().c_str(),exc.what()); } catch ( ... ) { @@ -542,7 +422,7 @@ public: inline void operator()(Topology &t,const SharedPtr &p) { - if ( ( (p->hasActiveDirectPath(_now)) && ( (_network->_isAllowed(p->address())) || (p->address() == _network->controller()) ) ) || (std::find(_rootAddresses.begin(),_rootAddresses.end(),p->address()) != _rootAddresses.end()) ) { + if ( ( (p->hasActiveDirectPath(_now)) && ( (_network->_isAllowed(p)) || (p->address() == _network->controller()) ) ) || (std::find(_rootAddresses.begin(),_rootAddresses.end(),p->address()) != _rootAddresses.end()) ) { Packet outp(p->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); for(std::vector::iterator mg(_allMulticastGroups.begin());mg!=_allMulticastGroups.end();++mg) { diff --git a/node/Network.hpp b/node/Network.hpp index ad9f18de..37077650 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -56,6 +56,7 @@ namespace ZeroTier { class RuntimeEnvironment; class _AnnounceMulticastGroupsToPeersWithActiveDirectPaths; +class Peer; /** * A virtual LAN @@ -94,6 +95,12 @@ public: */ inline Address controller() throw() { return Address(_id >> 24); } + /** + * @param nwid Network ID + * @return Address of network's controller + */ + static inline Address controllerFor(uint64_t nwid) throw() { return Address(nwid >> 24); } + /** * @return Multicast group memberships for this network's port (local, not learned via bridging) */ @@ -177,33 +184,10 @@ public: void requestConfiguration(); /** - * Add or update a membership certificate - * - * @param cert Certificate of membership - * @return True if certificate was accepted as valid - */ - bool validateAndAddMembershipCertificate(const CertificateOfMembership &cert); - - /** - * Check if we should push membership certificate to a peer, AND update last pushed - * - * If we haven't pushed a cert to this peer in a long enough time, this returns - * true and updates the last pushed time. Otherwise it returns false. - * - * This doesn't actually send anything, since COMs can hitch a ride with several - * different kinds of packets. - * - * @param to Destination peer - * @param now Current time - * @return True if we should include a COM with whatever we're currently sending - */ - bool peerNeedsOurMembershipCertificate(const Address &to,uint64_t now); - - /** - * @param peer Peer address to check + * @param peer Peer to check * @return True if peer is allowed to communicate on this network */ - inline bool isAllowed(const Address &peer) const + inline bool isAllowed(const SharedPtr &peer) const { Mutex::Lock _l(_lock); return _isAllowed(peer); @@ -347,16 +331,9 @@ public: inline bool operator>=(const Network &n) const throw() { return (_id >= n._id); } private: - struct _RemoteMemberCertificateInfo - { - _RemoteMemberCertificateInfo() : com(),lastPushed(0) {} - CertificateOfMembership com; // remote member's COM - uint64_t lastPushed; // when did we last push ours to them? - }; - ZT_VirtualNetworkStatus _status() const; void _externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked - bool _isAllowed(const Address &peer) const; + bool _isAllowed(const SharedPtr &peer) const; void _announceMulticastGroups(); std::vector _allMulticastGroups() const; @@ -370,8 +347,6 @@ private: Hashtable< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups that seem to be behind us and when we last saw them (if we are a bridge) Hashtable< MAC,Address > _remoteBridgeRoutes; // remote addresses where given MACs are reachable (for tracking devices behind remote bridges) - Hashtable< Address,_RemoteMemberCertificateInfo > _certInfo; - SharedPtr _config; // Most recent network configuration, which is an immutable value-object volatile uint64_t _lastConfigUpdate; diff --git a/node/Node.hpp b/node/Node.hpp index b81c1943..0f659f47 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -168,6 +168,16 @@ public: return _network(nwid); } + inline bool belongsToNetwork(uint64_t nwid) const + { + Mutex::Lock _l(_networks_m); + for(std::vector< std::pair< uint64_t, SharedPtr > >::const_iterator i=_networks.begin();i!=_networks.end();++i) { + if (i->first == nwid) + return true; + } + return false; + } + inline std::vector< SharedPtr > allNetworks() const { std::vector< SharedPtr > nw; diff --git a/node/OutboundMulticast.cpp b/node/OutboundMulticast.cpp index 46116c07..c26372cb 100644 --- a/node/OutboundMulticast.cpp +++ b/node/OutboundMulticast.cpp @@ -103,11 +103,11 @@ void OutboundMulticast::init( void OutboundMulticast::sendOnly(const RuntimeEnvironment *RR,const Address &toAddr) { if (_haveCom) { - SharedPtr network(RR->node->network(_nwid)); - if ((network)&&(network->peerNeedsOurMembershipCertificate(toAddr,RR->node->now()))) { + SharedPtr peer(RR->topology->getPeer(toAddr)); + if ( (!peer) || (peer->needsOurNetworkMembershipCertificate(_nwid,RR->node->now(),true)) ) { + //TRACE(">>MC %.16llx -> %s (with COM)",(unsigned long long)this,toAddr.toString().c_str()); _packetWithCom.newInitializationVector(); _packetWithCom.setDestination(toAddr); - //TRACE(">>MC %.16llx -> %s (with COM)",(unsigned long long)this,toAddr.toString().c_str()); RR->sw->send(_packetWithCom,true,_nwid); return; } diff --git a/node/Path.hpp b/node/Path.hpp index 9d97d2df..8d662ff7 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -122,14 +122,6 @@ public: */ inline operator bool() const throw() { return (_addr); } - // Comparisons are by address only - inline bool operator==(const Path &p) const throw() { return (_addr == p._addr); } - inline bool operator!=(const Path &p) const throw() { return (_addr != p._addr); } - inline bool operator<(const Path &p) const throw() { return (_addr < p._addr); } - inline bool operator>(const Path &p) const throw() { return (_addr > p._addr); } - inline bool operator<=(const Path &p) const throw() { return (_addr <= p._addr); } - inline bool operator>=(const Path &p) const throw() { return (_addr >= p._addr); } - /** * Check whether this address is valid for a ZeroTier path * diff --git a/node/Peer.cpp b/node/Peer.cpp index 48b77c85..6203d0b4 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -37,6 +37,8 @@ #include +#define ZT_PEER_PATH_SORT_INTERVAL 5000 + namespace ZeroTier { // Used to send varying values for NAT keepalive @@ -51,17 +53,38 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) _lastAnnouncedTo(0), _lastPathConfirmationSent(0), _lastDirectPathPush(0), + _lastPathSort(0), _vMajor(0), _vMinor(0), _vRevision(0), _id(peerIdentity), _numPaths(0), - _latency(0) + _latency(0), + _networkComs(4), + _lastPushedComs(4) { if (!myIdentity.agree(peerIdentity,_key,ZT_PEER_SECRET_KEY_LENGTH)) throw std::runtime_error("new peer identity key agreement failed"); } +struct _SortPathsByQuality +{ + uint64_t _now; + _SortPathsByQuality(const uint64_t now) : _now(now) {} + inline bool operator()(const RemotePath &a,const RemotePath &b) const + { + const uint64_t qa = ( + ((uint64_t)a.active(_now) << 63) | + (((uint64_t)(a.preferenceRank() & 0xfff)) << 51) | + ((uint64_t)a.lastReceived() & 0x7ffffffffffffULL) ); + const uint64_t qb = ( + ((uint64_t)b.active(_now) << 63) | + (((uint64_t)(b.preferenceRank() & 0xfff)) << 51) | + ((uint64_t)b.lastReceived() & 0x7ffffffffffffULL) ); + return (qb < qa); // invert sense to sort in descending order + } +}; + void Peer::received( const RuntimeEnvironment *RR, const InetAddress &localAddr, @@ -73,6 +96,8 @@ void Peer::received( Packet::Verb inReVerb) { const uint64_t now = RR->node->now(); + Mutex::Lock _l(_lock); + _lastReceive = now; if (!hops) { @@ -91,6 +116,7 @@ void Peer::received( if (!pathIsConfirmed) { if ((verb == Packet::VERB_OK)&&(inReVerb == Packet::VERB_HELLO)) { + // Learn paths if they've been confirmed via a HELLO RemotePath *slot = (RemotePath *)0; if (np < ZT_MAX_PEER_NETWORK_PATHS) { @@ -111,8 +137,11 @@ void Peer::received( slot->received(now); _numPaths = np; pathIsConfirmed = true; + _sortPaths(now); } + } else { + /* If this path is not known, send a HELLO. We don't learn * paths without confirming that a bidirectional link is in * fact present, but any packet that decodes and authenticates @@ -122,6 +151,7 @@ void Peer::received( TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str()); attemptToContactAt(RR,localAddr,remoteAddr,now); } + } } } @@ -129,6 +159,7 @@ void Peer::received( /* Announce multicast groups of interest to direct peers if they are * considered authorized members of a given network. Also announce to * root servers and network controllers. */ + /* if ((pathIsConfirmed)&&((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000))) { _lastAnnouncedTo = now; @@ -158,6 +189,7 @@ void Peer::received( RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size()); } } + */ } if ((verb == Packet::VERB_FRAME)||(verb == Packet::VERB_EXT_FRAME)) @@ -166,23 +198,10 @@ void Peer::received( _lastMulticastFrame = now; } -RemotePath *Peer::getBestPath(uint64_t now) -{ - RemotePath *bestPath = (RemotePath *)0; - uint64_t lrMax = 0; - int rank = 0; - for(unsigned int p=0,np=_numPaths;p= lrMax)||(_paths[p].preferenceRank() >= rank)) ) { - lrMax = _paths[p].lastReceived(); - rank = _paths[p].preferenceRank(); - bestPath = &(_paths[p]); - } - } - return bestPath; -} - void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now) { + // _lock not required here since _id is immutable and nothing else is accessed + Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO); outp.append((unsigned char)ZT_PROTO_VERSION); outp.append((unsigned char)ZEROTIER_ONE_VERSION_MAJOR); @@ -214,7 +233,8 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &lo void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) { - RemotePath *const bestPath = getBestPath(now); + Mutex::Lock _l(_lock); + RemotePath *const bestPath = _getBestPath(now); if (bestPath) { if ((now - bestPath->lastReceived()) >= ZT_PEER_DIRECT_PING_DELAY) { TRACE("PING %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); @@ -231,6 +251,8 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_t now,bool force) { + Mutex::Lock _l(_lock); + if (((now - _lastDirectPathPush) >= ZT_DIRECT_PATH_PUSH_INTERVAL)||(force)) { _lastDirectPathPush = now; @@ -299,13 +321,16 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ } } -void Peer::addPath(const RemotePath &newp) +void Peer::addPath(const RemotePath &newp,uint64_t now) { + Mutex::Lock _l(_lock); + unsigned int np = _numPaths; for(unsigned int p=0;pcom.agreesWith(com); + return false; +} + +bool Peer::validateAndSetNetworkMembershipCertificate(const RuntimeEnvironment *RR,uint64_t nwid,const CertificateOfMembership &com) +{ + // Sanity checks + if ((!com)||(com.issuedTo() != _id.address())) + return false; + + // Return true if we already have this *exact* COM + { + Mutex::Lock _l(_lock); + _NetworkCom *ourCom = _networkComs.get(nwid); + if ((ourCom)&&(ourCom->com == com)) + return true; + } + + // 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,cert.signedBy().toString().c_str()); + return false; // invalid signer + } + + if (com.signedBy() == RR->identity.address()) { + + // 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,cert.signedBy().toString().c_str()); + return false; // invalid signature + } + + } else { + + SharedPtr signer(RR->topology->getPeer(com.signedBy())); + + if (!signer) { + // This would be rather odd, since this is our controller... could happen + // if we get packets before we've gotten config. + RR->sw->requestWhois(com.signedBy()); + return false; // signer unknown + } + + if (!com.verify(signer->identity())) { + TRACE("rejected network membership certificate for %.16llx signed by %s: signature check failed",(unsigned long long)_id,cert.signedBy().toString().c_str()); + return false; // invalid signature + } + } + + // If we made it past all those checks, add or update cert in our cert info store + { + Mutex::Lock _l(_lock); + _networkComs.set(nwid,_NetworkCom(RR->node->now(),com)); + } + + return true; +} + +bool Peer::needsOurNetworkMembershipCertificate(uint64_t nwid,uint64_t now,bool updateLastPushedTime) +{ + Mutex::Lock _l(_lock); + uint64_t &lastPushed = _lastPushedComs[nwid]; + const uint64_t tmp = lastPushed; + if (updateLastPushedTime) + lastPushed = now; + return ((now - tmp) < (ZT_NETWORK_AUTOCONF_DELAY / 2)); +} + +void Peer::clean(const RuntimeEnvironment *RR,uint64_t now) +{ + Mutex::Lock _l(_lock); + + { + unsigned int np = _numPaths; + unsigned int x = 0; + unsigned int y = 0; + while (x < np) { + if (_paths[x].active(now)) + _paths[y++] = _paths[x]; + ++x; + } + _numPaths = y; + } + + { + uint64_t *k = (uint64_t *)0; + _NetworkCom *v = (_NetworkCom *)0; + Hashtable< uint64_t,_NetworkCom >::Iterator i(_networkComs); + while (i.next(k,v)) { + if ( (!RR->node->belongsToNetwork(*k)) && ((now - v->ts) >= ZT_PEER_NETWORK_COM_EXPIRATION) ) + _networkComs.erase(*k); + } + } + + { + uint64_t *k = (uint64_t *)0; + uint64_t *v = (uint64_t *)0; + Hashtable< uint64_t,uint64_t >::Iterator i(_lastPushedComs); + while (i.next(k,v)) { + if ((now - *v) > (ZT_NETWORK_AUTOCONF_DELAY * 2)) + _lastPushedComs.erase(*k); + } + } +} + +void Peer::_sortPaths(const uint64_t now) +{ + // assumes _lock is locked + _lastPathSort = now; + std::sort(&(_paths[0]),&(_paths[_numPaths]),_SortPathsByQuality(now)); +} + +RemotePath *Peer::_getBestPath(const uint64_t now) +{ + // assumes _lock is locked + if ((now - _lastPathSort) >= ZT_PEER_PATH_SORT_INTERVAL) + _sortPaths(now); + if (_paths[0].active(now)) { + return &(_paths[0]); + } else { + _sortPaths(now); + if (_paths[0].active(now)) + return &(_paths[0]); + } + return (RemotePath *)0; +} + } // namespace ZeroTier diff --git a/node/Peer.hpp b/node/Peer.hpp index 4d1031b8..c1692846 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -49,6 +49,8 @@ #include "Packet.hpp" #include "SharedPtr.hpp" #include "AtomicCounter.hpp" +#include "Hashtable.hpp" +#include "Mutex.hpp" #include "NonCopyable.hpp" namespace ZeroTier { @@ -129,7 +131,11 @@ public: * @param now Current time * @return Best path or NULL if there are no active (or fixed) direct paths */ - RemotePath *getBestPath(uint64_t now); + inline RemotePath *getBestPath(uint64_t now) + { + Mutex::Lock _l(_lock); + return _getBestPath(now); + } /** * Send via best path @@ -293,8 +299,9 @@ public: * Add a path (if we don't already have it) * * @param p New path to add + * @param now Current time */ - void addPath(const RemotePath &newp); + void addPath(const RemotePath &newp,uint64_t now); /** * Clear paths @@ -381,6 +388,37 @@ public: */ void getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const; + /** + * Check network COM agreement with this peer + * + * @param nwid Network ID + * @param com Another certificate of membership + * @return True if supplied COM agrees with ours, false if not or if we don't have one + */ + bool networkMembershipCertificatesAgree(uint64_t nwid,const CertificateOfMembership &com) const; + + /** + * Check the validity of the COM and add/update if valid and new + * + * @param RR Runtime Environment + * @param nwid Network ID + * @param com Externally supplied COM + */ + bool validateAndSetNetworkMembershipCertificate(const RuntimeEnvironment *RR,uint64_t nwid,const CertificateOfMembership &com); + + /** + * @param nwid Network ID + * @param now Current time + * @param updateLastPushedTime If true, go ahead and update the last pushed time regardless of return value + * @return Whether or not this peer needs another COM push from us + */ + bool needsOurNetworkMembershipCertificate(uint64_t nwid,uint64_t now,bool updateLastPushedTime); + + /** + * Perform periodic cleaning operations + */ + void clean(const RuntimeEnvironment *RR,uint64_t now); + /** * Find a common set of addresses by which two peers can link, if any * @@ -402,7 +440,8 @@ public: } private: - void _announceMulticastGroups(const RuntimeEnvironment *RR,uint64_t now); + void _sortPaths(const uint64_t now); + RemotePath *_getBestPath(const uint64_t now); unsigned char _key[ZT_PEER_SECRET_KEY_LENGTH]; uint64_t _lastUsed; @@ -412,6 +451,7 @@ private: uint64_t _lastAnnouncedTo; uint64_t _lastPathConfirmationSent; uint64_t _lastDirectPathPush; + uint64_t _lastPathSort; uint16_t _vProto; uint16_t _vMajor; uint16_t _vMinor; @@ -421,6 +461,17 @@ private: unsigned int _numPaths; unsigned int _latency; + struct _NetworkCom + { + _NetworkCom() {} + _NetworkCom(uint64_t t,const CertificateOfMembership &c) : ts(t),com(c) {} + uint64_t ts; + CertificateOfMembership com; + }; + Hashtable _networkComs; + Hashtable _lastPushedComs; + + Mutex _lock; AtomicCounter __refCount; }; diff --git a/node/Switch.cpp b/node/Switch.cpp index ecae9b76..9ea8ac49 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -202,7 +202,8 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c // Destination is another ZeroTier peer on the same network Address toZT(to.toAddress(network->id())); // since in-network MACs are derived from addresses and network IDs, we can reverse this - const bool includeCom = network->peerNeedsOurMembershipCertificate(toZT,RR->node->now()); + SharedPtr toPeer(RR->topology->getPeer(toZT)); + const bool includeCom = ((!toPeer)||(toPeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true)));; if ((fromBridged)||(includeCom)) { Packet outp(toZT,RR->identity.address(),Packet::VERB_EXT_FRAME); outp.append(network->id()); @@ -267,9 +268,10 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c } for(unsigned int b=0;b bridgePeer(RR->topology->getPeer(bridges[b])); Packet outp(bridges[b],RR->identity.address(),Packet::VERB_EXT_FRAME); outp.append(network->id()); - if (network->peerNeedsOurMembershipCertificate(bridges[b],RR->node->now())) { + if ((!bridgePeer)||(bridgePeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true))) { outp.append((unsigned char)0x01); // 0x01 -- COM included nconf->com().serialize(outp); } else { @@ -747,7 +749,7 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) return false; // no paths, no root servers? } - if ((network)&&(relay)&&(network->isAllowed(peer->address()))) { + if ((network)&&(relay)&&(network->isAllowed(peer))) { // Push hints for direct connectivity to this peer if we are relaying peer->pushDirectPaths(RR,viaPath,now,false); } diff --git a/node/Topology.cpp b/node/Topology.cpp index e931df1e..b2b4ebbd 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -62,7 +62,7 @@ void Topology::setRootServers(const std::map< Identity,std::vector if (!p) p = SharedPtr(new Peer(RR->identity,i->first)); for(std::vector::const_iterator j(i->second.begin());j!=i->second.end();++j) - p->addPath(RemotePath(InetAddress(),*j,true)); + p->addPath(RemotePath(InetAddress(),*j,true),now); p->use(now); _rootPeers.push_back(p); } @@ -252,9 +252,12 @@ void Topology::clean(uint64_t now) Hashtable< Address,SharedPtr >::Iterator i(_activePeers); Address *a = (Address *)0; SharedPtr *p = (SharedPtr *)0; - while (i.next(a,p)) + while (i.next(a,p)) { if (((now - (*p)->lastUsed()) >= ZT_PEER_IN_MEMORY_EXPIRATION)&&(std::find(_rootAddresses.begin(),_rootAddresses.end(),*a) == _rootAddresses.end())) { _activePeers.erase(*a); + } else { + (*p)->clean(RR,now); + } } } -- cgit v1.2.3 From 5076c49210542243075556aa1ab74f33d4d50ba3 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 1 Oct 2015 15:40:54 -0700 Subject: Peer serialization and related changes. --- include/ZeroTierOne.h | 4 +- node/CertificateOfMembership.hpp | 72 ----------------------- node/Identity.hpp | 2 - node/InetAddress.hpp | 46 +++++++++++++++ node/Path.hpp | 8 +-- node/Peer.hpp | 121 +++++++++++++++++++++++++++++++++++++++ node/RemotePath.hpp | 46 ++++++++++++--- service/OneService.cpp | 5 +- 8 files changed, 214 insertions(+), 90 deletions(-) (limited to 'node/Path.hpp') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index e8a19e33..8eacc993 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -627,8 +627,8 @@ typedef struct */ typedef enum { ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL = 0, - ZT_LOCAL_INTERFACE_ADDRESS_TRUST_PRIVACY = 1, - ZT_LOCAL_INTERFACE_ADDRESS_TRUST_ULTIMATE = 2 + ZT_LOCAL_INTERFACE_ADDRESS_TRUST_PRIVACY = 10, + ZT_LOCAL_INTERFACE_ADDRESS_TRUST_ULTIMATE = 20 } ZT_LocalInterfaceAddressTrust; /** diff --git a/node/CertificateOfMembership.hpp b/node/CertificateOfMembership.hpp index 9a03374d..81e00fbb 100644 --- a/node/CertificateOfMembership.hpp +++ b/node/CertificateOfMembership.hpp @@ -315,78 +315,6 @@ public: */ inline const Address &signedBy() const throw() { return _signedBy; } - /** - * Serialize to std::string or compatible class - * - * @param b String or other class supporting push_back() and append() like std::string - */ - template - inline void serialize2(T &b) const - { - uint64_t tmp[3]; - char tmp2[ZT_ADDRESS_LENGTH]; - b.push_back((char)COM_UINT64_ED25519); - b.push_back((char)((_qualifiers.size() >> 8) & 0xff)); - b.push_back((char)(_qualifiers.size() & 0xff)); - for(std::vector<_Qualifier>::const_iterator q(_qualifiers.begin());q!=_qualifiers.end();++q) { - tmp[0] = Utils::hton(q->id); - tmp[1] = Utils::hton(q->value); - tmp[2] = Utils::hton(q->maxDelta); - b.append(reinterpret_cast(reinterpret_cast(tmp)),sizeof(tmp)); - } - _signedBy.copyTo(tmp2,ZT_ADDRESS_LENGTH); - b.append(tmp2,ZT_ADDRESS_LENGTH); - if (_signedBy) - b.append((const char *)_signature.data,_signature.size()); - } - - /** - * Deserialize from std::string::iterator or compatible iterator or char* pointer - * - * @param p Iterator - * @param end End of buffer - */ - template - inline void deserialize2(T &p,const T &end) - { - uint64_t tmp[3]; - char tmp2[ZT_ADDRESS_LENGTH]; - unsigned int qcount; - - _qualifiers.clear(); - _signedBy.zero(); - - if (p == end) throw std::out_of_range("incomplete certificate of membership"); - if (*(p++) != (char)COM_UINT64_ED25519) throw std::invalid_argument("unknown certificate of membership type"); - - if (p == end) throw std::out_of_range("incomplete certificate of membership"); - qcount = (unsigned int)*(p++) << 8; - if (p == end) throw std::out_of_range("incomplete certificate of membership"); - qcount |= (unsigned int)*(p++); - - for(unsigned int i=0;i(reinterpret_cast(tmp)); - for(unsigned int j=0;j inline void serialize(Buffer &b) const { diff --git a/node/Identity.hpp b/node/Identity.hpp index cc72632e..18e67eb6 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -220,7 +220,6 @@ public: */ template inline void serialize(Buffer &b,bool includePrivate = false) const - throw(std::out_of_range) { _address.appendTo(b); b.append((unsigned char)IDENTITY_TYPE_C25519); @@ -245,7 +244,6 @@ public: */ template inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) - throw(std::out_of_range,std::invalid_argument) { delete _privateKey; _privateKey = (C25519::Private *)0; diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index 3c05d83b..c376a032 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -38,6 +38,7 @@ #include "../include/ZeroTierOne.h" #include "Utils.hpp" #include "MAC.hpp" +#include "Buffer.hpp" namespace ZeroTier { @@ -362,6 +363,51 @@ struct InetAddress : public sockaddr_storage */ inline operator bool() const throw() { return (ss_family != 0); } + template + inline void serialize(Buffer &b) const + { + // Format is the same as in VERB_HELLO in Packet.hpp + switch(ss_family) { + case AF_INET: + b.append((uint8_t)0x04); + b.append(&(reinterpret_cast(this)->sin_addr.s_addr),4); + b.append((uint16_t)port()); // just in case sin_port != uint16_t + return; + case AF_INET6: + b.append((uint8_t)0x06); + b.append(reinterpret_cast(this)->sin6_addr.s6_addr,16); + b.append((uint16_t)port()); // just in case sin_port != uint16_t + return; + default: + b.append((uint8_t)0); + return; + } + } + + template + inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + { + unsigned int p = startAt; + memset(this,0,sizeof(InetAddress)); + switch(b[p++]) { + case 0: + return 1; + case 0x04: + ss_family = AF_INET; + memcpy(&(reinterpret_cast(this)->sin_addr.s_addr),b.field(p,4),4); p += 4; + reinterpret_cast(this)->sin_port = Utils::hton(b.template at(p)); p += 2; + break; + case 0x06: + ss_family = AF_INET6; + memcpy(reinterpret_cast(this)->sin6_addr.s6_addr,b.field(p,16),16); p += 16; + reinterpret_cast(this)->sin_port = Utils::hton(b.template at(p)); p += 2; + break; + default: + throw std::invalid_argument("invalid serialized InetAddress"); + } + return (p - startAt); + } + bool operator==(const InetAddress &a) const throw(); bool operator<(const InetAddress &a) const throw(); inline bool operator!=(const InetAddress &a) const throw() { return !(*this == a); } diff --git a/node/Path.hpp b/node/Path.hpp index 8d662ff7..6a69e071 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -59,11 +59,11 @@ public: * * These values MUST match ZT_LocalInterfaceAddressTrust in ZeroTierOne.h */ - enum Trust + enum Trust // NOTE: max 255 { TRUST_NORMAL = 0, - TRUST_PRIVACY = 1, - TRUST_ULTIMATE = 2 + TRUST_PRIVACY = 10, + TRUST_ULTIMATE = 20 }; Path() : @@ -155,7 +155,7 @@ public: return false; } -private: +protected: InetAddress _addr; InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often Trust _trust; diff --git a/node/Peer.hpp b/node/Peer.hpp index 568de0d5..482c0a82 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -445,6 +445,127 @@ public: else return std::pair(); } + template + inline void serialize(Buffer &b) const + { + Mutex::Lock _l(_lock); + + const unsigned int lengthAt = b.size(); + b.addSize(4); // space for uint32_t field length + + b.append((uint32_t)1); // version of serialized Peer data + + _id.serialize(b,false); + + b.append((uint64_t)_lastUsed); + b.append((uint64_t)_lastReceive); + b.append((uint64_t)_lastUnicastFrame); + b.append((uint64_t)_lastMulticastFrame); + b.append((uint64_t)_lastAnnouncedTo); + b.append((uint64_t)_lastPathConfirmationSent); + b.append((uint64_t)_lastDirectPathPush); + b.append((uint64_t)_lastPathSort); + b.append((uint16_t)_vProto); + b.append((uint16_t)_vMajor); + b.append((uint16_t)_vMinor); + b.append((uint16_t)_vRevision); + b.append((uint32_t)_latency); + + b.append((uint32_t)_numPaths); + for(unsigned int i=0;i<_numPaths;++i) + _paths[i].serialize(b); + + b.append((uint32_t)_networkComs.size()); + { + uint64_t *k = (uint64_t *)0; + _NetworkCom *v = (_NetworkCom *)0; + Hashtable::Iterator i(const_cast(this)->_networkComs); + while (i.next(k,v)) { + b.append((uint64_t)*k); + b.append((uint64_t)v->ts); + v->com.serialize(b); + } + } + + b.append((uint32_t)_lastPushedComs.size()); + { + uint64_t *k = (uint64_t *)0; + uint64_t *v = (uint64_t *)0; + Hashtable::Iterator i(const_cast(this)->_lastPushedComs); + while (i.next(k,v)) { + b.append((uint64_t)*k); + b.append((uint64_t)*v); + } + } + + b.setAt(lengthAt,(uint32_t)((b.size() - 4) - lengthAt)); // set size, not including size field itself + } + + /** + * Create a new Peer from a serialized instance + * + * @param myIdentity This node's identity + * @param b Buffer containing serialized Peer data + * @param p Pointer to current position in buffer, will be updated in place as buffer is read (value/result) + * @return New instance of Peer or NULL if serialized data was corrupt or otherwise invalid (may also throw an exception via Buffer) + */ + template + static inline SharedPtr deserializeNew(const Identity &myIdentity,const Buffer &b,unsigned int &p) + { + const uint32_t recSize = b.template at(p); p += 4; + if ((p + recSize) > b.size()) + return SharedPtr(); // size invalid + if (b.template at(p) != 1) + return SharedPtr(); // version mismatch + p += 4; + + Identity npid; + p += npid.deserialize(b,p); + if (!npid) + return SharedPtr(); + + SharedPtr np(new Peer(myIdentity,npid)); + + np->_lastUsed = b.template at(p); p += 8; + np->_lastReceive = b.template at(p); p += 8; + np->_lastUnicastFrame = b.template at(p); p += 8; + np->_lastMulticastFrame = b.template at(p); p += 8; + np->_lastAnnouncedTo = b.template at(p); p += 8; + np->_lastPathConfirmationSent = b.template at(p); p += 8; + np->_lastDirectPathPush = b.template at(p); p += 8; + np->_lastPathSort = b.template at(p); p += 8; + np->_vProto = b.template at(p); p += 2; + np->_vMajor = b.template at(p); p += 2; + np->_vMinor = b.template at(p); p += 2; + np->_vRevision = b.template at(p); p += 2; + np->_latency = b.template at(p); p += 4; + + const unsigned int numPaths = b.template at(p); p += 2; + for(unsigned int i=0;i_paths[np->_numPaths++].deserialize(b,p); + } else { + // Skip any paths beyond max, but still read stream + RemotePath foo; + p += foo.deserialize(b,p); + } + } + + const unsigned int numNetworkComs = b.template at(p); p += 4; + for(unsigned int i=0;i_networkComs[b.template at(p)]; p += 8; + c.ts = b.template at(p); p += 8; + p += c.com.deserialize(b,p); + } + + const unsigned int numLastPushed = b.template at(p); p += 4; + for(unsigned int i=0;i(p); p += 8; + const uint64_t ts = b.template at(p); p += 8; + np->_lastPushedComs.set(nwid,ts); + } + } + private: void _sortPaths(const uint64_t now); RemotePath *_getBestPath(const uint64_t now); diff --git a/node/RemotePath.hpp b/node/RemotePath.hpp index 0034242e..9a8a3ff8 100644 --- a/node/RemotePath.hpp +++ b/node/RemotePath.hpp @@ -39,6 +39,8 @@ #include "AntiRecursion.hpp" #include "RuntimeEnvironment.hpp" +#define ZT_REMOTEPATH_FLAG_FIXED 0x0001 + namespace ZeroTier { /** @@ -54,14 +56,14 @@ public: _lastSend(0), _lastReceived(0), _localAddress(), - _fixed(false) {} + _flags(0) {} RemotePath(const InetAddress &localAddress,const InetAddress &addr,bool fixed) : Path(addr,0,TRUST_NORMAL), _lastSend(0), _lastReceived(0), _localAddress(localAddress), - _fixed(fixed) {} + _flags(fixed ? ZT_REMOTEPATH_FLAG_FIXED : 0) {} inline const InetAddress &localAddress() const throw() { return _localAddress; } @@ -71,7 +73,7 @@ public: /** * @return Is this a fixed path? */ - inline bool fixed() const throw() { return _fixed; } + inline bool fixed() const throw() { return ((_flags & ZT_REMOTEPATH_FLAG_FIXED) != 0); } /** * @param f New value of fixed flag @@ -79,7 +81,9 @@ public: inline void setFixed(const bool f) throw() { - _fixed = f; + if (f) + _flags |= ZT_REMOTEPATH_FLAG_FIXED; + else _flags &= ~ZT_REMOTEPATH_FLAG_FIXED; } /** @@ -113,7 +117,7 @@ public: inline bool active(uint64_t now) const throw() { - return ( (_fixed) || ((now - _lastReceived) < ZT_PEER_ACTIVITY_TIMEOUT) ); + return ( ((_flags & ZT_REMOTEPATH_FLAG_FIXED) != 0) || ((now - _lastReceived) < ZT_PEER_ACTIVITY_TIMEOUT) ); } /** @@ -135,11 +139,39 @@ public: return false; } -private: + template + inline void serialize(Buffer &b) const + { + b.append((uint8_t)1); // version + _addr.serialize(b); + b.append((uint8_t)_trust); + b.append((uint64_t)_lastSend); + b.append((uint64_t)_lastReceived); + _localAddress.serialize(b); + b.append((uint16_t)_flags); + } + + template + inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + { + unsigned int p = startAt; + if (b[p++] != 1) + throw std::invalid_argument("invalid serialized RemotePath"); + p += _addr.deserialize(b,p); + _ipScope = _addr.ipScope(); + _trust = (Path::Trust)b[p++]; + _lastSend = b.template at(p); p += 8; + _lastReceived = b.template at(p); p += 8; + p += _localAddress.deserialize(b,p); + _flags = b.template at(p); p += 4; + return (startAt - p); + } + +protected: uint64_t _lastSend; uint64_t _lastReceived; InetAddress _localAddress; - bool _fixed; + uint16_t _flags; }; } // namespace ZeroTier diff --git a/service/OneService.cpp b/service/OneService.cpp index 7b3c4ff6..4b374cd7 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -489,13 +489,12 @@ public: OSUtils::writeFile((_homePath + ZT_PATH_SEPARATOR_S + "zerotier-one.port").c_str(),std::string(portstr)); #ifdef ZT_USE_MINIUPNPC - // Bind a random secondary port for use with uPnP, since some NAT routers + // Bind a secondary port for use with uPnP, since some NAT routers // (cough Ubiquity Edge cough) barf up a lung if you do both conventional // NAT-t and uPnP from behind the same port. I think this is a bug, but // everyone else's router bugs are our problem. :P for(int k=0;k<512;++k) { - unsigned int upnport = 40000 + (((port + 1) * (k + 1)) % 25500); - + const unsigned int upnport = 40000 + (((port + 1) * (k + 1)) % 25500); _v4UpnpLocalAddress = InetAddress(0,upnport); _v4UpnpUdpSocket = _phy.udpBind((const struct sockaddr *)&_v4UpnpLocalAddress,reinterpret_cast(&_v4UpnpLocalAddress),131072); if (_v4UpnpUdpSocket) { -- cgit v1.2.3 From 0b2e5ed499aea0076caa2dc1d8784796e54da538 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 19 Oct 2015 15:11:43 -0700 Subject: Fix some broken logic in Path::reliable() --- node/Path.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'node/Path.hpp') diff --git a/node/Path.hpp b/node/Path.hpp index 6a69e071..6fa3c52e 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -114,7 +114,9 @@ public: */ inline bool reliable() const throw() { - return ( (_addr.ss_family == AF_INET6) || ((_ipScope != InetAddress::IP_SCOPE_GLOBAL)&&(_ipScope != InetAddress::IP_SCOPE_PSEUDOPRIVATE)) ); + if (_addr.ss_family == AF_INET) + return ((_ipScope != InetAddress::IP_SCOPE_GLOBAL)&&(_ipScope != InetAddress::IP_SCOPE_PSEUDOPRIVATE)); + return true; } /** -- cgit v1.2.3 From 16bc3e03982286232e1df2da17d8b2fc3c5a5c55 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 27 Oct 2015 15:00:16 -0700 Subject: Factor out RemotePath subclass of Path -- no longer needed, just cruft. --- include/ZeroTierOne.h | 3 +- node/Cluster.cpp | 1 + node/IncomingPacket.cpp | 5 +- node/Multicaster.cpp | 1 + node/Network.cpp | 1 + node/Node.cpp | 14 ++--- node/Node.hpp | 6 +- node/Path.cpp | 45 ++++++++++++++ node/Path.hpp | 117 +++++++++++++++++++++++++++++++++-- node/Peer.cpp | 32 +++++----- node/Peer.hpp | 24 ++++---- node/RemotePath.hpp | 161 ------------------------------------------------ node/SelfAwareness.cpp | 2 +- node/Switch.cpp | 2 +- objects.mk | 1 + service/OneService.cpp | 4 +- 16 files changed, 208 insertions(+), 211 deletions(-) create mode 100644 node/Path.cpp delete mode 100644 node/RemotePath.hpp (limited to 'node/Path.hpp') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 3457634b..01c8bcde 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -1356,11 +1356,10 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr); * reject bad, empty, and unusable addresses. * * @param addr Local interface address - * @param metric Local interface metric * @param trust How much do you trust the local network under this interface? * @return Boolean: non-zero if address was accepted and added */ -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,int metric, enum ZT_LocalInterfaceAddressTrust trust); +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,enum ZT_LocalInterfaceAddressTrust trust); /** * Clear local interface addresses diff --git a/node/Cluster.cpp b/node/Cluster.cpp index 73ff5846..07ca0ba1 100644 --- a/node/Cluster.cpp +++ b/node/Cluster.cpp @@ -48,6 +48,7 @@ #include "Topology.hpp" #include "Packet.hpp" #include "Switch.hpp" +#include "Node.hpp" namespace ZeroTier { diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 2514cd64..7015535a 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -44,6 +44,7 @@ #include "SHA512.hpp" #include "World.hpp" #include "Cluster.hpp" +#include "Node.hpp" namespace ZeroTier { @@ -888,7 +889,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha { try { const uint64_t now = RR->node->now(); - const RemotePath *currentBest = peer->getBestPath(now); + const Path *currentBest = peer->getBestPath(now); unsigned int count = at(ZT_PACKET_IDX_PAYLOAD); unsigned int ptr = ZT_PACKET_IDX_PAYLOAD + 2; @@ -1036,7 +1037,7 @@ bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPt remainingHopsPtr += ZT_ADDRESS_LENGTH; SharedPtr nhp(RR->topology->getPeer(nextHop[h])); if (nhp) { - RemotePath *const rp = nhp->getBestPath(now); + Path *const rp = nhp->getBestPath(now); if (rp) nextHopBestPathAddress[h] = rp->address(); } diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index 6e6cd628..e43d7d88 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -37,6 +37,7 @@ #include "Peer.hpp" #include "C25519.hpp" #include "CertificateOfMembership.hpp" +#include "Node.hpp" namespace ZeroTier { diff --git a/node/Network.cpp b/node/Network.cpp index cd30e386..afbe1074 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -37,6 +37,7 @@ #include "Packet.hpp" #include "Buffer.hpp" #include "NetworkController.hpp" +#include "Node.hpp" #include "../version.h" diff --git a/node/Node.cpp b/node/Node.cpp index 87871e20..82cda66d 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -448,10 +448,10 @@ ZT_PeerList *Node::peers() const p->latency = pi->second->latency(); p->role = RR->topology->isRoot(pi->second->identity()) ? ZT_PEER_ROLE_ROOT : ZT_PEER_ROLE_LEAF; - std::vector paths(pi->second->paths()); - RemotePath *bestPath = pi->second->getBestPath(_now); + std::vector paths(pi->second->paths()); + Path *bestPath = pi->second->getBestPath(_now); p->pathCount = 0; - for(std::vector::iterator path(paths.begin());path!=paths.end();++path) { + for(std::vector::iterator path(paths.begin());path!=paths.end();++path) { memcpy(&(p->paths[p->pathCount].address),&(path->address()),sizeof(struct sockaddr_storage)); p->paths[p->pathCount].lastSend = path->lastSend(); p->paths[p->pathCount].lastReceive = path->lastReceived(); @@ -499,11 +499,11 @@ void Node::freeQueryResult(void *qr) ::free(qr); } -int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT_LocalInterfaceAddressTrust trust) +int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,ZT_LocalInterfaceAddressTrust trust) { if (Path::isAddressValidForPath(*(reinterpret_cast(addr)))) { Mutex::Lock _l(_directPaths_m); - _directPaths.push_back(Path(*(reinterpret_cast(addr)),metric,(Path::Trust)trust)); + _directPaths.push_back(*(reinterpret_cast(addr))); std::sort(_directPaths.begin(),_directPaths.end()); _directPaths.erase(std::unique(_directPaths.begin(),_directPaths.end()),_directPaths.end()); return 1; @@ -900,10 +900,10 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr) } catch ( ... ) {} } -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,int metric, enum ZT_LocalInterfaceAddressTrust trust) +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,enum ZT_LocalInterfaceAddressTrust trust) { try { - return reinterpret_cast(node)->addLocalInterfaceAddress(addr,metric,trust); + return reinterpret_cast(node)->addLocalInterfaceAddress(addr,trust); } catch ( ... ) { return 0; } diff --git a/node/Node.hpp b/node/Node.hpp index 4094a79e..48c5ead8 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -105,7 +105,7 @@ public: ZT_VirtualNetworkConfig *networkConfig(uint64_t nwid) const; ZT_VirtualNetworkList *networks() const; void freeQueryResult(void *qr); - int addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT_LocalInterfaceAddressTrust trust); + int addLocalInterfaceAddress(const struct sockaddr_storage *addr,ZT_LocalInterfaceAddressTrust trust); void clearLocalInterfaceAddresses(); void setNetconfMaster(void *networkControllerInstance); ZT_ResultCode circuitTestBegin(ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *)); @@ -207,7 +207,7 @@ public: /** * @return Potential direct paths to me a.k.a. local interface addresses */ - inline std::vector directPaths() const + inline std::vector directPaths() const { Mutex::Lock _l(_directPaths_m); return _directPaths; @@ -285,7 +285,7 @@ private: std::vector< ZT_CircuitTest * > _circuitTests; Mutex _circuitTests_m; - std::vector _directPaths; + std::vector _directPaths; Mutex _directPaths_m; Mutex _backgroundTasksLock; diff --git a/node/Path.cpp b/node/Path.cpp new file mode 100644 index 00000000..e2475751 --- /dev/null +++ b/node/Path.cpp @@ -0,0 +1,45 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include "Path.hpp" +#include "AntiRecursion.hpp" +#include "RuntimeEnvironment.hpp" +#include "Node.hpp" + +namespace ZeroTier { + +bool Path::send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) +{ + if (RR->node->putPacket(_localAddress,address(),data,len)) { + sent(now); + RR->antiRec->logOutgoingZT(data,len); + return true; + } + return false; +} + +} // namespace ZeroTier diff --git a/node/Path.hpp b/node/Path.hpp index 6fa3c52e..99f6590b 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -28,12 +28,19 @@ #ifndef ZT_PATH_HPP #define ZT_PATH_HPP +#include +#include + +#include +#include + #include "Constants.hpp" #include "InetAddress.hpp" -#include "Utils.hpp" namespace ZeroTier { +class RuntimeEnvironment; + /** * Base class for paths * @@ -67,19 +74,87 @@ public: }; Path() : + _lastSend(0), + _lastReceived(0), _addr(), + _localAddress(), _ipScope(InetAddress::IP_SCOPE_NONE), - _trust(TRUST_NORMAL) + _trust(TRUST_NORMAL), + _flags(0) { } - Path(const InetAddress &addr,int metric,Trust trust) : + Path(const InetAddress &localAddress,const InetAddress &addr,Trust trust) : + _lastSend(0), + _lastReceived(0), _addr(addr), + _localAddress(localAddress), _ipScope(addr.ipScope()), - _trust(trust) + _trust(trust), + _flags(0) + { + } + + /** + * Called when a packet is sent to this remote path + * + * This is called automatically by Path::send(). + * + * @param t Time of send + */ + inline void sent(uint64_t t) + throw() { + _lastSend = t; } + /** + * Called when a packet is received from this remote path + * + * @param t Time of receive + */ + inline void received(uint64_t t) + throw() + { + _lastReceived = t; + } + + /** + * @param now Current time + * @return True if this path appears active + */ + inline bool active(uint64_t now) const + throw() + { + return ((now - _lastReceived) < ZT_PEER_ACTIVITY_TIMEOUT); + } + + /** + * Send a packet via this path + * + * @param RR Runtime environment + * @param data Packet data + * @param len Packet length + * @param now Current time + * @return True if transport reported success + */ + bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now); + + /** + * @return Address of local side of this path or NULL if unspecified + */ + inline const InetAddress &localAddress() const throw() { return _localAddress; } + + /** + * @return Time of last send to this path + */ + inline uint64_t lastSend() const throw() { return _lastSend; } + + /** + * @return Time of last receive from this path + */ + inline uint64_t lastReceived() const throw() { return _lastReceived; } + /** * @return Physical address */ @@ -157,10 +232,42 @@ public: return false; } -protected: + template + inline void serialize(Buffer &b) const + { + b.append((uint8_t)0); // version + b.append((uint64_t)_lastSend); + b.append((uint64_t)_lastReceived); + _addr.serialize(b); + _localAddress.serialize(b); + b.append((uint8_t)_trust); + b.append((uint16_t)_flags); + } + + template + inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + { + unsigned int p = startAt; + if (b[p++] != 0) + throw std::invalid_argument("invalid serialized Path"); + _lastSend = b.template at(p); p += 8; + _lastReceived = b.template at(p); p += 8; + p += _addr.deserialize(b,p); + p += _localAddress.deserialize(b,p); + _ipScope = _addr.ipScope(); + _trust = (Path::Trust)b[p++]; + _flags = b.template at(p); p += 2; + return (p - startAt); + } + +private: + uint64_t _lastSend; + uint64_t _lastReceived; InetAddress _addr; + InetAddress _localAddress; InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often Trust _trust; + uint16_t _flags; }; } // namespace ZeroTier diff --git a/node/Peer.cpp b/node/Peer.cpp index 009e2be5..ebdb6026 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -169,7 +169,7 @@ void Peer::received( if (!pathIsConfirmed) { if (verb == Packet::VERB_OK) { - RemotePath *slot = (RemotePath *)0; + Path *slot = (Path *)0; if (np < ZT_MAX_PEER_NETWORK_PATHS) { slot = &(_paths[np++]); } else { @@ -182,7 +182,7 @@ void Peer::received( } } if (slot) { - *slot = RemotePath(localAddr,remoteAddr); + *slot = Path(localAddr,remoteAddr,Path::TRUST_NORMAL); slot->received(now); _numPaths = np; pathIsConfirmed = true; @@ -240,7 +240,7 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &lo bool Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now,int inetAddressFamily) { - RemotePath *p = (RemotePath *)0; + Path *p = (Path *)0; Mutex::Lock _l(_lock); if (inetAddressFamily != 0) { @@ -268,7 +268,7 @@ bool Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now,int inet return false; } -void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_t now,bool force) +void Peer::pushDirectPaths(const RuntimeEnvironment *RR,Path *path,uint64_t now,bool force) { #ifdef ZT_ENABLE_CLUSTER // Cluster mode disables normal PUSH_DIRECT_PATHS in favor of cluster-based peer redirection @@ -281,7 +281,7 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ if (((now - _lastDirectPathPushSent) >= ZT_DIRECT_PATH_PUSH_INTERVAL)||(force)) { _lastDirectPathPushSent = now; - std::vector dps(RR->node->directPaths()); + std::vector dps(RR->node->directPaths()); if (dps.empty()) return; @@ -291,13 +291,13 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ for(std::vector::const_iterator p(dps.begin());p!=dps.end();++p) { if (ps.length() > 0) ps.push_back(','); - ps.append(p->address().toString()); + 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::const_iterator p(dps.begin()); + std::vector::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 @@ -305,7 +305,7 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ unsigned int count = 0; while ((p != dps.end())&&((outp.size() + 24) < ZT_PROTO_MAX_PACKET_LENGTH)) { uint8_t addressType = 4; - switch(p->address().ss_family) { + switch(p->ss_family) { case AF_INET: break; case AF_INET6: @@ -317,6 +317,7 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ } uint8_t flags = 0; + /* TODO: path trust is not implemented yet switch(p->trust()) { default: break; @@ -327,13 +328,14 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ flags |= (0x04 | 0x08); // no encryption, no authentication (redundant but go ahead and set both) break; } + */ outp.append(flags); outp.append((uint16_t)0); // no extensions outp.append(addressType); outp.append((uint8_t)((addressType == 4) ? 6 : 18)); - outp.append(p->address().rawIpData(),((addressType == 4) ? 4 : 16)); - outp.append((uint16_t)p->address().port()); + outp.append(p->rawIpData(),((addressType == 4) ? 4 : 16)); + outp.append((uint16_t)p->port()); ++count; ++p; @@ -506,7 +508,7 @@ struct _SortPathsByQuality { uint64_t _now; _SortPathsByQuality(const uint64_t now) : _now(now) {} - inline bool operator()(const RemotePath &a,const RemotePath &b) const + inline bool operator()(const Path &a,const Path &b) const { const uint64_t qa = ( ((uint64_t)a.active(_now) << 63) | @@ -526,7 +528,7 @@ void Peer::_sortPaths(const uint64_t now) std::sort(&(_paths[0]),&(_paths[_numPaths]),_SortPathsByQuality(now)); } -RemotePath *Peer::_getBestPath(const uint64_t now) +Path *Peer::_getBestPath(const uint64_t now) { // assumes _lock is locked if ((now - _lastPathSort) >= ZT_PEER_PATH_SORT_INTERVAL) @@ -538,10 +540,10 @@ RemotePath *Peer::_getBestPath(const uint64_t now) if (_paths[0].active(now)) return &(_paths[0]); } - return (RemotePath *)0; + return (Path *)0; } -RemotePath *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) +Path *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) { // assumes _lock is locked if ((now - _lastPathSort) >= ZT_PEER_PATH_SORT_INTERVAL) @@ -553,7 +555,7 @@ RemotePath *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) } _sortPaths(now); } - return (RemotePath *)0; + return (Path *)0; } } // namespace ZeroTier diff --git a/node/Peer.hpp b/node/Peer.hpp index 04b541af..aa75b3f4 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -41,7 +41,7 @@ #include "RuntimeEnvironment.hpp" #include "CertificateOfMembership.hpp" -#include "RemotePath.hpp" +#include "Path.hpp" #include "Address.hpp" #include "Utils.hpp" #include "Identity.hpp" @@ -135,7 +135,7 @@ public: * @param now Current time * @return Best path or NULL if there are no active direct paths */ - inline RemotePath *getBestPath(uint64_t now) + inline Path *getBestPath(uint64_t now) { Mutex::Lock _l(_lock); return _getBestPath(now); @@ -150,14 +150,14 @@ public: * @param now Current time * @return Path used on success or NULL on failure */ - inline RemotePath *send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) + inline Path *send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) { - RemotePath *bestPath = getBestPath(now); + Path *bestPath = getBestPath(now); if (bestPath) { if (bestPath->send(RR,data,len,now)) return bestPath; } - return (RemotePath *)0; + return (Path *)0; } /** @@ -191,14 +191,14 @@ public: * @param now Current time * @param force If true, push regardless of rate limit */ - void pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_t now,bool force); + void pushDirectPaths(const RuntimeEnvironment *RR,Path *path,uint64_t now,bool force); /** * @return All known direct paths to this peer */ - inline std::vector paths() const + inline std::vector paths() const { - std::vector pp; + std::vector pp; Mutex::Lock _l(_lock); for(unsigned int p=0,np=_numPaths;p_paths[np->_numPaths++].deserialize(b,p); } else { // Skip any paths beyond max, but still read stream - RemotePath foo; + Path foo; p += foo.deserialize(b,p); } } @@ -557,8 +557,8 @@ public: private: void _sortPaths(const uint64_t now); - RemotePath *_getBestPath(const uint64_t now); - RemotePath *_getBestPath(const uint64_t now,int inetAddressFamily); + Path *_getBestPath(const uint64_t now); + Path *_getBestPath(const uint64_t now,int inetAddressFamily); unsigned char _key[ZT_PEER_SECRET_KEY_LENGTH]; // computed with key agreement, not serialized @@ -575,7 +575,7 @@ private: uint16_t _vMinor; uint16_t _vRevision; Identity _id; - RemotePath _paths[ZT_MAX_PEER_NETWORK_PATHS]; + Path _paths[ZT_MAX_PEER_NETWORK_PATHS]; unsigned int _numPaths; unsigned int _latency; diff --git a/node/RemotePath.hpp b/node/RemotePath.hpp deleted file mode 100644 index 8b37621a..00000000 --- a/node/RemotePath.hpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * ZeroTier may be used and distributed under the terms of the GPLv3, which - * are available at: http://www.gnu.org/licenses/gpl-3.0.html - * - * If you would like to embed ZeroTier into a commercial application or - * redistribute it in a modified binary form, please contact ZeroTier Networks - * LLC. Start here: http://www.zerotier.com/ - */ - -#ifndef ZT_REMOTEPATH_HPP -#define ZT_REMOTEPATH_HPP - -#include -#include - -#include -#include - -#include "Path.hpp" -#include "Node.hpp" -#include "AntiRecursion.hpp" -#include "RuntimeEnvironment.hpp" - -namespace ZeroTier { - -/** - * Path to a remote peer - * - * This extends Path to include status information about path activity. - */ -class RemotePath : public Path -{ -public: - RemotePath() : - Path(), - _lastSend(0), - _lastReceived(0), - _localAddress(), - _flags(0) {} - - RemotePath(const InetAddress &localAddress,const InetAddress &addr) : - Path(addr,0,TRUST_NORMAL), - _lastSend(0), - _lastReceived(0), - _localAddress(localAddress), - _flags(0) {} - - inline const InetAddress &localAddress() const throw() { return _localAddress; } - - inline uint64_t lastSend() const throw() { return _lastSend; } - inline uint64_t lastReceived() const throw() { return _lastReceived; } - - /** - * Called when a packet is sent to this remote path - * - * This is called automatically by RemotePath::send(). - * - * @param t Time of send - */ - inline void sent(uint64_t t) - throw() - { - _lastSend = t; - } - - /** - * Called when a packet is received from this remote path - * - * @param t Time of receive - */ - inline void received(uint64_t t) - throw() - { - _lastReceived = t; - } - - /** - * @param now Current time - * @return True if this path appears active - */ - inline bool active(uint64_t now) const - throw() - { - return ((now - _lastReceived) < ZT_PEER_ACTIVITY_TIMEOUT); - } - - /** - * Send a packet via this path - * - * @param RR Runtime environment - * @param data Packet data - * @param len Packet length - * @param now Current time - * @return True if transport reported success - */ - inline bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) - { - if (RR->node->putPacket(_localAddress,address(),data,len)) { - sent(now); - RR->antiRec->logOutgoingZT(data,len); - return true; - } - return false; - } - - template - inline void serialize(Buffer &b) const - { - b.append((uint8_t)1); // version - _addr.serialize(b); - b.append((uint8_t)_trust); - b.append((uint64_t)_lastSend); - b.append((uint64_t)_lastReceived); - _localAddress.serialize(b); - b.append((uint16_t)_flags); - } - - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) - { - unsigned int p = startAt; - if (b[p++] != 1) - throw std::invalid_argument("invalid serialized RemotePath"); - p += _addr.deserialize(b,p); - _ipScope = _addr.ipScope(); - _trust = (Path::Trust)b[p++]; - _lastSend = b.template at(p); p += 8; - _lastReceived = b.template at(p); p += 8; - p += _localAddress.deserialize(b,p); - _flags = b.template at(p); p += 2; - return (p - startAt); - } - -protected: - uint64_t _lastSend; - uint64_t _lastReceived; - InetAddress _localAddress; - uint16_t _flags; -}; - -} // namespace ZeroTier - -#endif diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp index 81d19369..b4841544 100644 --- a/node/SelfAwareness.cpp +++ b/node/SelfAwareness.cpp @@ -125,7 +125,7 @@ void SelfAwareness::iam(const Address &reporter,const InetAddress &reporterPhysi // they are still considered alive so that we will re-establish direct links. SharedPtr r(RR->topology->getBestRoot()); if (r) { - RemotePath *rp = r->getBestPath(now); + Path *rp = r->getBestPath(now); if (rp) { for(std::vector< SharedPtr >::const_iterator p(rset.peersReset.begin());p!=rset.peersReset.end();++p) { if ((*p)->alive(now)) { diff --git a/node/Switch.cpp b/node/Switch.cpp index 772eaf02..2f72f57a 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -736,7 +736,7 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) return false; // sanity check: unconfigured network? why are we trying to talk to it? } - RemotePath *viaPath = peer->getBestPath(now); + Path *viaPath = peer->getBestPath(now); SharedPtr relay; if (!viaPath) { // See if this network has a preferred relay (if packet has an associated network) diff --git a/objects.mk b/objects.mk index 6dd5ea30..540072d5 100644 --- a/objects.mk +++ b/objects.mk @@ -15,6 +15,7 @@ OBJS=\ node/Node.o \ node/OutboundMulticast.o \ node/Packet.o \ + node/Path.o \ node/Peer.o \ node/Poly1305.o \ node/Salsa20.o \ diff --git a/service/OneService.cpp b/service/OneService.cpp index 1765b5c4..4e3f24c7 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -731,7 +731,7 @@ public: #ifdef ZT_USE_MINIUPNPC std::vector upnpAddresses(_upnpClient->get()); for(std::vector::const_iterator ext(upnpAddresses.begin());ext!=upnpAddresses.end();++ext) - _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),0,ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); #endif struct ifaddrs *ifatbl = (struct ifaddrs *)0; @@ -749,7 +749,7 @@ public: if (!isZT) { InetAddress ip(ifa->ifa_addr); ip.setPort(_port); - _node->addLocalInterfaceAddress(reinterpret_cast(&ip),0,ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&ip),ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); } } ifa = ifa->ifa_next; -- cgit v1.2.3 From 51fcc753549e4f7c18efb889a841c4dd4fb9e6cf Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 27 Oct 2015 17:36:47 -0700 Subject: Some cleanup, and use getPeerNoCache() exclusively in Cluster. --- node/Cluster.cpp | 42 ++++++++++++++++++++++++++++++------------ node/Cluster.hpp | 3 ++- node/Path.hpp | 8 ++++++++ 3 files changed, 40 insertions(+), 13 deletions(-) (limited to 'node/Path.hpp') diff --git a/node/Cluster.cpp b/node/Cluster.cpp index 0535f9ee..9b034822 100644 --- a/node/Cluster.cpp +++ b/node/Cluster.cpp @@ -83,7 +83,8 @@ Cluster::Cluster( _id(id), _zeroTierPhysicalEndpoints(zeroTierPhysicalEndpoints), _members(new _Member[ZT_CLUSTER_MAX_MEMBERS]), - _peerAffinities(65536) + _peerAffinities(65536), + _lastCleanedPeerAffinities(0) { uint16_t stmp[ZT_SHA512_DIGEST_LEN / sizeof(uint16_t)]; @@ -247,11 +248,13 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len) } break; case STATE_MESSAGE_COM: { + /* not currently used so not decoded yet CertificateOfMembership com; ptr += com.deserialize(dmsg,ptr); if (com) { TRACE("[%u] COM for %s on %.16llu rev %llu",(unsigned int)fromMemberId,com.issuedTo().toString().c_str(),com.networkId(),com.revision()); } + */ } break; case STATE_MESSAGE_PROXY_UNITE: { @@ -262,12 +265,13 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len) for(unsigned int i=0;i localPeer(RR->topology->getPeer(localPeerAddress)); + const uint64_t now = RR->node->now(); + SharedPtr localPeer(RR->topology->getPeerNoCache(localPeerAddress,now)); if ((localPeer)&&(numRemotePeerPaths > 0)) { InetAddress bestLocalV4,bestLocalV6; - localPeer->getBestActiveAddresses(RR->node->now(),bestLocalV4,bestLocalV6); + localPeer->getBestActiveAddresses(now,bestLocalV4,bestLocalV6); InetAddress bestRemoteV4,bestRemoteV6; for(unsigned int i=0;i buf; + Buffer<1024> buf; if (unite) { InetAddress v4,v6; if (fromPeerAddress) { - SharedPtr fromPeer(RR->topology->getPeer(fromPeerAddress)); + SharedPtr fromPeer(RR->topology->getPeerNoCache(fromPeerAddress,now)); if (fromPeer) fromPeer->getBestActiveAddresses(now,v4,v6); } @@ -408,7 +412,7 @@ bool Cluster::sendViaCluster(const Address &fromPeerAddress,const Address &toPee void Cluster::replicateHavePeer(const Identity &peerId,const InetAddress &physicalAddress) { const uint64_t now = RR->node->now(); - { // Use peer affinity table to track our own last announce time for peers + { Mutex::Lock _l2(_peerAffinities_m); _PA &pa = _peerAffinities[peerId.address()]; if (pa.mid != _id) { @@ -436,7 +440,7 @@ void Cluster::replicateHavePeer(const Identity &peerId,const InetAddress &physic void Cluster::replicateMulticastLike(uint64_t nwid,const Address &peerAddress,const MulticastGroup &group) { - Buffer<2048> buf; + Buffer<1024> buf; buf.append((uint64_t)nwid); peerAddress.appendTo(buf); group.mac().appendTo(buf); @@ -453,7 +457,7 @@ void Cluster::replicateMulticastLike(uint64_t nwid,const Address &peerAddress,co void Cluster::replicateCertificateOfNetworkMembership(const CertificateOfMembership &com) { - Buffer<2048> buf; + Buffer<4096> buf; com.serialize(buf); TRACE("replicating %s COM for %.16llx to all members",com.issuedTo().toString().c_str(),com.networkId()); { @@ -502,6 +506,20 @@ void Cluster::doPeriodicTasks() _flush(*mid); // does nothing if nothing to flush } } + + { + if ((now - _lastCleanedPeerAffinities) >= (ZT_PEER_ACTIVITY_TIMEOUT * 10)) { + _lastCleanedPeerAffinities = now; + Address *k = (Address *)0; + _PA *v = (_PA *)0; + Mutex::Lock _l(_peerAffinities_m); + Hashtable< Address,_PA >::Iterator i(_peerAffinities); + while (i.next(k,v)) { + if ((now - v->ts) >= (ZT_PEER_ACTIVITY_TIMEOUT * 10)) + _peerAffinities.erase(*k); + } + } + } } void Cluster::addMember(uint16_t memberId) @@ -563,7 +581,7 @@ bool Cluster::findBetterEndpoint(InetAddress &redirectTo,const Address &peerAddr // Find member closest to this peer const uint64_t now = RR->node->now(); - std::vector best; // initial "best" is for peer to stay put + std::vector best; const double currentDistance = _dist3d(_x,_y,_z,px,py,pz); double bestDistance = (offload ? 2147483648.0 : currentDistance); unsigned int bestMember = _id; @@ -575,7 +593,7 @@ bool Cluster::findBetterEndpoint(InetAddress &redirectTo,const Address &peerAddr // Consider member if it's alive and has sent us a location and one or more physical endpoints to send peers to if ( ((now - m.lastReceivedAliveAnnouncement) < ZT_CLUSTER_TIMEOUT) && ((m.x != 0)||(m.y != 0)||(m.z != 0)) && (m.zeroTierPhysicalEndpoints.size() > 0) ) { - double mdist = _dist3d(m.x,m.y,m.z,px,py,pz); + const double mdist = _dist3d(m.x,m.y,m.z,px,py,pz); if (mdist < bestDistance) { bestDistance = mdist; bestMember = *mid; @@ -585,7 +603,7 @@ bool Cluster::findBetterEndpoint(InetAddress &redirectTo,const Address &peerAddr } } - // Suggestion redirection if a closer member was found + // Redirect to a closer member if it has a ZeroTier endpoint address in the same ss_family for(std::vector::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()); diff --git a/node/Cluster.hpp b/node/Cluster.hpp index c3367d57..cc9edd1d 100644 --- a/node/Cluster.hpp +++ b/node/Cluster.hpp @@ -47,7 +47,7 @@ /** * Timeout for cluster members being considered "alive" */ -#define ZT_CLUSTER_TIMEOUT 10000 +#define ZT_CLUSTER_TIMEOUT 20000 /** * How often should we announce that we have a peer? @@ -349,6 +349,7 @@ private: }; Hashtable< Address,_PA > _peerAffinities; Mutex _peerAffinities_m; + uint64_t _lastCleanedPeerAffinities; }; } // namespace ZeroTier diff --git a/node/Path.hpp b/node/Path.hpp index 99f6590b..2b05b812 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -95,6 +95,14 @@ public: { } + inline Path &operator=(const Path &p) + throw() + { + if (this != &p) + memcpy(this,&p,sizeof(Path)); + return *this; + } + /** * Called when a packet is sent to this remote path * -- cgit v1.2.3 From a994573a436ec2835781d13ecd2307e18c67855b Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 29 Oct 2015 09:42:15 -0700 Subject: Eliminate some more dead code. We may do path trust, but not like that. --- include/ZeroTierOne.h | 17 +---------------- node/Node.cpp | 6 +++--- node/Node.hpp | 2 +- node/Path.hpp | 16 +++------------- node/Peer.cpp | 2 +- service/OneService.cpp | 4 ++-- 6 files changed, 11 insertions(+), 36 deletions(-) (limited to 'node/Path.hpp') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 01c8bcde..e9b38c52 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -424,15 +424,6 @@ enum ZT_VirtualNetworkConfigOperation ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY = 4 }; -/** - * Local interface trust levels - */ -enum ZT_LocalInterfaceAddressTrust { - ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL = 0, - ZT_LOCAL_INTERFACE_ADDRESS_TRUST_PRIVACY = 10, - ZT_LOCAL_INTERFACE_ADDRESS_TRUST_ULTIMATE = 20 -}; - /** * What trust hierarchy role does this peer have? */ @@ -1337,11 +1328,6 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr); /** * Add a local interface address * - * Local interface addresses may be added if you want remote peers - * with whom you have a trust relatinship (e.g. common network membership) - * to receive information about these endpoints as potential endpoints for - * direct communication. - * * Take care that these are never ZeroTier interface addresses, otherwise * strange things might happen or they simply won't work. * @@ -1356,10 +1342,9 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr); * reject bad, empty, and unusable addresses. * * @param addr Local interface address - * @param trust How much do you trust the local network under this interface? * @return Boolean: non-zero if address was accepted and added */ -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,enum ZT_LocalInterfaceAddressTrust trust); +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr); /** * Clear local interface addresses diff --git a/node/Node.cpp b/node/Node.cpp index 82cda66d..42180e99 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -499,7 +499,7 @@ void Node::freeQueryResult(void *qr) ::free(qr); } -int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,ZT_LocalInterfaceAddressTrust trust) +int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr) { if (Path::isAddressValidForPath(*(reinterpret_cast(addr)))) { Mutex::Lock _l(_directPaths_m); @@ -900,10 +900,10 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr) } catch ( ... ) {} } -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,enum ZT_LocalInterfaceAddressTrust trust) +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr) { try { - return reinterpret_cast(node)->addLocalInterfaceAddress(addr,trust); + return reinterpret_cast(node)->addLocalInterfaceAddress(addr); } catch ( ... ) { return 0; } diff --git a/node/Node.hpp b/node/Node.hpp index 48c5ead8..9b85b832 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -105,7 +105,7 @@ public: ZT_VirtualNetworkConfig *networkConfig(uint64_t nwid) const; ZT_VirtualNetworkList *networks() const; void freeQueryResult(void *qr); - int addLocalInterfaceAddress(const struct sockaddr_storage *addr,ZT_LocalInterfaceAddressTrust trust); + int addLocalInterfaceAddress(const struct sockaddr_storage *addr); void clearLocalInterfaceAddresses(); void setNetconfMaster(void *networkControllerInstance); ZT_ResultCode circuitTestBegin(ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *)); diff --git a/node/Path.hpp b/node/Path.hpp index 2b05b812..c0182990 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -79,18 +79,16 @@ public: _addr(), _localAddress(), _ipScope(InetAddress::IP_SCOPE_NONE), - _trust(TRUST_NORMAL), _flags(0) { } - Path(const InetAddress &localAddress,const InetAddress &addr,Trust trust) : + Path(const InetAddress &localAddress,const InetAddress &addr) : _lastSend(0), _lastReceived(0), _addr(addr), _localAddress(localAddress), _ipScope(addr.ipScope()), - _trust(trust), _flags(0) { } @@ -187,11 +185,6 @@ public: return ( ((int)_ipScope * 2) + ((_addr.ss_family == AF_INET6) ? 1 : 0) ); } - /** - * @return Path trust level - */ - inline Trust trust() const throw() { return _trust; } - /** * @return True if path is considered reliable (no NAT keepalives etc. are needed) */ @@ -243,12 +236,11 @@ public: template inline void serialize(Buffer &b) const { - b.append((uint8_t)0); // version + b.append((uint8_t)1); // version b.append((uint64_t)_lastSend); b.append((uint64_t)_lastReceived); _addr.serialize(b); _localAddress.serialize(b); - b.append((uint8_t)_trust); b.append((uint16_t)_flags); } @@ -256,14 +248,13 @@ public: inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) { unsigned int p = startAt; - if (b[p++] != 0) + if (b[p++] != 1) throw std::invalid_argument("invalid serialized Path"); _lastSend = b.template at(p); p += 8; _lastReceived = b.template at(p); p += 8; p += _addr.deserialize(b,p); p += _localAddress.deserialize(b,p); _ipScope = _addr.ipScope(); - _trust = (Path::Trust)b[p++]; _flags = b.template at(p); p += 2; return (p - startAt); } @@ -274,7 +265,6 @@ private: InetAddress _addr; InetAddress _localAddress; InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often - Trust _trust; uint16_t _flags; }; diff --git a/node/Peer.cpp b/node/Peer.cpp index 976c7c44..9d0d78e5 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -179,7 +179,7 @@ void Peer::received( } } if (slot) { - *slot = Path(localAddr,remoteAddr,Path::TRUST_NORMAL); + *slot = Path(localAddr,remoteAddr); slot->received(now); _numPaths = np; pathIsConfirmed = true; diff --git a/service/OneService.cpp b/service/OneService.cpp index 4e3f24c7..8c8ff1ed 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -731,7 +731,7 @@ public: #ifdef ZT_USE_MINIUPNPC std::vector upnpAddresses(_upnpClient->get()); for(std::vector::const_iterator ext(upnpAddresses.begin());ext!=upnpAddresses.end();++ext) - _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext))); #endif struct ifaddrs *ifatbl = (struct ifaddrs *)0; @@ -749,7 +749,7 @@ public: if (!isZT) { InetAddress ip(ifa->ifa_addr); ip.setPort(_port); - _node->addLocalInterfaceAddress(reinterpret_cast(&ip),ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&ip)); } } ifa = ifa->ifa_next; -- cgit v1.2.3 From 9f0f0197fe5a79ed04647b110485a530ed06ed8e Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 29 Oct 2015 09:44:25 -0700 Subject: More dead code removal. --- node/Path.hpp | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) (limited to 'node/Path.hpp') diff --git a/node/Path.hpp b/node/Path.hpp index c0182990..39a18c43 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -49,37 +49,12 @@ class RuntimeEnvironment; class Path { public: - /** - * Path trust category - * - * Note that this is NOT peer trust and has nothing to do with root server - * designations or other trust metrics. This indicates how much we trust - * this path to be secure and/or private. A trust level of normal means - * encrypt and authenticate all traffic. Privacy trust means we can send - * traffic in the clear. Ultimate trust means we don't even need - * authentication. Generally a private path would be a hard-wired local - * LAN, while an ultimate trust path would be a physically isolated private - * server backplane. - * - * Nearly all paths will be normal trust. The other levels are for high - * performance local SDN use only. - * - * These values MUST match ZT_LocalInterfaceAddressTrust in ZeroTierOne.h - */ - enum Trust // NOTE: max 255 - { - TRUST_NORMAL = 0, - TRUST_PRIVACY = 10, - TRUST_ULTIMATE = 20 - }; - Path() : _lastSend(0), _lastReceived(0), _addr(), _localAddress(), - _ipScope(InetAddress::IP_SCOPE_NONE), - _flags(0) + _ipScope(InetAddress::IP_SCOPE_NONE) { } @@ -88,8 +63,7 @@ public: _lastReceived(0), _addr(addr), _localAddress(localAddress), - _ipScope(addr.ipScope()), - _flags(0) + _ipScope(addr.ipScope()) { } @@ -241,7 +215,6 @@ public: b.append((uint64_t)_lastReceived); _addr.serialize(b); _localAddress.serialize(b); - b.append((uint16_t)_flags); } template @@ -255,7 +228,6 @@ public: p += _addr.deserialize(b,p); p += _localAddress.deserialize(b,p); _ipScope = _addr.ipScope(); - _flags = b.template at(p); p += 2; return (p - startAt); } @@ -265,7 +237,6 @@ private: InetAddress _addr; InetAddress _localAddress; InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often - uint16_t _flags; }; } // namespace ZeroTier -- cgit v1.2.3