summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.gitignore3
-rw-r--r--include/ZeroTierOne.h5
-rw-r--r--make-mac.mk4
-rw-r--r--node/IncomingPacket.cpp34
-rw-r--r--node/Node.cpp39
-rw-r--r--node/Packet.hpp35
-rw-r--r--node/Peer.cpp71
-rw-r--r--node/Peer.hpp25
-rw-r--r--node/RemotePath.hpp26
-rw-r--r--node/Topology.cpp11
-rw-r--r--node/Topology.hpp15
-rw-r--r--service/ControlPlane.cpp2
-rw-r--r--world/2015-10-13.binbin0 -> 494 bytes
-rw-r--r--world/2015-10-13.out6
-rw-r--r--world/mkworld.cpp (renamed from mkworld.cpp)0
15 files changed, 101 insertions, 175 deletions
diff --git a/.gitignore b/.gitignore
index 1cb16da5..2dbec1e5 100755
--- a/.gitignore
+++ b/.gitignore
@@ -31,7 +31,8 @@ Thumbs.db
/ZeroTierOneInstaller-*
/examples/docker/zerotier-one
/examples/docker/test-*.env
-/mkworld
+/world/mkworld
+/world/*.c25519
# Miscellaneous file types that we don't want to check in
*.log
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h
index f69ab54c..38db3222 100644
--- a/include/ZeroTierOne.h
+++ b/include/ZeroTierOne.h
@@ -583,11 +583,6 @@ typedef struct
uint64_t lastReceive;
/**
- * Is path fixed? (i.e. not learned, static)
- */
- int fixed;
-
- /**
* Is path active?
*/
int active;
diff --git a/make-mac.mk b/make-mac.mk
index 9fb613d8..174216fb 100644
--- a/make-mac.mk
+++ b/make-mac.mk
@@ -79,10 +79,6 @@ 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"
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index 39abe720..3c6268ed 100644
--- a/node/IncomingPacket.cpp
+++ b/node/IncomingPacket.cpp
@@ -42,6 +42,7 @@
#include "SelfAwareness.hpp"
#include "Salsa20.hpp"
#include "SHA512.hpp"
+#include "World.hpp"
namespace ZeroTier {
@@ -199,10 +200,18 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
const uint64_t timestamp = at<uint64_t>(ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP);
Identity id;
- const unsigned int destAddrPtr = ZT_PROTO_VERB_HELLO_IDX_IDENTITY + id.deserialize(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY);
InetAddress destAddr;
- if (destAddrPtr < size()) // ZeroTier One < 1.0.3 did not include this field
- destAddr.deserialize(*this,destAddrPtr);
+ uint64_t worldId = ZT_WORLD_ID_NULL;
+ uint64_t worldTimestamp = 0;
+ {
+ unsigned int ptr = ZT_PROTO_VERB_HELLO_IDX_IDENTITY + id.deserialize(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY);
+ if (ptr < size()) // ZeroTier One < 1.0.3 did not include physical destination address info
+ ptr += destAddr.deserialize(*this,ptr);
+ if ((ptr + 16) <= size()) { // older versions also did not include World IDs or timestamps
+ worldId = at<uint64_t>(ptr); ptr += 8;
+ worldTimestamp = at<uint64_t>(ptr);
+ }
+ }
if (protoVersion < ZT_PROTO_VERSION_MIN) {
TRACE("dropped HELLO from %s(%s): protocol version too old",id.address().toString().c_str(),_remoteAddress.toString().c_str());
@@ -286,8 +295,23 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR);
outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION);
_remoteAddress.serialize(outp);
- outp.armor(peer->key(),true);
- RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
+
+ if ((worldId != ZT_WORLD_ID_NULL)&&(worldId == RR->topology->worldId())) {
+ if (RR->topology->worldTimestamp() > worldTimestamp) {
+ World w(RR->topology->world());
+ const unsigned int sizeAt = outp.size();
+ outp.addSize(2); // make room for 16-bit size field
+ w.serialize(outp,false);
+ outp.setAt<uint16_t>(sizeAt,(uint16_t)(outp.size() - sizeAt));
+ } else {
+ outp.append((uint16_t)0); // no world update needed
+ }
+
+ outp.armor(peer->key(),true);
+ RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
+ } else {
+ TRACE("dropped HELLO from %s(%s): world ID mismatch: peer is %llu and we are %llu",source().toString().c_str(),_remoteAddress.toString().c_str(),worldId,RR->topology->worldId());
+ }
} catch ( ... ) {
TRACE("dropped HELLO from %s(%s): unexpected exception",source().toString().c_str(),_remoteAddress.toString().c_str());
}
diff --git a/node/Node.cpp b/node/Node.cpp
index 7496b045..5468f102 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -177,37 +177,47 @@ public:
RR(renv),
_now(now),
_relays(relays),
- _rootAddresses(RR->topology->rootAddresses())
+ _world(RR->topology->world())
{
}
- uint64_t lastReceiveFromUpstream;
+ uint64_t lastReceiveFromUpstream; // tracks last time we got a packet from an 'upstream' peer like a root or a relay
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
{
- bool isRelay = false;
- for(std::vector< std::pair<Address,InetAddress> >::const_iterator r(_relays.begin());r!=_relays.end();++r) {
- if (r->first == p->address()) {
- isRelay = true;
+ bool upstream = false;
+ InetAddress stableEndpoint;
+ for(std::vector<World::Root>::const_iterator r(_world.roots().begin());r!=_world.roots().end();++r) {
+ if (r->identity.address() == p->address()) {
+ if (r->stableEndpoints.size() > 0)
+ stableEndpoint = r->stableEndpoints[(unsigned long)RR->node->prng() % r->stableEndpoints.size()];
+ upstream = true;
break;
}
}
- if ((isRelay)||(std::find(_rootAddresses.begin(),_rootAddresses.end(),p->address()) != _rootAddresses.end())) {
- p->doPingAndKeepalive(RR,_now);
- if (p->lastReceive() > lastReceiveFromUpstream)
- lastReceiveFromUpstream = p->lastReceive();
- } else {
- if (p->alive(_now))
- p->doPingAndKeepalive(RR,_now);
+ if (!upstream) {
+ for(std::vector< std::pair<Address,InetAddress> >::const_iterator r(_relays.begin());r!=_relays.end();++r) {
+ if (r->first == p->address()) {
+ stableEndpoint = r->second;
+ upstream = true;
+ break;
+ }
+ }
}
+
+ if ((!p->doPingAndKeepalive(RR,_now))&&(stableEndpoint))
+ p->attemptToContactAt(RR,InetAddress(),stableEndpoint,_now);
+
+ if (upstream)
+ lastReceiveFromUpstream = std::max(p->lastReceive(),lastReceiveFromUpstream);
}
private:
const RuntimeEnvironment *RR;
uint64_t _now;
const std::vector< std::pair<Address,InetAddress> > &_relays;
- std::vector<Address> _rootAddresses;
+ World _world;
};
ZT_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline)
@@ -376,7 +386,6 @@ ZT_PeerList *Node::peers() const
memcpy(&(p->paths[p->pathCount].address),&(path->address()),sizeof(struct sockaddr_storage));
p->paths[p->pathCount].lastSend = path->lastSend();
p->paths[p->pathCount].lastReceive = path->lastReceived();
- p->paths[p->pathCount].fixed = path->fixed() ? 1 : 0;
p->paths[p->pathCount].active = path->active(_now) ? 1 : 0;
p->paths[p->pathCount].preferred = ((bestPath)&&(*path == *bestPath)) ? 1 : 0;
++p->pathCount;
diff --git a/node/Packet.hpp b/node/Packet.hpp
index 939d84a5..810f5d67 100644
--- a/node/Packet.hpp
+++ b/node/Packet.hpp
@@ -566,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 (of responder)>
- * <[8] 64-bit timestamp of current world (of responder)>
+ * <[2] 16-bit length of world update or 0 if none>
+ * [[...] world update]
*
* ERROR has no payload.
*/
@@ -1098,36 +1098,7 @@ public:
*
* ERROR has no payload.
*/
- 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
+ VERB_REQUEST_PROOF_OF_WORK = 19
};
/**
diff --git a/node/Peer.cpp b/node/Peer.cpp
index 111c849e..697ba75d 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -108,17 +108,16 @@ void Peer::received(
// Add new path
slot = &(_paths[np++]);
} else {
- // Replace oldest non-fixed path
uint64_t slotLRmin = 0xffffffffffffffffULL;
for(unsigned int p=0;p<ZT_MAX_PEER_NETWORK_PATHS;++p) {
- if ((!_paths[p].fixed())&&(_paths[p].lastReceived() <= slotLRmin)) {
+ if (_paths[p].lastReceived() <= slotLRmin) {
slotLRmin = _paths[p].lastReceived();
slot = &(_paths[p]);
}
}
}
if (slot) {
- *slot = RemotePath(localAddr,remoteAddr,false);
+ *slot = RemotePath(localAddr,remoteAddr);
slot->received(now);
_numPaths = np;
pathIsConfirmed = true;
@@ -172,12 +171,15 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &lo
outp.append(now);
RR->identity.serialize(outp,false);
atAddress.serialize(outp);
+ outp.append((uint64_t)RR->topology->worldId());
+ outp.append((uint64_t)RR->topology->worldTimestamp());
+
outp.armor(_key,false); // HELLO is sent in the clear
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size());
}
-void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
+RemotePath *Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
{
Mutex::Lock _l(_lock);
RemotePath *const bestPath = _getBestPath(now);
@@ -193,6 +195,7 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
bestPath->sent(now);
}
}
+ return bestPath;
}
void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_t now,bool force)
@@ -269,59 +272,6 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_
}
}
-void Peer::addPath(const RemotePath &newp,uint64_t now)
-{
- Mutex::Lock _l(_lock);
-
- unsigned int np = _numPaths;
-
- for(unsigned int p=0;p<np;++p) {
- if (_paths[p].address() == newp.address()) {
- _paths[p].setFixed(newp.fixed());
- _sortPaths(now);
- return;
- }
- }
-
- RemotePath *slot = (RemotePath *)0;
- if (np < ZT_MAX_PEER_NETWORK_PATHS) {
- // Add new path
- slot = &(_paths[np++]);
- } else {
- // Replace oldest non-fixed path
- uint64_t slotLRmin = 0xffffffffffffffffULL;
- for(unsigned int p=0;p<ZT_MAX_PEER_NETWORK_PATHS;++p) {
- if ((!_paths[p].fixed())&&(_paths[p].lastReceived() <= slotLRmin)) {
- slotLRmin = _paths[p].lastReceived();
- slot = &(_paths[p]);
- }
- }
- }
- if (slot) {
- *slot = newp;
- _numPaths = np;
- }
-
- _sortPaths(now);
-}
-
-void Peer::clearPaths(bool fixedToo)
-{
- if (fixedToo) {
- _numPaths = 0;
- } else {
- unsigned int np = _numPaths;
- unsigned int x = 0;
- unsigned int y = 0;
- while (x < np) {
- if (_paths[x].fixed())
- _paths[y++] = _paths[x];
- ++x;
- }
- _numPaths = y;
- }
-}
-
bool Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope scope,uint64_t now)
{
Mutex::Lock _l(_lock);
@@ -330,12 +280,9 @@ bool Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope sc
unsigned int y = 0;
while (x < np) {
if (_paths[x].address().ipScope() == scope) {
- if (_paths[x].fixed()) {
- attemptToContactAt(RR,_paths[x].localAddress(),_paths[x].address(),now);
- _paths[y++] = _paths[x]; // keep fixed paths
- }
+ attemptToContactAt(RR,_paths[x].localAddress(),_paths[x].address(),now);
} else {
- _paths[y++] = _paths[x]; // keep paths not in this scope
+ _paths[y++] = _paths[x];
}
++x;
}
diff --git a/node/Peer.hpp b/node/Peer.hpp
index 0988561a..cabf0793 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -133,7 +133,7 @@ public:
* Get the best direct path to this peer
*
* @param now Current time
- * @return Best path or NULL if there are no active (or fixed) direct paths
+ * @return Best path or NULL if there are no active direct paths
*/
inline RemotePath *getBestPath(uint64_t now)
{
@@ -178,8 +178,9 @@ public:
*
* @param RR Runtime environment
* @param now Current time
+ * @return Current best path or NULL if no active paths
*/
- void doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now);
+ RemotePath *doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now);
/**
* Push direct paths if we haven't done so in [rate limit] milliseconds
@@ -290,7 +291,7 @@ public:
/**
* @param now Current time
- * @return True if this peer has at least one active or fixed direct path
+ * @return True if this peer has at least one active direct path
*/
inline bool hasActiveDirectPath(uint64_t now) const
throw()
@@ -304,26 +305,8 @@ public:
}
/**
- * Add a path (if we don't already have it)
- *
- * @param p New path to add
- * @param now Current time
- */
- void addPath(const RemotePath &newp,uint64_t now);
-
- /**
- * Clear paths
- *
- * @param fixedToo If true, clear fixed paths as well as learned ones
- */
- void clearPaths(bool fixedToo);
-
- /**
* Reset paths within a given scope
*
- * For fixed paths in this scope, a packet is sent. Non-fixed paths in this
- * scope are forgotten.
- *
* @param RR Runtime environment
* @param scope IP scope of paths to reset
* @param now Current time
diff --git a/node/RemotePath.hpp b/node/RemotePath.hpp
index d2f99997..8b37621a 100644
--- a/node/RemotePath.hpp
+++ b/node/RemotePath.hpp
@@ -39,8 +39,6 @@
#include "AntiRecursion.hpp"
#include "RuntimeEnvironment.hpp"
-#define ZT_REMOTEPATH_FLAG_FIXED 0x0001
-
namespace ZeroTier {
/**
@@ -58,12 +56,12 @@ public:
_localAddress(),
_flags(0) {}
- RemotePath(const InetAddress &localAddress,const InetAddress &addr,bool fixed) :
+ RemotePath(const InetAddress &localAddress,const InetAddress &addr) :
Path(addr,0,TRUST_NORMAL),
_lastSend(0),
_lastReceived(0),
_localAddress(localAddress),
- _flags(fixed ? ZT_REMOTEPATH_FLAG_FIXED : 0) {}
+ _flags(0) {}
inline const InetAddress &localAddress() const throw() { return _localAddress; }
@@ -71,22 +69,6 @@ public:
inline uint64_t lastReceived() const throw() { return _lastReceived; }
/**
- * @return Is this a fixed path?
- */
- inline bool fixed() const throw() { return ((_flags & ZT_REMOTEPATH_FLAG_FIXED) != 0); }
-
- /**
- * @param f New value of fixed flag
- */
- inline void setFixed(const bool f)
- throw()
- {
- if (f)
- _flags |= ZT_REMOTEPATH_FLAG_FIXED;
- else _flags &= ~ZT_REMOTEPATH_FLAG_FIXED;
- }
-
- /**
* Called when a packet is sent to this remote path
*
* This is called automatically by RemotePath::send().
@@ -112,12 +94,12 @@ public:
/**
* @param now Current time
- * @return True if this path is fixed or has received data in last ACTIVITY_TIMEOUT ms
+ * @return True if this path appears active
*/
inline bool active(uint64_t now) const
throw()
{
- return ( ((_flags & ZT_REMOTEPATH_FLAG_FIXED) != 0) || ((now - _lastReceived) < ZT_PEER_ACTIVITY_TIMEOUT) );
+ return ((now - _lastReceived) < ZT_PEER_ACTIVITY_TIMEOUT);
}
/**
diff --git a/node/Topology.cpp b/node/Topology.cpp
index 0cf4cfe8..cdecfdae 100644
--- a/node/Topology.cpp
+++ b/node/Topology.cpp
@@ -35,8 +35,8 @@
namespace ZeroTier {
// Default World
-#define ZT_DEFAULT_WORLD_LENGTH 1
-static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = { 0 };
+#define ZT_DEFAULT_WORLD_LENGTH 494
+static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x4f,0xdf,0xbf,0xfc,0xbb,0x6c,0x7e,0x15,0x67,0x85,0x1b,0xb4,0x65,0x04,0x01,0xaf,0x56,0xbf,0xe7,0x63,0x9d,0x77,0xef,0xa4,0x1e,0x61,0x53,0x88,0xcb,0x8d,0x78,0xe5,0x47,0x38,0x98,0x5a,0x6c,0x8a,0xdd,0xe6,0x9c,0x65,0xdf,0x1a,0x80,0x63,0xce,0x2e,0x4d,0x48,0x24,0x3d,0x68,0x87,0x96,0x13,0x89,0xba,0x25,0x6f,0xc9,0xb0,0x9f,0x20,0xc5,0x4c,0x51,0x7b,0x30,0xb7,0x5f,0xba,0xca,0xa4,0xc5,0x48,0xa3,0x15,0xab,0x2f,0x1d,0x64,0xe8,0x04,0x42,0xb3,0x1c,0x51,0x8b,0x2a,0x04,0x01,0xf8,0xe1,0x81,0xaf,0x60,0x2f,0x70,0x3e,0xcd,0x0b,0x21,0x38,0x19,0x62,0x02,0xbd,0x0e,0x33,0x1d,0x0a,0x7b,0xf1,0xec,0xad,0xef,0x54,0xb3,0x7b,0x17,0x84,0xaa,0xda,0x0a,0x85,0x5d,0x0b,0x1c,0x05,0x83,0xb9,0x0e,0x3e,0xe3,0xb4,0xd1,0x8b,0x5b,0x64,0xf7,0xcf,0xe1,0xff,0x5d,0xc2,0x2a,0xcf,0x60,0x7b,0x09,0xb4,0xa3,0x86,0x3c,0x5a,0x7e,0x31,0xa0,0xc7,0xb4,0x86,0xe3,0x41,0x33,0x04,0x7e,0x19,0x87,0x6a,0xba,0x00,0x2a,0x6e,0x2b,0x23,0x18,0x93,0x0f,0x60,0xeb,0x09,0x7f,0x70,0xd0,0xf4,0xb0,0x28,0xb2,0xcd,0x6d,0x3d,0x0c,0x63,0xc0,0x14,0xb9,0x03,0x9f,0xf3,0x53,0x90,0xe4,0x11,0x81,0xf2,0x16,0xfb,0x2e,0x6f,0xa8,0xd9,0x5c,0x1e,0xe9,0x66,0x71,0x56,0x41,0x19,0x05,0xc3,0xdc,0xcf,0xea,0x78,0xd8,0xc6,0xdf,0xaf,0xba,0x68,0x81,0x70,0xb3,0xfa,0x00,0x01,0x04,0xc6,0xc7,0x61,0xdc,0x27,0x09,0x88,0x41,0x40,0x8a,0x2e,0x00,0xbb,0x1d,0x31,0xf2,0xc3,0x23,0xe2,0x64,0xe9,0xe6,0x41,0x72,0xc1,0xa7,0x4f,0x77,0x89,0x95,0x55,0xed,0x10,0x75,0x1c,0xd5,0x6e,0x86,0x40,0x5c,0xde,0x11,0x8d,0x02,0xdf,0xfe,0x55,0x5d,0x46,0x2c,0xcf,0x6a,0x85,0xb5,0x63,0x1c,0x12,0x35,0x0c,0x8d,0x5d,0xc4,0x09,0xba,0x10,0xb9,0x02,0x5d,0x0f,0x44,0x5c,0xf4,0x49,0xd9,0x2b,0x1c,0x00,0x01,0x04,0x6b,0xbf,0x2e,0xd2,0x27,0x09,0x8a,0xcf,0x05,0x9f,0xe3,0x00,0x48,0x2f,0x6e,0xe5,0xdf,0xe9,0x02,0x31,0x9b,0x41,0x9d,0xe5,0xbd,0xc7,0x65,0x20,0x9c,0x0e,0xcd,0xa3,0x8c,0x4d,0x6e,0x4f,0xcf,0x0d,0x33,0x65,0x83,0x98,0xb4,0x52,0x7d,0xcd,0x22,0xf9,0x31,0x12,0xfb,0x9b,0xef,0xd0,0x2f,0xd7,0x8b,0xf7,0x26,0x1b,0x33,0x3f,0xc1,0x05,0xd1,0x92,0xa6,0x23,0xca,0x9e,0x50,0xfc,0x60,0xb3,0x74,0xa5,0x00,0x01,0x04,0xa2,0xf3,0x4d,0x6f,0x27,0x09,0x9d,0x21,0x90,0x39,0xf3,0x00,0x01,0xf0,0x92,0x2a,0x98,0xe3,0xb3,0x4e,0xbc,0xbf,0xf3,0x33,0x26,0x9d,0xc2,0x65,0xd7,0xa0,0x20,0xaa,0xb6,0x9d,0x72,0xbe,0x4d,0x4a,0xcc,0x9c,0x8c,0x92,0x94,0x78,0x57,0x71,0x25,0x6c,0xd1,0xd9,0x42,0xa9,0x0d,0x1b,0xd1,0xd2,0xdc,0xa3,0xea,0x84,0xef,0x7d,0x85,0xaf,0xe6,0x61,0x1f,0xb4,0x3f,0xf0,0xb7,0x41,0x26,0xd9,0x0a,0x6e,0x00,0x01,0x04,0x80,0xc7,0xc5,0xd9,0x27,0x09};
Topology::Topology(const RuntimeEnvironment *renv) :
RR(renv),
@@ -276,6 +276,13 @@ bool Topology::worldUpdateIfValid(const World &newWorld)
Mutex::Lock _l(_lock);
if (_world.shouldBeReplacedBy(newWorld,true)) {
_setWorld(newWorld);
+ try {
+ Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> dswtmp;
+ newWorld.serialize(dswtmp,false);
+ RR->node->dataStorePut("world",dswtmp.data(),dswtmp.size(),false);
+ } catch ( ... ) {
+ RR->node->dataStoreDelete("world");
+ }
return true;
}
return false;
diff --git a/node/Topology.hpp b/node/Topology.hpp
index 3abc27e4..6f0170f0 100644
--- a/node/Topology.hpp
+++ b/node/Topology.hpp
@@ -147,12 +147,19 @@ public:
}
/**
- * @return Pair containing world ID and world timestamp (faster than world().id() etc.)
+ * @return Current world ID
*/
- inline std::pair<uint64_t,uint64_t> worldIdentification() const
+ inline uint64_t worldId() const
{
- Mutex::Lock _l(_lock);
- return std::pair<uint64_t,uint64_t>(_world.id(),_world.timestamp());
+ return _world.id(); // safe to read without lock, and used from within eachPeer() so don't lock
+ }
+
+ /**
+ * @return Current world timestamp
+ */
+ inline uint64_t worldTimestamp() const
+ {
+ return _world.timestamp(); // safe to read without lock, and used from within eachPeer() so don't lock
}
/**
diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp
index 6e731bdc..dd755a30 100644
--- a/service/ControlPlane.cpp
+++ b/service/ControlPlane.cpp
@@ -182,14 +182,12 @@ static std::string _jsonEnumerate(unsigned int depth,const ZT_PeerPhysicalPath *
"%s\t\"address\": \"%s\",\n"
"%s\t\"lastSend\": %llu,\n"
"%s\t\"lastReceive\": %llu,\n"
- "%s\t\"fixed\": %s,\n"
"%s\t\"active\": %s,\n"
"%s\t\"preferred\": %s\n"
"%s}",
prefix,_jsonEscape(reinterpret_cast<const InetAddress *>(&(pp[i].address))->toString()).c_str(),
prefix,pp[i].lastSend,
prefix,pp[i].lastReceive,
- prefix,(pp[i].fixed == 0) ? "false" : "true",
prefix,(pp[i].active == 0) ? "false" : "true",
prefix,(pp[i].preferred == 0) ? "false" : "true",
prefix);
diff --git a/world/2015-10-13.bin b/world/2015-10-13.bin
new file mode 100644
index 00000000..433a7763
--- /dev/null
+++ b/world/2015-10-13.bin
Binary files differ
diff --git a/world/2015-10-13.out b/world/2015-10-13.out
new file mode 100644
index 00000000..754e0692
--- /dev/null
+++ b/world/2015-10-13.out
@@ -0,0 +1,6 @@
+INFO: created initial world keys: previous.c25519, current.c25519
+INFO: generating and signing id==149604618 ts==1442567945403
+INFO: wrote 494 bytes to stdout
+
+#define ZT_DEFAULT_WORLD_LENGTH 494
+static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x4f,0xdf,0xbf,0xfc,0xbb,0x6c,0x7e,0x15,0x67,0x85,0x1b,0xb4,0x65,0x04,0x01,0xaf,0x56,0xbf,0xe7,0x63,0x9d,0x77,0xef,0xa4,0x1e,0x61,0x53,0x88,0xcb,0x8d,0x78,0xe5,0x47,0x38,0x98,0x5a,0x6c,0x8a,0xdd,0xe6,0x9c,0x65,0xdf,0x1a,0x80,0x63,0xce,0x2e,0x4d,0x48,0x24,0x3d,0x68,0x87,0x96,0x13,0x89,0xba,0x25,0x6f,0xc9,0xb0,0x9f,0x20,0xc5,0x4c,0x51,0x7b,0x30,0xb7,0x5f,0xba,0xca,0xa4,0xc5,0x48,0xa3,0x15,0xab,0x2f,0x1d,0x64,0xe8,0x04,0x42,0xb3,0x1c,0x51,0x8b,0x2a,0x04,0x01,0xf8,0xe1,0x81,0xaf,0x60,0x2f,0x70,0x3e,0xcd,0x0b,0x21,0x38,0x19,0x62,0x02,0xbd,0x0e,0x33,0x1d,0x0a,0x7b,0xf1,0xec,0xad,0xef,0x54,0xb3,0x7b,0x17,0x84,0xaa,0xda,0x0a,0x85,0x5d,0x0b,0x1c,0x05,0x83,0xb9,0x0e,0x3e,0xe3,0xb4,0xd1,0x8b,0x5b,0x64,0xf7,0xcf,0xe1,0xff,0x5d,0xc2,0x2a,0xcf,0x60,0x7b,0x09,0xb4,0xa3,0x86,0x3c,0x5a,0x7e,0x31,0xa0,0xc7,0xb4,0x86,0xe3,0x41,0x33,0x04,0x7e,0x19,0x87,0x6a,0xba,0x00,0x2a,0x6e,0x2b,0x23,0x18,0x93,0x0f,0x60,0xeb,0x09,0x7f,0x70,0xd0,0xf4,0xb0,0x28,0xb2,0xcd,0x6d,0x3d,0x0c,0x63,0xc0,0x14,0xb9,0x03,0x9f,0xf3,0x53,0x90,0xe4,0x11,0x81,0xf2,0x16,0xfb,0x2e,0x6f,0xa8,0xd9,0x5c,0x1e,0xe9,0x66,0x71,0x56,0x41,0x19,0x05,0xc3,0xdc,0xcf,0xea,0x78,0xd8,0xc6,0xdf,0xaf,0xba,0x68,0x81,0x70,0xb3,0xfa,0x00,0x01,0x04,0xc6,0xc7,0x61,0xdc,0x27,0x09,0x88,0x41,0x40,0x8a,0x2e,0x00,0xbb,0x1d,0x31,0xf2,0xc3,0x23,0xe2,0x64,0xe9,0xe6,0x41,0x72,0xc1,0xa7,0x4f,0x77,0x89,0x95,0x55,0xed,0x10,0x75,0x1c,0xd5,0x6e,0x86,0x40,0x5c,0xde,0x11,0x8d,0x02,0xdf,0xfe,0x55,0x5d,0x46,0x2c,0xcf,0x6a,0x85,0xb5,0x63,0x1c,0x12,0x35,0x0c,0x8d,0x5d,0xc4,0x09,0xba,0x10,0xb9,0x02,0x5d,0x0f,0x44,0x5c,0xf4,0x49,0xd9,0x2b,0x1c,0x00,0x01,0x04,0x6b,0xbf,0x2e,0xd2,0x27,0x09,0x8a,0xcf,0x05,0x9f,0xe3,0x00,0x48,0x2f,0x6e,0xe5,0xdf,0xe9,0x02,0x31,0x9b,0x41,0x9d,0xe5,0xbd,0xc7,0x65,0x20,0x9c,0x0e,0xcd,0xa3,0x8c,0x4d,0x6e,0x4f,0xcf,0x0d,0x33,0x65,0x83,0x98,0xb4,0x52,0x7d,0xcd,0x22,0xf9,0x31,0x12,0xfb,0x9b,0xef,0xd0,0x2f,0xd7,0x8b,0xf7,0x26,0x1b,0x33,0x3f,0xc1,0x05,0xd1,0x92,0xa6,0x23,0xca,0x9e,0x50,0xfc,0x60,0xb3,0x74,0xa5,0x00,0x01,0x04,0xa2,0xf3,0x4d,0x6f,0x27,0x09,0x9d,0x21,0x90,0x39,0xf3,0x00,0x01,0xf0,0x92,0x2a,0x98,0xe3,0xb3,0x4e,0xbc,0xbf,0xf3,0x33,0x26,0x9d,0xc2,0x65,0xd7,0xa0,0x20,0xaa,0xb6,0x9d,0x72,0xbe,0x4d,0x4a,0xcc,0x9c,0x8c,0x92,0x94,0x78,0x57,0x71,0x25,0x6c,0xd1,0xd9,0x42,0xa9,0x0d,0x1b,0xd1,0xd2,0xdc,0xa3,0xea,0x84,0xef,0x7d,0x85,0xaf,0xe6,0x61,0x1f,0xb4,0x3f,0xf0,0xb7,0x41,0x26,0xd9,0x0a,0x6e,0x00,0x01,0x04,0x80,0xc7,0xc5,0xd9,0x27,0x09};
diff --git a/mkworld.cpp b/world/mkworld.cpp
index baf693fc..baf693fc 100644
--- a/mkworld.cpp
+++ b/world/mkworld.cpp