瀏覽代碼

Clean up some old stuff.

Adam Ierymenko 7 年之前
父節點
當前提交
f3dfd63634

+ 0 - 117
node/Array.hpp

@@ -1,117 +0,0 @@
-/*
- * ZeroTier One - Network Virtualization Everywhere
- * Copyright (C) 2011-2018  ZeroTier, Inc.  https://www.zerotier.com/
- *
- * 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/>.
- *
- * --
- *
- * You can be released from the requirements of the license by purchasing
- * a commercial license. Buying such a license is mandatory as soon as you
- * develop commercial closed-source software that incorporates or links
- * directly against ZeroTier software without disclosing the source code
- * of your own application.
- */
-
-#ifndef ZT_ARRAY_HPP
-#define ZT_ARRAY_HPP
-
-#include <algorithm>
-
-namespace ZeroTier {
-
-/**
- * Static array -- a simple thing that's belonged in STL since the time of the dinosaurs
- */
-template<typename T,std::size_t S>
-class Array
-{
-public:
-	Array() {}
-
-	Array(const Array &a)
-	{
-		for(unsigned long i=0;i<S;++i)
-			data[i] = a.data[i];
-	}
-
-	Array(const T *ptr)
-	{
-		for(unsigned long i=0;i<S;++i)
-			data[i] = ptr[i];
-	}
-
-	inline Array &operator=(const Array &a)
-	{
-		for(unsigned long i=0;i<S;++i)
-			data[i] = a.data[i];
-		return *this;
-	}
-
-	typedef T value_type;
-	typedef T* pointer;
-	typedef const T* const_pointer;
-	typedef T& reference;
-	typedef const T& const_reference;
-	typedef unsigned long size_type;
-	typedef long difference_type;
-
-	/*
-	typedef T* iterator;
-	typedef const T* const_iterator;
-	typedef std::reverse_iterator<iterator> reverse_iterator;
-	typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
-	inline iterator begin() { return data; }
-	inline iterator end() { return &(data[S]); }
-	inline const_iterator begin() const { return data; }
-	inline const_iterator end() const { return &(data[S]); }
-
-	inline reverse_iterator rbegin() { return reverse_iterator(begin()); }
-	inline reverse_iterator rend() { return reverse_iterator(end()); }
-	inline const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
-	inline const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
-	*/
-
-	inline unsigned long size() const { return S; }
-	inline unsigned long max_size() const { return S; }
-
-	inline reference operator[](const std::size_t n) { return data[n]; }
-	inline const_reference operator[](const std::size_t n) const { return data[n]; }
-
-	inline reference front() { return data[0]; }
-	inline const_reference front() const { return data[0]; }
-	inline reference back() { return data[S-1]; }
-	inline const_reference back() const { return data[S-1]; }
-
-	inline bool operator==(const Array &k) const
-	{
-		for(unsigned long i=0;i<S;++i) {
-			if (data[i] != k.data[i])
-				return false;
-		}
-		return true;
-	}
-	inline bool operator!=(const Array &k) const { return !(*this == k); }
-	inline bool operator<(const Array &k) const { return std::lexicographical_compare(data,data + S,k.data,k.data + S); }
-	inline bool operator>(const Array &k) const { return (k < *this); }
-	inline bool operator<=(const Array &k) const { return !(k < *this); }
-	inline bool operator>=(const Array &k) const { return !(*this < k); }
-
-	T data[S];
-};
-
-} // namespace ZeroTier
-
-#endif

+ 6 - 25
node/C25519.hpp

@@ -27,7 +27,6 @@
 #ifndef ZT_C25519_HPP
 #define ZT_C25519_HPP
 
-#include "Array.hpp"
 #include "Utils.hpp"
 
 namespace ZeroTier {
@@ -42,28 +41,10 @@ namespace ZeroTier {
 class C25519
 {
 public:
-	/**
-	 * Public key (both crypto and signing)
-	 */
-	typedef Array<unsigned char,ZT_C25519_PUBLIC_KEY_LEN> Public; // crypto key, signing key (both 32 bytes)
-
-	/**
-	 * Private key (both crypto and signing)
-	 */
-	typedef Array<unsigned char,ZT_C25519_PRIVATE_KEY_LEN> Private; // crypto key, signing key (both 32 bytes)
-
-	/**
-	 * Message signature
-	 */
-	typedef Array<unsigned char,ZT_C25519_SIGNATURE_LEN> Signature;
-
-	/**
-	 * Public/private key pair
-	 */
-	typedef struct {
-		Public pub;
-		Private priv;
-	} Pair;
+	struct Public { uint8_t data[ZT_C25519_PUBLIC_KEY_LEN]; };
+	struct Private { uint8_t data[ZT_C25519_PRIVATE_KEY_LEN]; };
+	struct Signature { uint8_t data[ZT_C25519_SIGNATURE_LEN]; };
+	struct Pair { Public pub; Private priv; };
 
 	/**
 	 * Generate a C25519 elliptic curve key pair
@@ -71,7 +52,7 @@ public:
 	static inline Pair generate()
 	{
 		Pair kp;
-		Utils::getSecureRandom(kp.priv.data,(unsigned int)kp.priv.size());
+		Utils::getSecureRandom(kp.priv.data,ZT_C25519_PRIVATE_KEY_LEN);
 		_calcPubDH(kp);
 		_calcPubED(kp);
 		return kp;
@@ -95,7 +76,7 @@ public:
 	{
 		Pair kp;
 		void *const priv = (void *)kp.priv.data;
-		Utils::getSecureRandom(priv,(unsigned int)kp.priv.size());
+		Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN);
 		_calcPubED(kp); // do Ed25519 key -- bytes 32-63 of pub and priv
 		do {
 			++(((uint64_t *)priv)[1]);

+ 3 - 3
node/CertificateOfMembership.cpp

@@ -84,7 +84,7 @@ std::string CertificateOfMembership::toString() const
 
 	if (_signedBy) {
 		s.push_back(':');
-		s.append(Utils::hex(_signature.data,(unsigned int)_signature.size(),tmp));
+		s.append(Utils::hex(_signature.data,ZT_C25519_SIGNATURE_LEN,tmp));
 	}
 
 	return s;
@@ -94,7 +94,7 @@ void CertificateOfMembership::fromString(const char *s)
 {
 	_qualifierCount = 0;
 	_signedBy.zero();
-	memset(_signature.data,0,_signature.size());
+	memset(_signature.data,0,ZT_C25519_SIGNATURE_LEN);
 
 	if (!*s)
 		return;
@@ -145,7 +145,7 @@ void CertificateOfMembership::fromString(const char *s)
 				colonAt = 0;
 				while ((s[colonAt])&&(s[colonAt] != ':')) ++colonAt;
 				if (colonAt) {
-					if (Utils::unhex(s,colonAt,_signature.data,(unsigned int)_signature.size()) != _signature.size())
+					if (Utils::unhex(s,colonAt,_signature.data,ZT_C25519_SIGNATURE_LEN) != ZT_C25519_SIGNATURE_LEN)
 						_signedBy.zero();
 				} else {
 					_signedBy.zero();

+ 5 - 5
node/CertificateOfMembership.hpp

@@ -142,7 +142,7 @@ public:
 		_qualifiers[2].value = issuedTo.toInt();
 		_qualifiers[2].maxDelta = 0xffffffffffffffffULL;
 		_qualifierCount = 3;
-		memset(_signature.data,0,_signature.size());
+		memset(_signature.data,0,ZT_C25519_SIGNATURE_LEN);
 	}
 
 	inline CertificateOfMembership &operator=(const CertificateOfMembership &c)
@@ -293,7 +293,7 @@ public:
 		}
 		_signedBy.appendTo(b);
 		if (_signedBy)
-			b.append(_signature.data,(unsigned int)_signature.size());
+			b.append(_signature.data,ZT_C25519_SIGNATURE_LEN);
 	}
 
 	template<unsigned int C>
@@ -329,8 +329,8 @@ public:
 		p += ZT_ADDRESS_LENGTH;
 
 		if (_signedBy) {
-			ZT_FAST_MEMCPY(_signature.data,b.field(p,(unsigned int)_signature.size()),_signature.size());
-			p += (unsigned int)_signature.size();
+			ZT_FAST_MEMCPY(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN);
+			p += ZT_C25519_SIGNATURE_LEN;
 		}
 
 		return (p - startAt);
@@ -348,7 +348,7 @@ public:
 			if ((a.id != b.id)||(a.value != b.value)||(a.maxDelta != b.maxDelta))
 				return false;
 		}
-		return (_signature == c._signature);
+		return (memcmp(_signature.data,c._signature.data,ZT_C25519_SIGNATURE_LEN) == 0);
 	}
 	inline bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); }
 

+ 4 - 4
node/Identity.cpp

@@ -87,7 +87,7 @@ struct _Identity_generate_cond
 	_Identity_generate_cond(unsigned char *sb,char *gm) : digest(sb),genmem(gm) {}
 	inline bool operator()(const C25519::Pair &kp) const
 	{
-		_computeMemoryHardHash(kp.pub.data,(unsigned int)kp.pub.size(),digest,genmem);
+		_computeMemoryHardHash(kp.pub.data,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
 		return (digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN);
 	}
 	unsigned char *digest;
@@ -120,7 +120,7 @@ bool Identity::locallyValidate() const
 
 	unsigned char digest[64];
 	char *genmem = new char[ZT_IDENTITY_GEN_MEMORY];
-	_computeMemoryHardHash(_publicKey.data,(unsigned int)_publicKey.size(),digest,genmem);
+	_computeMemoryHardHash(_publicKey.data,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
 	delete [] genmem;
 
 	unsigned char addrb[5];
@@ -187,14 +187,14 @@ bool Identity::fromString(const char *str)
 				}
 				break;
 			case 2:
-				if (Utils::unhex(f,_publicKey.data,(unsigned int)_publicKey.size()) != _publicKey.size()) {
+				if (Utils::unhex(f,_publicKey.data,ZT_C25519_PUBLIC_KEY_LEN) != ZT_C25519_PUBLIC_KEY_LEN) {
 					_address.zero();
 					return false;
 				}
 				break;
 			case 3:
 				_privateKey = new C25519::Private();
-				if (Utils::unhex(f,_privateKey->data,(unsigned int)_privateKey->size()) != _privateKey->size()) {
+				if (Utils::unhex(f,_privateKey->data,ZT_C25519_PRIVATE_KEY_LEN) != ZT_C25519_PRIVATE_KEY_LEN) {
 					_address.zero();
 					return false;
 				}

+ 7 - 7
node/Identity.hpp

@@ -215,10 +215,10 @@ public:
 	{
 		_address.appendTo(b);
 		b.append((uint8_t)0); // C25519/Ed25519 identity type
-		b.append(_publicKey.data,(unsigned int)_publicKey.size());
+		b.append(_publicKey.data,ZT_C25519_PUBLIC_KEY_LEN);
 		if ((_privateKey)&&(includePrivate)) {
-			b.append((unsigned char)_privateKey->size());
-			b.append(_privateKey->data,(unsigned int)_privateKey->size());
+			b.append((unsigned char)ZT_C25519_PRIVATE_KEY_LEN);
+			b.append(_privateKey->data,ZT_C25519_PRIVATE_KEY_LEN);
 		} else b.append((unsigned char)0);
 	}
 
@@ -248,8 +248,8 @@ public:
 		if (b[p++] != 0)
 			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
 
-		ZT_FAST_MEMCPY(_publicKey.data,b.field(p,(unsigned int)_publicKey.size()),(unsigned int)_publicKey.size());
-		p += (unsigned int)_publicKey.size();
+		ZT_FAST_MEMCPY(_publicKey.data,b.field(p,ZT_C25519_PUBLIC_KEY_LEN),ZT_C25519_PUBLIC_KEY_LEN);
+		p += ZT_C25519_PUBLIC_KEY_LEN;
 
 		unsigned int privateKeyLength = (unsigned int)b[p++];
 		if (privateKeyLength) {
@@ -306,8 +306,8 @@ public:
 	 */
 	inline operator bool() const { return (_address); }
 
-	inline bool operator==(const Identity &id) const { return ((_address == id._address)&&(_publicKey == id._publicKey)); }
-	inline bool operator<(const Identity &id) const { return ((_address < id._address)||((_address == id._address)&&(_publicKey < id._publicKey))); }
+	inline bool operator==(const Identity &id) const { return ((_address == id._address)&&(memcmp(_publicKey.data,id._publicKey.data,ZT_C25519_PUBLIC_KEY_LEN) == 0)); }
+	inline bool operator<(const Identity &id) const { return ((_address < id._address)||((_address == id._address)&&(memcmp(_publicKey.data,id._publicKey.data,ZT_C25519_PUBLIC_KEY_LEN) < 0))); }
 	inline bool operator!=(const Identity &id) const { return !(*this == id); }
 	inline bool operator>(const Identity &id) const { return (id < *this); }
 	inline bool operator<=(const Identity &id) const { return !(id < *this); }

+ 32 - 34
node/Multicaster.hpp

@@ -42,7 +42,6 @@
 #include "OutboundMulticast.hpp"
 #include "Utils.hpp"
 #include "Mutex.hpp"
-#include "NonCopyable.hpp"
 
 namespace ZeroTier {
 
@@ -53,39 +52,8 @@ class Packet;
 /**
  * Database of known multicast peers within a network
  */
-class Multicaster : NonCopyable
+class Multicaster
 {
-private:
-	struct Key
-	{
-		Key() : nwid(0),mg() {}
-		Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {}
-
-		uint64_t nwid;
-		MulticastGroup mg;
-
-		inline bool operator==(const Key &k) const { return ((nwid == k.nwid)&&(mg == k.mg)); }
-		inline unsigned long hashCode() const { return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); }
-	};
-
-	struct MulticastGroupMember
-	{
-		MulticastGroupMember() {}
-		MulticastGroupMember(const Address &a,uint64_t ts) : address(a),timestamp(ts) {}
-
-		Address address;
-		uint64_t timestamp; // time of last notification
-	};
-
-	struct MulticastGroupStatus
-	{
-		MulticastGroupStatus() : lastExplicitGather(0) {}
-
-		uint64_t lastExplicitGather;
-		std::list<OutboundMulticast> txQueue; // pending outbound multicasts
-		std::vector<MulticastGroupMember> members; // members of this group
-	};
-
 public:
 	Multicaster(const RuntimeEnvironment *renv);
 	~Multicaster();
@@ -220,9 +188,39 @@ public:
 	}
 
 private:
+	struct Key
+	{
+		Key() : nwid(0),mg() {}
+		Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {}
+
+		uint64_t nwid;
+		MulticastGroup mg;
+
+		inline bool operator==(const Key &k) const { return ((nwid == k.nwid)&&(mg == k.mg)); }
+		inline unsigned long hashCode() const { return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); }
+	};
+
+	struct MulticastGroupMember
+	{
+		MulticastGroupMember() {}
+		MulticastGroupMember(const Address &a,uint64_t ts) : address(a),timestamp(ts) {}
+
+		Address address;
+		uint64_t timestamp; // time of last notification
+	};
+
+	struct MulticastGroupStatus
+	{
+		MulticastGroupStatus() : lastExplicitGather(0) {}
+
+		uint64_t lastExplicitGather;
+		std::list<OutboundMulticast> txQueue; // pending outbound multicasts
+		std::vector<MulticastGroupMember> members; // members of this group
+	};
+
 	void _add(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member);
 
-	const RuntimeEnvironment *RR;
+	const RuntimeEnvironment *const RR;
 
 	Hashtable<Multicaster::Key,MulticastGroupStatus> _groups;
 	Mutex _groups_m;

+ 1 - 3
node/World.hpp

@@ -240,11 +240,9 @@ public:
 		return (p - startAt);
 	}
 
-	inline bool operator==(const World &w) const { return ((_id == w._id)&&(_ts == w._ts)&&(_updatesMustBeSignedBy == w._updatesMustBeSignedBy)&&(_signature == w._signature)&&(_roots == w._roots)&&(_type == w._type)); }
+	inline bool operator==(const World &w) const { return ((_id == w._id)&&(_ts == w._ts)&&(memcmp(_updatesMustBeSignedBy.data,w._updatesMustBeSignedBy.data,ZT_C25519_PUBLIC_KEY_LEN) == 0)&&(memcmp(_signature.data,w._signature.data,ZT_C25519_SIGNATURE_LEN) == 0)&&(_roots == w._roots)&&(_type == w._type)); }
 	inline bool operator!=(const World &w) const { return (!(*this == w)); }
 
-	inline bool operator<(const World &w) const { return (((int)_type < (int)w._type) ? true : ((_type == w._type) ? (_id < w._id) : false)); }
-
 	/**
 	 * Create a World object signed with a key pair
 	 *

+ 6 - 6
one.cpp

@@ -795,7 +795,7 @@ static int idtool(int argc,char **argv)
 		}
 		C25519::Signature signature = id.sign(inf.data(),(unsigned int)inf.length());
 		char hexbuf[1024];
-		printf("%s",Utils::hex(signature.data,(unsigned int)signature.size(),hexbuf));
+		printf("%s",Utils::hex(signature.data,ZT_C25519_SIGNATURE_LEN,hexbuf));
 	} else if (!strcmp(argv[1],"verify")) {
 		if (argc < 4) {
 			idtoolPrintHelp(stdout,argv[0]);
@@ -838,8 +838,8 @@ static int idtool(int argc,char **argv)
 			nlohmann::json mj;
 			mj["objtype"] = "world";
 			mj["worldType"] = "moon";
-			mj["updatesMustBeSignedBy"] = mj["signingKey"] = Utils::hex(kp.pub.data,(unsigned int)kp.pub.size(),idtmp);
-			mj["signingKey_SECRET"] = Utils::hex(kp.priv.data,(unsigned int)kp.priv.size(),idtmp);
+			mj["updatesMustBeSignedBy"] = mj["signingKey"] = Utils::hex(kp.pub.data,ZT_C25519_PUBLIC_KEY_LEN,idtmp);
+			mj["signingKey_SECRET"] = Utils::hex(kp.priv.data,ZT_C25519_PRIVATE_KEY_LEN,idtmp);
 			mj["id"] = id.address().toString(idtmp);
 			nlohmann::json seedj;
 			seedj["identity"] = id.toString(false,idtmp);
@@ -878,9 +878,9 @@ static int idtool(int argc,char **argv)
 
 			C25519::Pair signingKey;
 			C25519::Public updatesMustBeSignedBy;
-			Utils::unhex(OSUtils::jsonString(mj["signingKey"],"").c_str(),signingKey.pub.data,(unsigned int)signingKey.pub.size());
-			Utils::unhex(OSUtils::jsonString(mj["signingKey_SECRET"],"").c_str(),signingKey.priv.data,(unsigned int)signingKey.priv.size());
-			Utils::unhex(OSUtils::jsonString(mj["updatesMustBeSignedBy"],"").c_str(),updatesMustBeSignedBy.data,(unsigned int)updatesMustBeSignedBy.size());
+			Utils::unhex(OSUtils::jsonString(mj["signingKey"],"").c_str(),signingKey.pub.data,ZT_C25519_PUBLIC_KEY_LEN);
+			Utils::unhex(OSUtils::jsonString(mj["signingKey_SECRET"],"").c_str(),signingKey.priv.data,ZT_C25519_PRIVATE_KEY_LEN);
+			Utils::unhex(OSUtils::jsonString(mj["updatesMustBeSignedBy"],"").c_str(),updatesMustBeSignedBy.data,ZT_C25519_PUBLIC_KEY_LEN);
 
 			std::vector<World::Root> roots;
 			nlohmann::json &rootsj = mj["roots"];

+ 12 - 11
osdep/Phy.hpp

@@ -688,25 +688,26 @@ public:
 	 * until one works.
 	 *
 	 * @param sock Socket
-	 * @param bufferSize Desired buffer sizes
+	 * @param receiveBufferSize Desired size of receive buffer
+	 * @param sendBufferSize Desired size of send buffer
 	 */
-	inline void setBufferSizes(const PhySocket *sock,int bufferSize)
+	inline void setBufferSizes(const PhySocket *sock,int receiveBufferSize,int sendBufferSize)
 	{
 		PhySocketImpl &sws = *(reinterpret_cast<PhySocketImpl *>(sock));
-		if (bufferSize > 0) {
-			int bs = bufferSize;
-			while (bs >= 65536) {
-				int tmpbs = bs;
+		if (receiveBufferSize > 0) {
+			while (receiveBufferSize > 0) {
+				int tmpbs = receiveBufferSize;
 				if (::setsockopt(sws.sock,SOL_SOCKET,SO_RCVBUF,(const char *)&tmpbs,sizeof(tmpbs)) == 0)
 					break;
-				bs -= 16384;
+				receiveBufferSize -= 16384;
 			}
-			bs = bufferSize;
-			while (bs >= 65536) {
-				int tmpbs = bs;
+		}
+		if (sendBufferSize > 0) {
+			while (sendBufferSize > 0) {
+				int tmpbs = sendBufferSize;
 				if (::setsockopt(sws.sock,SOL_SOCKET,SO_SNDBUF,(const char *)&tmpbs,sizeof(tmpbs)) == 0)
 					break;
-				bs -= 16384;
+				sendBufferSize -= 16384;
 			}
 		}
 	}

+ 5 - 5
selftest.cpp

@@ -321,10 +321,10 @@ static int testCrypto()
 	std::cout << "[crypto] Testing C25519 and Ed25519 against test vectors... "; std::cout.flush();
 	for(int k=0;k<ZT_NUM_C25519_TEST_VECTORS;++k) {
 		C25519::Pair p1,p2;
-		memcpy(p1.pub.data,C25519_TEST_VECTORS[k].pub1,p1.pub.size());
-		memcpy(p1.priv.data,C25519_TEST_VECTORS[k].priv1,p1.priv.size());
-		memcpy(p2.pub.data,C25519_TEST_VECTORS[k].pub2,p2.pub.size());
-		memcpy(p2.priv.data,C25519_TEST_VECTORS[k].priv2,p2.priv.size());
+		memcpy(p1.pub.data,C25519_TEST_VECTORS[k].pub1,ZT_C25519_PUBLIC_KEY_LEN);
+		memcpy(p1.priv.data,C25519_TEST_VECTORS[k].priv1,ZT_C25519_PRIVATE_KEY_LEN);
+		memcpy(p2.pub.data,C25519_TEST_VECTORS[k].pub2,ZT_C25519_PUBLIC_KEY_LEN);
+		memcpy(p2.priv.data,C25519_TEST_VECTORS[k].priv2,ZT_C25519_PRIVATE_KEY_LEN);
 		C25519::agree(p1,p2.pub,buf1,64);
 		C25519::agree(p2,p1.pub,buf2,64);
 		if (memcmp(buf1,buf2,64)) {
@@ -410,7 +410,7 @@ static int testCrypto()
 		}
 		for(unsigned int k=0;k<64;++k) {
 			C25519::Signature sig2(sig);
-			sig2.data[rand() % sig2.size()] ^= (unsigned char)(1 << (rand() & 7));
+			sig2.data[rand() % ZT_C25519_SIGNATURE_LEN] ^= (unsigned char)(1 << (rand() & 7));
 			if (C25519::verify(p1.pub,buf1,sizeof(buf1),sig2)) {
 				std::cout << "FAIL (5)" << std::endl;
 				return -1;

+ 2 - 2
service/OneService.cpp

@@ -285,8 +285,8 @@ static void _moonToJson(nlohmann::json &mj,const World &world)
 	OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",world.id());
 	mj["id"] = tmp;
 	mj["timestamp"] = world.timestamp();
-	mj["signature"] = Utils::hex(world.signature().data,(unsigned int)world.signature().size(),tmp);
-	mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data,(unsigned int)world.updatesMustBeSignedBy().size(),tmp);
+	mj["signature"] = Utils::hex(world.signature().data,ZT_C25519_SIGNATURE_LEN,tmp);
+	mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data,ZT_C25519_PUBLIC_KEY_LEN,tmp);
 	nlohmann::json ra = nlohmann::json::array();
 	for(std::vector<World::Root>::const_iterator r(world.roots().begin());r!=world.roots().end();++r) {
 		nlohmann::json rj;

+ 15 - 11
service/SoftwareUpdater.cpp

@@ -126,11 +126,13 @@ void SoftwareUpdater::setUpdateDistribution(bool distribute)
 						const std::string binPath(udd + ZT_PATH_SEPARATOR_S + u->substr(0,u->length() - 5));
 						const std::string metaHash(OSUtils::jsonBinFromHex(d.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH]));
 						if ((metaHash.length() == ZT_SHA512_DIGEST_LEN)&&(OSUtils::readFile(binPath.c_str(),d.bin))) {
-							uint8_t sha512[ZT_SHA512_DIGEST_LEN];
-							SHA512::hash(sha512,d.bin.data(),(unsigned int)d.bin.length());
-							if (!memcmp(sha512,metaHash.data(),ZT_SHA512_DIGEST_LEN)) { // double check that hash in JSON is correct
+							std::array<uint8_t,ZT_SHA512_DIGEST_LEN> sha512;
+							SHA512::hash(sha512.data(),d.bin.data(),(unsigned int)d.bin.length());
+							if (!memcmp(sha512.data(),metaHash.data(),ZT_SHA512_DIGEST_LEN)) { // double check that hash in JSON is correct
 								d.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIZE] = d.bin.length(); // override with correct value -- setting this in meta json is optional
-								_dist[Array<uint8_t,16>(sha512)] = d;
+								std::array<uint8_t,16> shakey;
+								memcpy(shakey.data(),sha512.data(),16);
+								_dist[shakey] = d;
 								if (_distLog) {
 									fprintf(_distLog,".......... INIT: DISTRIBUTING %s (%u bytes)" ZT_EOL_S,binPath.c_str(),(unsigned int)d.bin.length());
 									fflush(_distLog);
@@ -179,7 +181,7 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
 							unsigned int bestVMin = rvMin;
 							unsigned int bestVRev = rvRev;
 							unsigned int bestVBld = rvBld;
-							for(std::map< Array<uint8_t,16>,_D >::const_iterator d(_dist.begin());d!=_dist.end();++d) {
+							for(std::map< std::array<uint8_t,16>,_D >::const_iterator d(_dist.begin());d!=_dist.end();++d) {
 								// The arch field in update description .json files can be an array for e.g. multi-arch update files
 								const nlohmann::json &dvArch2 = d->second.meta[ZT_SOFTWARE_UPDATE_JSON_ARCHITECTURE];
 								std::vector<unsigned int> dvArch;
@@ -233,14 +235,14 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
 									_latestValid = false;
 									OSUtils::rm((_homePath + ZT_PATH_SEPARATOR_S ZT_SOFTWARE_UPDATE_BIN_FILENAME).c_str());
 									_download = std::string();
-									memcpy(_downloadHashPrefix.data,hash.data(),16);
+									memcpy(_downloadHashPrefix.data(),hash.data(),16);
 									_downloadLength = len;
 								}
 
 								if ((_downloadLength > 0)&&(_download.length() < _downloadLength)) {
 									Buffer<128> gd;
 									gd.append((uint8_t)VERB_GET_DATA);
-									gd.append(_downloadHashPrefix.data,16);
+									gd.append(_downloadHashPrefix.data(),16);
 									gd.append((uint32_t)_download.length());
 									_node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
 								}
@@ -257,7 +259,9 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
 					idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 18) << 16;
 					idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 19) << 8;
 					idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 20);
-					std::map< Array<uint8_t,16>,_D >::iterator d(_dist.find(Array<uint8_t,16>(reinterpret_cast<const uint8_t *>(data) + 1)));
+					std::array<uint8_t,16> shakey;
+					memcpy(shakey.data(),reinterpret_cast<const uint8_t *>(data) + 1,16);
+					std::map< std::array<uint8_t,16>,_D >::iterator d(_dist.find(shakey));
 					if ((d != _dist.end())&&(idx < (unsigned long)d->second.bin.length())) {
 						Buffer<ZT_SOFTWARE_UPDATE_CHUNK_SIZE + 128> buf;
 						buf.append((uint8_t)VERB_DATA);
@@ -270,7 +274,7 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
 				break;
 
 			case VERB_DATA:
-				if ((len >= 21)&&(_downloadLength > 0)&&(!memcmp(_downloadHashPrefix.data,reinterpret_cast<const uint8_t *>(data) + 1,16))) {
+				if ((len >= 21)&&(_downloadLength > 0)&&(!memcmp(_downloadHashPrefix.data(),reinterpret_cast<const uint8_t *>(data) + 1,16))) {
 					unsigned long idx = (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 17) << 24;
 					idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 18) << 16;
 					idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 19) << 8;
@@ -280,7 +284,7 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
 						if (_download.length() < _downloadLength) {
 							Buffer<128> gd;
 							gd.append((uint8_t)VERB_GET_DATA);
-							gd.append(_downloadHashPrefix.data,16);
+							gd.append(_downloadHashPrefix.data(),16);
 							gd.append((uint32_t)_download.length());
 							_node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
 						}
@@ -371,7 +375,7 @@ bool SoftwareUpdater::check(const int64_t now)
 		} else {
 			Buffer<128> gd;
 			gd.append((uint8_t)VERB_GET_DATA);
-			gd.append(_downloadHashPrefix.data,16);
+			gd.append(_downloadHashPrefix.data(),16);
 			gd.append((uint32_t)_download.length());
 			_node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
 		}

+ 3 - 3
service/SoftwareUpdater.hpp

@@ -33,11 +33,11 @@
 #include <vector>
 #include <map>
 #include <string>
+#include <array>
 
 #include "../include/ZeroTierOne.h"
 
 #include "../node/Identity.hpp"
-#include "../node/Array.hpp"
 #include "../node/Packet.hpp"
 
 #include "../ext/json/json.hpp"
@@ -202,13 +202,13 @@ private:
 		nlohmann::json meta;
 		std::string bin;
 	};
-	std::map< Array<uint8_t,16>,_D > _dist; // key is first 16 bytes of hash
+	std::map< std::array<uint8_t,16>,_D > _dist; // key is first 16 bytes of hash
 
 	nlohmann::json _latestMeta;
 	bool _latestValid;
 
 	std::string _download;
-	Array<uint8_t,16> _downloadHashPrefix;
+	std::array<uint8_t,16> _downloadHashPrefix;
 	unsigned long _downloadLength;
 };