mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-20 05:28:01 +00:00
More World stuff, and mkworld.
This commit is contained in:
parent
1b1945c63e
commit
cae58f43f1
@ -1023,7 +1023,6 @@ typedef int (*ZT_WirePacketSendFunction)(
|
||||
* @param dataStorePutFunction Function called to put objects in persistent storage
|
||||
* @param virtualNetworkConfigFunction Function to be called when virtual LANs are created, deleted, or their config parameters change
|
||||
* @param eventCallback Function to receive status updates and non-fatal error notices
|
||||
* @param overrideRootTopology Alternative root server topology or NULL for default (mostly for test/debug use)
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
enum ZT_ResultCode ZT_Node_new(
|
||||
@ -1035,8 +1034,7 @@ enum ZT_ResultCode ZT_Node_new(
|
||||
ZT_WirePacketSendFunction wirePacketSendFunction,
|
||||
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
||||
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
||||
ZT_EventCallback eventCallback,
|
||||
const char *overrideRootTopology);
|
||||
ZT_EventCallback eventCallback);
|
||||
|
||||
/**
|
||||
* Delete a node and free all resources it consumes
|
||||
|
@ -79,6 +79,10 @@ selftest: $(OBJS) selftest.o
|
||||
$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
|
||||
$(STRIP) zerotier-selftest
|
||||
|
||||
mkworld: $(OBJS)
|
||||
rm -f mkworld
|
||||
$(CXX) $(CXXFLAGS) -o mkworld mkworld.cpp $(OBJS) $(LIBS)
|
||||
|
||||
# Requires Packages: http://s.sudre.free.fr/Software/Packages/about.html
|
||||
mac-dist-pkg: FORCE
|
||||
packagesbuild "ext/installfiles/mac/ZeroTier One.pkgproj"
|
||||
@ -93,7 +97,7 @@ official: FORCE
|
||||
make ZT_OFFICIAL_RELEASE=1 mac-dist-pkg
|
||||
|
||||
clean:
|
||||
rm -rf *.dSYM build-* *.pkg *.dmg *.o node/*.o controller/*.o service/*.o osdep/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o zerotier-one zerotier-idtool zerotier-selftest zerotier-cli ZeroTierOneInstaller-*
|
||||
rm -rf *.dSYM build-* *.pkg *.dmg *.o node/*.o controller/*.o service/*.o osdep/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o zerotier-one zerotier-idtool zerotier-selftest zerotier-cli ZeroTierOneInstaller-* mkworld
|
||||
|
||||
# For those building from source -- installs signed binary tap driver in system ZT home
|
||||
install-mac-tap: FORCE
|
||||
|
153
mkworld.cpp
Normal file
153
mkworld.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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/
|
||||
*/
|
||||
|
||||
/*
|
||||
* This utility makes the World from the configuration specified below.
|
||||
* It probably won't be much use to anyone outside ZeroTier, Inc. except
|
||||
* for testing and experimentation purposes.
|
||||
*
|
||||
* If you want to make your own World you must edit this file.
|
||||
*
|
||||
* When run, it expects two files in the current directory:
|
||||
*
|
||||
* previous.c25519 - key pair to sign this world (key from previous world)
|
||||
* current.c25519 - key pair whose public key should be embedded in this world
|
||||
*
|
||||
* If these files do not exist, they are both created with the same key pair
|
||||
* and a self-signed initial World is born.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "node/Constants.hpp"
|
||||
#include "node/World.hpp"
|
||||
#include "node/C25519.hpp"
|
||||
#include "node/Identity.hpp"
|
||||
#include "node/InetAddress.hpp"
|
||||
#include "osdep/OSUtils.hpp"
|
||||
|
||||
using namespace ZeroTier;
|
||||
|
||||
class WorldMaker : public World
|
||||
{
|
||||
public:
|
||||
static inline World make(uint64_t id,uint64_t ts,const C25519::Public &sk,const std::vector<World::Root> &roots,const C25519::Pair &signWith)
|
||||
{
|
||||
WorldMaker w;
|
||||
w._id = id;
|
||||
w._ts = ts;
|
||||
w._updateSigningKey = sk;
|
||||
w._roots = roots;
|
||||
|
||||
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> tmp;
|
||||
w.serialize(tmp,true);
|
||||
w._signature = C25519::sign(signWith,tmp.data(),tmp.size());
|
||||
|
||||
return w;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
std::string previous,current;
|
||||
if ((!OSUtils::readFile("previous.c25519",previous))||(!OSUtils::readFile("current.c25519",current))) {
|
||||
C25519::Pair np(C25519::generate());
|
||||
previous = std::string();
|
||||
previous.append((const char *)np.pub.data,ZT_C25519_PUBLIC_KEY_LEN);
|
||||
previous.append((const char *)np.priv.data,ZT_C25519_PRIVATE_KEY_LEN);
|
||||
current = previous;
|
||||
OSUtils::writeFile("previous.c25519",previous);
|
||||
OSUtils::writeFile("current.c25519",current);
|
||||
fprintf(stderr,"INFO: created initial world keys: previous.c25519, current.c25519"ZT_EOL_S);
|
||||
}
|
||||
|
||||
if ((previous.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))||(current.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))) {
|
||||
fprintf(stderr,"FATAL: previous.c25519 or current.c25519 empty or invalid"ZT_EOL_S);
|
||||
return 1;
|
||||
}
|
||||
C25519::Pair previousKP;
|
||||
memcpy(previousKP.pub.data,previous.data(),ZT_C25519_PUBLIC_KEY_LEN);
|
||||
memcpy(previousKP.priv.data,previous.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN);
|
||||
C25519::Pair currentKP;
|
||||
memcpy(currentKP.pub.data,current.data(),ZT_C25519_PUBLIC_KEY_LEN);
|
||||
memcpy(currentKP.priv.data,current.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN);
|
||||
|
||||
// EDIT BELOW HERE ---------------------------------------------------------
|
||||
|
||||
std::vector<World::Root> roots;
|
||||
|
||||
// old US-SFO
|
||||
roots.push_back(World::Root());
|
||||
roots.back().identity = Identity("7e19876aba:0:2a6e2b2318930f60eb097f70d0f4b028b2cd6d3d0c63c014b9039ff35390e41181f216fb2e6fa8d95c1ee9667156411905c3dccfea78d8c6dfafba688170b3fa");
|
||||
roots.back().stableEndpoints.push_back(InetAddress("198.199.97.220/9993"));
|
||||
std::sort(roots.back().stableEndpoints.begin(),roots.back().stableEndpoints.end());
|
||||
|
||||
// old EU-PARIS
|
||||
roots.push_back(World::Root());
|
||||
roots.back().identity = Identity("8841408a2e:0:bb1d31f2c323e264e9e64172c1a74f77899555ed10751cd56e86405cde118d02dffe555d462ccf6a85b5631c12350c8d5dc409ba10b9025d0f445cf449d92b1c");
|
||||
roots.back().stableEndpoints.push_back(InetAddress("107.191.46.210/9993"));
|
||||
std::sort(roots.back().stableEndpoints.begin(),roots.back().stableEndpoints.end());
|
||||
|
||||
// old US-NYC
|
||||
roots.push_back(World::Root());
|
||||
roots.back().identity = Identity("8acf059fe3:0:482f6ee5dfe902319b419de5bdc765209c0ecda38c4d6e4fcf0d33658398b4527dcd22f93112fb9befd02fd78bf7261b333fc105d192a623ca9e50fc60b374a5");
|
||||
roots.back().stableEndpoints.push_back(InetAddress("162.243.77.111/9993"));
|
||||
std::sort(roots.back().stableEndpoints.begin(),roots.back().stableEndpoints.end());
|
||||
|
||||
// old AP-SNG
|
||||
roots.push_back(World::Root());
|
||||
roots.back().identity = Identity("9d219039f3:0:01f0922a98e3b34ebcbff333269dc265d7a020aab69d72be4d4acc9c8c9294785771256cd1d942a90d1bd1d2dca3ea84ef7d85afe6611fb43ff0b74126d90a6e");
|
||||
roots.back().stableEndpoints.push_back(InetAddress("128.199.197.217/9993"));
|
||||
std::sort(roots.back().stableEndpoints.begin(),roots.back().stableEndpoints.end());
|
||||
|
||||
std::sort(roots.begin(),roots.end());
|
||||
|
||||
const uint64_t id = ZT_WORLD_ID_EARTH;
|
||||
const uint64_t ts = OSUtils::now();
|
||||
|
||||
// END WORLD SETUP ---------------------------------------------------------
|
||||
|
||||
fprintf(stderr,"INFO: generating and signing id==%llu ts==%llu"ZT_EOL_S,(unsigned long long)id,(unsigned long long)ts);
|
||||
|
||||
World nw = WorldMaker::make(id,ts,currentKP.pub,roots,previousKP);
|
||||
|
||||
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> outtmp;
|
||||
nw.serialize(outtmp,false);
|
||||
fwrite(outtmp.data(),outtmp.size(),1,stdout);
|
||||
fflush(stdout);
|
||||
|
||||
fprintf(stderr,"INFO: wrote %u bytes to stdout"ZT_EOL_S,outtmp.size());
|
||||
|
||||
return 0;
|
||||
}
|
@ -33,7 +33,6 @@
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Defaults.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "IncomingPacket.hpp"
|
||||
#include "Topology.hpp"
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "Address.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "Defaults.hpp"
|
||||
|
||||
const struct sockaddr_storage ZT_SOCKADDR_NULL = {0};
|
||||
|
||||
@ -64,8 +63,7 @@ Node::Node(
|
||||
ZT_WirePacketSendFunction wirePacketSendFunction,
|
||||
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
||||
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
||||
ZT_EventCallback eventCallback,
|
||||
const char *overrideRootTopology) :
|
||||
ZT_EventCallback eventCallback) :
|
||||
_RR(this),
|
||||
RR(&_RR),
|
||||
_uPtr(uptr),
|
||||
@ -125,21 +123,6 @@ Node::Node(
|
||||
throw;
|
||||
}
|
||||
|
||||
Dictionary rt;
|
||||
if (overrideRootTopology) {
|
||||
rt.fromString(std::string(overrideRootTopology));
|
||||
} else {
|
||||
std::string rttmp(dataStoreGet("root-topology"));
|
||||
if (rttmp.length() > 0) {
|
||||
rt.fromString(rttmp);
|
||||
if (!Topology::authenticateRootTopology(rt))
|
||||
rt.clear();
|
||||
}
|
||||
if ((!rt.size())||(!rt.contains("rootservers")))
|
||||
rt.fromString(ZT_DEFAULTS.defaultRootTopology);
|
||||
}
|
||||
RR->topology->setRootServers(Dictionary(rt.get("rootservers","")));
|
||||
|
||||
postEvent(ZT_EVENT_UP);
|
||||
}
|
||||
|
||||
@ -609,12 +592,11 @@ enum ZT_ResultCode ZT_Node_new(
|
||||
ZT_WirePacketSendFunction wirePacketSendFunction,
|
||||
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
||||
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
||||
ZT_EventCallback eventCallback,
|
||||
const char *overrideRootTopology)
|
||||
ZT_EventCallback eventCallback)
|
||||
{
|
||||
*node = (ZT_Node *)0;
|
||||
try {
|
||||
*node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(now,uptr,dataStoreGetFunction,dataStorePutFunction,wirePacketSendFunction,virtualNetworkFrameFunction,virtualNetworkConfigFunction,eventCallback,overrideRootTopology));
|
||||
*node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(now,uptr,dataStoreGetFunction,dataStorePutFunction,wirePacketSendFunction,virtualNetworkFrameFunction,virtualNetworkConfigFunction,eventCallback));
|
||||
return ZT_RESULT_OK;
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -71,8 +71,7 @@ public:
|
||||
ZT_WirePacketSendFunction wirePacketSendFunction,
|
||||
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
||||
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
||||
ZT_EventCallback eventCallback,
|
||||
const char *overrideRootTopology);
|
||||
ZT_EventCallback eventCallback);
|
||||
|
||||
~Node();
|
||||
|
||||
|
@ -540,6 +540,8 @@ public:
|
||||
* <[...] binary serialized identity (see Identity)>
|
||||
* <[1] destination address type>
|
||||
* [<[...] destination address>]
|
||||
* <[8] 64-bit world ID of current world>
|
||||
* <[8] 64-bit timestamp of current world>
|
||||
*
|
||||
* This is the only message that ever must be sent in the clear, since it
|
||||
* is used to push an identity to a new peer.
|
||||
@ -564,8 +566,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>
|
||||
* <[8] 64-bit world ID of current world (of responder)>
|
||||
* <[8] 64-bit timestamp of current world (of responder)>
|
||||
*
|
||||
* ERROR has no payload.
|
||||
*/
|
||||
|
@ -42,23 +42,6 @@ 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");
|
||||
@ -97,19 +80,24 @@ 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);
|
||||
std::string dsWorld(RR->node->dataStoreGet("world"));
|
||||
World cachedWorld;
|
||||
try {
|
||||
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> dswtmp(dsWorld.data(),dsWorld.length());
|
||||
cachedWorld.deserialize(dswtmp,0);
|
||||
} catch ( ... ) {
|
||||
cachedWorld = World(); // clear 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 (cachedWorld.shouldBeReplacedBy(defaultWorld,false)) {
|
||||
_setWorld(defaultWorld);
|
||||
if (dsWorld.length() > 0)
|
||||
RR->node->dataStoreDelete("world");
|
||||
} else _setWorld(cachedWorld);
|
||||
}
|
||||
|
||||
Topology::~Topology()
|
||||
@ -283,6 +271,16 @@ keep_searching_for_roots:
|
||||
return bestRoot;
|
||||
}
|
||||
|
||||
bool Topology::worldUpdateIfValid(const World &newWorld)
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
if (_world.shouldBeReplacedBy(newWorld,true)) {
|
||||
_setWorld(newWorld);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Topology::clean(uint64_t now)
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
@ -320,4 +318,26 @@ void Topology::_saveIdentity(const Identity &id)
|
||||
}
|
||||
}
|
||||
|
||||
void Topology::_setWorld(const World &newWorld)
|
||||
{
|
||||
// assumed _lock is locked (or in constructor)
|
||||
_world = newWorld;
|
||||
_amRoot = false;
|
||||
_rootAddresses.clear();
|
||||
_rootPeers.clear();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -31,10 +31,10 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
@ -146,6 +146,23 @@ public:
|
||||
return _world;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Pair containing world ID and world timestamp (faster than world().id() etc.)
|
||||
*/
|
||||
inline std::pair<uint64_t,uint64_t> worldIdentification() const
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
return std::pair<uint64_t,uint64_t>(_world.id(),_world.timestamp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate new world and update if newer and signature is okay
|
||||
*
|
||||
* @param newWorld Potential new world definition revision
|
||||
* @return True if an update actually occurred
|
||||
*/
|
||||
bool worldUpdateIfValid(const World &newWorld);
|
||||
|
||||
/**
|
||||
* Clean and flush database
|
||||
*/
|
||||
@ -176,7 +193,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @return All currently active peers by address
|
||||
* @return All currently active peers by address (unsorted)
|
||||
*/
|
||||
inline std::vector< std::pair< Address,SharedPtr<Peer> > > allPeers() const
|
||||
{
|
||||
@ -187,6 +204,7 @@ public:
|
||||
private:
|
||||
Identity _getIdentity(const Address &zta);
|
||||
void _saveIdentity(const Identity &id);
|
||||
void _setWorld(const World &newWorld);
|
||||
|
||||
const RuntimeEnvironment *RR;
|
||||
|
||||
|
@ -55,7 +55,7 @@
|
||||
/**
|
||||
* 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)
|
||||
#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 + 128)
|
||||
|
||||
/**
|
||||
* World ID indicating null / empty World object
|
||||
@ -68,15 +68,11 @@
|
||||
#define ZT_WORLD_ID_TESTNET 1
|
||||
|
||||
/**
|
||||
* World ID for Earth -- its approximate distance from the sun in kilometers
|
||||
* World ID for Earth
|
||||
*
|
||||
* 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.
|
||||
* to the public network 8056c2e21c000001 of the same name. It was chosen
|
||||
* from Earth's approximate distance from the sun in kilometers.
|
||||
*/
|
||||
#define ZT_WORLD_ID_EARTH 149604618
|
||||
|
||||
@ -90,9 +86,24 @@ 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.
|
||||
* Think of a World as a single data center. Within this data center a set
|
||||
* of distributed fault tolerant root servers provide stable anchor points
|
||||
* for a peer to peer network that provides VLAN service. Updates to a world
|
||||
* definition can be published by signing them with the previous revision's
|
||||
* signing key, and should be very infrequent.
|
||||
*
|
||||
* The maximum data center size is approximately 2.5 cubic light seconds,
|
||||
* since many protocols have issues with >5s RTT latencies.
|
||||
*
|
||||
* ZeroTier operates a World for Earth capable of encompassing the planet, its
|
||||
* orbits, the Moon (about 1.3 light seconds), and nearby Lagrange points. A
|
||||
* world ID for Mars and nearby space is defined but not yet used, and a test
|
||||
* world ID is provided for testing purposes.
|
||||
*
|
||||
* If you absolutely must run your own "unofficial" ZeroTier network, please
|
||||
* define your world IDs above 0xffffffff (4294967295). Code to make a World
|
||||
* is in mkworld.cpp in the parent directory and must be edited to change
|
||||
* settings.
|
||||
*/
|
||||
class World
|
||||
{
|
||||
@ -130,24 +141,28 @@ public:
|
||||
inline uint64_t timestamp() const throw() { return _ts; }
|
||||
|
||||
/**
|
||||
* Verify a world update
|
||||
* Check whether a world update should replace this one
|
||||
*
|
||||
* 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
|
||||
* @param fullSignatureCheck Perform full cryptographic signature check (true == yes, false == skip)
|
||||
* @return True if update is newer than current and is properly signed
|
||||
*/
|
||||
inline bool verifyUpdate(const World &update)
|
||||
inline bool shouldBeReplacedBy(const World &update,bool fullSignatureCheck)
|
||||
{
|
||||
if (_id == ZT_WORLD_ID_NULL)
|
||||
return true;
|
||||
if ((update._id != _id)||(update._ts <= _ts))
|
||||
return false;
|
||||
if ((_id == update._id)&&(_ts < update._ts)) {
|
||||
if (fullSignatureCheck) {
|
||||
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> tmp;
|
||||
update.serialize(tmp);
|
||||
update.serialize(tmp,true);
|
||||
return C25519::verify(_updateSigningKey,tmp.data(),tmp.size(),update._signature);
|
||||
} else return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -156,12 +171,15 @@ public:
|
||||
inline operator bool() const throw() { return (_id != ZT_WORLD_ID_NULL); }
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b) const
|
||||
inline void serialize(Buffer<C> &b,bool forSign = false) const
|
||||
{
|
||||
if (forSign)
|
||||
b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
||||
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);
|
||||
if (!forSign)
|
||||
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) {
|
||||
@ -170,6 +188,8 @@ public:
|
||||
for(std::vector<InetAddress>::const_iterator ep(r->stableEndpoints.begin());ep!=r->stableEndpoints.end();++ep)
|
||||
ep->serialize(b);
|
||||
}
|
||||
if (forSign)
|
||||
b.append((uint64_t)0xf7f7f7f7f7f7f7f7ULL);
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
|
16
one.cpp
16
one.cpp
@ -911,7 +911,6 @@ static void printHelp(const char *cn,FILE *out)
|
||||
fprintf(out," -v - Show version"ZT_EOL_S);
|
||||
fprintf(out," -U - Run as unprivileged user (skip privilege check)"ZT_EOL_S);
|
||||
fprintf(out," -p<port> - Port for UDP and TCP/HTTP (default: 9993, 0 for random)"ZT_EOL_S);
|
||||
//fprintf(out," -T<path> - Override root topology, do not authenticate or update"ZT_EOL_S);
|
||||
|
||||
#ifdef __UNIX_LIKE__
|
||||
fprintf(out," -d - Fork and run as daemon (Unix-ish OSes)"ZT_EOL_S);
|
||||
@ -974,7 +973,6 @@ int main(int argc,char **argv)
|
||||
if ((strstr(argv[0],"zerotier-cli"))||(strstr(argv[0],"ZEROTIER-CLI")))
|
||||
return cli(argc,argv);
|
||||
|
||||
std::string overrideRootTopology;
|
||||
std::string homeDir;
|
||||
unsigned int port = ZT_DEFAULT_PORT;
|
||||
bool skipRootCheck = false;
|
||||
@ -1001,18 +999,6 @@ int main(int argc,char **argv)
|
||||
skipRootCheck = true;
|
||||
break;
|
||||
|
||||
case 'T': // Override root topology
|
||||
if (argv[i][2]) {
|
||||
if (!OSUtils::readFile(argv[i] + 2,overrideRootTopology)) {
|
||||
fprintf(stderr,"%s: cannot read root topology from %s"ZT_EOL_S,argv[0],argv[i] + 2);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
printHelp(argv[0],stdout);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v': // Display version
|
||||
printf("%d.%d.%d"ZT_EOL_S,ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION);
|
||||
return 0;
|
||||
@ -1169,7 +1155,7 @@ int main(int argc,char **argv)
|
||||
|
||||
try {
|
||||
for(;;) {
|
||||
zt1Service = OneService::newInstance(homeDir.c_str(),port,(overrideRootTopology.length() > 0) ? overrideRootTopology.c_str() : (const char *)0);
|
||||
zt1Service = OneService::newInstance(homeDir.c_str(),port);
|
||||
switch(zt1Service->run()) {
|
||||
case OneService::ONE_STILL_RUNNING: // shouldn't happen, run() won't return until done
|
||||
case OneService::ONE_NORMAL_TERMINATION:
|
||||
|
@ -418,14 +418,13 @@ struct TcpConnection
|
||||
class OneServiceImpl : public OneService
|
||||
{
|
||||
public:
|
||||
OneServiceImpl(const char *hp,unsigned int port,const char *overrideRootTopology) :
|
||||
OneServiceImpl(const char *hp,unsigned int port) :
|
||||
_homePath((hp) ? hp : "."),
|
||||
_tcpFallbackResolver(ZT_TCP_FALLBACK_RELAY),
|
||||
#ifdef ZT_ENABLE_NETWORK_CONTROLLER
|
||||
_controller((SqliteNetworkController *)0),
|
||||
#endif
|
||||
_phy(this,false,true),
|
||||
_overrideRootTopology((overrideRootTopology) ? overrideRootTopology : ""),
|
||||
_node((Node *)0),
|
||||
_controlPlane((ControlPlane *)0),
|
||||
_lastDirectReceiveFromGlobal(0),
|
||||
@ -550,8 +549,7 @@ public:
|
||||
SnodeWirePacketSendFunction,
|
||||
SnodeVirtualNetworkFrameFunction,
|
||||
SnodeVirtualNetworkConfigFunction,
|
||||
SnodeEventCallback,
|
||||
((_overrideRootTopology.length() > 0) ? _overrideRootTopology.c_str() : (const char *)0));
|
||||
SnodeEventCallback);
|
||||
|
||||
#ifdef ZT_ENABLE_NETWORK_CONTROLLER
|
||||
_controller = new SqliteNetworkController(_node,(_homePath + ZT_PATH_SEPARATOR_S + ZT_CONTROLLER_DB_PATH).c_str(),(_homePath + ZT_PATH_SEPARATOR_S + "circuitTestResults.d").c_str());
|
||||
@ -1329,7 +1327,6 @@ private:
|
||||
SqliteNetworkController *_controller;
|
||||
#endif
|
||||
Phy<OneServiceImpl *> _phy;
|
||||
std::string _overrideRootTopology;
|
||||
Node *_node;
|
||||
InetAddress _v4LocalAddress,_v6LocalAddress;
|
||||
PhySocket *_v4UdpSocket;
|
||||
@ -1526,7 +1523,7 @@ std::string OneService::autoUpdateUrl()
|
||||
return std::string();
|
||||
}
|
||||
|
||||
OneService *OneService::newInstance(const char *hp,unsigned int port,const char *overrideRootTopology) { return new OneServiceImpl(hp,port,overrideRootTopology); }
|
||||
OneService *OneService::newInstance(const char *hp,unsigned int port) { return new OneServiceImpl(hp,port); }
|
||||
OneService::~OneService() {}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -95,12 +95,10 @@ public:
|
||||
*
|
||||
* @param hp Home path
|
||||
* @param port TCP and UDP port for packets and HTTP control (if 0, pick random port)
|
||||
* @param overrideRootTopology String-serialized root topology (for testing, default: NULL)
|
||||
*/
|
||||
static OneService *newInstance(
|
||||
const char *hp,
|
||||
unsigned int port,
|
||||
const char *overrideRootTopology = (const char *)0);
|
||||
unsigned int port);
|
||||
|
||||
virtual ~OneService();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user