Selaa lähdekoodia

Minor cleanup.

Adam Ierymenko 8 vuotta sitten
vanhempi
commit
b9e1d53d7a

+ 31 - 29
node/Array.hpp

@@ -27,7 +27,6 @@
 #ifndef ZT_ARRAY_HPP
 #define ZT_ARRAY_HPP
 
-#include <string>
 #include <algorithm>
 
 namespace ZeroTier {
@@ -39,23 +38,23 @@ template<typename T,std::size_t S>
 class Array
 {
 public:
-	Array() throw() {}
+	Array() {}
 
 	Array(const Array &a)
 	{
-		for(std::size_t i=0;i<S;++i)
+		for(unsigned long i=0;i<S;++i)
 			data[i] = a.data[i];
 	}
 
 	Array(const T *ptr)
 	{
-		for(std::size_t i=0;i<S;++i)
+		for(unsigned long i=0;i<S;++i)
 			data[i] = ptr[i];
 	}
 
 	inline Array &operator=(const Array &a)
 	{
-		for(std::size_t i=0;i<S;++i)
+		for(unsigned long i=0;i<S;++i)
 			data[i] = a.data[i];
 		return *this;
 	}
@@ -65,35 +64,38 @@ public:
 	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::size_t size_type;
-	typedef std::ptrdiff_t difference_type;
 	typedef std::reverse_iterator<iterator> reverse_iterator;
 	typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
-	inline iterator begin() throw() { return data; }
-	inline iterator end() throw() { return &(data[S]); }
-	inline const_iterator begin() const throw() { return data; }
-	inline const_iterator end() const throw() { return &(data[S]); }
+	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() throw() { return reverse_iterator(begin()); }
-	inline reverse_iterator rend() throw() { return reverse_iterator(end()); }
-	inline const_reverse_iterator rbegin() const throw() { return const_reverse_iterator(begin()); }
-	inline const_reverse_iterator rend() const throw() { return const_reverse_iterator(end()); }
+	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 std::size_t size() const throw() { return S; }
-	inline std::size_t max_size() const throw() { return S; }
+	inline unsigned long size() const { return S; }
+	inline unsigned long max_size() const { return S; }
 
-	inline reference operator[](const std::size_t n) throw() { return data[n]; }
-	inline const_reference operator[](const std::size_t n) const throw() { return data[n]; }
+	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() throw() { return data[0]; }
-	inline const_reference front() const throw() { return data[0]; }
-	inline reference back() throw() { return data[S-1]; }
-	inline const_reference back() const throw() { return data[S-1]; }
+	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 throw()
+	inline bool operator==(const Array &k) const
 	{
 		for(unsigned long i=0;i<S;++i) {
 			if (data[i] != k.data[i])
@@ -101,11 +103,11 @@ public:
 		}
 		return true;
 	}
-	inline bool operator<(const Array &k) const throw() { return std::lexicographical_compare(begin(),end(),k.begin(),k.end()); }
-	inline bool operator!=(const Array &k) const throw() { return !(*this == k); }
-	inline bool operator>(const Array &k) const throw() { return (k < *this); }
-	inline bool operator<=(const Array &k) const throw() { return !(k < *this); }
-	inline bool operator>=(const Array &k) const throw() { return !(*this < k); }
+	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];
 };

+ 21 - 21
node/Buffer.hpp

@@ -95,7 +95,7 @@ public:
 	Buffer(unsigned int l)
 	{
 		if (l > C)
-			throw std::out_of_range("Buffer: construct with size larger than capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		_l = l;
 	}
 
@@ -119,7 +119,7 @@ public:
 	inline Buffer &operator=(const Buffer<C2> &b)
 	{
 		if (unlikely(b._l > C))
-			throw std::out_of_range("Buffer: assignment from buffer larger than capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		if (C2 == C) {
 			memcpy(this,&b,sizeof(Buffer<C>));
 		} else {
@@ -131,7 +131,7 @@ public:
 	inline void copyFrom(const void *b,unsigned int l)
 	{
 		if (unlikely(l > C))
-			throw std::out_of_range("Buffer: set from C array larger than capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		memcpy(_b,b,l);
 		_l = l;
 	}
@@ -139,14 +139,14 @@ public:
 	unsigned char operator[](const unsigned int i) const
 	{
 		if (unlikely(i >= _l))
-			throw std::out_of_range("Buffer: [] beyond end of data");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		return (unsigned char)_b[i];
 	}
 
 	unsigned char &operator[](const unsigned int i)
 	{
 		if (unlikely(i >= _l))
-			throw std::out_of_range("Buffer: [] beyond end of data");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		return ((unsigned char *)_b)[i];
 	}
 
@@ -166,13 +166,13 @@ public:
 	unsigned char *field(unsigned int i,unsigned int l)
 	{
 		if (unlikely((i + l) > _l))
-			throw std::out_of_range("Buffer: field() beyond end of data");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		return (unsigned char *)(_b + i);
 	}
 	const unsigned char *field(unsigned int i,unsigned int l) const
 	{
 		if (unlikely((i + l) > _l))
-			throw std::out_of_range("Buffer: field() beyond end of data");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		return (const unsigned char *)(_b + i);
 	}
 
@@ -187,7 +187,7 @@ public:
 	inline void setAt(unsigned int i,const T v)
 	{
 		if (unlikely((i + sizeof(T)) > _l))
-			throw std::out_of_range("Buffer: setAt() beyond end of data");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 #ifdef ZT_NO_TYPE_PUNNING
 		uint8_t *p = reinterpret_cast<uint8_t *>(_b + i);
 		for(unsigned int x=1;x<=sizeof(T);++x)
@@ -209,7 +209,7 @@ public:
 	inline T at(unsigned int i) const
 	{
 		if (unlikely((i + sizeof(T)) > _l))
-			throw std::out_of_range("Buffer: at() beyond end of data");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 #ifdef ZT_NO_TYPE_PUNNING
 		T v = 0;
 		const uint8_t *p = reinterpret_cast<const uint8_t *>(_b + i);
@@ -235,7 +235,7 @@ public:
 	inline void append(const T v)
 	{
 		if (unlikely((_l + sizeof(T)) > C))
-			throw std::out_of_range("Buffer: append beyond capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 #ifdef ZT_NO_TYPE_PUNNING
 		uint8_t *p = reinterpret_cast<uint8_t *>(_b + _l);
 		for(unsigned int x=1;x<=sizeof(T);++x)
@@ -257,7 +257,7 @@ public:
 	inline void append(unsigned char c,unsigned int n)
 	{
 		if (unlikely((_l + n) > C))
-			throw std::out_of_range("Buffer: append beyond capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		for(unsigned int i=0;i<n;++i)
 			_b[_l++] = (char)c;
 	}
@@ -270,7 +270,7 @@ public:
 	inline void appendRandom(unsigned int n)
 	{
 		if (unlikely((_l + n) > C))
-			throw std::out_of_range("Buffer: append beyond capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		Utils::getSecureRandom(_b + _l,n);
 		_l += n;
 	}
@@ -285,7 +285,7 @@ public:
 	inline void append(const void *b,unsigned int l)
 	{
 		if (unlikely((_l + l) > C))
-			throw std::out_of_range("Buffer: append beyond capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		memcpy(_b + _l,b,l);
 		_l += l;
 	}
@@ -311,7 +311,7 @@ public:
 	{
 		for(;;) {
 			if (unlikely(_l >= C))
-				throw std::out_of_range("Buffer: append beyond capacity");
+				throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 			if (!(_b[_l++] = *(s++)))
 				break;
 		}
@@ -343,7 +343,7 @@ public:
 	inline char *appendField(unsigned int l)
 	{
 		if (unlikely((_l + l) > C))
-			throw std::out_of_range("Buffer: append beyond capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		char *r = _b + _l;
 		_l += l;
 		return r;
@@ -360,7 +360,7 @@ public:
 	inline void addSize(unsigned int i)
 	{
 		if (unlikely((i + _l) > C))
-			throw std::out_of_range("Buffer: setSize to larger than capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		_l += i;
 	}
 
@@ -375,7 +375,7 @@ public:
 	inline void setSize(const unsigned int i)
 	{
 		if (unlikely(i > C))
-			throw std::out_of_range("Buffer: setSize to larger than capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		_l = i;
 	}
 
@@ -383,14 +383,14 @@ public:
 	 * Move everything after 'at' to the buffer's front and truncate
 	 *
 	 * @param at Truncate before this position
-	 * @throw std::out_of_range Position is beyond size of buffer
+	 * @throws std::out_of_range Position is beyond size of buffer
 	 */
 	inline void behead(const unsigned int at)
 	{
 		if (!at)
 			return;
 		if (unlikely(at > _l))
-			throw std::out_of_range("Buffer: behead() beyond capacity");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		::memmove(_b,_b + at,_l -= at);
 	}
 
@@ -399,13 +399,13 @@ public:
 	 *
 	 * @param start Starting position
 	 * @param length Length of block to erase
-	 * @throw std::out_of_range Position plus length is beyond size of buffer
+	 * @throws std::out_of_range Position plus length is beyond size of buffer
 	 */
 	inline void erase(const unsigned int at,const unsigned int length)
 	{
 		const unsigned int endr = at + length;
 		if (unlikely(endr > _l))
-			throw std::out_of_range("Buffer: erase() range beyond end of buffer");
+			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		::memmove(_b + at,_b + endr,_l - endr);
 		_l -= length;
 	}

+ 0 - 5
node/C25519.cpp

@@ -1998,7 +1998,6 @@ static inline void get_hram(unsigned char *hram, const unsigned char *sm, const
 //////////////////////////////////////////////////////////////////////////////
 
 void C25519::agree(const C25519::Private &mine,const C25519::Public &their,void *keybuf,unsigned int keylen)
-  throw()
 {
 	unsigned char rawkey[32];
 	unsigned char digest[64];
@@ -2015,7 +2014,6 @@ void C25519::agree(const C25519::Private &mine,const C25519::Public &their,void
 }
 
 void C25519::sign(const C25519::Private &myPrivate,const C25519::Public &myPublic,const void *msg,unsigned int len,void *signature)
-  throw()
 {
   sc25519 sck, scs, scsk;
   ge25519 ger;
@@ -2065,7 +2063,6 @@ void C25519::sign(const C25519::Private &myPrivate,const C25519::Public &myPubli
 }
 
 bool C25519::verify(const C25519::Public &their,const void *msg,unsigned int len,const void *signature)
-  throw()
 {
   unsigned char t2[32];
   ge25519 get1, get2;
@@ -2096,7 +2093,6 @@ bool C25519::verify(const C25519::Public &their,const void *msg,unsigned int len
 }
 
 void C25519::_calcPubDH(C25519::Pair &kp)
-  throw()
 {
   // First 32 bytes of pub and priv are the keys for ECDH key
   // agreement. This generates the public portion from the private.
@@ -2104,7 +2100,6 @@ void C25519::_calcPubDH(C25519::Pair &kp)
 }
 
 void C25519::_calcPubED(C25519::Pair &kp)
-  throw()
 {
   unsigned char extsk[64];
   sc25519 scsk;

+ 7 - 25
node/C25519.hpp

@@ -69,7 +69,6 @@ public:
 	 * Generate a C25519 elliptic curve key pair
 	 */
 	static inline Pair generate()
-		throw()
 	{
 		Pair kp;
 		Utils::getSecureRandom(kp.priv.data,(unsigned int)kp.priv.size());
@@ -93,7 +92,6 @@ public:
 	 */
 	template<typename F>
 	static inline Pair generateSatisfying(F cond)
-		throw()
 	{
 		Pair kp;
 		void *const priv = (void *)kp.priv.data;
@@ -118,13 +116,8 @@ public:
 	 * @param keybuf Buffer to fill
 	 * @param keylen Number of key bytes to generate
 	 */
-	static void agree(const Private &mine,const Public &their,void *keybuf,unsigned int keylen)
-		throw();
-	static inline void agree(const Pair &mine,const Public &their,void *keybuf,unsigned int keylen)
-		throw()
-	{
-		agree(mine.priv,their,keybuf,keylen);
-	}
+	static void agree(const Private &mine,const Public &their,void *keybuf,unsigned int keylen);
+	static inline void agree(const Pair &mine,const Public &their,void *keybuf,unsigned int keylen) { agree(mine.priv,their,keybuf,keylen); }
 
 	/**
 	 * Sign a message with a sender's key pair
@@ -145,13 +138,8 @@ public:
 	 * @param len Length of message in bytes
 	 * @param signature Buffer to fill with signature -- MUST be 96 bytes in length
 	 */
-	static void sign(const Private &myPrivate,const Public &myPublic,const void *msg,unsigned int len,void *signature)
-		throw();
-	static inline void sign(const Pair &mine,const void *msg,unsigned int len,void *signature)
-		throw()
-	{
-		sign(mine.priv,mine.pub,msg,len,signature);
-	}
+	static void sign(const Private &myPrivate,const Public &myPublic,const void *msg,unsigned int len,void *signature);
+	static inline void sign(const Pair &mine,const void *msg,unsigned int len,void *signature) { sign(mine.priv,mine.pub,msg,len,signature); }
 
 	/**
 	 * Sign a message with a sender's key pair
@@ -163,14 +151,12 @@ public:
 	 * @return Signature
 	 */
 	static inline Signature sign(const Private &myPrivate,const Public &myPublic,const void *msg,unsigned int len)
-		throw()
 	{
 		Signature sig;
 		sign(myPrivate,myPublic,msg,len,sig.data);
 		return sig;
 	}
 	static inline Signature sign(const Pair &mine,const void *msg,unsigned int len)
-		throw()
 	{
 		Signature sig;
 		sign(mine.priv,mine.pub,msg,len,sig.data);
@@ -186,8 +172,7 @@ public:
 	 * @param signature 96-byte signature
 	 * @return True if signature is valid and the message is authentic and unmodified
 	 */
-	static bool verify(const Public &their,const void *msg,unsigned int len,const void *signature)
-		throw();
+	static bool verify(const Public &their,const void *msg,unsigned int len,const void *signature);
 
 	/**
 	 * Verify a message's signature
@@ -199,7 +184,6 @@ public:
 	 * @return True if signature is valid and the message is authentic and unmodified
 	 */
 	static inline bool verify(const Public &their,const void *msg,unsigned int len,const Signature &signature)
-		throw()
 	{
 		return verify(their,msg,len,signature.data);
 	}
@@ -207,13 +191,11 @@ public:
 private:
 	// derive first 32 bytes of kp.pub from first 32 bytes of kp.priv
 	// this is the ECDH key
-	static void _calcPubDH(Pair &kp)
-		throw();
+	static void _calcPubDH(Pair &kp);
 
 	// derive 2nd 32 bytes of kp.pub from 2nd 32 bytes of kp.priv
 	// this is the Ed25519 sign/verify key
-	static void _calcPubED(Pair &kp)
-		throw();
+	static void _calcPubED(Pair &kp);
 };
 
 } // namespace ZeroTier

+ 5 - 5
node/Capability.hpp

@@ -420,24 +420,24 @@ public:
 
 		const unsigned int rc = b.template at<uint16_t>(p); p += 2;
 		if (rc > ZT_MAX_CAPABILITY_RULES)
-			throw std::runtime_error("rule overflow");
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 		deserializeRules(b,p,_rules,_ruleCount,rc);
 
 		_maxCustodyChainLength = (unsigned int)b[p++];
 		if ((_maxCustodyChainLength < 1)||(_maxCustodyChainLength > ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH))
-			throw std::runtime_error("invalid max custody chain length");
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 
 		for(unsigned int i=0;;++i) {
 			const Address to(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH;
 			if (!to)
 				break;
 			if ((i >= _maxCustodyChainLength)||(i >= ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH))
-				throw std::runtime_error("unterminated custody chain");
+				throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 			_custody[i].to = to;
 			_custody[i].from.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH;
 			if (b[p++] == 1) {
 				if (b.template at<uint16_t>(p) != ZT_C25519_SIGNATURE_LEN)
-					throw std::runtime_error("invalid signature");
+					throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
 				p += 2;
 				memcpy(_custody[i].signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN;
 			} else {
@@ -447,7 +447,7 @@ public:
 
 		p += 2 + b.template at<uint16_t>(p);
 		if (p > b.size())
-			throw std::runtime_error("extended field overflow");
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 
 		return (p - startAt);
 	}

+ 4 - 4
node/CertificateOfMembership.hpp

@@ -305,14 +305,14 @@ public:
 		_signedBy.zero();
 
 		if (b[p++] != 1)
-			throw std::invalid_argument("invalid object");
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
 
 		unsigned int numq = b.template at<uint16_t>(p); p += sizeof(uint16_t);
 		uint64_t lastId = 0;
 		for(unsigned int i=0;i<numq;++i) {
 			const uint64_t qid = b.template at<uint64_t>(p);
 			if (qid < lastId)
-				throw std::invalid_argument("qualifiers not sorted");
+				throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING;
 			else lastId = qid;
 			if (_qualifierCount < ZT_NETWORK_COM_MAX_QUALIFIERS) {
 				_qualifiers[_qualifierCount].id = qid;
@@ -321,7 +321,7 @@ public:
 				p += 24;
 				++_qualifierCount;
 			} else {
-				throw std::invalid_argument("too many qualifiers");
+				throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 			}
 		}
 
@@ -359,7 +359,7 @@ private:
 		uint64_t id;
 		uint64_t value;
 		uint64_t maxDelta;
-		inline bool operator<(const _Qualifier &q) const throw() { return (id < q.id); } // sort order
+		inline bool operator<(const _Qualifier &q) const { return (id < q.id); } // sort order
 	};
 
 	Address _signedBy;

+ 2 - 2
node/CertificateOfOwnership.hpp

@@ -207,7 +207,7 @@ public:
 		_signedBy.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH;
 		if (b[p++] == 1) {
 			if (b.template at<uint16_t>(p) != ZT_C25519_SIGNATURE_LEN)
-				throw std::runtime_error("invalid signature length");
+				throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
 			p += 2;
 			memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN;
 		} else {
@@ -216,7 +216,7 @@ public:
 
 		p += 2 + b.template at<uint16_t>(p);
 		if (p > b.size())
-			throw std::runtime_error("extended field overflow");
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 
 		return (p - startAt);
 	}

+ 2 - 2
node/CertificateOfRepresentation.hpp

@@ -164,14 +164,14 @@ public:
 				p += 2;
 				memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN);
 				p += ZT_C25519_SIGNATURE_LEN;
-			} else throw std::runtime_error("invalid signature");
+			} else throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
 		} else {
 			p += 2 + b.template at<uint16_t>(p);
 		}
 
 		p += 2 + b.template at<uint16_t>(p);
 		if (p > b.size())
-			throw std::runtime_error("extended field overflow");
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 
 		return (p - startAt);
 	}

+ 9 - 0
node/Constants.hpp

@@ -478,4 +478,13 @@
 #define ZT_ETHERTYPE_IPX_B 0x8138
 #define ZT_ETHERTYPE_IPV6 0x86dd
 
+#define ZT_EXCEPTION_OUT_OF_BOUNDS 100
+#define ZT_EXCEPTION_OUT_OF_MEMORY 101
+#define ZT_EXCEPTION_PRIVATE_KEY_REQUIRED 102
+#define ZT_EXCEPTION_INVALID_ARGUMENT 103
+#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE 200
+#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW 201
+#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN 202
+#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING 203
+
 #endif

+ 4 - 4
node/Hashtable.hpp

@@ -119,7 +119,7 @@ public:
 		_s(0)
 	{
 		if (!_t)
-			throw std::bad_alloc();
+			throw ZT_EXCEPTION_OUT_OF_MEMORY;
 		for(unsigned long i=0;i<bc;++i)
 			_t[i] = (_Bucket *)0;
 	}
@@ -130,7 +130,7 @@ public:
 		_s(ht._s)
 	{
 		if (!_t)
-			throw std::bad_alloc();
+			throw ZT_EXCEPTION_OUT_OF_MEMORY;
 		for(unsigned long i=0;i<_bc;++i)
 			_t[i] = (_Bucket *)0;
 		for(unsigned long i=0;i<_bc;++i) {
@@ -359,12 +359,12 @@ public:
 	/**
 	 * @return Number of entries
 	 */
-	inline unsigned long size() const throw() { return _s; }
+	inline unsigned long size() const { return _s; }
 
 	/**
 	 * @return True if table is empty
 	 */
-	inline bool empty() const throw() { return (_s == 0); }
+	inline bool empty() const { return (_s == 0); }
 
 private:
 	template<typename O>

+ 2 - 3
node/Identity.cpp

@@ -83,10 +83,9 @@ static inline void _computeMemoryHardHash(const void *publicKey,unsigned int pub
 // threshold value.
 struct _Identity_generate_cond
 {
-	_Identity_generate_cond() throw() {}
-	_Identity_generate_cond(unsigned char *sb,char *gm) throw() : digest(sb),genmem(gm) {}
+	_Identity_generate_cond() {}
+	_Identity_generate_cond(unsigned char *sb,char *gm) : digest(sb),genmem(gm) {}
 	inline bool operator()(const C25519::Pair &kp) const
-		throw()
 	{
 		_computeMemoryHardHash(kp.pub.data,(unsigned int)kp.pub.size(),digest,genmem);
 		return (digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN);

+ 14 - 15
node/Identity.hpp

@@ -71,7 +71,7 @@ public:
 		_privateKey((C25519::Private *)0)
 	{
 		if (!fromString(str))
-			throw std::invalid_argument(std::string("invalid string-serialized identity: ") + str);
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
 	}
 
 	template<unsigned int C>
@@ -121,7 +121,7 @@ public:
 	/**
 	 * @return True if this identity contains a private key
 	 */
-	inline bool hasPrivate() const throw() { return (_privateKey != (C25519::Private *)0); }
+	inline bool hasPrivate() const { return (_privateKey != (C25519::Private *)0); }
 
 	/**
 	 * Compute the SHA512 hash of our private key (if we have one)
@@ -145,11 +145,10 @@ public:
 	 * @param len Length of data
 	 */
 	inline C25519::Signature sign(const void *data,unsigned int len) const
-		throw(std::runtime_error)
 	{
 		if (_privateKey)
 			return C25519::sign(*_privateKey,_publicKey,data,len);
-		throw std::runtime_error("sign() requires a private key");
+		throw ZT_EXCEPTION_PRIVATE_KEY_REQUIRED;
 	}
 
 	/**
@@ -203,7 +202,7 @@ public:
 	/**
 	 * @return This identity's address
 	 */
-	inline const Address &address() const throw() { return _address; }
+	inline const Address &address() const { return _address; }
 
 	/**
 	 * Serialize this identity (binary)
@@ -248,7 +247,7 @@ public:
 		p += ZT_ADDRESS_LENGTH;
 
 		if (b[p++] != 0)
-			throw std::invalid_argument("unsupported identity type");
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
 
 		memcpy(_publicKey.data,b.field(p,(unsigned int)_publicKey.size()),(unsigned int)_publicKey.size());
 		p += (unsigned int)_publicKey.size();
@@ -256,7 +255,7 @@ public:
 		unsigned int privateKeyLength = (unsigned int)b[p++];
 		if (privateKeyLength) {
 			if (privateKeyLength != ZT_C25519_PRIVATE_KEY_LEN)
-				throw std::invalid_argument("invalid private key");
+				throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
 			_privateKey = new C25519::Private();
 			memcpy(_privateKey->data,b.field(p,ZT_C25519_PRIVATE_KEY_LEN),ZT_C25519_PRIVATE_KEY_LEN);
 			p += ZT_C25519_PRIVATE_KEY_LEN;
@@ -306,14 +305,14 @@ public:
 	/**
 	 * @return True if this identity contains something
 	 */
-	inline operator bool() const throw() { return (_address); }
-
-	inline bool operator==(const Identity &id) const throw() { return ((_address == id._address)&&(_publicKey == id._publicKey)); }
-	inline bool operator<(const Identity &id) const throw() { return ((_address < id._address)||((_address == id._address)&&(_publicKey < id._publicKey))); }
-	inline bool operator!=(const Identity &id) const throw() { return !(*this == id); }
-	inline bool operator>(const Identity &id) const throw() { return (id < *this); }
-	inline bool operator<=(const Identity &id) const throw() { return !(id < *this); }
-	inline bool operator>=(const Identity &id) const throw() { return !(*this < id); }
+	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 !(*this == id); }
+	inline bool operator>(const Identity &id) const { return (id < *this); }
+	inline bool operator<=(const Identity &id) const { return !(id < *this); }
+	inline bool operator>=(const Identity &id) const { return !(*this < id); }
 
 private:
 	Address _address;

+ 1 - 1
node/IncomingPacket.hpp

@@ -118,7 +118,7 @@ public:
 	/**
 	 * @return Time of packet receipt / start of decode
 	 */
-	inline uint64_t receiveTime() const throw() { return _receiveTime; }
+	inline uint64_t receiveTime() const { return _receiveTime; }
 
 private:
 	// These are called internally to handle packet contents once it has

+ 1 - 1
node/InetAddress.hpp

@@ -521,7 +521,7 @@ struct InetAddress : public sockaddr_storage
 				reinterpret_cast<struct sockaddr_in *>(this)->sin_port = Utils::hton(b.template at<uint16_t>(p)); p += 2;
 				break;
 			default:
-				throw std::invalid_argument("invalid serialized InetAddress");
+				throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING;
 		}
 		return (p - startAt);
 	}

+ 1 - 1
node/MAC.hpp

@@ -191,7 +191,7 @@ public:
 	 * @param i Value from 0 to 5 (inclusive)
 	 * @return Byte at said position (address interpreted in big-endian order)
 	 */
-	inline unsigned char operator[](unsigned int i) const throw() { return (unsigned char)((_m >> (40 - (i * 8))) & 0xff); }
+	inline unsigned char operator[](unsigned int i) const { return (unsigned char)((_m >> (40 - (i * 8))) & 0xff); }
 
 	/**
 	 * @return 6, which is the number of bytes in a MAC, for container compliance

+ 11 - 14
node/MulticastGroup.hpp

@@ -52,15 +52,13 @@ namespace ZeroTier {
 class MulticastGroup
 {
 public:
-	MulticastGroup()
-		throw() :
+	MulticastGroup() :
 		_mac(),
 		_adi(0)
 	{
 	}
 
-	MulticastGroup(const MAC &m,uint32_t a)
-		throw() :
+	MulticastGroup(const MAC &m,uint32_t a) :
 		_mac(m),
 		_adi(a)
 	{
@@ -73,7 +71,6 @@ public:
 	 * @return Multicat group for ARP/NDP
 	 */
 	static inline MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress &ip)
-		throw()
 	{
 		if (ip.isV4()) {
 			// IPv4 wants broadcast MACs, so we shove the V4 address itself into
@@ -95,18 +92,18 @@ public:
 	/**
 	 * @return Multicast address
 	 */
-	inline const MAC &mac() const throw() { return _mac; }
+	inline const MAC &mac() const { return _mac; }
 
 	/**
 	 * @return Additional distinguishing information
 	 */
-	inline uint32_t adi() const throw() { return _adi; }
+	inline uint32_t adi() const { return _adi; }
 
-	inline unsigned long hashCode() const throw() { return (_mac.hashCode() ^ (unsigned long)_adi); }
+	inline unsigned long hashCode() const { return (_mac.hashCode() ^ (unsigned long)_adi); }
 
-	inline bool operator==(const MulticastGroup &g) const throw() { return ((_mac == g._mac)&&(_adi == g._adi)); }
-	inline bool operator!=(const MulticastGroup &g) const throw() { return ((_mac != g._mac)||(_adi != g._adi)); }
-	inline bool operator<(const MulticastGroup &g) const throw()
+	inline bool operator==(const MulticastGroup &g) const { return ((_mac == g._mac)&&(_adi == g._adi)); }
+	inline bool operator!=(const MulticastGroup &g) const { return ((_mac != g._mac)||(_adi != g._adi)); }
+	inline bool operator<(const MulticastGroup &g) const
 	{
 		if (_mac < g._mac)
 			return true;
@@ -114,9 +111,9 @@ public:
 			return (_adi < g._adi);
 		return false;
 	}
-	inline bool operator>(const MulticastGroup &g) const throw() { return (g < *this); }
-	inline bool operator<=(const MulticastGroup &g) const throw() { return !(g < *this); }
-	inline bool operator>=(const MulticastGroup &g) const throw() { return !(*this < g); }
+	inline bool operator>(const MulticastGroup &g) const { return (g < *this); }
+	inline bool operator<=(const MulticastGroup &g) const { return !(g < *this); }
+	inline bool operator>=(const MulticastGroup &g) const { return !(*this < g); }
 
 private:
 	MAC _mac;

+ 2 - 2
node/Multicaster.hpp

@@ -64,8 +64,8 @@ private:
 		uint64_t nwid;
 		MulticastGroup mg;
 
-		inline bool operator==(const Key &k) const throw() { return ((nwid == k.nwid)&&(mg == k.mg)); }
-		inline unsigned long hashCode() const throw() { return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); }
+		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

+ 4 - 18
node/Mutex.hpp

@@ -41,7 +41,6 @@ class Mutex : NonCopyable
 {
 public:
 	Mutex()
-		throw()
 	{
 		pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0);
 	}
@@ -52,25 +51,21 @@ public:
 	}
 
 	inline void lock()
-		throw()
 	{
 		pthread_mutex_lock(&_mh);
 	}
 
 	inline void unlock()
-		throw()
 	{
 		pthread_mutex_unlock(&_mh);
 	}
 
 	inline void lock() const
-		throw()
 	{
 		(const_cast <Mutex *> (this))->lock();
 	}
 
 	inline void unlock() const
-		throw()
 	{
 		(const_cast <Mutex *> (this))->unlock();
 	}
@@ -81,15 +76,13 @@ public:
 	class Lock : NonCopyable
 	{
 	public:
-		Lock(Mutex &m)
-			throw() :
+		Lock(Mutex &m) :
 			_m(&m)
 		{
 			m.lock();
 		}
 
-		Lock(const Mutex &m)
-			throw() :
+		Lock(const Mutex &m) :
 			_m(const_cast<Mutex *>(&m))
 		{
 			_m->lock();
@@ -123,7 +116,6 @@ class Mutex : NonCopyable
 {
 public:
 	Mutex()
-		throw()
 	{
 		InitializeCriticalSection(&_cs);
 	}
@@ -134,25 +126,21 @@ public:
 	}
 
 	inline void lock()
-		throw()
 	{
 		EnterCriticalSection(&_cs);
 	}
 
 	inline void unlock()
-		throw()
 	{
 		LeaveCriticalSection(&_cs);
 	}
 
 	inline void lock() const
-		throw()
 	{
 		(const_cast <Mutex *> (this))->lock();
 	}
 
 	inline void unlock() const
-		throw()
 	{
 		(const_cast <Mutex *> (this))->unlock();
 	}
@@ -160,15 +148,13 @@ public:
 	class Lock : NonCopyable
 	{
 	public:
-		Lock(Mutex &m)
-			throw() :
+		Lock(Mutex &m) :
 			_m(&m)
 		{
 			m.lock();
 		}
 
-		Lock(const Mutex &m)
-			throw() :
+		Lock(const Mutex &m) :
 			_m(const_cast<Mutex *>(&m))
 		{
 			_m->lock();

+ 2 - 2
node/Network.hpp

@@ -76,7 +76,7 @@ public:
 	/**
 	 * Compute primary controller device ID from network ID
 	 */
-	static inline Address controllerFor(uint64_t nwid) throw() { return Address(nwid >> 24); }
+	static inline Address controllerFor(uint64_t nwid) { return Address(nwid >> 24); }
 
 	/**
 	 * Construct a new network
@@ -98,7 +98,7 @@ public:
 	inline Address controller() const { return Address(_id >> 24); }
 	inline bool multicastEnabled() const { return (_config.multicastLimit > 0); }
 	inline bool hasConfig() const { return (_config); }
-	inline uint64_t lastConfigUpdate() const throw() { return _lastConfigUpdate; }
+	inline uint64_t lastConfigUpdate() const { return _lastConfigUpdate; }
 	inline ZT_VirtualNetworkStatus status() const { Mutex::Lock _l(_lock); return _status(); }
 	inline const NetworkConfig &config() const { return _config; }
 	inline const MAC &mac() const { return _mac; }

+ 7 - 7
node/NetworkConfig.hpp

@@ -262,32 +262,32 @@ public:
 	/**
 	 * @return True if passive bridging is allowed (experimental)
 	 */
-	inline bool allowPassiveBridging() const throw() { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ALLOW_PASSIVE_BRIDGING) != 0); }
+	inline bool allowPassiveBridging() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ALLOW_PASSIVE_BRIDGING) != 0); }
 
 	/**
 	 * @return True if broadcast (ff:ff:ff:ff:ff:ff) address should work on this network
 	 */
-	inline bool enableBroadcast() const throw() { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST) != 0); }
+	inline bool enableBroadcast() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST) != 0); }
 
 	/**
 	 * @return True if IPv6 NDP emulation should be allowed for certain "magic" IPv6 address patterns
 	 */
-	inline bool ndpEmulation() const throw() { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION) != 0); }
+	inline bool ndpEmulation() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION) != 0); }
 
 	/**
 	 * @return True if frames should not be compressed
 	 */
-	inline bool disableCompression() const throw() { return ((this->flags & ZT_NETWORKCONFIG_FLAG_DISABLE_COMPRESSION) != 0); }
+	inline bool disableCompression() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_DISABLE_COMPRESSION) != 0); }
 
 	/**
 	 * @return Network type is public (no access control)
 	 */
-	inline bool isPublic() const throw() { return (this->type == ZT_NETWORK_TYPE_PUBLIC); }
+	inline bool isPublic() const { return (this->type == ZT_NETWORK_TYPE_PUBLIC); }
 
 	/**
 	 * @return Network type is private (certificate access control)
 	 */
-	inline bool isPrivate() const throw() { return (this->type == ZT_NETWORK_TYPE_PRIVATE); }
+	inline bool isPrivate() const { return (this->type == ZT_NETWORK_TYPE_PRIVATE); }
 
 	/**
 	 * @return ZeroTier addresses of devices on this network designated as active bridges
@@ -361,7 +361,7 @@ public:
 	/**
 	 * @return True if this network config is non-NULL
 	 */
-	inline operator bool() const throw() { return (networkId != 0); }
+	inline operator bool() const { return (networkId != 0); }
 
 	inline bool operator==(const NetworkConfig &nc) const { return (memcmp(this,&nc,sizeof(NetworkConfig)) == 0); }
 	inline bool operator!=(const NetworkConfig &nc) const { return (!(*this == nc)); }

+ 1 - 1
node/Node.cpp

@@ -64,7 +64,7 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint6
 	_lastHousekeepingRun(0)
 {
 	if (callbacks->version != 0)
-		throw std::runtime_error("callbacks struct version mismatch");
+		throw ZT_EXCEPTION_INVALID_ARGUMENT;
 	memcpy(&_cb,callbacks,sizeof(ZT_Node_Callbacks));
 
 	// Initialize non-cryptographic PRNG from a good random source

+ 2 - 2
node/Node.hpp

@@ -114,7 +114,7 @@ public:
 
 	// Internal functions ------------------------------------------------------
 
-	inline uint64_t now() const throw() { return _now; }
+	inline uint64_t now() const { return _now; }
 
 	inline bool putPacket(void *tPtr,const int64_t localSocket,const InetAddress &addr,const void *data,unsigned int len,unsigned int ttl = 0)
 	{
@@ -182,7 +182,7 @@ public:
 
 	inline int configureVirtualNetworkPort(void *tPtr,uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,nwid,nuptr,op,nc); }
 
-	inline bool online() const throw() { return _online; }
+	inline bool online() const { return _online; }
 
 	inline int stateObjectGet(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],void *const data,const unsigned int maxlen) { return _cb.stateGetFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,data,maxlen); }
 	inline void stateObjectPut(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],const void *const data,const unsigned int len) { _cb.statePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,data,(int)len); }

+ 1 - 1
node/NonCopyable.hpp

@@ -35,7 +35,7 @@ namespace ZeroTier {
 class NonCopyable
 {
 protected:
-	NonCopyable() throw() {}
+	NonCopyable() {}
 private:
 	NonCopyable(const NonCopyable&);
 	const NonCopyable& operator=(const NonCopyable&);

+ 3 - 3
node/OutboundMulticast.hpp

@@ -90,18 +90,18 @@ public:
 	/**
 	 * @return Multicast creation time
 	 */
-	inline uint64_t timestamp() const throw() { return _timestamp; }
+	inline uint64_t timestamp() const { return _timestamp; }
 
 	/**
 	 * @param now Current time
 	 * @return True if this multicast is expired (has exceeded transmit timeout)
 	 */
-	inline bool expired(uint64_t now) const throw() { return ((now - _timestamp) >= ZT_MULTICAST_TRANSMIT_TIMEOUT); }
+	inline bool expired(uint64_t now) const { return ((now - _timestamp) >= ZT_MULTICAST_TRANSMIT_TIMEOUT); }
 
 	/**
 	 * @return True if this outbound multicast has been sent to enough peers
 	 */
-	inline bool atLimit() const throw() { return (_alreadySentTo.size() >= _limit); }
+	inline bool atLimit() const { return (_alreadySentTo.size() >= _limit); }
 
 	/**
 	 * Just send without checking log

+ 2 - 7
node/Packet.hpp

@@ -424,8 +424,7 @@ public:
 		}
 
 		template<unsigned int C2>
-		Fragment(const Buffer<C2> &b)
-	 		throw(std::out_of_range) :
+		Fragment(const Buffer<C2> &b) :
 	 		Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b)
 		{
 		}
@@ -443,10 +442,8 @@ public:
 		 * @param fragLen Length of fragment in bytes
 		 * @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off)
 		 * @param fragTotal Total number of fragments (including 0)
-		 * @throws std::out_of_range Packet size would exceed buffer
 		 */
 		Fragment(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal)
-			throw(std::out_of_range)
 		{
 			init(p,fragStart,fragLen,fragNo,fragTotal);
 		}
@@ -459,13 +456,11 @@ public:
 		 * @param fragLen Length of fragment in bytes
 		 * @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off)
 		 * @param fragTotal Total number of fragments (including 0)
-		 * @throws std::out_of_range Packet size would exceed buffer
 		 */
 		inline void init(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal)
-			throw(std::out_of_range)
 		{
 			if ((fragStart + fragLen) > p.size())
-				throw std::out_of_range("Packet::Fragment: tried to construct fragment of packet past its length");
+				throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 			setSize(fragLen + ZT_PROTO_MIN_FRAGMENT_LENGTH);
 
 			// NOTE: this copies both the IV/packet ID and the destination address.

+ 1 - 1
node/Peer.cpp

@@ -61,7 +61,7 @@ Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Ident
 	_credentialsCutoffCount(0)
 {
 	if (!myIdentity.agree(peerIdentity,_key,ZT_PEER_SECRET_KEY_LENGTH))
-		throw std::runtime_error("new peer identity key agreement failed");
+		throw ZT_EXCEPTION_INVALID_ARGUMENT;
 }
 
 void Peer::received(

+ 2 - 2
node/Peer.hpp

@@ -81,12 +81,12 @@ public:
 	/**
 	 * @return This peer's ZT address (short for identity().address())
 	 */
-	inline const Address &address() const throw() { return _id.address(); }
+	inline const Address &address() const { return _id.address(); }
 
 	/**
 	 * @return This peer's identity
 	 */
-	inline const Identity &identity() const throw() { return _id; }
+	inline const Identity &identity() const { return _id; }
 
 	/**
 	 * Log receipt of an authenticated packet

+ 0 - 2
node/Poly1305.cpp

@@ -121,7 +121,6 @@ static inline int crypto_onetimeauth(unsigned char *out,const unsigned char *in,
 }
 
 void Poly1305::compute(void *auth,const void *data,unsigned int len,const void *key)
-	throw()
 {
 	crypto_onetimeauth((unsigned char *)auth,(const unsigned char *)data,len,(const unsigned char *)key);
 }
@@ -623,7 +622,6 @@ poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) {
 } // anonymous namespace
 
 void Poly1305::compute(void *auth,const void *data,unsigned int len,const void *key)
-  throw()
 {
   poly1305_context ctx;
   poly1305_init(&ctx,reinterpret_cast<const unsigned char *>(key));

+ 1 - 2
node/Poly1305.hpp

@@ -54,8 +54,7 @@ public:
 	 * @param len Length of data to authenticate in bytes
 	 * @param key 32-byte one-time use key to authenticate data (must not be reused)
 	 */
-	static void compute(void *auth,const void *data,unsigned int len,const void *key)
-		throw();
+	static void compute(void *auth,const void *data,unsigned int len,const void *key);
 };
 
 } // namespace ZeroTier

+ 2 - 2
node/Revocation.hpp

@@ -168,14 +168,14 @@ public:
 				p += 2;
 				memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN);
 				p += ZT_C25519_SIGNATURE_LEN;
-			} else throw std::runtime_error("invalid signature");
+			} else throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
 		} else {
 			p += 2 + b.template at<uint16_t>(p);
 		}
 
 		p += 2 + b.template at<uint16_t>(p);
 		if (p > b.size())
-			throw std::runtime_error("extended field overflow");
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 
 		return (p - startAt);
 	}

+ 2 - 2
node/Switch.hpp

@@ -222,8 +222,8 @@ private:
 				y = a2.toInt();
 			}
 		}
-		inline unsigned long hashCode() const throw() { return ((unsigned long)x ^ (unsigned long)y); }
-		inline bool operator==(const _LastUniteKey &k) const throw() { return ((x == k.x)&&(y == k.y)); }
+		inline unsigned long hashCode() const { return ((unsigned long)x ^ (unsigned long)y); }
+		inline bool operator==(const _LastUniteKey &k) const { return ((x == k.x)&&(y == k.y)); }
 		uint64_t x,y;
 	};
 	Hashtable< _LastUniteKey,uint64_t > _lastUniteAttempt; // key is always sorted in ascending order, for set-like behavior

+ 2 - 2
node/Tag.hpp

@@ -161,7 +161,7 @@ public:
 		_signedBy.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH;
 		if (b[p++] == 1) {
 			if (b.template at<uint16_t>(p) != ZT_C25519_SIGNATURE_LEN)
-				throw std::runtime_error("invalid signature length");
+				throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
 			p += 2;
 			memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN;
 		} else {
@@ -170,7 +170,7 @@ public:
 
 		p += 2 + b.template at<uint16_t>(p);
 		if (p > b.size())
-			throw std::runtime_error("extended field overflow");
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 
 		return (p - startAt);
 	}

+ 6 - 6
node/World.hpp

@@ -110,9 +110,9 @@ public:
 		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
+		inline bool operator==(const Root &r) const { return ((identity == r.identity)&&(stableEndpoints == r.stableEndpoints)); }
+		inline bool operator!=(const Root &r) const { return (!(*this == r)); }
+		inline bool operator<(const Root &r) const { return (identity < r.identity); } // for sorting
 	};
 
 	/**
@@ -212,7 +212,7 @@ public:
 			case TYPE_PLANET: _type = TYPE_PLANET; break;
 			case TYPE_MOON: _type = TYPE_MOON; break;
 			default:
-				throw std::invalid_argument("invalid world type");
+				throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
 		}
 
 		_id = b.template at<uint64_t>(p); p += 8;
@@ -221,14 +221,14 @@ public:
 		memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN;
 		const unsigned int numRoots = (unsigned int)b[p++];
 		if (numRoots > ZT_WORLD_MAX_ROOTS)
-			throw std::invalid_argument("too many roots in World");
+			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 		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");
+				throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 			for(unsigned int kk=0;kk<numStableEndpoints;++kk) {
 				r.stableEndpoints.push_back(InetAddress());
 				p += r.stableEndpoints.back().deserialize(b,p);