summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2015-07-06 14:08:13 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2015-07-06 14:08:13 -0700
commit93bb934d4e77fd1436ebe81336d396fa769aa59b (patch)
tree37bdf28002a09429c02995e6dc2701fa1c021abe
parentfeddd946f9d3ac6a643968582610eb4ffaebb69d (diff)
downloadinfinitytier-93bb934d4e77fd1436ebe81336d396fa769aa59b.tar.gz
infinitytier-93bb934d4e77fd1436ebe81336d396fa769aa59b.zip
Some cleanup, docs, and Path -> Path > RemotePath refactor.
-rw-r--r--node/Node.cpp6
-rw-r--r--node/Packet.hpp32
-rw-r--r--node/Path.hpp113
-rw-r--r--node/Peer.cpp15
-rw-r--r--node/Peer.hpp36
-rw-r--r--node/RemotePath.hpp97
-rw-r--r--node/SelfAwareness.cpp2
-rw-r--r--node/Switch.cpp2
-rw-r--r--node/Topology.cpp2
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);
}