mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-29 15:43:52 +00:00
Some cleanup, docs, and Path -> Path > RemotePath refactor.
This commit is contained in:
parent
feddd946f9
commit
93bb934d4e
@ -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();
|
||||
|
@ -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
|
||||
};
|
||||
|
113
node/Path.hpp
Normal file
113
node/Path.hpp
Normal file
@ -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
|
@ -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++]);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -182,12 +178,21 @@ 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;
|
||||
|
||||
|
@ -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) {}
|
||||
|
||||
inline void init(const InetAddress &addr,bool fixed)
|
||||
{
|
||||
_addr = addr;
|
||||
_lastSend = 0;
|
||||
_lastReceived = 0;
|
||||
_fixed = fixed;
|
||||
}
|
||||
|
||||
inline Path &operator=(const Path &p)
|
||||
{
|
||||
if (this != &p)
|
||||
memcpy(this,&p,sizeof(Path));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const InetAddress &address() const throw() { return _addr; }
|
||||
_lastReceived(0) {}
|
||||
|
||||
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
|
||||
* @param f New value of parent 'fixed' field
|
||||
*/
|
||||
inline void setFixed(const bool f)
|
||||
throw()
|
||||
{
|
||||
_fixed = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ -111,16 +95,6 @@ public:
|
||||
_lastReceived = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user