mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-01 00:45:27 +00:00
Work in progress on refactoring root-topology into World and adding in-band updates.
This commit is contained in:
parent
70fe7dd1fd
commit
1b1945c63e
@ -1,82 +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 <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/
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Defaults.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
// bin2c'd signed default root topology dictionary
|
||||
#include "../root-topology/ZT_DEFAULT_ROOT_TOPOLOGY.c"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <WinSock2.h>
|
||||
#include <Windows.h>
|
||||
#include <ShlObj.h>
|
||||
#endif
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
const Defaults ZT_DEFAULTS;
|
||||
|
||||
static inline std::map< Address,Identity > _mkRootTopologyAuth()
|
||||
{
|
||||
std::map< Address,Identity > ua;
|
||||
|
||||
{ // 0001
|
||||
Identity id("77792b1c02:0:b5c361e8e9c2154e82c3e902fdfc337468b092a7c4d8dc685c37eb10ee4f3c17cc0bb1d024167e8cb0824d12263428373582da3d0a9a14b36e4546c317e811e6");
|
||||
ua[id.address()] = id;
|
||||
}
|
||||
{ // 0002
|
||||
Identity id("86921e6de1:0:9ba04f9f12ed54ef567f548cb69d31e404537d7b0ee000c63f3d7c8d490a1a47a5a5b2af0cbe12d23f9194270593f298d936d7c872612ea509ef1c67ce2c7fc1");
|
||||
ua[id.address()] = id;
|
||||
}
|
||||
{ // 0003
|
||||
Identity id("90302b7025:0:358154a57af1b7afa07d0d91b69b92eaad2f11ade7f02343861f0c1b757d15626e8cb7f08fc52993d2202a39cbf5128c5647ee8c63d27d92db5a1d0fbe1eba19");
|
||||
ua[id.address()] = id;
|
||||
}
|
||||
{ // 0004
|
||||
Identity id("e5174078ee:0:c3f90daa834a74ee47105f5726ae2e29fc8ae0e939c9326788b52b16d847354de8de3b13a81896bbb509b91e1da21763073a30bbfb2b8e994550798d30a2d709");
|
||||
ua[id.address()] = id;
|
||||
}
|
||||
|
||||
return ua;
|
||||
}
|
||||
|
||||
Defaults::Defaults() :
|
||||
defaultRootTopology((const char *)ZT_DEFAULT_ROOT_TOPOLOGY,ZT_DEFAULT_ROOT_TOPOLOGY_LEN),
|
||||
rootTopologyAuthorities(_mkRootTopologyAuth()),
|
||||
v4Broadcast(((uint32_t)0xffffffff),ZT_DEFAULT_PORT)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
@ -1,74 +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 <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_DEFAULTS_HPP
|
||||
#define ZT_DEFAULTS_HPP
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* Static configuration defaults
|
||||
*
|
||||
* These are the default values that ship baked into the ZeroTier binary. They
|
||||
* define the basic parameters required for it to connect to the rest of the
|
||||
* network and obtain software updates.
|
||||
*/
|
||||
class Defaults
|
||||
{
|
||||
public:
|
||||
Defaults();
|
||||
|
||||
/**
|
||||
* Default root topology dictionary
|
||||
*/
|
||||
const std::string defaultRootTopology;
|
||||
|
||||
/**
|
||||
* Identities permitted to sign root topology dictionaries
|
||||
*/
|
||||
const std::map< Address,Identity > rootTopologyAuthorities;
|
||||
|
||||
/**
|
||||
* Address for IPv4 LAN auto-location broadcasts: 255.255.255.255:9993
|
||||
*/
|
||||
const InetAddress v4Broadcast;
|
||||
};
|
||||
|
||||
extern const Defaults ZT_DEFAULTS;
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
@ -835,7 +835,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
|
||||
unsigned int ptr = ZT_PACKET_IDX_PAYLOAD + 2;
|
||||
|
||||
while (count--) { // if ptr overflows Buffer will throw
|
||||
// TODO: properly handle blacklisting, support other features... see Packet.hpp.
|
||||
// TODO: some flags are not yet implemented
|
||||
|
||||
unsigned int flags = (*this)[ptr++];
|
||||
unsigned int extLen = at<uint16_t>(ptr); ptr += 2;
|
||||
@ -846,14 +846,14 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
|
||||
switch(addrType) {
|
||||
case 4: {
|
||||
InetAddress a(field(ptr,4),4,at<uint16_t>(ptr + 4));
|
||||
if ( ((flags & (0x01 | 0x02)) == 0) && (Path::isAddressValidForPath(a)) ) {
|
||||
if ( ((flags & 0x01) == 0) && (Path::isAddressValidForPath(a)) ) {
|
||||
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
|
||||
peer->attemptToContactAt(RR,_localAddress,a,RR->node->now());
|
||||
}
|
||||
} break;
|
||||
case 6: {
|
||||
InetAddress a(field(ptr,16),16,at<uint16_t>(ptr + 16));
|
||||
if ( ((flags & (0x01 | 0x02)) == 0) && (Path::isAddressValidForPath(a)) ) {
|
||||
if ( ((flags & 0x01) == 0) && (Path::isAddressValidForPath(a)) ) {
|
||||
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
|
||||
peer->attemptToContactAt(RR,_localAddress,a,RR->node->now());
|
||||
}
|
||||
|
@ -564,6 +564,8 @@ public:
|
||||
* <[2] software revision (of responder)>
|
||||
* <[1] destination address type (for this OK, not copied from HELLO)>
|
||||
* [<[...] destination address>]
|
||||
* <[8] 64-bit world ID of current world>
|
||||
* <[8] 64-bit timestamp of current world>
|
||||
*
|
||||
* ERROR has no payload.
|
||||
*/
|
||||
@ -911,7 +913,7 @@ public:
|
||||
*
|
||||
* Path record flags:
|
||||
* 0x01 - Forget this path if it is currently known
|
||||
* 0x02 - Blacklist this path, do not use
|
||||
* 0x02 - (Unused)
|
||||
* 0x04 - Disable encryption (trust: privacy)
|
||||
* 0x08 - Disable encryption and authentication (trust: ultimate)
|
||||
*
|
||||
@ -1094,7 +1096,36 @@ public:
|
||||
*
|
||||
* ERROR has no payload.
|
||||
*/
|
||||
VERB_REQUEST_PROOF_OF_WORK = 19
|
||||
VERB_REQUEST_PROOF_OF_WORK = 19,
|
||||
|
||||
/**
|
||||
* Generic binary object access:
|
||||
* <[8] 64-bit request ID>
|
||||
* <[4] 32-bit index in blob to retrieve>
|
||||
* <[2] 16-bit max length of block to retrieve>
|
||||
* <[2] 16-bit length of blob identifier>
|
||||
* <[...] blob identifier>
|
||||
*
|
||||
* This is used as a generic remote object retrieval mechanism. It returns
|
||||
* OK if the object is accessible, INVALID_REQUEST if the index is beyond
|
||||
* the size of the blob or another element is invalid, and OBJ_NOT_FOUND
|
||||
* if no blob with the given identifier is available.
|
||||
*
|
||||
* Blob identifiers follow a de facto path-like schema, with the following
|
||||
* names reserved:
|
||||
* world - Current world definition (see World.hpp)
|
||||
* updates.d/<any> - Software updates (not used yet, but reserved)
|
||||
*
|
||||
* OK payload:
|
||||
* <[8] 64-bit request ID>
|
||||
* <[4] 32-bit total length of blob>
|
||||
* <[4] 32-bit index of this data in blob>
|
||||
* <[...] data>
|
||||
*
|
||||
* ERROR payload:
|
||||
* <[8] 64-bit request ID>
|
||||
*/
|
||||
VERB_GET_OBJECT = 20
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -28,17 +28,37 @@
|
||||
#include "Constants.hpp"
|
||||
#include "Topology.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "Defaults.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Buffer.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
// Default World
|
||||
#define ZT_DEFAULT_WORLD_LENGTH 1
|
||||
static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = { 0 };
|
||||
|
||||
Topology::Topology(const RuntimeEnvironment *renv) :
|
||||
RR(renv),
|
||||
_amRoot(false)
|
||||
{
|
||||
try {
|
||||
std::string dsWorld(RR->node->dataStoreGet("world"));
|
||||
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> dswtmp(dsWorld.data(),dsWorld.length());
|
||||
_world.deserialize(dswtmp,0);
|
||||
} catch ( ... ) {
|
||||
_world = World(); // set to null if cached world is invalid
|
||||
}
|
||||
{
|
||||
World defaultWorld;
|
||||
Buffer<ZT_DEFAULT_WORLD_LENGTH> wtmp(ZT_DEFAULT_WORLD,ZT_DEFAULT_WORLD_LENGTH);
|
||||
defaultWorld.deserialize(wtmp,0); // throws on error, which would indicate a bad static variable up top
|
||||
if (_world.verifyUpdate(defaultWorld)) {
|
||||
_world = defaultWorld;
|
||||
RR->node->dataStorePut("world",ZT_DEFAULT_WORLD,ZT_DEFAULT_WORLD_LENGTH,false);
|
||||
}
|
||||
}
|
||||
|
||||
std::string alls(RR->node->dataStoreGet("peers.save"));
|
||||
const uint8_t *all = reinterpret_cast<const uint8_t *>(alls.data());
|
||||
RR->node->dataStoreDelete("peers.save");
|
||||
@ -76,6 +96,20 @@ Topology::Topology(const RuntimeEnvironment *renv) :
|
||||
}
|
||||
|
||||
clean(RR->node->now());
|
||||
|
||||
for(std::vector<World::Root>::const_iterator r(_world.roots().begin());r!=_world.roots().end();++r) {
|
||||
if (r->identity == RR->identity)
|
||||
_amRoot = true;
|
||||
_rootAddresses.push_back(r->identity.address());
|
||||
SharedPtr<Peer> *rp = _peers.get(r->identity.address());
|
||||
if (rp) {
|
||||
_rootPeers.push_back(*rp);
|
||||
} else if (r->identity.address() != RR->identity.address()) {
|
||||
SharedPtr<Peer> newrp(new Peer(RR->identity,r->identity));
|
||||
_peers.set(r->identity.address(),newrp);
|
||||
_rootPeers.push_back(newrp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Topology::~Topology()
|
||||
@ -103,55 +137,6 @@ Topology::~Topology()
|
||||
RR->node->dataStorePut("peers.save",all,true);
|
||||
}
|
||||
|
||||
void Topology::setRootServers(const std::map< Identity,std::vector<InetAddress> > &sn)
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
|
||||
if (_roots == sn)
|
||||
return; // no change
|
||||
|
||||
_roots = sn;
|
||||
_rootAddresses.clear();
|
||||
_rootPeers.clear();
|
||||
const uint64_t now = RR->node->now();
|
||||
|
||||
for(std::map< Identity,std::vector<InetAddress> >::const_iterator i(sn.begin());i!=sn.end();++i) {
|
||||
if (i->first != RR->identity) { // do not add self as a peer
|
||||
SharedPtr<Peer> &p = _peers[i->first.address()];
|
||||
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(RemotePath(InetAddress(),*j,true),now);
|
||||
p->use(now);
|
||||
_rootPeers.push_back(p);
|
||||
}
|
||||
_rootAddresses.push_back(i->first.address());
|
||||
}
|
||||
|
||||
std::sort(_rootAddresses.begin(),_rootAddresses.end());
|
||||
|
||||
_amRoot = (_roots.find(RR->identity) != _roots.end());
|
||||
}
|
||||
|
||||
void Topology::setRootServers(const Dictionary &sn)
|
||||
{
|
||||
std::map< Identity,std::vector<InetAddress> > m;
|
||||
for(Dictionary::const_iterator d(sn.begin());d!=sn.end();++d) {
|
||||
if ((d->first.length() == ZT_ADDRESS_LENGTH_HEX)&&(d->second.length() > 0)) {
|
||||
try {
|
||||
Dictionary snspec(d->second);
|
||||
std::vector<InetAddress> &a = m[Identity(snspec.get("id",""))];
|
||||
std::string udp(snspec.get("udp",std::string()));
|
||||
if (udp.length() > 0)
|
||||
a.push_back(InetAddress(udp));
|
||||
} catch ( ... ) {
|
||||
TRACE("root server list contained invalid entry for: %s",d->first.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
this->setRootServers(m);
|
||||
}
|
||||
|
||||
SharedPtr<Peer> Topology::addPeer(const SharedPtr<Peer> &peer)
|
||||
{
|
||||
if (peer->address() == RR->identity.address()) {
|
||||
@ -298,13 +283,6 @@ keep_searching_for_roots:
|
||||
return bestRoot;
|
||||
}
|
||||
|
||||
bool Topology::isRoot(const Identity &id) const
|
||||
throw()
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
return (_roots.count(id) != 0);
|
||||
}
|
||||
|
||||
void Topology::clean(uint64_t now)
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
@ -320,24 +298,6 @@ void Topology::clean(uint64_t now)
|
||||
}
|
||||
}
|
||||
|
||||
bool Topology::authenticateRootTopology(const Dictionary &rt)
|
||||
{
|
||||
try {
|
||||
std::string signer(rt.signingIdentity());
|
||||
if (!signer.length())
|
||||
return false;
|
||||
Identity signerId(signer);
|
||||
std::map< Address,Identity >::const_iterator authority(ZT_DEFAULTS.rootTopologyAuthorities.find(signerId.address()));
|
||||
if (authority == ZT_DEFAULTS.rootTopologyAuthorities.end())
|
||||
return false;
|
||||
if (signerId != authority->second)
|
||||
return false;
|
||||
return rt.verify(authority->second);
|
||||
} catch ( ... ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Identity Topology::_getIdentity(const Address &zta)
|
||||
{
|
||||
char p[128];
|
||||
|
@ -43,8 +43,8 @@
|
||||
#include "Peer.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
#include "Hashtable.hpp"
|
||||
#include "World.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -59,21 +59,6 @@ public:
|
||||
Topology(const RuntimeEnvironment *renv);
|
||||
~Topology();
|
||||
|
||||
/**
|
||||
* @param sn Root server identities and addresses
|
||||
*/
|
||||
void setRootServers(const std::map< Identity,std::vector<InetAddress> > &sn);
|
||||
|
||||
/**
|
||||
* Set up root servers for this network
|
||||
*
|
||||
* This performs no signature verification of any kind. The caller must
|
||||
* check the signature of the root topology dictionary first.
|
||||
*
|
||||
* @param sn 'rootservers' key from root-topology Dictionary (deserialized as Dictionary)
|
||||
*/
|
||||
void setRootServers(const Dictionary &sn);
|
||||
|
||||
/**
|
||||
* Add a peer to database
|
||||
*
|
||||
@ -128,10 +113,20 @@ public:
|
||||
|
||||
/**
|
||||
* @param id Identity to check
|
||||
* @return True if this is a designated root server
|
||||
* @return True if this is a designated root server in this world
|
||||
*/
|
||||
bool isRoot(const Identity &id) const
|
||||
throw();
|
||||
inline bool isRoot(const Identity &id) const
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
if (std::find(_rootAddresses.begin(),_rootAddresses.end(),id.address()) != _rootAddresses.end()) {
|
||||
// Double check full identity for security reasons
|
||||
for(std::vector<World::Root>::const_iterator r(_world.roots().begin());r!=_world.roots().end();++r) {
|
||||
if (id == r->identity)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Vector of root server addresses
|
||||
@ -142,6 +137,15 @@ public:
|
||||
return _rootAddresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Current World (copy)
|
||||
*/
|
||||
inline World world() const
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
return _world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean and flush database
|
||||
*/
|
||||
@ -180,28 +184,19 @@ public:
|
||||
return _peers.entries();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a root topology dictionary against the identities specified in Defaults
|
||||
*
|
||||
* @param rt Root topology dictionary
|
||||
* @return True if dictionary signature is valid
|
||||
*/
|
||||
static bool authenticateRootTopology(const Dictionary &rt);
|
||||
|
||||
private:
|
||||
Identity _getIdentity(const Address &zta);
|
||||
void _saveIdentity(const Identity &id);
|
||||
|
||||
const RuntimeEnvironment *RR;
|
||||
|
||||
World _world;
|
||||
Hashtable< Address,SharedPtr<Peer> > _peers;
|
||||
std::map< Identity,std::vector<InetAddress> > _roots;
|
||||
std::vector< Address > _rootAddresses;
|
||||
std::vector< SharedPtr<Peer> > _rootPeers;
|
||||
bool _amRoot;
|
||||
|
||||
Mutex _lock;
|
||||
|
||||
bool _amRoot;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
221
node/World.hpp
Normal file
221
node/World.hpp
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* 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_WORLD_HPP
|
||||
#define ZT_WORLD_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "C25519.hpp"
|
||||
|
||||
/**
|
||||
* Maximum number of roots (sanity limit, okay to increase)
|
||||
*
|
||||
* A given root can (through multi-homing) be distributed across any number of
|
||||
* physical endpoints, but having more than one is good to permit total failure
|
||||
* of one root or its withdrawal due to compromise without taking the whole net
|
||||
* down.
|
||||
*/
|
||||
#define ZT_WORLD_MAX_ROOTS 4
|
||||
|
||||
/**
|
||||
* Maximum number of stable endpoints per root (sanity limit, okay to increase)
|
||||
*/
|
||||
#define ZT_WORLD_MAX_STABLE_ENDPOINTS_PER_ROOT 32
|
||||
|
||||
/**
|
||||
* The (more than) maximum length of a serialized World
|
||||
*/
|
||||
#define ZT_WORLD_MAX_SERIALIZED_LENGTH (((1024 + (32 * ZT_WORLD_MAX_STABLE_ENDPOINTS_PER_ROOT)) * ZT_WORLD_MAX_ROOTS) + ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_SIGNATURE_LEN + 64)
|
||||
|
||||
/**
|
||||
* World ID indicating null / empty World object
|
||||
*/
|
||||
#define ZT_WORLD_ID_NULL 0
|
||||
|
||||
/**
|
||||
* World ID for a test network with ephemeral or temporary roots
|
||||
*/
|
||||
#define ZT_WORLD_ID_TESTNET 1
|
||||
|
||||
/**
|
||||
* World ID for Earth -- its approximate distance from the sun in kilometers
|
||||
*
|
||||
* This is the ID for the ZeroTier World used on planet Earth. It is unrelated
|
||||
* to the public network 8056c2e21c000001 of the same name.
|
||||
*
|
||||
* It's advisable to create a new World for network regions spaced more than
|
||||
* 2-3 light seconds, since RTT times in excess of 5s are problematic for some
|
||||
* protocols. Earth could therefore include its low and high orbits, the Moon,
|
||||
* and nearby Lagrange points.
|
||||
*/
|
||||
#define ZT_WORLD_ID_EARTH 149604618
|
||||
|
||||
/**
|
||||
* World ID for Mars -- for future use by SpaceX or others
|
||||
*/
|
||||
#define ZT_WORLD_ID_MARS 227883110
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* A world definition (formerly known as a root topology)
|
||||
*
|
||||
* A world consists of a set of root servers and a signature scheme enabling
|
||||
* it to be updated going forward. It defines a single ZeroTier VL1 network
|
||||
* area within which any device can reach any other.
|
||||
*/
|
||||
class World
|
||||
{
|
||||
public:
|
||||
struct Root
|
||||
{
|
||||
Identity identity;
|
||||
std::vector<InetAddress> stableEndpoints;
|
||||
|
||||
inline bool operator==(const Root &r) const throw() { return ((identity == r.identity)&&(stableEndpoints == r.stableEndpoints)); }
|
||||
inline bool operator!=(const Root &r) const throw() { return (!(*this == r)); }
|
||||
inline bool operator<(const Root &r) const throw() { return (identity < r.identity); } // for sorting
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct an empty / null World
|
||||
*/
|
||||
World() :
|
||||
_id(ZT_WORLD_ID_NULL),
|
||||
_ts(0) {}
|
||||
|
||||
/**
|
||||
* @return Root servers for this world and their stable endpoints
|
||||
*/
|
||||
inline const std::vector<World::Root> &roots() const throw() { return _roots; }
|
||||
|
||||
/**
|
||||
* @return World unique identifier
|
||||
*/
|
||||
inline uint64_t id() const throw() { return _id; }
|
||||
|
||||
/**
|
||||
* @return World definition timestamp
|
||||
*/
|
||||
inline uint64_t timestamp() const throw() { return _ts; }
|
||||
|
||||
/**
|
||||
* Verify a world update
|
||||
*
|
||||
* A new world update is valid if it is for the same world ID, is newer,
|
||||
* and is signed by the current world's signing key. If this world object
|
||||
* is null, it can always be updated.
|
||||
*
|
||||
* @param update Candidate update
|
||||
* @return True if update is newer than current and is properly signed
|
||||
*/
|
||||
inline bool verifyUpdate(const World &update)
|
||||
{
|
||||
if (_id == ZT_WORLD_ID_NULL)
|
||||
return true;
|
||||
if ((update._id != _id)||(update._ts <= _ts))
|
||||
return false;
|
||||
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> tmp;
|
||||
update.serialize(tmp);
|
||||
return C25519::verify(_updateSigningKey,tmp.data(),tmp.size(),update._signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if this World is non-empty
|
||||
*/
|
||||
inline operator bool() const throw() { return (_id != ZT_WORLD_ID_NULL); }
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b) const
|
||||
{
|
||||
b.append((uint8_t)0x01); // version -- only one valid value for now
|
||||
b.append((uint64_t)_id);
|
||||
b.append((uint64_t)_ts);
|
||||
b.append(_updateSigningKey.data,ZT_C25519_PUBLIC_KEY_LEN);
|
||||
b.append(_signature.data,ZT_C25519_SIGNATURE_LEN);
|
||||
b.append((uint8_t)_roots.size());
|
||||
for(std::vector<Root>::const_iterator r(_roots.begin());r!=_roots.end();++r) {
|
||||
r->identity.serialize(b);
|
||||
b.append((uint8_t)r->stableEndpoints.size());
|
||||
for(std::vector<InetAddress>::const_iterator ep(r->stableEndpoints.begin());ep!=r->stableEndpoints.end();++ep)
|
||||
ep->serialize(b);
|
||||
}
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
{
|
||||
unsigned int p = startAt;
|
||||
|
||||
_roots.clear();
|
||||
|
||||
if (b[p++] != 0x01)
|
||||
throw std::invalid_argument("invalid World serialized version");
|
||||
|
||||
_id = b.template at<uint64_t>(p); p += 8;
|
||||
_ts = b.template at<uint64_t>(p); p += 8;
|
||||
memcpy(_updateSigningKey.data,b.field(p,ZT_C25519_PUBLIC_KEY_LEN),ZT_C25519_PUBLIC_KEY_LEN); p += ZT_C25519_PUBLIC_KEY_LEN;
|
||||
memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN;
|
||||
unsigned int numRoots = b[p++];
|
||||
if (numRoots > ZT_WORLD_MAX_ROOTS)
|
||||
throw std::invalid_argument("too many roots in World");
|
||||
for(unsigned int k=0;k<numRoots;++k) {
|
||||
_roots.push_back(Root());
|
||||
Root &r = _roots.back();
|
||||
p += r.identity.deserialize(b,p);
|
||||
unsigned int numStableEndpoints = b[p++];
|
||||
if (numStableEndpoints > ZT_WORLD_MAX_STABLE_ENDPOINTS_PER_ROOT)
|
||||
throw std::invalid_argument("too many stable endpoints in World/Root");
|
||||
for(unsigned int kk=0;kk<numStableEndpoints;++kk) {
|
||||
r.stableEndpoints.push_back(InetAddress());
|
||||
p += r.stableEndpoints.back().deserialize(b,p);
|
||||
}
|
||||
}
|
||||
|
||||
return (p - startAt);
|
||||
}
|
||||
|
||||
inline bool operator==(const World &w) const throw() { return ((_id == w._id)&&(_ts == w._ts)&&(_roots == w._roots)); }
|
||||
inline bool operator!=(const World &w) const throw() { return (!(*this == w)); }
|
||||
|
||||
protected:
|
||||
uint64_t _id;
|
||||
uint64_t _ts;
|
||||
C25519::Public _updateSigningKey;
|
||||
C25519::Signature _signature;
|
||||
std::vector<Root> _roots;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
@ -4,7 +4,6 @@ OBJS=\
|
||||
ext/http-parser/http_parser.o \
|
||||
node/C25519.o \
|
||||
node/CertificateOfMembership.o \
|
||||
node/Defaults.o \
|
||||
node/Dictionary.o \
|
||||
node/Identity.o \
|
||||
node/IncomingPacket.o \
|
||||
|
@ -1,17 +0,0 @@
|
||||
all: FORCE
|
||||
g++ -o mktopology mktopology.cpp ../osdep/OSUtils.cpp ../node/Utils.cpp ../node/InetAddress.cpp ../node/Identity.cpp ../node/C25519.cpp ../node/Salsa20.cpp ../node/Dictionary.cpp ../node/SHA512.cpp
|
||||
gcc -o bin2c bin2c.c
|
||||
|
||||
official: FORCE
|
||||
rm -f ZT_DEFAULT_ROOT_TOPOLOGY.dict
|
||||
./mktopology >ZT_DEFAULT_ROOT_TOPOLOGY.dict
|
||||
./bin2c ZT_DEFAULT_ROOT_TOPOLOGY < ZT_DEFAULT_ROOT_TOPOLOGY.dict > ZT_DEFAULT_ROOT_TOPOLOGY.c
|
||||
ls -l ZT_DEFAULT_ROOT_TOPOLOGY.c
|
||||
|
||||
clean:
|
||||
rm -f *.o mktopology bin2c
|
||||
|
||||
realclean: clean
|
||||
rm -f ZT_DEFAULT_ROOT_TOPOLOGY.c ZT_DEFAULT_ROOT_TOPOLOGY.dict
|
||||
|
||||
FORCE:
|
@ -1,18 +0,0 @@
|
||||
This folder contains the source files to compile the signed network root topology dictionary. Users outside ZeroTier won't find this useful except for testing, since the root topology must be signed by the root topology authority (public identity in root-topology-authority.public) to be considered valid.
|
||||
|
||||
Keys in the root topology dictionary are:
|
||||
|
||||
* **rootservers**: contains another Dictionary mapping rootserver address to rootserver definition
|
||||
* **##########**: rootserver address, contains rootserver definition
|
||||
* **id**: rootserver identity (public) in string-serialized format
|
||||
* **udp**: comma-delimited list of ip/port UDP addresses of node
|
||||
* **tcp**: *DEPRECATED* comma-delimited list of ip/port TCP addresses of node
|
||||
* **desc**: human-readable description (optional)
|
||||
* **dns**: DNS name (optional, not currently used for anything)
|
||||
* **noupdate**: if the value of this is '1', do not auto-update from ZeroTier's servers
|
||||
|
||||
ZT_DEFAULT_ROOT_TOPOLOGY.c contains the current default value, and this URL is periodically checked for updates:
|
||||
|
||||
http://download.zerotier.com/net/topology/ROOT
|
||||
|
||||
Obviously nothing prevents OSS users from replacing this topology with their own, changing the hard coded topology signing identity and update URL in Defaults, and signing their own dictionary. But doing so would yield a network that would have a tough(ish) time talking to the main one. Since the main network is a free service, why bother? (Except for building testnets, which ZeroTier already does for internal testing.)
|
@ -1,90 +0,0 @@
|
||||
static unsigned char ZT_DEFAULT_ROOT_TOPOLOGY[] = {
|
||||
0x72, 0x6f, 0x6f, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x3d, 0x37, 0x65, 0x31, 0x39,
|
||||
0x38, 0x37, 0x36, 0x61, 0x62, 0x61, 0x5c, 0x3d, 0x69, 0x64, 0x5c, 0x5c, 0x5c, 0x3d, 0x37, 0x65,
|
||||
0x31, 0x39, 0x38, 0x37, 0x36, 0x61, 0x62, 0x61, 0x3a, 0x30, 0x3a, 0x32, 0x61, 0x36, 0x65, 0x32,
|
||||
0x62, 0x32, 0x33, 0x31, 0x38, 0x39, 0x33, 0x30, 0x66, 0x36, 0x30, 0x65, 0x62, 0x30, 0x39, 0x37,
|
||||
0x66, 0x37, 0x30, 0x64, 0x30, 0x66, 0x34, 0x62, 0x30, 0x32, 0x38, 0x62, 0x32, 0x63, 0x64, 0x36,
|
||||
0x64, 0x33, 0x64, 0x30, 0x63, 0x36, 0x33, 0x63, 0x30, 0x31, 0x34, 0x62, 0x39, 0x30, 0x33, 0x39,
|
||||
0x66, 0x66, 0x33, 0x35, 0x33, 0x39, 0x30, 0x65, 0x34, 0x31, 0x31, 0x38, 0x31, 0x66, 0x32, 0x31,
|
||||
0x36, 0x66, 0x62, 0x32, 0x65, 0x36, 0x66, 0x61, 0x38, 0x64, 0x39, 0x35, 0x63, 0x31, 0x65, 0x65,
|
||||
0x39, 0x36, 0x36, 0x37, 0x31, 0x35, 0x36, 0x34, 0x31, 0x31, 0x39, 0x30, 0x35, 0x63, 0x33, 0x64,
|
||||
0x63, 0x63, 0x66, 0x65, 0x61, 0x37, 0x38, 0x64, 0x38, 0x63, 0x36, 0x64, 0x66, 0x61, 0x66, 0x62,
|
||||
0x61, 0x36, 0x38, 0x38, 0x31, 0x37, 0x30, 0x62, 0x33, 0x66, 0x61, 0x5c, 0x5c, 0x6e, 0x75, 0x64,
|
||||
0x70, 0x5c, 0x5c, 0x5c, 0x3d, 0x31, 0x39, 0x38, 0x2e, 0x31, 0x39, 0x39, 0x2e, 0x39, 0x37, 0x2e,
|
||||
0x32, 0x32, 0x30, 0x2f, 0x39, 0x39, 0x39, 0x33, 0x5c, 0x5c, 0x6e, 0x74, 0x63, 0x70, 0x5c, 0x5c,
|
||||
0x5c, 0x3d, 0x31, 0x39, 0x38, 0x2e, 0x31, 0x39, 0x39, 0x2e, 0x39, 0x37, 0x2e, 0x32, 0x32, 0x30,
|
||||
0x2f, 0x34, 0x34, 0x33, 0x5c, 0x5c, 0x6e, 0x64, 0x65, 0x73, 0x63, 0x5c, 0x5c, 0x5c, 0x3d, 0x53,
|
||||
0x61, 0x6e, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x2c, 0x20, 0x43, 0x61,
|
||||
0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x2c, 0x20, 0x55, 0x53, 0x41, 0x5c, 0x5c, 0x6e,
|
||||
0x5c, 0x6e, 0x38, 0x38, 0x34, 0x31, 0x34, 0x30, 0x38, 0x61, 0x32, 0x65, 0x5c, 0x3d, 0x69, 0x64,
|
||||
0x5c, 0x5c, 0x5c, 0x3d, 0x38, 0x38, 0x34, 0x31, 0x34, 0x30, 0x38, 0x61, 0x32, 0x65, 0x3a, 0x30,
|
||||
0x3a, 0x62, 0x62, 0x31, 0x64, 0x33, 0x31, 0x66, 0x32, 0x63, 0x33, 0x32, 0x33, 0x65, 0x32, 0x36,
|
||||
0x34, 0x65, 0x39, 0x65, 0x36, 0x34, 0x31, 0x37, 0x32, 0x63, 0x31, 0x61, 0x37, 0x34, 0x66, 0x37,
|
||||
0x37, 0x38, 0x39, 0x39, 0x35, 0x35, 0x35, 0x65, 0x64, 0x31, 0x30, 0x37, 0x35, 0x31, 0x63, 0x64,
|
||||
0x35, 0x36, 0x65, 0x38, 0x36, 0x34, 0x30, 0x35, 0x63, 0x64, 0x65, 0x31, 0x31, 0x38, 0x64, 0x30,
|
||||
0x32, 0x64, 0x66, 0x66, 0x65, 0x35, 0x35, 0x35, 0x64, 0x34, 0x36, 0x32, 0x63, 0x63, 0x66, 0x36,
|
||||
0x61, 0x38, 0x35, 0x62, 0x35, 0x36, 0x33, 0x31, 0x63, 0x31, 0x32, 0x33, 0x35, 0x30, 0x63, 0x38,
|
||||
0x64, 0x35, 0x64, 0x63, 0x34, 0x30, 0x39, 0x62, 0x61, 0x31, 0x30, 0x62, 0x39, 0x30, 0x32, 0x35,
|
||||
0x64, 0x30, 0x66, 0x34, 0x34, 0x35, 0x63, 0x66, 0x34, 0x34, 0x39, 0x64, 0x39, 0x32, 0x62, 0x31,
|
||||
0x63, 0x5c, 0x5c, 0x6e, 0x75, 0x64, 0x70, 0x5c, 0x5c, 0x5c, 0x3d, 0x31, 0x30, 0x37, 0x2e, 0x31,
|
||||
0x39, 0x31, 0x2e, 0x34, 0x36, 0x2e, 0x32, 0x31, 0x30, 0x2f, 0x39, 0x39, 0x39, 0x33, 0x5c, 0x5c,
|
||||
0x6e, 0x74, 0x63, 0x70, 0x5c, 0x5c, 0x5c, 0x3d, 0x31, 0x30, 0x37, 0x2e, 0x31, 0x39, 0x31, 0x2e,
|
||||
0x34, 0x36, 0x2e, 0x32, 0x31, 0x30, 0x2f, 0x34, 0x34, 0x33, 0x5c, 0x5c, 0x6e, 0x64, 0x65, 0x73,
|
||||
0x63, 0x5c, 0x5c, 0x5c, 0x3d, 0x50, 0x61, 0x72, 0x69, 0x73, 0x2c, 0x20, 0x46, 0x72, 0x61, 0x6e,
|
||||
0x63, 0x65, 0x5c, 0x5c, 0x6e, 0x5c, 0x6e, 0x38, 0x61, 0x63, 0x66, 0x30, 0x35, 0x39, 0x66, 0x65,
|
||||
0x33, 0x5c, 0x3d, 0x69, 0x64, 0x5c, 0x5c, 0x5c, 0x3d, 0x38, 0x61, 0x63, 0x66, 0x30, 0x35, 0x39,
|
||||
0x66, 0x65, 0x33, 0x3a, 0x30, 0x3a, 0x34, 0x38, 0x32, 0x66, 0x36, 0x65, 0x65, 0x35, 0x64, 0x66,
|
||||
0x65, 0x39, 0x30, 0x32, 0x33, 0x31, 0x39, 0x62, 0x34, 0x31, 0x39, 0x64, 0x65, 0x35, 0x62, 0x64,
|
||||
0x63, 0x37, 0x36, 0x35, 0x32, 0x30, 0x39, 0x63, 0x30, 0x65, 0x63, 0x64, 0x61, 0x33, 0x38, 0x63,
|
||||
0x34, 0x64, 0x36, 0x65, 0x34, 0x66, 0x63, 0x66, 0x30, 0x64, 0x33, 0x33, 0x36, 0x35, 0x38, 0x33,
|
||||
0x39, 0x38, 0x62, 0x34, 0x35, 0x32, 0x37, 0x64, 0x63, 0x64, 0x32, 0x32, 0x66, 0x39, 0x33, 0x31,
|
||||
0x31, 0x32, 0x66, 0x62, 0x39, 0x62, 0x65, 0x66, 0x64, 0x30, 0x32, 0x66, 0x64, 0x37, 0x38, 0x62,
|
||||
0x66, 0x37, 0x32, 0x36, 0x31, 0x62, 0x33, 0x33, 0x33, 0x66, 0x63, 0x31, 0x30, 0x35, 0x64, 0x31,
|
||||
0x39, 0x32, 0x61, 0x36, 0x32, 0x33, 0x63, 0x61, 0x39, 0x65, 0x35, 0x30, 0x66, 0x63, 0x36, 0x30,
|
||||
0x62, 0x33, 0x37, 0x34, 0x61, 0x35, 0x5c, 0x5c, 0x6e, 0x75, 0x64, 0x70, 0x5c, 0x5c, 0x5c, 0x3d,
|
||||
0x31, 0x36, 0x32, 0x2e, 0x32, 0x34, 0x33, 0x2e, 0x37, 0x37, 0x2e, 0x31, 0x31, 0x31, 0x2f, 0x39,
|
||||
0x39, 0x39, 0x33, 0x5c, 0x5c, 0x6e, 0x74, 0x63, 0x70, 0x5c, 0x5c, 0x5c, 0x3d, 0x31, 0x36, 0x32,
|
||||
0x2e, 0x32, 0x34, 0x33, 0x2e, 0x37, 0x37, 0x2e, 0x31, 0x31, 0x31, 0x2f, 0x34, 0x34, 0x33, 0x5c,
|
||||
0x5c, 0x6e, 0x64, 0x65, 0x73, 0x63, 0x5c, 0x5c, 0x5c, 0x3d, 0x4e, 0x65, 0x77, 0x20, 0x59, 0x6f,
|
||||
0x72, 0x6b, 0x2c, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, 0x2c, 0x20, 0x55, 0x53,
|
||||
0x41, 0x5c, 0x5c, 0x6e, 0x5c, 0x6e, 0x39, 0x64, 0x32, 0x31, 0x39, 0x30, 0x33, 0x39, 0x66, 0x33,
|
||||
0x5c, 0x3d, 0x69, 0x64, 0x5c, 0x5c, 0x5c, 0x3d, 0x39, 0x64, 0x32, 0x31, 0x39, 0x30, 0x33, 0x39,
|
||||
0x66, 0x33, 0x3a, 0x30, 0x3a, 0x30, 0x31, 0x66, 0x30, 0x39, 0x32, 0x32, 0x61, 0x39, 0x38, 0x65,
|
||||
0x33, 0x62, 0x33, 0x34, 0x65, 0x62, 0x63, 0x62, 0x66, 0x66, 0x33, 0x33, 0x33, 0x32, 0x36, 0x39,
|
||||
0x64, 0x63, 0x32, 0x36, 0x35, 0x64, 0x37, 0x61, 0x30, 0x32, 0x30, 0x61, 0x61, 0x62, 0x36, 0x39,
|
||||
0x64, 0x37, 0x32, 0x62, 0x65, 0x34, 0x64, 0x34, 0x61, 0x63, 0x63, 0x39, 0x63, 0x38, 0x63, 0x39,
|
||||
0x32, 0x39, 0x34, 0x37, 0x38, 0x35, 0x37, 0x37, 0x31, 0x32, 0x35, 0x36, 0x63, 0x64, 0x31, 0x64,
|
||||
0x39, 0x34, 0x32, 0x61, 0x39, 0x30, 0x64, 0x31, 0x62, 0x64, 0x31, 0x64, 0x32, 0x64, 0x63, 0x61,
|
||||
0x33, 0x65, 0x61, 0x38, 0x34, 0x65, 0x66, 0x37, 0x64, 0x38, 0x35, 0x61, 0x66, 0x65, 0x36, 0x36,
|
||||
0x31, 0x31, 0x66, 0x62, 0x34, 0x33, 0x66, 0x66, 0x30, 0x62, 0x37, 0x34, 0x31, 0x32, 0x36, 0x64,
|
||||
0x39, 0x30, 0x61, 0x36, 0x65, 0x5c, 0x5c, 0x6e, 0x75, 0x64, 0x70, 0x5c, 0x5c, 0x5c, 0x3d, 0x31,
|
||||
0x32, 0x38, 0x2e, 0x31, 0x39, 0x39, 0x2e, 0x31, 0x39, 0x37, 0x2e, 0x32, 0x31, 0x37, 0x2f, 0x39,
|
||||
0x39, 0x39, 0x33, 0x5c, 0x5c, 0x6e, 0x74, 0x63, 0x70, 0x5c, 0x5c, 0x5c, 0x3d, 0x31, 0x32, 0x38,
|
||||
0x2e, 0x31, 0x39, 0x39, 0x2e, 0x31, 0x39, 0x37, 0x2e, 0x32, 0x31, 0x37, 0x2f, 0x34, 0x34, 0x33,
|
||||
0x5c, 0x5c, 0x6e, 0x64, 0x65, 0x73, 0x63, 0x5c, 0x5c, 0x5c, 0x3d, 0x53, 0x69, 0x6e, 0x67, 0x61,
|
||||
0x70, 0x6f, 0x72, 0x65, 0x5c, 0x5c, 0x6e, 0x5c, 0x6e, 0x0a, 0x7e, 0x21, 0x65, 0x64, 0x32, 0x35,
|
||||
0x35, 0x31, 0x39, 0x3d, 0x38, 0x33, 0x32, 0x62, 0x33, 0x35, 0x64, 0x61, 0x64, 0x64, 0x37, 0x66,
|
||||
0x35, 0x36, 0x66, 0x66, 0x33, 0x38, 0x31, 0x66, 0x61, 0x37, 0x32, 0x31, 0x64, 0x65, 0x37, 0x64,
|
||||
0x35, 0x62, 0x65, 0x34, 0x63, 0x65, 0x62, 0x66, 0x63, 0x63, 0x63, 0x32, 0x30, 0x30, 0x32, 0x30,
|
||||
0x38, 0x33, 0x38, 0x30, 0x64, 0x33, 0x30, 0x38, 0x34, 0x66, 0x36, 0x34, 0x38, 0x65, 0x32, 0x63,
|
||||
0x31, 0x61, 0x35, 0x63, 0x66, 0x34, 0x33, 0x65, 0x35, 0x39, 0x66, 0x39, 0x32, 0x61, 0x36, 0x36,
|
||||
0x35, 0x64, 0x66, 0x34, 0x64, 0x62, 0x63, 0x62, 0x38, 0x33, 0x37, 0x38, 0x38, 0x66, 0x36, 0x62,
|
||||
0x64, 0x36, 0x37, 0x37, 0x66, 0x30, 0x32, 0x62, 0x32, 0x31, 0x30, 0x65, 0x35, 0x30, 0x63, 0x61,
|
||||
0x66, 0x65, 0x66, 0x64, 0x32, 0x65, 0x66, 0x31, 0x38, 0x39, 0x62, 0x62, 0x66, 0x34, 0x38, 0x31,
|
||||
0x62, 0x64, 0x30, 0x32, 0x63, 0x64, 0x63, 0x39, 0x38, 0x34, 0x35, 0x33, 0x38, 0x37, 0x64, 0x38,
|
||||
0x34, 0x39, 0x62, 0x63, 0x35, 0x36, 0x66, 0x39, 0x63, 0x37, 0x32, 0x35, 0x31, 0x65, 0x35, 0x64,
|
||||
0x30, 0x65, 0x61, 0x34, 0x34, 0x34, 0x66, 0x66, 0x63, 0x66, 0x38, 0x66, 0x37, 0x32, 0x32, 0x63,
|
||||
0x32, 0x66, 0x65, 0x62, 0x38, 0x39, 0x36, 0x30, 0x33, 0x61, 0x30, 0x65, 0x35, 0x62, 0x61, 0x32,
|
||||
0x39, 0x35, 0x66, 0x63, 0x0a, 0x7e, 0x21, 0x73, 0x69, 0x67, 0x69, 0x64, 0x3d, 0x37, 0x37, 0x37,
|
||||
0x39, 0x32, 0x62, 0x31, 0x63, 0x30, 0x32, 0x3a, 0x30, 0x3a, 0x62, 0x35, 0x63, 0x33, 0x36, 0x31,
|
||||
0x65, 0x38, 0x65, 0x39, 0x63, 0x32, 0x31, 0x35, 0x34, 0x65, 0x38, 0x32, 0x63, 0x33, 0x65, 0x39,
|
||||
0x30, 0x32, 0x66, 0x64, 0x66, 0x63, 0x33, 0x33, 0x37, 0x34, 0x36, 0x38, 0x62, 0x30, 0x39, 0x32,
|
||||
0x61, 0x37, 0x63, 0x34, 0x64, 0x38, 0x64, 0x63, 0x36, 0x38, 0x35, 0x63, 0x33, 0x37, 0x65, 0x62,
|
||||
0x31, 0x30, 0x65, 0x65, 0x34, 0x66, 0x33, 0x63, 0x31, 0x37, 0x63, 0x63, 0x30, 0x62, 0x62, 0x31,
|
||||
0x64, 0x30, 0x32, 0x34, 0x31, 0x36, 0x37, 0x65, 0x38, 0x63, 0x62, 0x30, 0x38, 0x32, 0x34, 0x64,
|
||||
0x31, 0x32, 0x32, 0x36, 0x33, 0x34, 0x32, 0x38, 0x33, 0x37, 0x33, 0x35, 0x38, 0x32, 0x64, 0x61,
|
||||
0x33, 0x64, 0x30, 0x61, 0x39, 0x61, 0x31, 0x34, 0x62, 0x33, 0x36, 0x65, 0x34, 0x35, 0x34, 0x36,
|
||||
0x63, 0x33, 0x31, 0x37, 0x65, 0x38, 0x31, 0x31, 0x65, 0x36, 0x0a, 0x7e, 0x21, 0x73, 0x69, 0x67,
|
||||
0x74, 0x73, 0x3d, 0x31, 0x34, 0x65, 0x30, 0x63, 0x62, 0x62, 0x39, 0x38, 0x64, 0x36, 0x0a
|
||||
};
|
||||
#define ZT_DEFAULT_ROOT_TOPOLOGY_LEN 1391
|
@ -1,4 +0,0 @@
|
||||
rootservers=7e19876aba\=id\\\=7e19876aba:0:2a6e2b2318930f60eb097f70d0f4b028b2cd6d3d0c63c014b9039ff35390e41181f216fb2e6fa8d95c1ee9667156411905c3dccfea78d8c6dfafba688170b3fa\\nudp\\\=198.199.97.220/9993\\ntcp\\\=198.199.97.220/443\\ndesc\\\=San Francisco, California, USA\\n\n8841408a2e\=id\\\=8841408a2e:0:bb1d31f2c323e264e9e64172c1a74f77899555ed10751cd56e86405cde118d02dffe555d462ccf6a85b5631c12350c8d5dc409ba10b9025d0f445cf449d92b1c\\nudp\\\=107.191.46.210/9993\\ntcp\\\=107.191.46.210/443\\ndesc\\\=Paris, France\\n\n8acf059fe3\=id\\\=8acf059fe3:0:482f6ee5dfe902319b419de5bdc765209c0ecda38c4d6e4fcf0d33658398b4527dcd22f93112fb9befd02fd78bf7261b333fc105d192a623ca9e50fc60b374a5\\nudp\\\=162.243.77.111/9993\\ntcp\\\=162.243.77.111/443\\ndesc\\\=New York, New York, USA\\n\n9d219039f3\=id\\\=9d219039f3:0:01f0922a98e3b34ebcbff333269dc265d7a020aab69d72be4d4acc9c8c9294785771256cd1d942a90d1bd1d2dca3ea84ef7d85afe6611fb43ff0b74126d90a6e\\nudp\\\=128.199.197.217/9993\\ntcp\\\=128.199.197.217/443\\ndesc\\\=Singapore\\n\n
|
||||
~!ed25519=832b35dadd7f56ff381fa721de7d5be4cebfccc200208380d3084f648e2c1a5cf43e59f92a665df4dbcb83788f6bd677f02b210e50cafefd2ef189bbf481bd02cdc9845387d849bc56f9c7251e5d0ea444ffcf8f722c2feb89603a0e5ba295fc
|
||||
~!sigid=77792b1c02:0:b5c361e8e9c2154e82c3e902fdfc337468b092a7c4d8dc685c37eb10ee4f3c17cc0bb1d024167e8cb0824d12263428373582da3d0a9a14b36e4546c317e811e6
|
||||
~!sigts=14e0cbb98d6
|
@ -1,57 +0,0 @@
|
||||
/**
|
||||
Converts input from stdin into an array of binary data for use in C.
|
||||
|
||||
License: Public Domain
|
||||
|
||||
Usage: app VariableName < input > output.c
|
||||
*/
|
||||
|
||||
#include <stdint.h> /* uintXX_t */
|
||||
#include <inttypes.h> /* PRIuXX macros */
|
||||
#include <stdio.h>
|
||||
|
||||
static char const * appName = 0;
|
||||
|
||||
static void usage()
|
||||
{
|
||||
printf("Usage: %s OBJECT_NAME < input > output.c\n\n", appName );
|
||||
}
|
||||
|
||||
int main( int argc, char const ** argv )
|
||||
{
|
||||
appName = argv[0];
|
||||
if( (argc != 2) || (argv[1][0] == '-') )
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
char const * varname = argv[1];
|
||||
enum { bufSize = 1024 * 8 };
|
||||
unsigned char buf[bufSize];
|
||||
size_t rd = 0;
|
||||
size_t i = 0;
|
||||
size_t flip = 0;
|
||||
|
||||
printf( "static unsigned char %s[] = {\n\t", varname);
|
||||
uint32_t size = 0;
|
||||
while( 0 != (rd = fread( buf, 1, bufSize, stdin ) ) )
|
||||
{
|
||||
size += rd;
|
||||
for(i = 0; i < rd; ++i )
|
||||
{
|
||||
printf( "0x%02x", buf[i] );
|
||||
if( !( (rd < bufSize) && (i == rd-1)) ) putchar(',');
|
||||
if( 16 == ++flip )
|
||||
{
|
||||
flip = 0;
|
||||
printf("\n\t");
|
||||
}
|
||||
else putchar(' ');
|
||||
}
|
||||
}
|
||||
printf("\n};\n");
|
||||
printf("#define %s_LEN %llu\n",varname,(unsigned long long)size);
|
||||
//printf( "enum { %s_length = %"PRIu32"%s }; ", varname, size,"UL");
|
||||
//printf("enum { %s_length = sizeof(%s) };\n", varname, varname );
|
||||
return 0;
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
#include "../osdep/OSUtils.hpp"
|
||||
#include "../node/Identity.hpp"
|
||||
#include "../node/Dictionary.hpp"
|
||||
|
||||
using namespace ZeroTier;
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
std::string buf;
|
||||
|
||||
// Read root-topology-authority.secret signing authority, must be symlinked and online
|
||||
Identity topologyAuthority;
|
||||
if (OSUtils::readFile("root-topology-authority.secret",buf))
|
||||
topologyAuthority.fromString(buf);
|
||||
else std::cerr << "Warning: root-topology-authority.secret not found, creating unsigned topology." << std::endl;
|
||||
|
||||
Dictionary topology;
|
||||
|
||||
// Read template.dict to populate default fields in root topology
|
||||
// if this file exists. Otherwise we just start empty.
|
||||
buf.clear();
|
||||
if (OSUtils::readFile("template.dict",buf))
|
||||
topology.fromString(buf);
|
||||
|
||||
// Read all entries in rootservers/ that correspond to rootserver entry dictionaries
|
||||
// and add them to topology under rootservers/ subkey.
|
||||
Dictionary rootservers;
|
||||
std::vector<std::string> rootserverDictionaries(OSUtils::listDirectory("rootservers"));
|
||||
for(std::vector<std::string>::const_iterator sn(rootserverDictionaries.begin());sn!=rootserverDictionaries.end();++sn) {
|
||||
if (sn->length() == 10) {
|
||||
buf.clear();
|
||||
if (!OSUtils::readFile((std::string("rootservers/")+(*sn)).c_str(),buf)) {
|
||||
std::cerr << "Cannot read rootservers/" << *sn << std::endl;
|
||||
return 1;
|
||||
}
|
||||
rootservers[*sn] = buf;
|
||||
}
|
||||
}
|
||||
topology["rootservers"] = rootservers.toString();
|
||||
|
||||
if ((topologyAuthority)&&(topologyAuthority.hasPrivate())) {
|
||||
// Sign topology with root-topology-authority.secret
|
||||
if (!topology.sign(topologyAuthority,OSUtils::now())) {
|
||||
std::cerr << "Unable to sign!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Test signature to make sure signing worked
|
||||
Dictionary test(topology.toString());
|
||||
if (!test.verify(topologyAuthority)) {
|
||||
std::cerr << "Test verification of signed dictionary failed!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Output to stdout
|
||||
std::cout << topology.toString();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
id=7e19876aba:0:2a6e2b2318930f60eb097f70d0f4b028b2cd6d3d0c63c014b9039ff35390e41181f216fb2e6fa8d95c1ee9667156411905c3dccfea78d8c6dfafba688170b3fa
|
||||
udp=198.199.97.220/9993
|
||||
tcp=198.199.97.220/443
|
||||
desc=San Francisco, California, USA
|
@ -1,4 +0,0 @@
|
||||
id=8841408a2e:0:bb1d31f2c323e264e9e64172c1a74f77899555ed10751cd56e86405cde118d02dffe555d462ccf6a85b5631c12350c8d5dc409ba10b9025d0f445cf449d92b1c
|
||||
udp=107.191.46.210/9993
|
||||
tcp=107.191.46.210/443
|
||||
desc=Paris, France
|
@ -1,4 +0,0 @@
|
||||
id=8acf059fe3:0:482f6ee5dfe902319b419de5bdc765209c0ecda38c4d6e4fcf0d33658398b4527dcd22f93112fb9befd02fd78bf7261b333fc105d192a623ca9e50fc60b374a5
|
||||
udp=162.243.77.111/9993
|
||||
tcp=162.243.77.111/443
|
||||
desc=New York, New York, USA
|
@ -1,4 +0,0 @@
|
||||
id=9d219039f3:0:01f0922a98e3b34ebcbff333269dc265d7a020aab69d72be4d4acc9c8c9294785771256cd1d942a90d1bd1d2dca3ea84ef7d85afe6611fb43ff0b74126d90a6e
|
||||
udp=128.199.197.217/9993
|
||||
tcp=128.199.197.217/443
|
||||
desc=Singapore
|
@ -1,6 +0,0 @@
|
||||
Test Root Topology Script
|
||||
======
|
||||
|
||||
This builds a test-root-topology from any number of running test-rootserver-# Docker containers. This can then be used with the (undocumented) -T (override root topology) option to run test networks under Docker.
|
||||
|
||||
Once you have a local Docker test network running you can use iptables rules to simulate a variety of network pathologies, or you can just use it to test any new changes to the protocol or node behavior at some limited scale.
|
@ -1,31 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ ! -e ../mktopology ]; then
|
||||
echo 'Build ../mktopology first!'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 'Populating rootservers/* with all Docker test-rootserver-* container IPs and identities...'
|
||||
|
||||
rm -rf rootservers
|
||||
mkdir rootservers
|
||||
|
||||
for cid in `docker ps -f 'name=test-rootserver-*' -q`; do
|
||||
id=`docker exec $cid cat /var/lib/zerotier-one/identity.secret | cut -d : -f 1-3`
|
||||
ztaddr=`echo $id | cut -d : -f 1`
|
||||
ip=`docker exec $cid ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'`
|
||||
echo $cid $ztaddr $id $ip
|
||||
echo "id=$id" >rootservers/$ztaddr
|
||||
echo "udp=$ip/9993" >>rootservers/$ztaddr
|
||||
done
|
||||
|
||||
echo 'Creating test-root-topology...'
|
||||
|
||||
rm -f test-root-topology
|
||||
../mktopology >test-root-topology
|
||||
|
||||
echo 'Done!'
|
||||
echo
|
||||
cat test-root-topology
|
||||
|
||||
exit 0
|
@ -50,7 +50,6 @@
|
||||
#include "node/C25519.hpp"
|
||||
#include "node/Poly1305.hpp"
|
||||
#include "node/CertificateOfMembership.hpp"
|
||||
#include "node/Defaults.hpp"
|
||||
#include "node/Node.hpp"
|
||||
#include "node/IncomingPacket.hpp"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user