mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-20 05:28:01 +00:00
More threading improvements in root, more DNS TXT and multicast work (in progress)
This commit is contained in:
parent
9f9032ae36
commit
e08fc81397
@ -129,6 +129,67 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a DNS name contiaining a public key that can sign DNS entries
|
||||
*
|
||||
* This generates the initial fields of a DNS name that contains an
|
||||
* encoded public key. Users may append any domain suffix to this name.
|
||||
*
|
||||
* @return First field(s) of DNS name
|
||||
*/
|
||||
static inline Str makeSecureDnsName(const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE])
|
||||
{
|
||||
uint8_t tmp[ZT_ECC384_PUBLIC_KEY_SIZE+2];
|
||||
memcpy(tmp,p384SigningKeyPublic,ZT_ECC384_PUBLIC_KEY_SIZE);
|
||||
const uint16_t crc = Utils::crc16(tmp,ZT_ECC384_PUBLIC_KEY_SIZE);
|
||||
tmp[ZT_ECC384_PUBLIC_KEY_SIZE-2] = (uint8_t)(crc >> 8);
|
||||
tmp[ZT_ECC384_PUBLIC_KEY_SIZE-1] = (uint8_t)(crc);
|
||||
Str name;
|
||||
char b32[128];
|
||||
Utils::b32e(tmp,35,b32,sizeof(b32));
|
||||
name << b32;
|
||||
Utils::b32e(tmp + 35,(ZT_ECC384_PUBLIC_KEY_SIZE+2) - 35,b32,sizeof(b32));
|
||||
name << '.';
|
||||
name << b32;
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if a key was found and successfully decoded
|
||||
*/
|
||||
static inline bool decodeSecureDnsName(const char *name,uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE])
|
||||
{
|
||||
uint8_t b32[128];
|
||||
unsigned int b32ptr = 0;
|
||||
char tmp[1024];
|
||||
Utils::scopy(tmp,sizeof(tmp),name);
|
||||
bool ok = false;
|
||||
for(char *saveptr=(char *)0,*p=Utils::stok(tmp,".",&saveptr);p;p=Utils::stok((char *)0,".",&saveptr)) {
|
||||
if (b32ptr >= sizeof(b32))
|
||||
break;
|
||||
int s = Utils::b32d(p,b32 + b32ptr,sizeof(b32) - b32ptr);
|
||||
if (s > 0) {
|
||||
b32ptr += (unsigned int)s;
|
||||
if (b32ptr > 2) {
|
||||
const uint16_t crc = Utils::crc16(b32,b32ptr);
|
||||
if ((b32[b32ptr-2] == (uint8_t)(crc >> 8))&&(b32[b32ptr-1] == (uint8_t)(crc & 0xff))) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else break;
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (b32ptr == (ZT_ECC384_PUBLIC_KEY_SIZE + 2)) {
|
||||
memcpy(p384SigningKeyPublic,b32,ZT_ECC384_PUBLIC_KEY_SIZE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make DNS TXT records for this locator
|
||||
*
|
||||
@ -184,7 +245,7 @@ public:
|
||||
* now contains the contents of the supplied TXT records.
|
||||
*/
|
||||
template<typename I>
|
||||
inline bool decodeTxtRecords(I start,I end,const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE])
|
||||
inline bool decodeTxtRecords(const Str &dnsName,I start,I end)
|
||||
{
|
||||
uint8_t dec[256],s384[48];
|
||||
try {
|
||||
@ -204,11 +265,12 @@ public:
|
||||
for(std::vector<Str>::const_iterator i(txtRecords.begin());i!=txtRecords.end();++i)
|
||||
tmp->append(dec,Utils::b64d(i->c_str() + 2,dec,sizeof(dec)));
|
||||
|
||||
if (tmp->size() <= ZT_ECC384_SIGNATURE_SIZE) {
|
||||
uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE];
|
||||
if (decodeSecureDnsName(dnsName.c_str(),p384SigningKeyPublic)) {
|
||||
if (tmp->size() <= ZT_ECC384_SIGNATURE_SIZE)
|
||||
return false;
|
||||
}
|
||||
SHA384(s384,tmp->data(),tmp->size() - ZT_ECC384_SIGNATURE_SIZE);
|
||||
if (!ECC384ECDSAVerify(p384SigningKeyPublic,s384,((const uint8_t *)tmp->data()) + (tmp->size() - ZT_ECC384_SIGNATURE_SIZE))) {
|
||||
if (!ECC384ECDSAVerify(p384SigningKeyPublic,s384,((const uint8_t *)tmp->data()) + (tmp->size() - ZT_ECC384_SIGNATURE_SIZE)))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "Network.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "ScopedPtr.hpp"
|
||||
#include "Locator.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -172,6 +173,7 @@ ZT_ResultCode Node::processVirtualNetworkFrame(
|
||||
} else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct _processBackgroundTasks_ping_eachRoot
|
||||
{
|
||||
Hashtable< void *,bool > roots;
|
||||
@ -179,7 +181,7 @@ struct _processBackgroundTasks_ping_eachRoot
|
||||
void *tPtr;
|
||||
bool online;
|
||||
|
||||
inline void operator()(const Root &root,const SharedPtr<Peer> &peer)
|
||||
ZT_ALWAYS_INLINE void operator()(const Root &root,const SharedPtr<Peer> &peer)
|
||||
{
|
||||
unsigned int v4SendCount = 0,v6SendCount = 0;
|
||||
peer->ping(tPtr,now,v4SendCount,v6SendCount);
|
||||
@ -204,6 +206,7 @@ struct _processBackgroundTasks_ping_eachRoot
|
||||
roots.set((void *)peer.ptr(),true);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
struct _processBackgroundTasks_ping_eachPeer
|
||||
{
|
||||
@ -211,7 +214,7 @@ struct _processBackgroundTasks_ping_eachPeer
|
||||
void *tPtr;
|
||||
Hashtable< void *,bool > *roots;
|
||||
|
||||
inline void operator()(const SharedPtr<Peer> &peer)
|
||||
ZT_ALWAYS_INLINE void operator()(const SharedPtr<Peer> &peer)
|
||||
{
|
||||
if (!roots->contains((void *)peer.ptr())) {
|
||||
unsigned int v4SendCount = 0,v6SendCount = 0;
|
||||
@ -234,22 +237,24 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
|
||||
if ((now - _lastPing) >= ZT_PEER_PING_PERIOD) {
|
||||
_lastPing = now;
|
||||
try {
|
||||
#if 0
|
||||
_processBackgroundTasks_ping_eachRoot rf;
|
||||
rf.now = now;
|
||||
rf.tPtr = tptr;
|
||||
rf.online = false;
|
||||
RR->topology->eachRoot(rf);
|
||||
#endif
|
||||
|
||||
_processBackgroundTasks_ping_eachPeer pf;
|
||||
pf.now = now;
|
||||
pf.tPtr = tptr;
|
||||
pf.roots = &rf.roots;
|
||||
//pf.roots = &rf.roots;
|
||||
RR->topology->eachPeer(pf);
|
||||
|
||||
if (rf.online != _online) {
|
||||
_online = rf.online;
|
||||
postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
|
||||
}
|
||||
//if (rf.online != _online) {
|
||||
// _online = rf.online;
|
||||
// postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
|
||||
//}
|
||||
} catch ( ... ) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
|
43
node/Str.hpp
43
node/Str.hpp
@ -151,14 +151,35 @@ public:
|
||||
return ((*this) << a.toString(tmp));
|
||||
}
|
||||
|
||||
ZT_ALWAYS_INLINE Str &append(const char *s,const unsigned int max)
|
||||
{
|
||||
if (likely(s != (const char *)0)) {
|
||||
unsigned long l = _l;
|
||||
unsigned int c = 0;
|
||||
while (*s) {
|
||||
if (c++ >= max) break;
|
||||
if (unlikely(l >= ZT_STR_CAPACITY)) {
|
||||
_s[ZT_STR_CAPACITY] = 0;
|
||||
_l = ZT_STR_CAPACITY;
|
||||
throw ZT_EXCEPTION_OUT_OF_BOUNDS;
|
||||
}
|
||||
_s[l++] = *s;
|
||||
++s;
|
||||
}
|
||||
_s[l] = 0;
|
||||
_l = (uint8_t)l;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZT_ALWAYS_INLINE operator bool() const { return (_l != 0); }
|
||||
|
||||
ZT_ALWAYS_INLINE bool operator==(const Str &s) const { return ((_l == s._l)&&(strcmp(_s,s._s) == 0)); }
|
||||
ZT_ALWAYS_INLINE bool operator!=(const Str &s) const { return ((_l != s._l)||(strcmp(_s,s._s) != 0)); }
|
||||
ZT_ALWAYS_INLINE bool operator<(const Str &s) const { return ((_l < s._l)&&(strcmp(_s,s._s) < 0)); }
|
||||
ZT_ALWAYS_INLINE bool operator>(const Str &s) const { return ((_l > s._l)&&(strcmp(_s,s._s) > 0)); }
|
||||
ZT_ALWAYS_INLINE bool operator<=(const Str &s) const { return ((_l <= s._l)&&(strcmp(_s,s._s) <= 0)); }
|
||||
ZT_ALWAYS_INLINE bool operator>=(const Str &s) const { return ((_l >= s._l)&&(strcmp(_s,s._s) >= 0)); }
|
||||
ZT_ALWAYS_INLINE bool operator==(const Str &s) const { return ((_l == s._l)&&(memcmp(_s,s._s,_l) == 0)); }
|
||||
ZT_ALWAYS_INLINE bool operator!=(const Str &s) const { return ((_l != s._l)||(memcmp(_s,s._s,_l) != 0)); }
|
||||
ZT_ALWAYS_INLINE bool operator<(const Str &s) const { return ( (_l < s._l) ? true : ((_l == s._l) ? (memcmp(_s,s._s,_l) < 0) : false) ); }
|
||||
ZT_ALWAYS_INLINE bool operator>(const Str &s) const { return (s < *this); }
|
||||
ZT_ALWAYS_INLINE bool operator<=(const Str &s) const { return !(s < *this); }
|
||||
ZT_ALWAYS_INLINE bool operator>=(const Str &s) const { return !(*this < s); }
|
||||
|
||||
ZT_ALWAYS_INLINE bool operator==(const char *s) const { return (strcmp(_s,s) == 0); }
|
||||
ZT_ALWAYS_INLINE bool operator!=(const char *s) const { return (strcmp(_s,s) != 0); }
|
||||
@ -167,6 +188,16 @@ public:
|
||||
ZT_ALWAYS_INLINE bool operator<=(const char *s) const { return (strcmp(_s,s) <= 0); }
|
||||
ZT_ALWAYS_INLINE bool operator>=(const char *s) const { return (strcmp(_s,s) >= 0); }
|
||||
|
||||
ZT_ALWAYS_INLINE unsigned long hashCode() const
|
||||
{
|
||||
const char *p = _s;
|
||||
unsigned long h = 0;
|
||||
char c;
|
||||
while ((c = *(p++)))
|
||||
h = (31 * h) + (unsigned long)c;
|
||||
return h;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t _l;
|
||||
char _s[ZT_STR_CAPACITY+1];
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <set>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "../include/ZeroTierOne.h"
|
||||
@ -32,8 +33,9 @@
|
||||
#include "Mutex.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "Root.hpp"
|
||||
#include "Locator.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "ScopedPtr.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -65,7 +67,7 @@ public:
|
||||
{
|
||||
SharedPtr<Peer> np;
|
||||
{
|
||||
Mutex::Lock _l(_peers_m);
|
||||
Mutex::Lock _l(_peers_l);
|
||||
SharedPtr<Peer> &hp = _peers[peer->address()];
|
||||
if (!hp)
|
||||
hp = peer;
|
||||
@ -86,11 +88,12 @@ public:
|
||||
if (zta == _myIdentity.address())
|
||||
return SharedPtr<Peer>();
|
||||
|
||||
Mutex::Lock l1(_peers_m);
|
||||
Mutex::Lock l1(_peers_l);
|
||||
const SharedPtr<Peer> *const ap = _peers.get(zta);
|
||||
if (ap)
|
||||
return *ap;
|
||||
|
||||
#if 0
|
||||
Mutex::Lock l2(_roots_m);
|
||||
for(std::vector<Root>::const_iterator r(_roots.begin());r!=_roots.end();++r) {
|
||||
if (r->address() == zta) {
|
||||
@ -101,6 +104,7 @@ public:
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return SharedPtr<Peer>();
|
||||
}
|
||||
@ -115,7 +119,7 @@ public:
|
||||
if (zta == _myIdentity.address()) {
|
||||
return _myIdentity;
|
||||
} else {
|
||||
Mutex::Lock _l(_peers_m);
|
||||
Mutex::Lock _l(_peers_l);
|
||||
const SharedPtr<Peer> *const ap = _peers.get(zta);
|
||||
if (ap)
|
||||
return (*ap)->identity();
|
||||
@ -132,7 +136,7 @@ public:
|
||||
*/
|
||||
ZT_ALWAYS_INLINE SharedPtr<Path> getPath(const int64_t l,const InetAddress &r)
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
Mutex::Lock _l(_paths_l);
|
||||
SharedPtr<Path> &p = _paths[Path::HashKey(l,r)];
|
||||
if (!p)
|
||||
p.set(new Path(l,r));
|
||||
@ -145,11 +149,13 @@ public:
|
||||
*/
|
||||
ZT_ALWAYS_INLINE bool isRoot(const Identity &id) const
|
||||
{
|
||||
#if 0
|
||||
Mutex::Lock l(_roots_m);
|
||||
for(std::vector<Root>::const_iterator r(_roots.begin());r!=_roots.end();++r) {
|
||||
if (r->is(id))
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -159,7 +165,7 @@ public:
|
||||
ZT_ALWAYS_INLINE void doPeriodicTasks(int64_t now)
|
||||
{
|
||||
{
|
||||
Mutex::Lock _l1(_peers_m);
|
||||
Mutex::Lock _l1(_peers_l);
|
||||
Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
|
||||
Address *a = (Address *)0;
|
||||
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
|
||||
@ -170,7 +176,7 @@ public:
|
||||
}
|
||||
}
|
||||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
Mutex::Lock _l(_paths_l);
|
||||
Hashtable< Path::HashKey,SharedPtr<Path> >::Iterator i(_paths);
|
||||
Path::HashKey *k = (Path::HashKey *)0;
|
||||
SharedPtr<Path> *p = (SharedPtr<Path> *)0;
|
||||
@ -188,7 +194,7 @@ public:
|
||||
ZT_ALWAYS_INLINE unsigned long countActive(int64_t now) const
|
||||
{
|
||||
unsigned long cnt = 0;
|
||||
Mutex::Lock _l(_peers_m);
|
||||
Mutex::Lock _l(_peers_l);
|
||||
Hashtable< Address,SharedPtr<Peer> >::Iterator i(const_cast<Topology *>(this)->_peers);
|
||||
Address *a = (Address *)0;
|
||||
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
|
||||
@ -212,7 +218,7 @@ public:
|
||||
template<typename F>
|
||||
ZT_ALWAYS_INLINE void eachPeer(F f)
|
||||
{
|
||||
Mutex::Lock l(_peers_m);
|
||||
Mutex::Lock l(_peers_l);
|
||||
Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
|
||||
Address *a = (Address *)0;
|
||||
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
|
||||
@ -221,6 +227,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Apply a function or function object to all roots
|
||||
*
|
||||
@ -237,7 +244,7 @@ public:
|
||||
SharedPtr<Peer> rp;
|
||||
for(std::vector<Root>::const_iterator i(_roots.begin());i!=_roots.end();++i) {
|
||||
{
|
||||
Mutex::Lock l2(_peers_m);
|
||||
Mutex::Lock l2(_peers_l);
|
||||
const SharedPtr<Peer> *const ap = _peers.get(i->address());
|
||||
if (ap) {
|
||||
rp = *ap;
|
||||
@ -256,7 +263,7 @@ public:
|
||||
* @param now Current time
|
||||
* @return Best/fastest currently connected root or NULL if none
|
||||
*/
|
||||
ZT_ALWAYS_INLINE SharedPtr<Peer> root(const int64_t now)
|
||||
inline SharedPtr<Peer> root(const int64_t now)
|
||||
{
|
||||
Mutex::Lock l(_bestRoot_m);
|
||||
if ((!_bestRoot)||((now - _lastRankedBestRoot) >= ZT_FIND_BEST_ROOT_PERIOD)) {
|
||||
@ -266,7 +273,7 @@ public:
|
||||
long bestQuality = 2147483647;
|
||||
for(std::vector<Root>::const_iterator i(_roots.begin());i!=_roots.end();++i) {
|
||||
{
|
||||
Mutex::Lock l2(_peers_m);
|
||||
Mutex::Lock l2(_peers_l);
|
||||
const SharedPtr<Peer> *const ap = _peers.get(i->address());
|
||||
if (ap) {
|
||||
rp = *ap;
|
||||
@ -287,6 +294,54 @@ public:
|
||||
}
|
||||
return _bestRoot;
|
||||
}
|
||||
#endif
|
||||
|
||||
ZT_ALWAYS_INLINE SharedPtr<Peer> root(const int64_t now)
|
||||
{
|
||||
return SharedPtr<Peer>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Names of dynamic roots currently known by the system
|
||||
*/
|
||||
ZT_ALWAYS_INLINE std::vector<Str> dynamicRootNames() const
|
||||
{
|
||||
Mutex::Lock l(_dynamicRoots_l);
|
||||
return _dynamicRoots.keys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or update a static root entry
|
||||
*
|
||||
* @param id Static root's identity
|
||||
* @param addrs Static root's IP address(es)
|
||||
*/
|
||||
ZT_ALWAYS_INLINE void setStaticRoot(const Identity &id,const std::vector<InetAddress> &addrs)
|
||||
{
|
||||
Mutex::Lock l(_staticRoots_l);
|
||||
_staticRoots[id] = addrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or update dynamic root if new locator is newer and valid
|
||||
*
|
||||
* This checks internal validity of the new locator including its internal self-signature.
|
||||
* It does not check any DNS signatures.
|
||||
*
|
||||
* @param dnsName DNS name used to retrive root
|
||||
* @param latestLocator Latest locator
|
||||
* @return True if latest locator is internally valid and newer
|
||||
*/
|
||||
ZT_ALWAYS_INLINE bool setDynamicRoot(const Str &dnsName,const Locator &latestLocator)
|
||||
{
|
||||
Mutex::Lock l(_dynamicRoots_l);
|
||||
Locator &ll = _dynamicRoots[dnsName];
|
||||
if (ll.timestamp() < latestLocator.timestamp()) {
|
||||
ll = latestLocator;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the best relay to a given address, which may or may not be a root
|
||||
@ -298,15 +353,15 @@ public:
|
||||
ZT_ALWAYS_INLINE SharedPtr<Peer> findRelayTo(const int64_t now,const Address &toAddr)
|
||||
{
|
||||
// TODO: in the future this will check 'mesh-like' relays and if enabled consult LF for other roots (for if this is a root)
|
||||
return root(now);
|
||||
//return root(now);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allPeers vector to fill with all current peers
|
||||
*/
|
||||
ZT_ALWAYS_INLINE void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const
|
||||
inline void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const
|
||||
{
|
||||
Mutex::Lock l(_peers_m);
|
||||
Mutex::Lock l(_peers_l);
|
||||
allPeers.clear();
|
||||
allPeers.reserve(_peers.size());
|
||||
Hashtable< Address,SharedPtr<Peer> >::Iterator i(*(const_cast<Hashtable< Address,SharedPtr<Peer> > *>(&_peers)));
|
||||
@ -385,7 +440,7 @@ public:
|
||||
/**
|
||||
* Set or clear physical path configuration (called via Node::setPhysicalPathConfiguration)
|
||||
*/
|
||||
ZT_ALWAYS_INLINE void setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig)
|
||||
inline void setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig)
|
||||
{
|
||||
if (!pathNetwork) {
|
||||
_numConfiguredPhysicalPaths = 0;
|
||||
@ -422,17 +477,26 @@ public:
|
||||
private:
|
||||
const RuntimeEnvironment *const RR;
|
||||
const Identity _myIdentity;
|
||||
|
||||
std::pair<InetAddress,ZT_PhysicalPathConfiguration> _physicalPathConfig[ZT_MAX_CONFIGURABLE_PATHS];
|
||||
unsigned int _numConfiguredPhysicalPaths;
|
||||
std::vector<Root> _roots;
|
||||
SharedPtr<Peer> _bestRoot;
|
||||
int64_t _lastRankedBestRoot;
|
||||
|
||||
Hashtable< Address,SharedPtr<Peer> > _peers;
|
||||
Hashtable< Path::HashKey,SharedPtr<Path> > _paths;
|
||||
Mutex _roots_m;
|
||||
Mutex _bestRoot_m;
|
||||
Mutex _peers_m;
|
||||
Mutex _paths_m;
|
||||
|
||||
Hashtable< Identity,std::vector<InetAddress> > _staticRoots;
|
||||
Hashtable< Str,Locator > _dynamicRoots;
|
||||
|
||||
//std::vector<Root> _roots;
|
||||
//SharedPtr<Peer> _bestRoot;
|
||||
//int64_t _lastRankedBestRoot;
|
||||
//Mutex _roots_m;
|
||||
//Mutex _bestRoot_m;
|
||||
|
||||
Mutex _peers_l;
|
||||
Mutex _paths_l;
|
||||
Mutex _staticRoots_l;
|
||||
Mutex _dynamicRoots_l;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -95,6 +95,49 @@ char *Utils::decimal(unsigned long n,char s[24])
|
||||
return s;
|
||||
}
|
||||
|
||||
unsigned short Utils::crc16(const void *buf,unsigned int len)
|
||||
{
|
||||
static const uint16_t crc16tab[256]= {
|
||||
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
|
||||
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
|
||||
0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
|
||||
0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
|
||||
0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
|
||||
0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
|
||||
0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
|
||||
0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
|
||||
0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
|
||||
0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
|
||||
0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
|
||||
0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
|
||||
0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
|
||||
0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
|
||||
0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
|
||||
0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
|
||||
0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
|
||||
0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
|
||||
0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
|
||||
0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
|
||||
0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
|
||||
0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
|
||||
0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
|
||||
0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
|
||||
0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
|
||||
0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
|
||||
0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
|
||||
0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
|
||||
0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
|
||||
0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
|
||||
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
|
||||
0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
|
||||
};
|
||||
uint16_t crc = 0;
|
||||
const uint8_t *p = (const uint8_t *)buf;
|
||||
for(unsigned int i=0;i<len;++i)
|
||||
crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *(p++)) & 0x00ff];
|
||||
return crc;
|
||||
}
|
||||
|
||||
unsigned int Utils::unhex(const char *h,void *buf,unsigned int buflen)
|
||||
{
|
||||
unsigned int l = 0;
|
||||
|
@ -68,6 +68,11 @@ public:
|
||||
*/
|
||||
static char *decimal(unsigned long n,char s[24]);
|
||||
|
||||
/**
|
||||
* Compute CRC16-CCITT
|
||||
*/
|
||||
static uint16_t crc16(const void *buf,unsigned int len);
|
||||
|
||||
/**
|
||||
* Convert an unsigned integer into hex
|
||||
*
|
||||
|
5
one.cpp
5
one.cpp
@ -94,10 +94,9 @@ static OneService *volatile zt1Service = (OneService *)0;
|
||||
static void cliPrintHelp(const char *pn,FILE *out)
|
||||
{
|
||||
fprintf(out,
|
||||
"%s version %d.%d.%d build %d (platform %d arch %d)" ZT_EOL_S,
|
||||
"%s version %d.%d.%d build %d" ZT_EOL_S,
|
||||
PROGRAM_NAME,
|
||||
ZEROTIER_ONE_VERSION_MAJOR, ZEROTIER_ONE_VERSION_MINOR, ZEROTIER_ONE_VERSION_REVISION, ZEROTIER_ONE_VERSION_BUILD,
|
||||
ZT_BUILD_PLATFORM, ZT_BUILD_ARCHITECTURE);
|
||||
ZEROTIER_ONE_VERSION_MAJOR, ZEROTIER_ONE_VERSION_MINOR, ZEROTIER_ONE_VERSION_REVISION, ZEROTIER_ONE_VERSION_BUILD);
|
||||
fprintf(out,
|
||||
COPYRIGHT_NOTICE ZT_EOL_S
|
||||
LICENSE_GRANT ZT_EOL_S);
|
||||
|
@ -107,8 +107,10 @@ using json = nlohmann::json;
|
||||
|
||||
#ifdef MSG_DONTWAIT
|
||||
#define SENDTO_FLAGS MSG_DONTWAIT
|
||||
#define RECVFROM_FLAGS 0
|
||||
#else
|
||||
#define SENDTO_FLAGS 0
|
||||
#define RECVFROM_FLAGS 0
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -911,7 +913,7 @@ int main(int argc,char **argv)
|
||||
memset(&in6,0,sizeof(in6));
|
||||
for(;;) {
|
||||
socklen_t sl = sizeof(in6);
|
||||
const int pl = (int)recvfrom(s6,pkt.unsafeData(),pkt.capacity(),0,(struct sockaddr *)&in6,&sl);
|
||||
const int pl = (int)recvfrom(s6,pkt.unsafeData(),pkt.capacity(),RECVFROM_FLAGS,(struct sockaddr *)&in6,&sl);
|
||||
if (pl > 0) {
|
||||
if (pl >= ZT_PROTO_MIN_FRAGMENT_LENGTH) {
|
||||
try {
|
||||
@ -940,7 +942,7 @@ int main(int argc,char **argv)
|
||||
memset(&in4,0,sizeof(in4));
|
||||
for(;;) {
|
||||
socklen_t sl = sizeof(in4);
|
||||
const int pl = (int)recvfrom(s4,pkt.unsafeData(),pkt.capacity(),0,(struct sockaddr *)&in4,&sl);
|
||||
const int pl = (int)recvfrom(s4,pkt.unsafeData(),pkt.capacity(),RECVFROM_FLAGS,(struct sockaddr *)&in4,&sl);
|
||||
if (pl > 0) {
|
||||
if (pl >= ZT_PROTO_MIN_FRAGMENT_LENGTH) {
|
||||
try {
|
||||
@ -986,43 +988,43 @@ int main(int argc,char **argv)
|
||||
o << '[';
|
||||
try {
|
||||
bool first = true;
|
||||
std::lock_guard<std::mutex> l(s_peersByIdentity_l);
|
||||
for(auto p=s_peersByIdentity.begin();p!=s_peersByIdentity.end();++p) {
|
||||
std::lock_guard<std::mutex> l(s_peers_l);
|
||||
for(auto p=s_peers.begin();p!=s_peers.end();++p) {
|
||||
if (first)
|
||||
first = false;
|
||||
else o << ',';
|
||||
o <<
|
||||
"{\"address\":\"" << p->first.address().toString(tmp) << "\""
|
||||
"{\"address\":\"" << (*p)->id.address().toString(tmp) << "\""
|
||||
",\"latency\":-1"
|
||||
",\"paths\":[";
|
||||
if (p->second->ip4) {
|
||||
if ((*p)->ip4) {
|
||||
o <<
|
||||
"{\"active\":true"
|
||||
",\"address\":\"" << p->second->ip4.toIpString(tmp) << "\\/" << p->second->ip4.port() << "\""
|
||||
",\"address\":\"" << (*p)->ip4.toIpString(tmp) << "\\/" << (*p)->ip4.port() << "\""
|
||||
",\"expired\":false"
|
||||
",\"lastReceive\":" << p->second->lastReceive <<
|
||||
",\"lastSend\":" << p->second->lastSend <<
|
||||
",\"lastReceive\":" << (*p)->lastReceive <<
|
||||
",\"lastSend\":" << (*p)->lastSend <<
|
||||
",\"preferred\":true"
|
||||
",\"trustedPathId\":0}";
|
||||
}
|
||||
if (p->second->ip6) {
|
||||
if (p->second->ip4)
|
||||
if ((*p)->ip6) {
|
||||
if ((*p)->ip4)
|
||||
o << ',';
|
||||
o <<
|
||||
"{\"active\":true"
|
||||
",\"address\":\"" << p->second->ip6.toIpString(tmp) << "\\/" << p->second->ip6.port() << "\""
|
||||
",\"address\":\"" << (*p)->ip6.toIpString(tmp) << "\\/" << (*p)->ip6.port() << "\""
|
||||
",\"expired\":false"
|
||||
",\"lastReceive\":" << p->second->lastReceive <<
|
||||
",\"lastSend\":" << p->second->lastSend <<
|
||||
",\"preferred\":" << ((p->second->ip4) ? "false" : "true") <<
|
||||
",\"lastReceive\":" << (*p)->lastReceive <<
|
||||
",\"lastSend\":" << (*p)->lastSend <<
|
||||
",\"preferred\":" << (((*p)->ip4) ? "false" : "true") <<
|
||||
",\"trustedPathId\":0}";
|
||||
}
|
||||
o << "]"
|
||||
",\"role\":\"LEAF\""
|
||||
",\"version\":\"" << p->second->vMajor << '.' << p->second->vMinor << '.' << p->second->vRev << "\""
|
||||
",\"versionMajor\":" << p->second->vMajor <<
|
||||
",\"versionMinor\":" << p->second->vMinor <<
|
||||
",\"versionRev\":" << p->second->vRev << "}";
|
||||
",\"version\":\"" << (*p)->vMajor << '.' << (*p)->vMinor << '.' << (*p)->vRev << "\""
|
||||
",\"versionMajor\":" << (*p)->vMajor <<
|
||||
",\"versionMinor\":" << (*p)->vMinor <<
|
||||
",\"versionRev\":" << (*p)->vRev << "}";
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
o << ']';
|
||||
@ -1146,10 +1148,19 @@ int main(int argc,char **argv)
|
||||
}
|
||||
|
||||
// Remove expired peers
|
||||
try {
|
||||
std::vector< SharedPtr<RootPeer> > toRemove;
|
||||
toRemove.reserve(1024);
|
||||
{
|
||||
std::lock_guard<std::mutex> pbi_l(s_peers_l);
|
||||
for(auto p=s_peers.begin();p!=s_peers.end();) {
|
||||
if ((now - (*p)->lastReceive) > ZT_PEER_ACTIVITY_TIMEOUT) {
|
||||
toRemove.emplace_back(*p);
|
||||
s_peers.erase(p++);
|
||||
} else ++p;
|
||||
}
|
||||
}
|
||||
for(auto p=toRemove.begin();p!=toRemove.end();++p) {
|
||||
{
|
||||
std::lock_guard<std::mutex> pbi_l(s_peersByIdentity_l);
|
||||
s_peersByIdentity.erase((*p)->id);
|
||||
@ -1163,10 +1174,8 @@ int main(int argc,char **argv)
|
||||
s_peersByVirtAddr.erase(pbv);
|
||||
}
|
||||
}
|
||||
s_peers.erase(p++);
|
||||
} else ++p;
|
||||
}
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
|
||||
// Remove old rendezvous entries
|
||||
{
|
||||
@ -1212,17 +1221,16 @@ int main(int argc,char **argv)
|
||||
if (pf) {
|
||||
std::vector< SharedPtr<RootPeer> > sp;
|
||||
{
|
||||
std::lock_guard<std::mutex> pbi_l(s_peersByIdentity_l);
|
||||
sp.reserve(s_peersByIdentity.size());
|
||||
for(auto p=s_peersByIdentity.begin();p!=s_peersByIdentity.end();++p) {
|
||||
sp.push_back(p->second);
|
||||
std::lock_guard<std::mutex> pbi_l(s_peers_l);
|
||||
sp.reserve(s_peers.size());
|
||||
for(auto p=s_peers.begin();p!=s_peers.end();++p) {
|
||||
sp.emplace_back(*p);
|
||||
}
|
||||
}
|
||||
std::sort(sp.begin(),sp.end(),[](const SharedPtr<RootPeer> &a,const SharedPtr<RootPeer> &b) { return (a->id < b->id); });
|
||||
|
||||
fprintf(pf,"Address %21s %45s %10s %6s %10s" ZT_EOL_S,"IPv4","IPv6","Age(sec)","Vers","Fwd(KiB/s)");
|
||||
{
|
||||
std::lock_guard<std::mutex> lf_l(s_lastForwardedTo_l);
|
||||
char ip4[128],ip6[128],ver[128];
|
||||
for(auto p=sp.begin();p!=sp.end();++p) {
|
||||
if ((*p)->ip4) {
|
||||
@ -1239,9 +1247,11 @@ int main(int argc,char **argv)
|
||||
}
|
||||
OSUtils::ztsnprintf(ver,sizeof(ver),"%d.%d.%d",(*p)->vMajor,(*p)->vMinor,(*p)->vRev);
|
||||
double forwardingSpeed = 0.0;
|
||||
s_lastForwardedTo_l.lock();
|
||||
auto lft = s_lastForwardedTo.find((*p)->id.address());
|
||||
if (lft != s_lastForwardedTo.end())
|
||||
forwardingSpeed = lft->second.bps.perSecond(now) / 1024.0;
|
||||
s_lastForwardedTo_l.unlock();
|
||||
fprintf(pf,"%.10llx %21s %45s %10.4f %6s %10.4f" ZT_EOL_S,
|
||||
(unsigned long long)(*p)->id.address().toInt(),
|
||||
ip4,
|
||||
@ -1265,11 +1275,12 @@ int main(int argc,char **argv)
|
||||
if (sf) {
|
||||
fprintf(sf,"Uptime (seconds) : %ld" ZT_EOL_S,(long)((now - s_startTime) / 1000));
|
||||
s_peersByIdentity_l.lock();
|
||||
fprintf(sf,"Peers : %llu" ZT_EOL_S,(unsigned long long)s_peersByIdentity.size());
|
||||
s_peersByVirtAddr_l.lock();
|
||||
fprintf(sf,"Virtual Address Collisions : %llu" ZT_EOL_S,(unsigned long long)(s_peersByIdentity.size() - s_peersByVirtAddr.size()));
|
||||
s_peersByVirtAddr_l.unlock();
|
||||
auto peersByIdentitySize = s_peersByIdentity.size();
|
||||
s_peersByIdentity_l.unlock();
|
||||
fprintf(sf,"Peers : %llu" ZT_EOL_S,(unsigned long long)peersByIdentitySize);
|
||||
s_peersByVirtAddr_l.lock();
|
||||
fprintf(sf,"Virtual Address Collisions : %llu" ZT_EOL_S,(unsigned long long)(peersByIdentitySize - s_peersByVirtAddr.size()));
|
||||
s_peersByVirtAddr_l.unlock();
|
||||
s_rendezvousTracking_l.lock();
|
||||
uint64_t unsuccessfulp2p = 0;
|
||||
for(auto lr=s_rendezvousTracking.begin();lr!=s_rendezvousTracking.end();++lr) {
|
||||
|
@ -620,6 +620,7 @@ static int testIdentity()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
try {
|
||||
std::cout << "[identity] Testing Locator and DNS TXT encoding... "; std::cout.flush();
|
||||
uint8_t dnsPub[ZT_ECC384_PUBLIC_KEY_SIZE],dnsPriv[ZT_ECC384_PRIVATE_KEY_SIZE];
|
||||
@ -633,7 +634,7 @@ static int testIdentity()
|
||||
l->sign(*ti);
|
||||
auto tr = l->makeTxtRecords(dnsPub,dnsPriv);
|
||||
std::unique_ptr<Locator> l2(new Locator());
|
||||
if (!l2->decodeTxtRecords(tr.begin(),tr.end(),dnsPub)) {
|
||||
if (!l2->decodeTxtRecords(tr.begin(),tr.end())) {
|
||||
std::cout << "FAILED (decode TXT records returned false)" ZT_EOL_S;
|
||||
return -1;
|
||||
}
|
||||
@ -642,6 +643,7 @@ static int testIdentity()
|
||||
std::cout << "FAILED (threw integer exception " << e << ")" ZT_EOL_S;
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user