mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-18 20:47:53 +00:00
Changes to how new-style binary network configs are detected, and a new-style binary serialized meta-data representation.
This commit is contained in:
parent
69d0562e2c
commit
529515d1d1
@ -300,6 +300,23 @@ public:
|
||||
append(s.data(),(unsigned int)s.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a C string including null termination byte
|
||||
*
|
||||
* @param s C string
|
||||
* @throws std::out_of_range Attempt to append beyond capacity
|
||||
*/
|
||||
inline void appendCString(const char *s)
|
||||
throw(std::out_of_range)
|
||||
{
|
||||
for(;;) {
|
||||
if (_l >= C)
|
||||
throw std::out_of_range("Buffer: append beyond capacity");
|
||||
if (!(_b[_l++] = *(s++)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a buffer
|
||||
*
|
||||
|
@ -181,12 +181,23 @@ bool Network::applyConfiguration(const NetworkConfig &conf)
|
||||
int Network::setConfiguration(const void *confBytes,unsigned int confLen,bool saveToDisk)
|
||||
{
|
||||
try {
|
||||
if (!confLen)
|
||||
if (confLen <= 1)
|
||||
return 0;
|
||||
|
||||
NetworkConfig newConfig;
|
||||
if (reinterpret_cast<const uint8_t *>(confBytes)[0] == ZT_NETWORKCONFIG_V2_MARKER_BYTE) {
|
||||
Buffer<8194> tmp(confBytes,confLen);
|
||||
|
||||
// Find the length of any string-serialized old-style Dictionary,
|
||||
// including its terminating NULL (if any). If this is before
|
||||
// the end of the config, that tells us there is a new-style
|
||||
// binary config which is preferred.
|
||||
unsigned int dictLen = 0;
|
||||
while (dictLen < confLen) {
|
||||
if (!(reinterpret_cast<const uint8_t *>(confBytes)[dictLen++]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (dictLen < (confLen - 2)) {
|
||||
Buffer<8194> tmp(reinterpret_cast<const uint8_t *>(confBytes) + dictLen,confLen - dictLen);
|
||||
newConfig.deserialize(tmp,0);
|
||||
} else {
|
||||
#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF
|
||||
@ -422,15 +433,15 @@ public:
|
||||
_now(renv->node->now()),
|
||||
_controller(nw->controller()),
|
||||
_network(nw),
|
||||
_anchors(nw->config().anchors()),
|
||||
_rootAddresses(renv->topology->rootAddresses())
|
||||
{}
|
||||
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
|
||||
{
|
||||
if (
|
||||
(_network->_isAllowed(p)) ||
|
||||
(p->address() == _controller) ||
|
||||
(std::find(_rootAddresses.begin(),_rootAddresses.end(),p->address()) != _rootAddresses.end())
|
||||
) {
|
||||
if ( (_network->_isAllowed(p)) || // FIXME: this causes multicast LIKEs for public networks to get spammed
|
||||
(p->address() == _controller) ||
|
||||
(std::find(_rootAddresses.begin(),_rootAddresses.end(),p->address()) != _rootAddresses.end()) ||
|
||||
(std::find(_anchors.begin(),_anchors.end(),p->address()) != _anchors.end()) ) {
|
||||
peers.push_back(p);
|
||||
}
|
||||
}
|
||||
@ -439,14 +450,15 @@ private:
|
||||
const uint64_t _now;
|
||||
const Address _controller;
|
||||
Network *const _network;
|
||||
const std::vector<Address> _anchors;
|
||||
const std::vector<Address> _rootAddresses;
|
||||
};
|
||||
void Network::_announceMulticastGroups()
|
||||
{
|
||||
// Assumes _lock is locked
|
||||
std::vector<MulticastGroup> allMulticastGroups(_allMulticastGroups());
|
||||
_MulticastAnnounceAll gpfunc(RR,this);
|
||||
RR->topology->eachPeer<_MulticastAnnounceAll &>(gpfunc);
|
||||
std::vector<MulticastGroup> allMulticastGroups(_allMulticastGroups());
|
||||
for(std::vector< SharedPtr<Peer> >::const_iterator i(gpfunc.peers.begin());i!=gpfunc.peers.end();++i)
|
||||
_announceMulticastGroupsTo(*i,allMulticastGroups);
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
|
||||
@ -40,13 +41,6 @@
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* First byte of V2 binary-serialized network configs
|
||||
*
|
||||
* This will never begin a Dictionary, so it serves to distinguish.
|
||||
*/
|
||||
#define ZT_NETWORKCONFIG_V2_MARKER_BYTE 0x00
|
||||
|
||||
/**
|
||||
* Flag: allow passive bridging (experimental)
|
||||
*/
|
||||
@ -68,9 +62,9 @@
|
||||
#define ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE 0x0000020000000000ULL
|
||||
|
||||
/**
|
||||
* This device is allowed to send packets from any Ethernet MAC, including ZeroTier-reserved ones
|
||||
* An anchor is a device that is willing to be one and has been online/stable for a long time on this network
|
||||
*/
|
||||
#define ZT_NETWORKCONFIG_SPECIALIST_TYPE_IMPOSTOR 0x0000040000000000ULL
|
||||
#define ZT_NETWORKCONFIG_SPECIALIST_TYPE_ANCHOR 0x0000040000000000ULL
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -302,6 +296,19 @@ public:
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ZeroTier addresses of "anchor" devices on this network
|
||||
*/
|
||||
inline std::vector<Address> anchors() const
|
||||
{
|
||||
std::vector<Address> r;
|
||||
for(unsigned int i=0;i<_specialistCount;++i) {
|
||||
if ((_specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ANCHOR) != 0)
|
||||
r.push_back(Address(_specialists[i]));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a static physical address for a given ZeroTier address
|
||||
*
|
||||
@ -321,6 +328,8 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets network preferred relays with their static physical address if one is defined
|
||||
*
|
||||
* @return Network-preferred relays for this network (if none, only roots will be used)
|
||||
*/
|
||||
inline std::vector<Relay> relays() const
|
||||
@ -393,9 +402,7 @@ public:
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b) const
|
||||
{
|
||||
b.append((uint8_t)ZT_NETWORKCONFIG_V2_MARKER_BYTE);
|
||||
|
||||
b.append((uint16_t)0); // version
|
||||
b.append((uint16_t)1); // version
|
||||
|
||||
b.append((uint64_t)_nwid);
|
||||
b.append((uint64_t)_timestamp);
|
||||
@ -517,9 +524,7 @@ public:
|
||||
|
||||
unsigned int p = startAt;
|
||||
|
||||
if (b[p++] != ZT_NETWORKCONFIG_V2_MARKER_BYTE)
|
||||
throw std::invalid_argument("unrecognized format");
|
||||
if (b.template at<uint16_t>(p) != 0)
|
||||
if (b.template at<uint16_t>(p) != 1)
|
||||
throw std::invalid_argument("unrecognized version");
|
||||
p += 2;
|
||||
|
||||
@ -532,9 +537,8 @@ public:
|
||||
_type = (ZT_VirtualNetworkType)b[p++];
|
||||
|
||||
unsigned int nl = (unsigned int)b[p++];
|
||||
if (nl > ZT_MAX_NETWORK_SHORT_NAME_LENGTH)
|
||||
nl = ZT_MAX_NETWORK_SHORT_NAME_LENGTH;
|
||||
memcpy(_name,b.field(p,nl),nl);
|
||||
memcpy(_name,b.field(p,nl),std::max(nl,(unsigned int)ZT_MAX_NETWORK_SHORT_NAME_LENGTH));
|
||||
p += nl;
|
||||
// _name will always be null terminated since field size is ZT_MAX_NETWORK_SHORT_NAME_LENGTH + 1
|
||||
|
||||
_specialistCount = (unsigned int)b.template at<uint16_t>(p); p += 2;
|
||||
|
@ -25,6 +25,9 @@
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "NetworkConfig.hpp"
|
||||
#include "Buffer.hpp"
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF
|
||||
#include <string>
|
||||
@ -33,27 +36,122 @@
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* Network configuration request meta data
|
||||
*/
|
||||
class NetworkConfigRequestMetaData
|
||||
{
|
||||
public:
|
||||
NetworkConfigRequestMetaData() :
|
||||
_vendor(0),
|
||||
_majorVersion(0),
|
||||
_minorVersion(0),
|
||||
_revision(0),
|
||||
_buildNo(0),
|
||||
_flags(0)
|
||||
NetworkConfigRequestMetaData()
|
||||
{
|
||||
memset(this,0,sizeof(NetworkConfigRequestMetaData));
|
||||
}
|
||||
|
||||
protected:
|
||||
unsigned int _vendor;
|
||||
unsigned int _majorVersion;
|
||||
unsigned int _minorVersion;
|
||||
unsigned int _revision;
|
||||
unsigned int _buildNo;
|
||||
unsigned int _flags;
|
||||
char _passcode[ZT_MAX_NETWORK_SHORT_NAME_LENGTH + 1];
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b) const
|
||||
{
|
||||
// Unlike network config we always send the old fields. Newer network
|
||||
// controllers will detect the presence of the new serialized data by
|
||||
// detecting extra data after the terminating NULL. But always sending
|
||||
// these maintains backward compatibility with old controllers.
|
||||
b.appendCString("majv="ZEROTIER_ONE_VERSION_MAJOR_S"\nminv="ZEROTIER_ONE_VERSION_MINOR_S"\nrevv="ZEROTIER_ONE_VERSION_REVISION_S"\n");
|
||||
|
||||
b.append((uint16_t)1); // version
|
||||
|
||||
b.append((uint64_t)buildId);
|
||||
b.append((uint64_t)flags);
|
||||
b.append((uint16_t)vendor);
|
||||
b.append((uint16_t)platform);
|
||||
b.append((uint16_t)architecture);
|
||||
b.append((uint16_t)majorVersion);
|
||||
b.append((uint16_t)minorVersion);
|
||||
b.append((uint16_t)revision);
|
||||
|
||||
unsigned int tl = (unsigned int)strlen(_auth);
|
||||
if (tl > 255) tl = 255; // sanity check
|
||||
b.append((uint8_t)tl);
|
||||
b.append((const void *)auth,tl);
|
||||
|
||||
b.append((uint16_t)0); // extended bytes, currently 0 since unused
|
||||
}
|
||||
|
||||
template<unsigned int C>
|
||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
||||
{
|
||||
memset(this,0,sizeof(NetworkConfigRequestMetaData));
|
||||
|
||||
unsigned int p = startAt;
|
||||
|
||||
// Seek past old style meta-data
|
||||
while (b[p]) ++p;
|
||||
|
||||
if (b.template at<uint16_t>(p) != 1)
|
||||
throw std::invalid_argument("unrecognized version");
|
||||
p += 2;
|
||||
|
||||
buildId = b.template at<uint64_t>(p); p += 8;
|
||||
flags = b.template at<uint64_t>(p); p += 8;
|
||||
vendor = (ZT_Vendor)b.template at<uint16_t>(p); p += 2;
|
||||
platform = (ZT_Platform)b.template at<uint16_t>(p); p += 2;
|
||||
architecture = (ZT_Architecture)b.template at<uint16_t>(p); p += 2;
|
||||
majorVersion = b.template at<uint16_t>(p); p += 2;
|
||||
minorVersion = b.template at<uint16_t>(p); p += 2;
|
||||
revision = b.template at<uint16_t>(p); p += 2;
|
||||
|
||||
unsigned int tl = (unsigned int)b[p++];
|
||||
memcpy(auth,b.field(p,tl),std::max(tl,(unsigned int)ZT_MAX_NETWORK_SHORT_NAME_LENGTH));
|
||||
// auth[] is ZT_MAX_NETWORK_SHORT_NAME_LENGTH + 1 and so will always end up null-terminated since we zeroed the structure
|
||||
p += tl;
|
||||
|
||||
p += b.template at<uint16_t>(p) + 2;
|
||||
|
||||
return (p - startAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build ID (currently unused, must be 0)
|
||||
*/
|
||||
uint64_t buildId;
|
||||
|
||||
/**
|
||||
* Flags (currently unused, must be 0)
|
||||
*/
|
||||
uint64_t flags;
|
||||
|
||||
/**
|
||||
* ZeroTier vendor or 0 for unspecified
|
||||
*/
|
||||
ZT_Vendor vendor;
|
||||
|
||||
/**
|
||||
* ZeroTier platform or 0 for unspecified
|
||||
*/
|
||||
ZT_Platform platform;
|
||||
|
||||
/**
|
||||
* ZeroTier architecture or 0 for unspecified
|
||||
*/
|
||||
ZT_Architecture architecture;
|
||||
|
||||
/**
|
||||
* ZeroTier software major version
|
||||
*/
|
||||
unsigned int majorVersion;
|
||||
|
||||
/**
|
||||
* ZeroTier software minor version
|
||||
*/
|
||||
unsigned int minorVersion;
|
||||
|
||||
/**
|
||||
* ZeroTier software revision
|
||||
*/
|
||||
unsigned int revision;
|
||||
|
||||
/**
|
||||
* Authentication data (e.g. bearer=<token>)
|
||||
*/
|
||||
char auth[ZT_MAX_NETWORK_SHORT_NAME_LENGTH + 1];
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -23,15 +23,18 @@
|
||||
* Major version
|
||||
*/
|
||||
#define ZEROTIER_ONE_VERSION_MAJOR 1
|
||||
#define ZEROTIER_ONE_VERSION_MAJOR_S "1"
|
||||
|
||||
/**
|
||||
* Minor version
|
||||
*/
|
||||
#define ZEROTIER_ONE_VERSION_MINOR 1
|
||||
#define ZEROTIER_ONE_VERSION_MINOR_S "1"
|
||||
|
||||
/**
|
||||
* Revision
|
||||
*/
|
||||
#define ZEROTIER_ONE_VERSION_REVISION 5
|
||||
#define ZEROTIER_ONE_VERSION_REVISION_S "5"
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user