diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-07-06 14:08:13 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-07-06 14:08:13 -0700 |
commit | 93bb934d4e77fd1436ebe81336d396fa769aa59b (patch) | |
tree | 37bdf28002a09429c02995e6dc2701fa1c021abe | |
parent | feddd946f9d3ac6a643968582610eb4ffaebb69d (diff) | |
download | infinitytier-93bb934d4e77fd1436ebe81336d396fa769aa59b.tar.gz infinitytier-93bb934d4e77fd1436ebe81336d396fa769aa59b.zip |
Some cleanup, docs, and Path -> Path > RemotePath refactor.
-rw-r--r-- | node/Node.cpp | 6 | ||||
-rw-r--r-- | node/Packet.hpp | 32 | ||||
-rw-r--r-- | node/Path.hpp | 113 | ||||
-rw-r--r-- | node/Peer.cpp | 15 | ||||
-rw-r--r-- | node/Peer.hpp | 36 | ||||
-rw-r--r-- | node/RemotePath.hpp | 97 | ||||
-rw-r--r-- | node/SelfAwareness.cpp | 2 | ||||
-rw-r--r-- | node/Switch.cpp | 2 | ||||
-rw-r--r-- | node/Topology.cpp | 2 |
9 files changed, 197 insertions, 108 deletions
diff --git a/node/Node.cpp b/node/Node.cpp index 8cdc6d62..8eacf753 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -388,10 +388,10 @@ ZT1_PeerList *Node::peers() const p->latency = pi->second->latency(); p->role = RR->topology->isRoot(pi->second->identity()) ? ZT1_PEER_ROLE_ROOT : ZT1_PEER_ROLE_LEAF; - std::vector<Path> paths(pi->second->paths()); - Path *bestPath = pi->second->getBestPath(_now); + std::vector<RemotePath> paths(pi->second->paths()); + RemotePath *bestPath = pi->second->getBestPath(_now); p->pathCount = 0; - for(std::vector<Path>::iterator path(paths.begin());path!=paths.end();++path) { + for(std::vector<RemotePath>::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(); diff --git a/node/Packet.hpp b/node/Packet.hpp index 5572e235..14fac1bf 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -899,16 +899,17 @@ public: * Path record format: * <[1] flags> * <[1] metric from 0 (highest priority) to 255 (lowest priority)> + * <[2] length of extended path characteristics or 0 for none> + * <[...] extended path characteristics> * <[1] address type> * <[...] address> * * Path record flags: - * 0x01 - Blacklist this path, do not use - * 0x02 - Reliable path (no keepalives, etc. necessary) - * 0x04 - Trusted path (encryption and authentication optional) - * - * None of the above flags are implemented yet as of 1.0.4. They're - * reserved for future use. + * 0x01 - Forget this path if it is currently known + * 0x02 - Blacklist this path, do not use + * 0x04 - Reliable path (no NAT keepalives, etc. are necessary) + * 0x08 - Disable encryption (trust: privacy) + * 0x10 - Disable encryption and authentication (trust: ultimate) * * Address types and addresses are of the same format as the destination * address type and address in HELLO. @@ -916,9 +917,24 @@ public: * The receiver may, upon receiving a push, attempt to establish a * direct link to one or more of the indicated addresses. It is the * responsibility of the sender to limit which peers it pushes direct - * paths to to those with whom it has a trust relationship. + * paths to to those with whom it has a trust relationship. The receiver + * must obey any restrictions provided such as exclusivity or blacklists. + * OK responses to this message are optional. * - * OK/ERROR are not generated. + * Note that a direct path push does not imply that learned paths can't + * be used unless they are blacklisted explicitly or unless flag 0x01 + * is set. + * + * Only a subset of this functionality is currently implemented: basic + * path pushing and learning. Metrics, most flags, and OK responses are + * not yet implemented as of 1.0.4. + * + * OK response payload: + * <[2] 16-bit number of active direct paths we already have> + * <[2] 16-bit number of paths in push that we don't already have> + * <[2] 16-bit number of new paths we are trying (or will try)> + * + * ERROR is presently not sent. */ VERB_PUSH_DIRECT_PATHS = 16 }; diff --git a/node/Path.hpp b/node/Path.hpp new file mode 100644 index 00000000..b43b3f6d --- /dev/null +++ b/node/Path.hpp @@ -0,0 +1,113 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + * + * -- + * + * 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_PATH_HPP +#define ZT_PATH_HPP + +#include "Constants.hpp" +#include "InetAddress.hpp" +#include "Utils.hpp" + +namespace ZeroTier { + +class Path +{ +public: + enum Trust + { + TRUST_NORMAL, + TRUST_PRIVACY, + TRUST_ULTIMATE + }; + + Path() : + _addr(), + _metric(0), + _trust(TRUST_NORMAL), + _reliable(false), + _fixed(false) + { + } + + Path(const InetAddress &addr,int metric,Trust trust,bool reliable,bool fixed) : + _addr(addr), + _metric(metric), + _trust(trust), + _reliable(reliable), + _fixed(fixed) + { + } + + /** + * @return Physical address + */ + inline const InetAddress &address() const throw() { return _addr; } + + /** + * @return Metric (higher == worse) or negative if path is blacklisted + */ + inline int metric() const throw() { return _metric; } + + /** + * @return Path trust level + */ + inline Trust trust() const throw() { return _trust; } + + /** + * @return True if path is considered reliable (no NAT keepalives etc. are needed) + */ + inline bool reliable() const throw() { return _reliable; } + + /** + * @return Is this a fixed path? + */ + inline bool fixed() const throw() { return _fixed; } + + /** + * @return True if address is non-NULL + */ + 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); } + +protected: + InetAddress _addr; + int _metric; // negative == blacklisted + Trust _trust; + bool _reliable; + bool _fixed; +}; + +} // namespace ZeroTier + +#endif diff --git a/node/Peer.cpp b/node/Peer.cpp index 96caa72c..cb046b9b 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -46,6 +46,7 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) _lastMulticastFrame(0), _lastAnnouncedTo(0), _lastPathConfirmationSent(0), + _lastDirectPathPush(0), _vMajor(0), _vMinor(0), _vRevision(0), @@ -86,7 +87,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 - Path *slot = (Path *)0; + RemotePath *slot = (RemotePath *)0; if (np < ZT1_MAX_PEER_NETWORK_PATHS) { // Add new path slot = &(_paths[np++]); @@ -101,7 +102,7 @@ void Peer::received( } } if (slot) { - slot->init(remoteAddr,false); + *slot = RemotePath(remoteAddr,false); slot->received(now); _numPaths = np; pathIsConfirmed = true; @@ -193,7 +194,7 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &at void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) { - Path *const bestPath = getBestPath(now); + RemotePath *const bestPath = getBestPath(now); if ((bestPath)&&(bestPath->active(now))) { if ((now - bestPath->lastReceived()) >= ZT_PEER_DIRECT_PING_DELAY) { TRACE("PING %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); @@ -207,7 +208,11 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) } } -void Peer::addPath(const Path &newp) +//void Peer::pushDirectPaths(const std::vector<Path> &dps,uint64_t now,bool force) +//{ +//} + +void Peer::addPath(const RemotePath &newp) { unsigned int np = _numPaths; @@ -218,7 +223,7 @@ void Peer::addPath(const Path &newp) } } - Path *slot = (Path *)0; + RemotePath *slot = (RemotePath *)0; if (np < ZT1_MAX_PEER_NETWORK_PATHS) { // Add new path slot = &(_paths[np++]); diff --git a/node/Peer.hpp b/node/Peer.hpp index 8d8b7cb4..6ca29393 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -40,7 +40,7 @@ #include "../include/ZeroTierOne.h" #include "RuntimeEnvironment.hpp" -#include "Path.hpp" +#include "RemotePath.hpp" #include "Address.hpp" #include "Utils.hpp" #include "Identity.hpp" @@ -53,11 +53,7 @@ namespace ZeroTier { /** - * Peer on P2P Network - * - * This struture is not locked, volatile, and memcpy-able. NonCopyable - * semantics are just there to prevent bugs, not because it isn't safe - * to copy. + * Peer on P2P Network (virtual layer 1) */ class Peer : NonCopyable { @@ -130,9 +126,9 @@ public: * @param now Current time * @return Best path or NULL if there are no active (or fixed) direct paths */ - inline Path *getBestPath(uint64_t now) + inline RemotePath *getBestPath(uint64_t now) { - Path *bestPath = (Path *)0; + RemotePath *bestPath = (RemotePath *)0; uint64_t lrMax = 0; for(unsigned int p=0,np=_numPaths;p<np;++p) { if ((_paths[p].active(now))&&(_paths[p].lastReceived() >= lrMax)) { @@ -152,14 +148,14 @@ public: * @param now Current time * @return Path used on success or NULL on failure */ - inline Path *send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) + inline RemotePath *send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) { - Path *bestPath = getBestPath(now); + RemotePath *bestPath = getBestPath(now); if (bestPath) { if (bestPath->send(RR,data,len,now)) return bestPath; } - return (Path *)0; + return (RemotePath *)0; } /** @@ -183,11 +179,20 @@ public: void doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now); /** + * Push direct paths (if within rate limit) + * + * @param dps Direct paths to me to push to this peer + * @param now Current time + * @param force If true, force regardless of when we pushed direct paths last + */ + void pushDirectPaths(const std::vector<InetAddress> &dps,uint64_t now,bool force); + + /** * @return All known direct paths to this peer */ - inline std::vector<Path> paths() const + inline std::vector<RemotePath> paths() const { - std::vector<Path> pp; + std::vector<RemotePath> pp; for(unsigned int p=0,np=_numPaths;p<np;++p) pp.push_back(_paths[p]); return pp; @@ -295,7 +300,7 @@ public: * * @param p New path to add */ - void addPath(const Path &newp); + void addPath(const RemotePath &newp); /** * Clear paths @@ -412,12 +417,13 @@ private: uint64_t _lastMulticastFrame; uint64_t _lastAnnouncedTo; uint64_t _lastPathConfirmationSent; + uint64_t _lastDirectPathPush; uint16_t _vProto; uint16_t _vMajor; uint16_t _vMinor; uint16_t _vRevision; Identity _id; - Path _paths[ZT1_MAX_PEER_NETWORK_PATHS]; + RemotePath _paths[ZT1_MAX_PEER_NETWORK_PATHS]; unsigned int _numPaths; unsigned int _latency; diff --git a/node/RemotePath.hpp b/node/RemotePath.hpp index 393b7225..47c8916d 100644 --- a/node/RemotePath.hpp +++ b/node/RemotePath.hpp @@ -25,72 +25,56 @@ * LLC. Start here: http://www.zerotier.com/ */ -#ifndef ZT_PATH_HPP -#define ZT_PATH_HPP +#ifndef ZT_REMOTEPATH_HPP +#define ZT_REMOTEPATH_HPP #include <stdint.h> #include <string.h> #include <stdexcept> -#include <string> #include <algorithm> -#include "Constants.hpp" +#include "Path.hpp" #include "Node.hpp" -#include "InetAddress.hpp" -#include "Utils.hpp" #include "AntiRecursion.hpp" #include "RuntimeEnvironment.hpp" namespace ZeroTier { /** - * WAN address and protocol for reaching a peer + * Path to a remote peer * - * This structure is volatile and memcpy-able, and depends on - * InetAddress being similarly safe. + * This extends Path to include status information about path activity. */ -class Path +class RemotePath : public Path { public: - Path() : - _addr(), + RemotePath() : + Path(), _lastSend(0), - _lastReceived(0), - _fixed(false) {} + _lastReceived(0) {} - Path(const Path &p) throw() { memcpy(this,&p,sizeof(Path)); } - - Path(const InetAddress &addr,bool fixed) : - _addr(addr), + RemotePath(const InetAddress &addr,bool fixed) : + Path(addr,0,TRUST_NORMAL,false,fixed), _lastSend(0), - _lastReceived(0), - _fixed(fixed) {} + _lastReceived(0) {} - inline void init(const InetAddress &addr,bool fixed) - { - _addr = addr; - _lastSend = 0; - _lastReceived = 0; - _fixed = fixed; - } + inline uint64_t lastSend() const throw() { return _lastSend; } + inline uint64_t lastReceived() const throw() { return _lastReceived; } - inline Path &operator=(const Path &p) + /** + * @param f New value of parent 'fixed' field + */ + inline void setFixed(const bool f) + throw() { - if (this != &p) - memcpy(this,&p,sizeof(Path)); - return *this; + _fixed = f; } - inline const InetAddress &address() const throw() { return _addr; } - - inline uint64_t lastSend() const throw() { return _lastSend; } - inline uint64_t lastReceived() const throw() { return _lastReceived; } - /** - * Called when a packet is sent to this path + * Called when a packet is sent to this remote path * - * This is called automatically by Path::send(). + * This is called automatically by RemotePath::send(). * * @param t Time of send */ @@ -101,7 +85,7 @@ public: } /** - * Called when a packet is received from this path + * Called when a packet is received from this remote path * * @param t Time of receive */ @@ -112,16 +96,6 @@ public: } /** - * @return Is this a fixed path? - */ - inline bool fixed() const throw() { return _fixed; } - - /** - * @param f New value of fixed path flag - */ - inline void setFixed(bool f) throw() { _fixed = f; } - - /** * @param now Current time * @return True if this path is fixed or has received data in last ACTIVITY_TIMEOUT ms */ @@ -150,34 +124,9 @@ public: return false; } - /** - * @param now Current time - * @return Human-readable address and other information about this path - */ - inline std::string toString(uint64_t now) const - { - char tmp[1024]; - Utils::snprintf(tmp,sizeof(tmp),"%s(%s)", - _addr.toString().c_str(), - ((_fixed) ? "fixed" : (active(now) ? "active" : "inactive")) - ); - return std::string(tmp); - } - - inline operator bool() const throw() { return (_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); } - inline bool operator>=(const Path &p) const throw() { return (_addr >= p._addr); } - private: - InetAddress _addr; uint64_t _lastSend; uint64_t _lastReceived; - bool _fixed; }; } // namespace ZeroTier diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp index 9f7c41d7..00015788 100644 --- a/node/SelfAwareness.cpp +++ b/node/SelfAwareness.cpp @@ -120,7 +120,7 @@ void SelfAwareness::iam(const Address &reporter,const InetAddress &reporterPhysi // they are still considered alive so that we will re-establish direct links. SharedPtr<Peer> sn(RR->topology->getBestRoot()); if (sn) { - Path *snp = sn->getBestPath(now); + RemotePath *snp = sn->getBestPath(now); if (snp) { for(std::vector< SharedPtr<Peer> >::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 f022122e..891c4a45 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -733,7 +733,7 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) if (peer) { const uint64_t now = RR->node->now(); - Path *viaPath = peer->getBestPath(now); + RemotePath *viaPath = peer->getBestPath(now); if (!viaPath) { SharedPtr<Peer> relay; diff --git a/node/Topology.cpp b/node/Topology.cpp index 2b1cc31f..b255080e 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -62,7 +62,7 @@ void Topology::setRootServers(const std::map< Identity,std::vector<InetAddress> if (!p) p = SharedPtr<Peer>(new Peer(RR->identity,i->first)); for(std::vector<InetAddress>::const_iterator j(i->second.begin());j!=i->second.end();++j) - p->addPath(Path(*j,true)); + p->addPath(RemotePath(*j,true)); p->use(now); _rootPeers.push_back(p); } |