Browse Source

Optimization and cleanup

Adam Ierymenko 6 years ago
parent
commit
6f22570648

+ 9 - 9
node/Capability.hpp

@@ -94,27 +94,27 @@ public:
 	/**
 	 * @return Rules -- see ruleCount() for size of array
 	 */
-	inline const ZT_VirtualNetworkRule *rules() const { return _rules; }
+	ZT_ALWAYS_INLINE const ZT_VirtualNetworkRule *rules() const { return _rules; }
 
 	/**
 	 * @return Number of rules in rules()
 	 */
-	inline unsigned int ruleCount() const { return _ruleCount; }
+	ZT_ALWAYS_INLINE unsigned int ruleCount() const { return _ruleCount; }
 
 	/**
 	 * @return ID and evaluation order of this capability in network
 	 */
-	inline uint32_t id() const { return _id; }
+	ZT_ALWAYS_INLINE uint32_t id() const { return _id; }
 
 	/**
 	 * @return Network ID for which this capability was issued
 	 */
-	inline uint64_t networkId() const { return _nwid; }
+	ZT_ALWAYS_INLINE uint64_t networkId() const { return _nwid; }
 
 	/**
 	 * @return Timestamp
 	 */
-	inline int64_t timestamp() const { return _ts; }
+	ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; }
 
 	/**
 	 * @return Last 'to' address in chain of custody
@@ -159,7 +159,7 @@ public:
 		} catch ( ... ) {}
 		return false;
 	}
-	
+
 	/**
 	 * Verify this capability's chain of custody and signatures
 	 *
@@ -460,10 +460,10 @@ public:
 	}
 
 	// Provides natural sort order by ID
-	inline bool operator<(const Capability &c) const { return (_id < c._id); }
+	ZT_ALWAYS_INLINE bool operator<(const Capability &c) const { return (_id < c._id); }
 
-	inline bool operator==(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) == 0); }
-	inline bool operator!=(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) != 0); }
+	ZT_ALWAYS_INLINE bool operator==(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) == 0); }
+	ZT_ALWAYS_INLINE bool operator!=(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) != 0); }
 
 private:
 	uint64_t _nwid;

+ 7 - 7
node/CertificateOfMembership.hpp

@@ -143,17 +143,17 @@ public:
 	/**
 	 * @return True if there's something here
 	 */
-	inline operator bool() const { return (_qualifierCount != 0); }
+	ZT_ALWAYS_INLINE operator bool() const { return (_qualifierCount != 0); }
 
 	/**
 	 * @return Credential ID, always 0 for COMs
 	 */
-	inline uint32_t id() const { return 0; }
+	ZT_ALWAYS_INLINE uint32_t id() const { return 0; }
 
 	/**
 	 * @return Timestamp for this cert and maximum delta for timestamp
 	 */
-	inline int64_t timestamp() const
+	ZT_ALWAYS_INLINE int64_t timestamp() const
 	{
 		for(unsigned int i=0;i<_qualifierCount;++i) {
 			if (_qualifiers[i].id == COM_RESERVED_ID_TIMESTAMP)
@@ -165,7 +165,7 @@ public:
 	/**
 	 * @return Address to which this cert was issued
 	 */
-	inline Address issuedTo() const
+	ZT_ALWAYS_INLINE Address issuedTo() const
 	{
 		for(unsigned int i=0;i<_qualifierCount;++i) {
 			if (_qualifiers[i].id == COM_RESERVED_ID_ISSUED_TO)
@@ -177,7 +177,7 @@ public:
 	/**
 	 * @return Network ID for which this cert was issued
 	 */
-	inline uint64_t networkId() const
+	ZT_ALWAYS_INLINE uint64_t networkId() const
 	{
 		for(unsigned int i=0;i<_qualifierCount;++i) {
 			if (_qualifiers[i].id == COM_RESERVED_ID_NETWORK_ID)
@@ -372,7 +372,7 @@ public:
 		return (p - startAt);
 	}
 
-	inline bool operator==(const CertificateOfMembership &c) const
+	ZT_ALWAYS_INLINE bool operator==(const CertificateOfMembership &c) const
 	{
 		if (_signedBy != c._signedBy)
 			return false;
@@ -388,7 +388,7 @@ public:
 		}
 		return (memcmp(_signature,c._signature,_signatureLength) == 0);
 	}
-	inline bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); }
+	ZT_ALWAYS_INLINE bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); }
 
 private:
 	struct _Qualifier

+ 17 - 17
node/CertificateOfOwnership.hpp

@@ -70,17 +70,17 @@ public:
 		_issuedTo = issuedTo;
 	}
 
-	inline uint64_t networkId() const { return _networkId; }
-	inline int64_t timestamp() const { return _ts; }
-	inline uint32_t id() const { return _id; }
-	inline const Address &issuedTo() const { return _issuedTo; }
-	inline const Address &signer() const { return _signedBy; }
-	inline const uint8_t *signature() const { return _signature; }
-	inline unsigned int signatureLength() const { return _signatureLength; }
-
-	inline unsigned int thingCount() const { return (unsigned int)_thingCount; }
-	inline Thing thingType(const unsigned int i) const { return (Thing)_thingTypes[i]; }
-	inline const uint8_t *thingValue(const unsigned int i) const { return _thingValues[i]; }
+	ZT_ALWAYS_INLINE uint64_t networkId() const { return _networkId; }
+	ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; }
+	ZT_ALWAYS_INLINE uint32_t id() const { return _id; }
+	ZT_ALWAYS_INLINE const Address &issuedTo() const { return _issuedTo; }
+	ZT_ALWAYS_INLINE const Address &signer() const { return _signedBy; }
+	ZT_ALWAYS_INLINE const uint8_t *signature() const { return _signature; }
+	ZT_ALWAYS_INLINE unsigned int signatureLength() const { return _signatureLength; }
+
+	ZT_ALWAYS_INLINE unsigned int thingCount() const { return (unsigned int)_thingCount; }
+	ZT_ALWAYS_INLINE Thing thingType(const unsigned int i) const { return (Thing)_thingTypes[i]; }
+	ZT_ALWAYS_INLINE const uint8_t *thingValue(const unsigned int i) const { return _thingValues[i]; }
 
 	inline bool owns(const InetAddress &ip) const
 	{
@@ -111,7 +111,7 @@ public:
 			++_thingCount;
 		}
 	}
-	
+
 	inline void addThing(const MAC &mac)
 	{
 		if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) return;
@@ -136,7 +136,7 @@ public:
 		return false;
 	}
 
-	inline Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
+	ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
 
 	template<unsigned int C>
 	inline void serialize(Buffer<C> &b,const bool forSign = false) const
@@ -206,10 +206,10 @@ public:
 	}
 
 	// Provides natural sort order by ID
-	inline bool operator<(const CertificateOfOwnership &coo) const { return (_id < coo._id); }
+	ZT_ALWAYS_INLINE bool operator<(const CertificateOfOwnership &coo) const { return (_id < coo._id); }
 
-	inline bool operator==(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) == 0); }
-	inline bool operator!=(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) != 0); }
+	ZT_ALWAYS_INLINE bool operator==(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) == 0); }
+	ZT_ALWAYS_INLINE bool operator!=(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) != 0); }
 
 private:
 	inline bool _owns(const Thing &t,const void *v,unsigned int l) const
@@ -228,7 +228,7 @@ private:
 		}
 		return false;
 	}
-	
+
 	uint64_t _networkId;
 	int64_t _ts;
 	uint64_t _flags;

+ 12 - 15
node/Dictionary.hpp

@@ -49,9 +49,9 @@ template<unsigned int C>
 class Dictionary
 {
 public:
-	inline Dictionary() { memset(_d,0,sizeof(_d)); }
-	inline Dictionary(const char *s) { this->load(s); }
-	inline Dictionary(const char *s,unsigned int len)
+	ZT_ALWAYS_INLINE Dictionary() { memset(_d,0,sizeof(_d)); }
+	ZT_ALWAYS_INLINE Dictionary(const char *s) { this->load(s); }
+	ZT_ALWAYS_INLINE Dictionary(const char *s,unsigned int len)
 	{
 		for(unsigned int i=0;i<C;++i) {
 			if ((s)&&(i < len)) {
@@ -62,15 +62,15 @@ public:
 		}
 		_d[C - 1] = (char)0;
 	}
-	inline Dictionary(const Dictionary &d) { memcpy(_d,d._d,C); }
+	ZT_ALWAYS_INLINE Dictionary(const Dictionary &d) { memcpy(_d,d._d,C); }
 
-	inline Dictionary &operator=(const Dictionary &d)
+	ZT_ALWAYS_INLINE Dictionary &operator=(const Dictionary &d)
 	{
 		memcpy(_d,d._d,C);
 		return *this;
 	}
 
-	inline operator bool() const { return (_d[0] != 0); }
+	ZT_ALWAYS_INLINE operator bool() const { return (_d[0] != 0); }
 
 	/**
 	 * Load a dictionary from a C-string
@@ -78,7 +78,7 @@ public:
 	 * @param s Dictionary in string form
 	 * @return False if 's' was longer than our capacity
 	 */
-	inline bool load(const char *s)
+	ZT_ALWAYS_INLINE bool load(const char *s)
 	{
 		for(unsigned int i=0;i<C;++i) {
 			if (s) {
@@ -94,15 +94,12 @@ public:
 	/**
 	 * Delete all entries
 	 */
-	inline void clear()
-	{
-		memset(_d,0,sizeof(_d));
-	}
+	ZT_ALWAYS_INLINE void clear() { memset(_d,0,sizeof(_d)); }
 
 	/**
 	 * @return Size of dictionary in bytes not including terminating NULL
 	 */
-	inline unsigned int sizeBytes() const
+	ZT_ALWAYS_INLINE unsigned int sizeBytes() const
 	{
 		for(unsigned int i=0;i<C;++i) {
 			if (!_d[i])
@@ -430,10 +427,10 @@ public:
 	/**
 	 * @return Value of C template parameter
 	 */
-	inline unsigned int capacity() const { return C; }
+	ZT_ALWAYS_INLINE unsigned int capacity() const { return C; }
 
-	inline const char *data() const { return _d; }
-	inline char *unsafeData() { return _d; }
+	ZT_ALWAYS_INLINE const char *data() const { return _d; }
+	ZT_ALWAYS_INLINE char *unsafeData() { return _d; }
 
 private:
 	char _d[C];

+ 11 - 11
node/Hashtable.hpp

@@ -36,10 +36,10 @@ class Hashtable
 private:
 	struct _Bucket
 	{
-		inline _Bucket(const K &k,const V &v) : k(k),v(v) {}
-		inline _Bucket(const K &k) : k(k),v() {}
-		inline _Bucket(const _Bucket &b) : k(b.k),v(b.v) {}
-		inline _Bucket &operator=(const _Bucket &b) { k = b.k; v = b.v; return *this; }
+		ZT_ALWAYS_INLINE _Bucket(const K &k,const V &v) : k(k),v(v) {}
+		ZT_ALWAYS_INLINE _Bucket(const K &k) : k(k),v() {}
+		ZT_ALWAYS_INLINE _Bucket(const _Bucket &b) : k(b.k),v(b.v) {}
+		ZT_ALWAYS_INLINE _Bucket &operator=(const _Bucket &b) { k = b.k; v = b.v; return *this; }
 		K k;
 		V v;
 		_Bucket *next; // must be set manually for each _Bucket
@@ -59,7 +59,7 @@ public:
 		/**
 		 * @param ht Hash table to iterate over
 		 */
-		inline Iterator(Hashtable &ht) :
+		ZT_ALWAYS_INLINE Iterator(Hashtable &ht) :
 			_idx(0),
 			_ht(&ht),
 			_b(ht._t[0])
@@ -71,7 +71,7 @@ public:
 		 * @param vptr Pointer to set to point to next value
 		 * @return True if kptr and vptr are set, false if no more entries
 		 */
-		inline bool next(K *&kptr,V *&vptr)
+		ZT_ALWAYS_INLINE bool next(K *&kptr,V *&vptr)
 		{
 			for(;;) {
 				if (_b) {
@@ -230,7 +230,7 @@ public:
 	 * @param k Key
 	 * @return Pointer to value or NULL if not found
 	 */
-	inline V *get(const K &k)
+	ZT_ALWAYS_INLINE V *get(const K &k)
 	{
 		_Bucket *b = _t[_hc(k) % _bc];
 		while (b) {
@@ -247,7 +247,7 @@ public:
 	 * @param v Value to fill with result
 	 * @return True if value was found and set (if false, v is not modified)
 	 */
-	inline bool get(const K &k,V &v) const
+	ZT_ALWAYS_INLINE bool get(const K &k,V &v) const
 	{
 		_Bucket *b = _t[_hc(k) % _bc];
 		while (b) {
@@ -264,7 +264,7 @@ public:
 	 * @param k Key to check
 	 * @return True if key is present
 	 */
-	inline bool contains(const K &k) const
+	ZT_ALWAYS_INLINE bool contains(const K &k) const
 	{
 		_Bucket *b = _t[_hc(k) % _bc];
 		while (b) {
@@ -361,12 +361,12 @@ public:
 	/**
 	 * @return Number of entries
 	 */
-	inline unsigned long size() const { return _s; }
+	ZT_ALWAYS_INLINE unsigned long size() const { return _s; }
 
 	/**
 	 * @return True if table is empty
 	 */
-	inline bool empty() const { return (_s == 0); }
+	ZT_ALWAYS_INLINE bool empty() const { return (_s == 0); }
 
 private:
 	template<typename O>

+ 14 - 14
node/Identity.hpp

@@ -51,8 +51,8 @@ public:
 		P384 = ZT_CRYPTO_ALG_P384      // Type 1 -- NIST P-384 with linked Curve25519 and Ed25519 secondaries (2.x+)
 	};
 
-	inline Identity() { memset(reinterpret_cast<void *>(this),0,sizeof(Identity)); }
-	inline Identity(const Identity &id) { memcpy(reinterpret_cast<void *>(this),&id,sizeof(Identity)); }
+	ZT_ALWAYS_INLINE Identity() { memset(reinterpret_cast<void *>(this),0,sizeof(Identity)); }
+	ZT_ALWAYS_INLINE Identity(const Identity &id) { memcpy(reinterpret_cast<void *>(this),&id,sizeof(Identity)); }
 
 	inline Identity(const char *str)
 	{
@@ -63,14 +63,14 @@ public:
 	template<unsigned int C>
 	inline Identity(const Buffer<C> &b,unsigned int startAt = 0) { deserialize(b,startAt); }
 
-	inline ~Identity() { Utils::burn(reinterpret_cast<void *>(this),sizeof(Identity)); }
+	ZT_ALWAYS_INLINE ~Identity() { Utils::burn(reinterpret_cast<void *>(this),sizeof(Identity)); }
 
 	/**
 	 * Set identity to NIL value (all zero)
 	 */
-	inline void zero() { Utils::burn(reinterpret_cast<void *>(this),sizeof(Identity)); }
+	ZT_ALWAYS_INLINE void zero() { Utils::burn(reinterpret_cast<void *>(this),sizeof(Identity)); }
 
-	inline Identity &operator=(const Identity &id)
+	ZT_ALWAYS_INLINE Identity &operator=(const Identity &id)
 	{
 		memcpy(reinterpret_cast<void *>(this),&id,sizeof(Identity));
 		return *this;
@@ -79,7 +79,7 @@ public:
 	/**
 	 * @return Identity type
 	 */
-	inline Type type() const { return _type; }
+	ZT_ALWAYS_INLINE Type type() const { return _type; }
 
 	/**
 	 * Generate a new identity (address, key pair)
@@ -100,7 +100,7 @@ public:
 	/**
 	 * @return True if this identity contains a private key
 	 */
-	inline bool hasPrivate() const { return _hasPrivate; }
+	ZT_ALWAYS_INLINE bool hasPrivate() const { return _hasPrivate; }
 
 	/**
 	 * Compute the SHA512 hash of our private key (if we have one)
@@ -258,7 +258,7 @@ public:
 	/**
 	 * @return This identity's address
 	 */
-	inline const Address &address() const { return _address; }
+	ZT_ALWAYS_INLINE const Address &address() const { return _address; }
 
 	/**
 	 * Serialize this identity (binary)
@@ -389,7 +389,7 @@ public:
 	/**
 	 * @return True if this identity contains something
 	 */
-	inline operator bool() const { return (_address); }
+	ZT_ALWAYS_INLINE operator bool() const { return (_address); }
 
 	inline bool operator==(const Identity &id) const
 	{
@@ -423,12 +423,12 @@ public:
 		}
 		return false;
 	}
-	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); }
+	ZT_ALWAYS_INLINE bool operator!=(const Identity &id) const { return !(*this == id); }
+	ZT_ALWAYS_INLINE bool operator>(const Identity &id) const { return (id < *this); }
+	ZT_ALWAYS_INLINE bool operator<=(const Identity &id) const { return !(id < *this); }
+	ZT_ALWAYS_INLINE bool operator>=(const Identity &id) const { return !(*this < id); }
 
-	inline unsigned long hashCode() const { return (unsigned long)_address.toInt(); }
+	ZT_ALWAYS_INLINE unsigned long hashCode() const { return (unsigned long)_address.toInt(); }
 
 private:
 	Address _address;

+ 10 - 10
node/Membership.hpp

@@ -67,7 +67,7 @@ public:
 	/**
 	 * @return Time we last pushed credentials to this member
 	 */
-	inline int64_t lastPushedCredentials() const { return _lastPushedCredentials; }
+	ZT_ALWAYS_INLINE int64_t lastPushedCredentials() const { return _lastPushedCredentials; }
 
 	/**
 	 * Check whether we should push MULTICAST_LIKEs to this peer, and update last sent time if true
@@ -75,7 +75,7 @@ public:
 	 * @param now Current time
 	 * @return True if we should update multicasts
 	 */
-	inline bool multicastLikeGate(const int64_t now)
+	ZT_ALWAYS_INLINE bool multicastLikeGate(const int64_t now)
 	{
 		if ((now - _lastUpdatedMulticast) >= ZT_MULTICAST_ANNOUNCE_PERIOD) {
 			_lastUpdatedMulticast = now;
@@ -90,7 +90,7 @@ public:
 	 * @param nconf Our network config
 	 * @return True if this peer is allowed on this network at all
 	 */
-	inline bool isAllowedOnNetwork(const NetworkConfig &nconf) const
+	ZT_ALWAYS_INLINE bool isAllowedOnNetwork(const NetworkConfig &nconf) const
 	{
 		if (nconf.isPublic()) return true; // public network
 		if (_com.timestamp() <= _comRevocationThreshold) return false; // COM has been revoked
@@ -100,7 +100,7 @@ public:
 	/**
 	 * @return True if this peer has sent us a valid certificate within ZT_PEER_ACTIVITY_TIMEOUT
 	 */
-	inline bool recentlyAssociated(const int64_t now) const { return ((_com)&&((now - _com.timestamp()) < ZT_PEER_ACTIVITY_TIMEOUT)); }
+	ZT_ALWAYS_INLINE bool recentlyAssociated(const int64_t now) const { return ((_com)&&((now - _com.timestamp()) < ZT_PEER_ACTIVITY_TIMEOUT)); }
 
 	/**
 	 * Check whether the peer represented by this Membership owns a given address
@@ -160,22 +160,22 @@ public:
 	/**
 	 * @return Bytes received so far
 	 */
-	inline uint64_t receivedBytes() const { return _received; }
+	ZT_ALWAYS_INLINE uint64_t receivedBytes() const { return _received; }
 
 	/**
 	 * @return Bytes sent so far
 	 */
-	inline uint64_t sentBytes() const { return _sent; }
+	ZT_ALWAYS_INLINE uint64_t sentBytes() const { return _sent; }
 
 	/**
 	 * @param bytes Bytes received
 	 */
-	inline void logReceivedBytes(const unsigned int bytes) { _received = (uint64_t)bytes; }
+	ZT_ALWAYS_INLINE void logReceivedBytes(const unsigned int bytes) { _received = (uint64_t)bytes; }
 
 	/**
 	 * @param bytes Bytes sent
 	 */
-	inline void logSentBytes(const unsigned int bytes) { _sent = (uint64_t)bytes; }
+	ZT_ALWAYS_INLINE void logSentBytes(const unsigned int bytes) { _sent = (uint64_t)bytes; }
 
 private:
 	// This returns true if a resource is an IPv6 NDP-emulated address. These embed the ZT
@@ -275,7 +275,7 @@ public:
 	class CapabilityIterator
 	{
 	public:
-		inline CapabilityIterator(Membership &m,const NetworkConfig &nconf) :
+		ZT_ALWAYS_INLINE CapabilityIterator(Membership &m,const NetworkConfig &nconf) :
 			_hti(m._remoteCaps),
 			_k((uint32_t *)0),
 			_c((Capability *)0),
@@ -284,7 +284,7 @@ public:
 		{
 		}
 
-		inline Capability *next()
+		ZT_ALWAYS_INLINE Capability *next()
 		{
 			while (_hti.next(_k,_c)) {
 				if (_m._isCredentialTimestampValid(_nconf,*_c))

+ 12 - 12
node/MulticastGroup.hpp

@@ -41,13 +41,13 @@ namespace ZeroTier {
 class MulticastGroup
 {
 public:
-	inline MulticastGroup() :
+	ZT_ALWAYS_INLINE MulticastGroup() :
 		_mac(),
 		_adi(0)
 	{
 	}
 
-	inline MulticastGroup(const MAC &m,uint32_t a) :
+	ZT_ALWAYS_INLINE MulticastGroup(const MAC &m,uint32_t a) :
 		_mac(m),
 		_adi(a)
 	{
@@ -59,7 +59,7 @@ public:
 	 * @param ip IP address (port field is ignored)
 	 * @return Multicast group for ARP/NDP
 	 */
-	static inline MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress &ip)
+	static ZT_ALWAYS_INLINE MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress &ip)
 	{
 		if (ip.isV4()) {
 			// IPv4 wants broadcast MACs, so we shove the V4 address itself into
@@ -78,14 +78,14 @@ public:
 		return MulticastGroup();
 	}
 
-	inline const MAC &mac() const { return _mac; }
-	inline uint32_t adi() const { return _adi; }
+	ZT_ALWAYS_INLINE const MAC &mac() const { return _mac; }
+	ZT_ALWAYS_INLINE uint32_t adi() const { return _adi; }
 
-	inline unsigned long hashCode() const { return (_mac.hashCode() + (unsigned long)_adi); }
+	ZT_ALWAYS_INLINE unsigned long hashCode() const { return (_mac.hashCode() + (unsigned long)_adi); }
 
-	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
+	ZT_ALWAYS_INLINE bool operator==(const MulticastGroup &g) const { return ((_mac == g._mac)&&(_adi == g._adi)); }
+	ZT_ALWAYS_INLINE bool operator!=(const MulticastGroup &g) const { return ((_mac != g._mac)||(_adi != g._adi)); }
+	ZT_ALWAYS_INLINE bool operator<(const MulticastGroup &g) const
 	{
 		if (_mac < g._mac)
 			return true;
@@ -93,9 +93,9 @@ public:
 			return (_adi < g._adi);
 		return false;
 	}
-	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); }
+	ZT_ALWAYS_INLINE bool operator>(const MulticastGroup &g) const { return (g < *this); }
+	ZT_ALWAYS_INLINE bool operator<=(const MulticastGroup &g) const { return !(g < *this); }
+	ZT_ALWAYS_INLINE bool operator>=(const MulticastGroup &g) const { return !(*this < g); }
 
 private:
 	MAC _mac;

+ 42 - 42
node/Packet.hpp

@@ -53,7 +53,7 @@
  * 8  - 1.1.17 ... 1.2.0
  *    + Multipart network configurations for large network configs
  *    + Tags and Capabilities
- *    + Inline push of CertificateOfMembership deprecated
+ *    + ZT_ALWAYS_INLINE push of CertificateOfMembership deprecated
  * 9  - 1.2.0 ... 1.2.14
  * 10 - 1.4.0 ... 1.6.0
  *    + Multipath capability and load balancing
@@ -311,18 +311,18 @@ public:
 	class Fragment : public Buffer<ZT_PROTO_MAX_PACKET_LENGTH>
 	{
 	public:
-		inline Fragment() :
+		ZT_ALWAYS_INLINE Fragment() :
 			Buffer<ZT_PROTO_MAX_PACKET_LENGTH>()
 		{
 		}
 
 		template<unsigned int C2>
-		inline Fragment(const Buffer<C2> &b) :
+		ZT_ALWAYS_INLINE Fragment(const Buffer<C2> &b) :
 			Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b)
 		{
 		}
 
-		inline Fragment(const void *data,unsigned int len) :
+		ZT_ALWAYS_INLINE Fragment(const void *data,unsigned int len) :
 			Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(data,len)
 		{
 		}
@@ -336,7 +336,7 @@ public:
 		 * @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off)
 		 * @param fragTotal Total number of fragments (including 0)
 		 */
-		inline Fragment(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal)
+		ZT_ALWAYS_INLINE Fragment(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal)
 		{
 			init(p,fragStart,fragLen,fragNo,fragTotal);
 		}
@@ -350,7 +350,7 @@ public:
 		 * @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off)
 		 * @param fragTotal Total number of fragments (including 0)
 		 */
-		inline void init(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal)
+		ZT_ALWAYS_INLINE void init(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal)
 		{
 			if ((fragStart + fragLen) > p.size())
 				throw ZT_EXCEPTION_OUT_OF_BOUNDS;
@@ -371,37 +371,37 @@ public:
 		 *
 		 * @return Destination ZT address
 		 */
-		inline Address destination() const { return Address(field(ZT_PACKET_FRAGMENT_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
+		ZT_ALWAYS_INLINE Address destination() const { return Address(field(ZT_PACKET_FRAGMENT_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
 
 		/**
 		 * @return True if fragment is of a valid length
 		 */
-		inline bool lengthValid() const { return (size() >= ZT_PACKET_FRAGMENT_IDX_PAYLOAD); }
+		ZT_ALWAYS_INLINE bool lengthValid() const { return (size() >= ZT_PACKET_FRAGMENT_IDX_PAYLOAD); }
 
 		/**
 		 * @return ID of packet this is a fragment of
 		 */
-		inline uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_FRAGMENT_IDX_PACKET_ID); }
+		ZT_ALWAYS_INLINE uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_FRAGMENT_IDX_PACKET_ID); }
 
 		/**
 		 * @return Total number of fragments in packet
 		 */
-		inline unsigned int totalFragments() const { return (((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) >> 4) & 0xf); }
+		ZT_ALWAYS_INLINE unsigned int totalFragments() const { return (((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) >> 4) & 0xf); }
 
 		/**
 		 * @return Fragment number of this fragment
 		 */
-		inline unsigned int fragmentNumber() const { return ((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) & 0xf); }
+		ZT_ALWAYS_INLINE unsigned int fragmentNumber() const { return ((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) & 0xf); }
 
 		/**
 		 * @return Fragment ZT hop count
 		 */
-		inline unsigned int hops() const { return (unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]); }
+		ZT_ALWAYS_INLINE unsigned int hops() const { return (unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]); }
 
 		/**
 		 * Increment this packet's hop count
 		 */
-		inline void incrementHops()
+		ZT_ALWAYS_INLINE void incrementHops()
 		{
 			(*this)[ZT_PACKET_FRAGMENT_IDX_HOPS] = (((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]) + 1) & ZT_PROTO_MAX_HOPS;
 		}
@@ -409,12 +409,12 @@ public:
 		/**
 		 * @return Length of payload in bytes
 		 */
-		inline unsigned int payloadLength() const { return ((size() > ZT_PACKET_FRAGMENT_IDX_PAYLOAD) ? (size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD) : 0); }
+		ZT_ALWAYS_INLINE unsigned int payloadLength() const { return ((size() > ZT_PACKET_FRAGMENT_IDX_PAYLOAD) ? (size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD) : 0); }
 
 		/**
 		 * @return Raw packet payload
 		 */
-		inline const unsigned char *payload() const
+		ZT_ALWAYS_INLINE const unsigned char *payload() const
 		{
 			return field(ZT_PACKET_FRAGMENT_IDX_PAYLOAD,size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD);
 		}
@@ -980,12 +980,12 @@ public:
 	};
 
 	template<unsigned int C2>
-	inline Packet(const Buffer<C2> &b) :
+	ZT_ALWAYS_INLINE Packet(const Buffer<C2> &b) :
 		Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b)
 	{
 	}
 
-	inline Packet(const void *data,unsigned int len) :
+	ZT_ALWAYS_INLINE Packet(const void *data,unsigned int len) :
 		Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(data,len)
 	{
 	}
@@ -997,7 +997,7 @@ public:
 	 * Use the header access methods (setDestination() and friends) to fill out
 	 * the header. Payload should be appended; initial size is header size.
 	 */
-	inline Packet() :
+	ZT_ALWAYS_INLINE Packet() :
 		Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(ZT_PROTO_MIN_PACKET_LENGTH)
 	{
 		Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8);
@@ -1013,7 +1013,7 @@ public:
 	 * @param prototype Prototype packet
 	 * @param dest Destination ZeroTier address for new packet
 	 */
-	inline Packet(const Packet &prototype,const Address &dest) :
+	ZT_ALWAYS_INLINE Packet(const Packet &prototype,const Address &dest) :
 		Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(prototype)
 	{
 		Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8);
@@ -1027,7 +1027,7 @@ public:
 	 * @param source Source ZT address
 	 * @param v Verb
 	 */
-	inline Packet(const Address &dest,const Address &source,const Verb v) :
+	ZT_ALWAYS_INLINE Packet(const Address &dest,const Address &source,const Verb v) :
 		Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(ZT_PROTO_MIN_PACKET_LENGTH)
 	{
 		Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8);
@@ -1044,7 +1044,7 @@ public:
 	 * @param source Source ZT address
 	 * @param v Verb
 	 */
-	inline void reset(const Address &dest,const Address &source,const Verb v)
+	ZT_ALWAYS_INLINE void reset(const Address &dest,const Address &source,const Verb v)
 	{
 		setSize(ZT_PROTO_MIN_PACKET_LENGTH);
 		Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8);
@@ -1061,52 +1061,52 @@ public:
 	 * technically different but otherwise identical copies of the same
 	 * packet.
 	 */
-	inline void newInitializationVector() { Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8); }
+	ZT_ALWAYS_INLINE void newInitializationVector() { Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8); }
 
 	/**
 	 * Set this packet's destination
 	 *
 	 * @param dest ZeroTier address of destination
 	 */
-	inline void setDestination(const Address &dest) { dest.copyTo(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
+	ZT_ALWAYS_INLINE void setDestination(const Address &dest) { dest.copyTo(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
 
 	/**
 	 * Set this packet's source
 	 *
 	 * @param source ZeroTier address of source
 	 */
-	inline void setSource(const Address &source) { source.copyTo(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
+	ZT_ALWAYS_INLINE void setSource(const Address &source) { source.copyTo(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
 
 	/**
 	 * Get this packet's destination
 	 *
 	 * @return Destination ZT address
 	 */
-	inline Address destination() const { return Address(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
+	ZT_ALWAYS_INLINE Address destination() const { return Address(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
 
 	/**
 	 * Get this packet's source
 	 *
 	 * @return Source ZT address
 	 */
-	inline Address source() const { return Address(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
+	ZT_ALWAYS_INLINE Address source() const { return Address(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
 
 	/**
 	 * @return True if packet is of valid length
 	 */
-	inline bool lengthValid() const { return (size() >= ZT_PROTO_MIN_PACKET_LENGTH); }
+	ZT_ALWAYS_INLINE bool lengthValid() const { return (size() >= ZT_PROTO_MIN_PACKET_LENGTH); }
 
 	/**
 	 * @return True if packet is fragmented (expect fragments)
 	 */
-	inline bool fragmented() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0); }
+	ZT_ALWAYS_INLINE bool fragmented() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0); }
 
 	/**
 	 * Set this packet's fragmented flag
 	 *
 	 * @param f Fragmented flag value
 	 */
-	inline void setFragmented(bool f)
+	ZT_ALWAYS_INLINE void setFragmented(bool f)
 	{
 		if (f)
 			(*this)[ZT_PACKET_IDX_FLAGS] |= (char)ZT_PROTO_FLAG_FRAGMENTED;
@@ -1116,17 +1116,17 @@ public:
 	/**
 	 * @return True if compressed (result only valid if unencrypted)
 	 */
-	inline bool compressed() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_VERB] & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0); }
+	ZT_ALWAYS_INLINE bool compressed() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_VERB] & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0); }
 
 	/**
 	 * @return ZeroTier forwarding hops (0 to 7)
 	 */
-	inline unsigned int hops() const { return ((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x07); }
+	ZT_ALWAYS_INLINE unsigned int hops() const { return ((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x07); }
 
 	/**
 	 * Increment this packet's hop count
 	 */
-	inline void incrementHops()
+	ZT_ALWAYS_INLINE void incrementHops()
 	{
 		unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS];
 		b = (b & 0xf8) | ((b + 1) & 0x07);
@@ -1135,7 +1135,7 @@ public:
 	/**
 	 * @return Cipher suite selector: 0 - 7 (see #defines)
 	 */
-	inline unsigned int cipher() const
+	ZT_ALWAYS_INLINE unsigned int cipher() const
 	{
 		return (((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x38) >> 3);
 	}
@@ -1143,7 +1143,7 @@ public:
 	/**
 	 * Set this packet's cipher suite
 	 */
-	inline void setCipher(unsigned int c)
+	ZT_ALWAYS_INLINE void setCipher(unsigned int c)
 	{
 		unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS];
 		b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38); // bits: FFCCCHHH
@@ -1154,14 +1154,14 @@ public:
 	 *
 	 * @return Trusted path ID (from MAC field)
 	 */
-	inline uint64_t trustedPathId() const { return at<uint64_t>(ZT_PACKET_IDX_MAC); }
+	ZT_ALWAYS_INLINE uint64_t trustedPathId() const { return at<uint64_t>(ZT_PACKET_IDX_MAC); }
 
 	/**
 	 * Set this packet's trusted path ID and set the cipher spec to trusted path
 	 *
 	 * @param tpid Trusted path ID
 	 */
-	inline void setTrusted(const uint64_t tpid)
+	ZT_ALWAYS_INLINE void setTrusted(const uint64_t tpid)
 	{
 		setCipher(ZT_PROTO_CIPHER_SUITE__NO_CRYPTO_TRUSTED_PATH);
 		setAt(ZT_PACKET_IDX_MAC,tpid);
@@ -1178,7 +1178,7 @@ public:
 	 *
 	 * @return Packet ID
 	 */
-	inline uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_IDX_IV); }
+	ZT_ALWAYS_INLINE uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_IDX_IV); }
 
 	/**
 	 * Set packet verb
@@ -1188,22 +1188,22 @@ public:
 	 *
 	 * @param v New packet verb
 	 */
-	inline void setVerb(Verb v) { (*this)[ZT_PACKET_IDX_VERB] = (char)v; }
+	ZT_ALWAYS_INLINE void setVerb(Verb v) { (*this)[ZT_PACKET_IDX_VERB] = (char)v; }
 
 	/**
 	 * @return Packet verb (not including flag bits)
 	 */
-	inline Verb verb() const { return (Verb)((*this)[ZT_PACKET_IDX_VERB] & 0x1f); }
+	ZT_ALWAYS_INLINE Verb verb() const { return (Verb)((*this)[ZT_PACKET_IDX_VERB] & 0x1f); }
 
 	/**
 	 * @return Length of packet payload
 	 */
-	inline unsigned int payloadLength() const { return ((size() < ZT_PROTO_MIN_PACKET_LENGTH) ? 0 : (size() - ZT_PROTO_MIN_PACKET_LENGTH)); }
+	ZT_ALWAYS_INLINE unsigned int payloadLength() const { return ((size() < ZT_PROTO_MIN_PACKET_LENGTH) ? 0 : (size() - ZT_PROTO_MIN_PACKET_LENGTH)); }
 
 	/**
 	 * @return Raw packet payload
 	 */
-	inline const unsigned char *payload() const { return field(ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD); }
+	ZT_ALWAYS_INLINE const unsigned char *payload() const { return field(ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD); }
 
 	/**
 	 * Armor packet for transport
@@ -1261,7 +1261,7 @@ private:
 	 * @param in Input key (32 bytes)
 	 * @param out Output buffer (32 bytes)
 	 */
-	inline void _salsa20MangleKey(const unsigned char *in,unsigned char *out) const
+	ZT_ALWAYS_INLINE void _salsa20MangleKey(const unsigned char *in,unsigned char *out) const
 	{
 		const unsigned char *d = (const unsigned char *)data();
 

+ 20 - 20
node/Path.hpp

@@ -55,9 +55,9 @@ public:
 	class HashKey
 	{
 	public:
-		inline HashKey() {}
+		ZT_ALWAYS_INLINE HashKey() {}
 
-		inline HashKey(const int64_t l,const InetAddress &r)
+		ZT_ALWAYS_INLINE HashKey(const int64_t l,const InetAddress &r)
 		{
 			if (r.ss_family == AF_INET) {
 				_k[0] = (uint64_t)reinterpret_cast<const struct sockaddr_in *>(&r)->sin_addr.s_addr;
@@ -72,10 +72,10 @@ public:
 			}
 		}
 
-		inline unsigned long hashCode() const { return (unsigned long)(_k[0] + _k[1] + _k[2]); }
+		ZT_ALWAYS_INLINE unsigned long hashCode() const { return (unsigned long)(_k[0] + _k[1] + _k[2]); }
 
-		inline bool operator==(const HashKey &k) const { return ( (_k[0] == k._k[0]) && (_k[1] == k._k[1]) && (_k[2] == k._k[2]) ); }
-		inline bool operator!=(const HashKey &k) const { return (!(*this == k)); }
+		ZT_ALWAYS_INLINE bool operator==(const HashKey &k) const { return ( (_k[0] == k._k[0]) && (_k[1] == k._k[1]) && (_k[2] == k._k[2]) ); }
+		ZT_ALWAYS_INLINE bool operator!=(const HashKey &k) const { return (!(*this == k)); }
 
 	private:
 		uint64_t _k[3];
@@ -153,7 +153,7 @@ public:
 	 *
 	 * @param t Time of receive
 	 */
-	inline void received(const uint64_t t) { _lastIn = t; }
+	ZT_ALWAYS_INLINE void received(const uint64_t t) { _lastIn = t; }
 
 	/**
 	 * Send a packet via this path (last out time is also updated)
@@ -172,14 +172,14 @@ public:
 	 *
 	 * @param t Time of send
 	 */
-	inline void sent(const int64_t t) { _lastOut = t; }
+	ZT_ALWAYS_INLINE void sent(const int64_t t) { _lastOut = t; }
 
 	/**
 	 * Update path latency with a new measurement
 	 *
 	 * @param l Measured latency
 	 */
-	inline void updateLatency(const unsigned int l, int64_t now)
+	ZT_ALWAYS_INLINE void updateLatency(const unsigned int l, int64_t now)
 	{
 		unsigned int pl = _latency;
 		if (pl < 0xffff) {
@@ -194,22 +194,22 @@ public:
 	/**
 	 * @return Local socket as specified by external code
 	 */
-	inline int64_t localSocket() const { return _localSocket; }
+	ZT_ALWAYS_INLINE int64_t localSocket() const { return _localSocket; }
 
 	/**
 	 * @return Physical address
 	 */
-	inline const InetAddress &address() const { return _addr; }
+	ZT_ALWAYS_INLINE const InetAddress &address() const { return _addr; }
 
 	/**
 	 * @return IP scope -- faster shortcut for address().ipScope()
 	 */
-	inline InetAddress::IpScope ipScope() const { return _ipScope; }
+	ZT_ALWAYS_INLINE InetAddress::IpScope ipScope() const { return _ipScope; }
 
 	/**
 	 * @return Preference rank, higher == better
 	 */
-	inline unsigned int preferenceRank() const
+	ZT_ALWAYS_INLINE unsigned int preferenceRank() const
 	{
 		// This causes us to rank paths in order of IP scope rank (see InetAdddress.hpp) but
 		// within each IP scope class to prefer IPv6 over IPv4.
@@ -259,12 +259,12 @@ public:
 	/**
 	 * @return Latency or 0xffff if unknown
 	 */
-	inline unsigned int latency() const { return _latency; }
+	ZT_ALWAYS_INLINE unsigned int latency() const { return _latency; }
 
 	/**
 	 * @return Path quality -- lower is better
 	 */
-	inline long quality(const int64_t now) const
+	ZT_ALWAYS_INLINE long quality(const int64_t now) const
 	{
 		const long l = (long)_latency;
 		const long age = (long)std::min((long)(now - _lastIn),(long)(ZT_PEER_PING_PERIOD * 10)); // set an upper sanity limit to avoid overflow
@@ -279,7 +279,7 @@ public:
 	 * @param payloadLength Length of payload
 	 * @param verb Packet verb
 	 */
-	inline void recordOutgoingPacket(int64_t now, int64_t packetId, uint16_t payloadLength, Packet::Verb verb)
+	ZT_ALWAYS_INLINE void recordOutgoingPacket(int64_t now, int64_t packetId, uint16_t payloadLength, Packet::Verb verb)
 	{
 		Mutex::Lock _l(_statistics_m);
 		if (verb != Packet::VERB_ACK && verb != Packet::VERB_QOS_MEASUREMENT) {
@@ -302,7 +302,7 @@ public:
 	 * @param payloadLength Length of payload
 	 * @param verb Packet verb
 	 */
-	inline void recordIncomingPacket(int64_t now, int64_t packetId, uint16_t payloadLength, Packet::Verb verb)
+	ZT_ALWAYS_INLINE void recordIncomingPacket(int64_t now, int64_t packetId, uint16_t payloadLength, Packet::Verb verb)
 	{
 		Mutex::Lock _l(_statistics_m);
 		if (verb != Packet::VERB_ACK && verb != Packet::VERB_QOS_MEASUREMENT) {
@@ -322,7 +322,7 @@ public:
 	 * @param now Current time
 	 * @param ackedBytes Number of bytes acknowledged by other peer
 	 */
-	inline void receivedAck(int64_t now, int32_t ackedBytes)
+	ZT_ALWAYS_INLINE void receivedAck(int64_t now, int32_t ackedBytes)
 	{
 		_expectingAckAsOf = 0;
 		_unackedBytes = (ackedBytes > _unackedBytes) ? 0 : _unackedBytes - ackedBytes;
@@ -600,17 +600,17 @@ public:
 	/**
 	 * @return True if this path is alive (receiving data)
 	 */
-	inline bool alive(const int64_t now) const { return ((now - _lastIn) < ((ZT_PEER_PING_PERIOD * 2) + 5000)); }
+	ZT_ALWAYS_INLINE bool alive(const int64_t now) const { return ((now - _lastIn) < ((ZT_PEER_PING_PERIOD * 2) + 5000)); }
 
 	/**
 	 * @return Last time we sent something
 	 */
-	inline int64_t lastOut() const { return _lastOut; }
+	ZT_ALWAYS_INLINE int64_t lastOut() const { return _lastOut; }
 
 	/**
 	 * @return Last time we received anything
 	 */
-	inline int64_t lastIn() const { return _lastIn; }
+	ZT_ALWAYS_INLINE int64_t lastIn() const { return _lastIn; }
 
 private:
 	Mutex _statistics_m;

+ 22 - 23
node/Peer.hpp

@@ -60,12 +60,12 @@ public:
 	/**
 	 * @return This peer's ZT address (short for identity().address())
 	 */
-	inline const Address &address() const { return _id.address(); }
+	ZT_ALWAYS_INLINE const Address &address() const { return _id.address(); }
 
 	/**
 	 * @return This peer's identity
 	 */
-	inline const Identity &identity() const { return _id; }
+	ZT_ALWAYS_INLINE const Identity &identity() const { return _id; }
 
 	/**
 	 * Log receipt of an authenticated packet
@@ -122,7 +122,7 @@ public:
 	 * @param force If true, send even if path is not alive
 	 * @return True if we actually sent something
 	 */
-	inline bool sendDirect(void *tPtr,const void *data,unsigned int len,int64_t now,bool force)
+	ZT_ALWAYS_INLINE bool sendDirect(void *tPtr,const void *data,unsigned int len,int64_t now,bool force)
 	{
 		SharedPtr<Path> bp(getAppropriatePath(now,force));
 		if (bp)
@@ -276,17 +276,17 @@ public:
 	/**
 	 * @return Time of last receive of anything, whether direct or relayed
 	 */
-	inline int64_t lastReceive() const { return _lastReceive; }
+	ZT_ALWAYS_INLINE int64_t lastReceive() const { return _lastReceive; }
 
 	/**
 	 * @return True if we've heard from this peer in less than ZT_PEER_ACTIVITY_TIMEOUT
 	 */
-	inline bool alive(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
+	ZT_ALWAYS_INLINE bool alive(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
 
 	/**
 	 * @return Latency in milliseconds of best/aggregate path or 0xffff if unknown / no paths
 	 */
-	inline unsigned int latency(const int64_t now)
+	ZT_ALWAYS_INLINE unsigned int latency(const int64_t now)
 	{
 		if (_canUseMultipath) {
 			return (int)computeAggregateLinkMeanLatency();
@@ -309,7 +309,7 @@ public:
 	 *
 	 * @return Relay quality score computed from latency and other factors, lower is better
 	 */
-	inline unsigned int relayQuality(const int64_t now)
+	ZT_ALWAYS_INLINE unsigned int relayQuality(const int64_t now)
 	{
 		const uint64_t tsr = now - _lastReceive;
 		if (tsr >= ZT_PEER_ACTIVITY_TIMEOUT)
@@ -323,7 +323,7 @@ public:
 	/**
 	 * @return 256-bit secret symmetric encryption key
 	 */
-	inline const unsigned char *key() const { return _key; }
+	ZT_ALWAYS_INLINE const unsigned char *key() const { return _key; }
 
 	/**
 	 * Set the currently known remote version of this peer's client
@@ -333,7 +333,7 @@ public:
 	 * @param vmin Minor version
 	 * @param vrev Revision
 	 */
-	inline void setRemoteVersion(unsigned int vproto,unsigned int vmaj,unsigned int vmin,unsigned int vrev)
+	ZT_ALWAYS_INLINE void setRemoteVersion(unsigned int vproto,unsigned int vmaj,unsigned int vmin,unsigned int vrev)
 	{
 		_vProto = (uint16_t)vproto;
 		_vMajor = (uint16_t)vmaj;
@@ -341,12 +341,11 @@ public:
 		_vRevision = (uint16_t)vrev;
 	}
 
-	inline unsigned int remoteVersionProtocol() const { return _vProto; }
-	inline unsigned int remoteVersionMajor() const { return _vMajor; }
-	inline unsigned int remoteVersionMinor() const { return _vMinor; }
-	inline unsigned int remoteVersionRevision() const { return _vRevision; }
-
-	inline bool remoteVersionKnown() const { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); }
+	ZT_ALWAYS_INLINE unsigned int remoteVersionProtocol() const { return _vProto; }
+	ZT_ALWAYS_INLINE unsigned int remoteVersionMajor() const { return _vMajor; }
+	ZT_ALWAYS_INLINE unsigned int remoteVersionMinor() const { return _vMinor; }
+	ZT_ALWAYS_INLINE unsigned int remoteVersionRevision() const { return _vRevision; }
+	ZT_ALWAYS_INLINE bool remoteVersionKnown() const { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); }
 
 	/**
 	 * Periodically update known multipath activation constraints. This is done so that we know when and when
@@ -382,7 +381,7 @@ public:
 	/**
 	 * Rate limit gate for VERB_PUSH_DIRECT_PATHS
 	 */
-	inline bool rateGatePushDirectPaths(const int64_t now)
+	ZT_ALWAYS_INLINE bool rateGatePushDirectPaths(const int64_t now)
 	{
 		if ((now - _lastDirectPathPushReceive) <= ZT_PUSH_DIRECT_PATHS_CUTOFF_TIME)
 			++_directPathPushCutoffCount;
@@ -394,7 +393,7 @@ public:
 	/**
 	 * Rate limit gate for VERB_NETWORK_CREDENTIALS
 	 */
-	inline bool rateGateCredentialsReceived(const int64_t now)
+	ZT_ALWAYS_INLINE bool rateGateCredentialsReceived(const int64_t now)
 	{
 		if ((now - _lastCredentialsReceived) <= ZT_PEER_CREDENTIALS_CUTOFF_TIME)
 			++_credentialsCutoffCount;
@@ -406,7 +405,7 @@ public:
 	/**
 	 * Rate limit gate for sending of ERROR_NEED_MEMBERSHIP_CERTIFICATE
 	 */
-	inline bool rateGateRequestCredentials(const int64_t now)
+	ZT_ALWAYS_INLINE bool rateGateRequestCredentials(const int64_t now)
 	{
 		if ((now - _lastCredentialRequestSent) >= ZT_PEER_GENERAL_RATE_LIMIT) {
 			_lastCredentialRequestSent = now;
@@ -418,7 +417,7 @@ public:
 	/**
 	 * Rate limit gate for inbound WHOIS requests
 	 */
-	inline bool rateGateInboundWhoisRequest(const int64_t now)
+	ZT_ALWAYS_INLINE bool rateGateInboundWhoisRequest(const int64_t now)
 	{
 		if ((now - _lastWhoisRequestReceived) >= ZT_PEER_WHOIS_RATE_LIMIT) {
 			_lastWhoisRequestReceived = now;
@@ -430,7 +429,7 @@ public:
 	/**
 	 * Rate limit gate for inbound ECHO requests
 	 */
-	inline bool rateGateEchoRequest(const int64_t now)
+	ZT_ALWAYS_INLINE bool rateGateEchoRequest(const int64_t now)
 	{
 		if ((now - _lastEchoRequestReceived) >= ZT_PEER_GENERAL_RATE_LIMIT) {
 			_lastEchoRequestReceived = now;
@@ -442,7 +441,7 @@ public:
 	/**
 	 * Rate limit gate for VERB_ACK
 	 */
-	inline bool rateGateACK(const int64_t now)
+	ZT_ALWAYS_INLINE bool rateGateACK(const int64_t now)
 	{
 		if ((now - _lastACKWindowReset) >= ZT_PATH_QOS_ACK_CUTOFF_TIME) {
 			_lastACKWindowReset = now;
@@ -456,7 +455,7 @@ public:
 	/**
 	 * Rate limit gate for VERB_QOS_MEASUREMENT
 	 */
-	inline bool rateGateQoS(const int64_t now)
+	ZT_ALWAYS_INLINE bool rateGateQoS(const int64_t now)
 	{
 		if ((now - _lastQoSWindowReset) >= ZT_PATH_QOS_ACK_CUTOFF_TIME) {
 			_lastQoSWindowReset = now;
@@ -470,7 +469,7 @@ public:
 	/**
 	 * Rate limit gate for trying externally defined or static path
 	 */
-	inline bool rateGateTryStaticPath(const int64_t now)
+	ZT_ALWAYS_INLINE bool rateGateTryStaticPath(const int64_t now)
 	{
 		if ((now - _lastTriedStaticPath) >= ZT_PEER_PING_PERIOD) {
 			_lastTriedStaticPath = now;

+ 10 - 11
node/Revocation.hpp

@@ -82,17 +82,16 @@ public:
 	{
 	}
 
-	inline uint32_t id() const { return _id; }
-	inline uint32_t credentialId() const { return _credentialId; }
-	inline uint64_t networkId() const { return _networkId; }
-	inline int64_t threshold() const { return _threshold; }
-	inline const Address &target() const { return _target; }
-	inline const Address &signer() const { return _signedBy; }
-	inline Credential::Type type() const { return _type; }
-	inline const uint8_t *signature() const { return _signature; }
-	inline unsigned int signatureLength() const { return _signatureLength; }
-
-	inline bool fastPropagate() const { return ((_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0); }
+	ZT_ALWAYS_INLINE uint32_t id() const { return _id; }
+	ZT_ALWAYS_INLINE uint32_t credentialId() const { return _credentialId; }
+	ZT_ALWAYS_INLINE uint64_t networkId() const { return _networkId; }
+	ZT_ALWAYS_INLINE int64_t threshold() const { return _threshold; }
+	ZT_ALWAYS_INLINE const Address &target() const { return _target; }
+	ZT_ALWAYS_INLINE const Address &signer() const { return _signedBy; }
+	ZT_ALWAYS_INLINE Credential::Type type() const { return _type; }
+	ZT_ALWAYS_INLINE const uint8_t *signature() const { return _signature; }
+	ZT_ALWAYS_INLINE unsigned int signatureLength() const { return _signatureLength; }
+	ZT_ALWAYS_INLINE bool fastPropagate() const { return ((_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0); }
 
 	/**
 	 * @param signer Signing identity, must have private key

+ 17 - 17
node/RingBuffer.hpp

@@ -43,7 +43,7 @@ private:
 	bool wrap;
 
 public:
-	inline RingBuffer() :
+	ZT_ALWAYS_INLINE RingBuffer() :
 		begin(0),
 		end(0),
 		wrap(false)
@@ -54,7 +54,7 @@ public:
 	/**
 	 * @return A pointer to the underlying buffer
 	 */
-	inline T *get_buf()
+	ZT_ALWAYS_INLINE T *get_buf()
 	{
 		return buf + begin;
 	}
@@ -64,7 +64,7 @@ public:
 	 * @param n Number of elements to copy in
 	 * @return Number of elements we copied in
 	 */
-	inline size_t produce(size_t n)
+	ZT_ALWAYS_INLINE size_t produce(size_t n)
 	{
 		n = std::min(n, getFree());
 		if (n == 0) {
@@ -86,14 +86,14 @@ public:
 	 * Fast erase, O(1).
 	 * Merely reset the buffer pointer, doesn't erase contents
 	 */
-	inline void reset() { consume(count()); }
+	ZT_ALWAYS_INLINE void reset() { consume(count()); }
 
 	/**
 	 * adjust buffer index pointer as if we copied data out
 	 * @param n Number of elements we copied from the buffer
 	 * @return Number of elements actually available from the buffer
 	 */
-	inline size_t consume(size_t n)
+	ZT_ALWAYS_INLINE size_t consume(size_t n)
 	{
 		n = std::min(n, count());
 		if (n == 0) {
@@ -115,7 +115,7 @@ public:
 	 * @param data Buffer that is to be written to the ring
 	 * @param n Number of elements to write to the buffer
 	 */
-	inline size_t write(const T * data, size_t n)
+	ZT_ALWAYS_INLINE size_t write(const T * data, size_t n)
 	{
 		n = std::min(n, getFree());
 		if (n == 0) {
@@ -140,7 +140,7 @@ public:
 	 *
 	 * @param value A single value to be placed in the buffer
 	 */
-	inline void push(const T value)
+	ZT_ALWAYS_INLINE void push(const T value)
 	{
 		if (count() == S) {
 			consume(1);
@@ -156,14 +156,14 @@ public:
 	/**
 	 * @return The most recently pushed element on the buffer
 	 */
-	inline T get_most_recent() { return *(buf + end); }
+	ZT_ALWAYS_INLINE T get_most_recent() { return *(buf + end); }
 
 	/**
 	 * @param dest Destination buffer
 	 * @param n Size (in terms of number of elements) of the destination buffer
 	 * @return Number of elements read from the buffer
 	 */
-	inline size_t read(T *dest,size_t n)
+	ZT_ALWAYS_INLINE size_t read(T *dest,size_t n)
 	{
 		n = std::min(n, count());
 		if (n == 0) {
@@ -188,7 +188,7 @@ public:
 	 *
 	 * @return The number of elements in the buffer
 	 */
-	inline size_t count()
+	ZT_ALWAYS_INLINE size_t count()
 	{
 		if (end == begin) {
 			return wrap ? S : 0;
@@ -204,12 +204,12 @@ public:
 	/**
 	 * @return The number of slots that are unused in the buffer
 	 */
-	inline size_t getFree() { return S - count(); }
+	ZT_ALWAYS_INLINE size_t getFree() { return S - count(); }
 
 	/**
 	 * @return The arithmetic mean of the contents of the buffer
 	 */
-	inline float mean()
+	ZT_ALWAYS_INLINE float mean()
 	{
 		size_t iterator = begin;
 		float subtotal = 0;
@@ -224,7 +224,7 @@ public:
 	/**
 	 * @return The arithmetic mean of the most recent 'n' elements of the buffer
 	 */
-	inline float mean(size_t n)
+	ZT_ALWAYS_INLINE float mean(size_t n)
 	{
 		n = n < S ? n : S;
 		size_t iterator = begin;
@@ -240,12 +240,12 @@ public:
 	/**
 	 * @return The sample standard deviation of element values
 	 */
-	inline float stddev() { return sqrt(variance()); }
+	ZT_ALWAYS_INLINE float stddev() { return sqrt(variance()); }
 
 	/**
 	 * @return The variance of element values
 	 */
-	inline float variance()
+	ZT_ALWAYS_INLINE float variance()
 	{
 		size_t iterator = begin;
 		float cached_mean = mean();
@@ -263,7 +263,7 @@ public:
 	/**
 	 * @return The number of elements of zero value
 	 */
-	inline size_t zeroCount()
+	ZT_ALWAYS_INLINE size_t zeroCount()
 	{
 		size_t iterator = begin;
 		size_t zeros = 0;
@@ -281,7 +281,7 @@ public:
 	 * @param value Value to match against in buffer
 	 * @return The number of values held in the ring buffer which match a given value
 	 */
-	inline size_t countValue(T value)
+	ZT_ALWAYS_INLINE size_t countValue(T value)
 	{
 		size_t iterator = begin;
 		size_t cnt = 0;

+ 6 - 6
node/SHA512.hpp

@@ -36,21 +36,21 @@ namespace ZeroTier {
 
 #ifdef __APPLE__
 #define ZT_HAVE_NATIVE_SHA512 1
-static inline void SHA512(void *digest,const void *data,unsigned int len)
+static ZT_ALWAYS_INLINE void SHA512(void *digest,const void *data,unsigned int len)
 {
 	CC_SHA512_CTX ctx;
 	CC_SHA512_Init(&ctx);
 	CC_SHA512_Update(&ctx,data,len);
 	CC_SHA512_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
 }
-static inline void SHA384(void *digest,const void *data,unsigned int len)
+static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data,unsigned int len)
 {
 	CC_SHA512_CTX ctx;
 	CC_SHA384_Init(&ctx);
 	CC_SHA384_Update(&ctx,data,len);
 	CC_SHA384_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
 }
-static inline void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1)
+static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1)
 {
 	CC_SHA512_CTX ctx;
 	CC_SHA384_Init(&ctx);
@@ -62,21 +62,21 @@ static inline void SHA384(void *digest,const void *data0,unsigned int len0,const
 
 #ifdef ZT_USE_LIBCRYPTO
 #define ZT_HAVE_NATIVE_SHA512 1
-static inline void SHA512(void *digest,const void *data,unsigned int len)
+static ZT_ALWAYS_INLINE void SHA512(void *digest,const void *data,unsigned int len)
 {
 	SHA512_CTX ctx;
 	SHA512_Init(&ctx);
 	SHA512_Update(&ctx,data,len);
 	SHA512_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
 }
-static inline void SHA384(void *digest,const void *data,unsigned int len)
+static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data,unsigned int len)
 {
 	SHA512_CTX ctx;
 	SHA384_Init(&ctx);
 	SHA384_Update(&ctx,data,len);
 	SHA384_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
 }
-static inline void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1)
+static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1)
 {
 	SHA512_CTX ctx;
 	SHA384_Init(&ctx);

+ 7 - 7
node/SelfAwareness.hpp

@@ -59,13 +59,13 @@ private:
 		InetAddress reporterPhysicalAddress;
 		InetAddress::IpScope scope;
 
-		inline PhySurfaceKey() : reporter(),scope(InetAddress::IP_SCOPE_NONE) {}
-		inline PhySurfaceKey(const Address &r,const int64_t rol,const InetAddress &ra,InetAddress::IpScope s) : reporter(r),receivedOnLocalSocket(rol),reporterPhysicalAddress(ra),scope(s) {}
+		ZT_ALWAYS_INLINE PhySurfaceKey() : reporter(),scope(InetAddress::IP_SCOPE_NONE) {}
+		ZT_ALWAYS_INLINE PhySurfaceKey(const Address &r,const int64_t rol,const InetAddress &ra,InetAddress::IpScope s) : reporter(r),receivedOnLocalSocket(rol),reporterPhysicalAddress(ra),scope(s) {}
 
-		inline unsigned long hashCode() const { return ((unsigned long)reporter.toInt() + (unsigned long)scope); }
+		ZT_ALWAYS_INLINE unsigned long hashCode() const { return ((unsigned long)reporter.toInt() + (unsigned long)scope); }
 
-		inline bool operator==(const PhySurfaceKey &k) const { return ((reporter == k.reporter)&&(receivedOnLocalSocket == k.receivedOnLocalSocket)&&(reporterPhysicalAddress == k.reporterPhysicalAddress)&&(scope == k.scope)); }
-		inline bool operator!=(const PhySurfaceKey &k) const { return (!(*this == k)); }
+		ZT_ALWAYS_INLINE bool operator==(const PhySurfaceKey &k) const { return ((reporter == k.reporter)&&(receivedOnLocalSocket == k.receivedOnLocalSocket)&&(reporterPhysicalAddress == k.reporterPhysicalAddress)&&(scope == k.scope)); }
+		ZT_ALWAYS_INLINE bool operator!=(const PhySurfaceKey &k) const { return (!(*this == k)); }
 	};
 	struct PhySurfaceEntry
 	{
@@ -73,8 +73,8 @@ private:
 		uint64_t ts;
 		bool trusted;
 
-		inline PhySurfaceEntry() : mySurface(),ts(0),trusted(false) {}
-		inline PhySurfaceEntry(const InetAddress &a,const uint64_t t) : mySurface(a),ts(t),trusted(false) {}
+		ZT_ALWAYS_INLINE PhySurfaceEntry() : mySurface(),ts(0),trusted(false) {}
+		ZT_ALWAYS_INLINE PhySurfaceEntry(const InetAddress &a,const uint64_t t) : mySurface(a),ts(t),trusted(false) {}
 	};
 
 	const RuntimeEnvironment *RR;

+ 39 - 39
node/Str.hpp

@@ -35,36 +35,36 @@ public:
 	typedef char * iterator;
 	typedef const char * const_iterator;
 
-	inline Str() { _l = 0; _s[0] = 0; }
-	inline Str(const Str &s)
+	ZT_ALWAYS_INLINE Str() { _l = 0; _s[0] = 0; }
+	ZT_ALWAYS_INLINE Str(const Str &s)
 	{
 		_l = s._l;
 		memcpy(_s,s._s,_l+1);
 	}
-	inline Str(const char *s)
+	ZT_ALWAYS_INLINE Str(const char *s)
 	{
 		_l = 0;
 		_s[0] = 0;
 		(*this) << s;
 	}
-	inline Str(const std::string &s)
+	ZT_ALWAYS_INLINE Str(const std::string &s)
 	{
 		*this = s;
 	}
 
-	inline Str &operator=(const Str &s)
+	ZT_ALWAYS_INLINE Str &operator=(const Str &s)
 	{
 		_l = s._l;
 		memcpy(_s,s._s,_l+1);
 		return *this;
 	}
-	inline Str &operator=(const char *s)
+	ZT_ALWAYS_INLINE Str &operator=(const char *s)
 	{
 		_l = 0;
 		_s[0] = 0;
 		return ((*this) << s);
 	}
-	inline Str &operator=(const std::string &s)
+	ZT_ALWAYS_INLINE Str &operator=(const std::string &s)
 	{
 		if (s.length() > ZT_STR_CAPACITY) {
 			_l = 0;
@@ -78,23 +78,23 @@ public:
 		return *this;
 	}
 
-	inline char operator[](const unsigned int i) const
+	ZT_ALWAYS_INLINE char operator[](const unsigned int i) const
 	{
 		if (unlikely(i >= (unsigned int)_l))
 			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 		return _s[i];
 	}
 
-	inline void clear() { _l = 0; _s[0] = 0; }
-	inline const char *c_str() const { return _s; }
-	inline unsigned int length() const { return (unsigned int)_l; }
-	inline bool empty() const { return (_l == 0); }
-	inline iterator begin() { return (iterator)_s; }
-	inline iterator end() { return (iterator)(_s + (unsigned long)_l); }
-	inline const_iterator begin() const { return (const_iterator)_s; }
-	inline const_iterator end() const { return (const_iterator)(_s + (unsigned long)_l); }
+	ZT_ALWAYS_INLINE void clear() { _l = 0; _s[0] = 0; }
+	ZT_ALWAYS_INLINE const char *c_str() const { return _s; }
+	ZT_ALWAYS_INLINE unsigned int length() const { return (unsigned int)_l; }
+	ZT_ALWAYS_INLINE bool empty() const { return (_l == 0); }
+	ZT_ALWAYS_INLINE iterator begin() { return (iterator)_s; }
+	ZT_ALWAYS_INLINE iterator end() { return (iterator)(_s + (unsigned long)_l); }
+	ZT_ALWAYS_INLINE const_iterator begin() const { return (const_iterator)_s; }
+	ZT_ALWAYS_INLINE const_iterator end() const { return (const_iterator)(_s + (unsigned long)_l); }
 
-	inline Str &operator<<(const char *s)
+	ZT_ALWAYS_INLINE Str &operator<<(const char *s)
 	{
 		if (likely(s != (const char *)0)) {
 			unsigned long l = _l;
@@ -112,8 +112,8 @@ public:
 		}
 		return *this;
 	}
-	inline Str &operator<<(const Str &s) { return ((*this) << s._s); }
-	inline Str &operator<<(const char c)
+	ZT_ALWAYS_INLINE Str &operator<<(const Str &s) { return ((*this) << s._s); }
+	ZT_ALWAYS_INLINE Str &operator<<(const char c)
 	{
 		if (unlikely(_l >= ZT_STR_CAPACITY)) {
 			_s[ZT_STR_CAPACITY] = 0;
@@ -123,49 +123,49 @@ public:
 		_s[(unsigned long)_l] = 0;
 		return *this;
 	}
-	inline Str &operator<<(const unsigned long n)
+	ZT_ALWAYS_INLINE Str &operator<<(const unsigned long n)
 	{
 		char tmp[32];
 		Utils::decimal(n,tmp);
 		return ((*this) << tmp);
 	}
-	inline Str &operator<<(const unsigned int n)
+	ZT_ALWAYS_INLINE Str &operator<<(const unsigned int n)
 	{
 		char tmp[32];
 		Utils::decimal((unsigned long)n,tmp);
 		return ((*this) << tmp);
 	}
-	inline Str &operator<<(const Address &a)
+	ZT_ALWAYS_INLINE Str &operator<<(const Address &a)
 	{
 		char tmp[32];
 		return ((*this) << a.toString(tmp));
 	}
-	inline Str &operator<<(const InetAddress &a)
+	ZT_ALWAYS_INLINE Str &operator<<(const InetAddress &a)
 	{
 		char tmp[128];
 		return ((*this) << a.toString(tmp));
 	}
-	inline Str &operator<<(const MAC &a)
+	ZT_ALWAYS_INLINE Str &operator<<(const MAC &a)
 	{
 		char tmp[64];
 		return ((*this) << a.toString(tmp));
 	}
 
-	inline operator bool() const { return (_l != 0); }
-
-	inline bool operator==(const Str &s) const { return ((_l == s._l)&&(strcmp(_s,s._s) == 0)); }
-	inline bool operator!=(const Str &s) const { return ((_l != s._l)||(strcmp(_s,s._s) != 0)); }
-	inline bool operator<(const Str &s) const { return ((_l < s._l)&&(strcmp(_s,s._s) < 0)); }
-	inline bool operator>(const Str &s) const { return ((_l > s._l)&&(strcmp(_s,s._s) > 0)); }
-	inline bool operator<=(const Str &s) const { return ((_l <= s._l)&&(strcmp(_s,s._s) <= 0)); }
-	inline bool operator>=(const Str &s) const { return ((_l >= s._l)&&(strcmp(_s,s._s) >= 0)); }
-
-	inline bool operator==(const char *s) const { return (strcmp(_s,s) == 0); }
-	inline bool operator!=(const char *s) const { return (strcmp(_s,s) != 0); }
-	inline bool operator<(const char *s) const { return (strcmp(_s,s) < 0); }
-	inline bool operator>(const char *s) const { return (strcmp(_s,s) > 0); }
-	inline bool operator<=(const char *s) const { return (strcmp(_s,s) <= 0); }
-	inline bool operator>=(const char *s) const { return (strcmp(_s,s) >= 0); }
+	ZT_ALWAYS_INLINE operator bool() const { return (_l != 0); }
+
+	ZT_ALWAYS_INLINE bool operator==(const Str &s) const { return ((_l == s._l)&&(strcmp(_s,s._s) == 0)); }
+	ZT_ALWAYS_INLINE bool operator!=(const Str &s) const { return ((_l != s._l)||(strcmp(_s,s._s) != 0)); }
+	ZT_ALWAYS_INLINE bool operator<(const Str &s) const { return ((_l < s._l)&&(strcmp(_s,s._s) < 0)); }
+	ZT_ALWAYS_INLINE bool operator>(const Str &s) const { return ((_l > s._l)&&(strcmp(_s,s._s) > 0)); }
+	ZT_ALWAYS_INLINE bool operator<=(const Str &s) const { return ((_l <= s._l)&&(strcmp(_s,s._s) <= 0)); }
+	ZT_ALWAYS_INLINE bool operator>=(const Str &s) const { return ((_l >= s._l)&&(strcmp(_s,s._s) >= 0)); }
+
+	ZT_ALWAYS_INLINE bool operator==(const char *s) const { return (strcmp(_s,s) == 0); }
+	ZT_ALWAYS_INLINE bool operator!=(const char *s) const { return (strcmp(_s,s) != 0); }
+	ZT_ALWAYS_INLINE bool operator<(const char *s) const { return (strcmp(_s,s) < 0); }
+	ZT_ALWAYS_INLINE bool operator>(const char *s) const { return (strcmp(_s,s) > 0); }
+	ZT_ALWAYS_INLINE bool operator<=(const char *s) const { return (strcmp(_s,s) <= 0); }
+	ZT_ALWAYS_INLINE bool operator>=(const char *s) const { return (strcmp(_s,s) >= 0); }
 
 private:
 	uint8_t _l;

+ 9 - 9
node/Tag.hpp

@@ -81,14 +81,14 @@ public:
 	{
 	}
 
-	inline uint32_t id() const { return _id; }
-	inline const uint32_t &value() const { return _value; }
-	inline uint64_t networkId() const { return _networkId; }
-	inline int64_t timestamp() const { return _ts; }
-	inline const Address &issuedTo() const { return _issuedTo; }
-	inline const Address &signer() const { return _signedBy; }
-	inline const uint8_t *signature() const { return _signature; }
-	inline unsigned int signatureLength() const { return _signatureLength; }
+	ZT_ALWAYS_INLINE uint32_t id() const { return _id; }
+	ZT_ALWAYS_INLINE const uint32_t &value() const { return _value; }
+	ZT_ALWAYS_INLINE uint64_t networkId() const { return _networkId; }
+	ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; }
+	ZT_ALWAYS_INLINE const Address &issuedTo() const { return _issuedTo; }
+	ZT_ALWAYS_INLINE const Address &signer() const { return _signedBy; }
+	ZT_ALWAYS_INLINE const uint8_t *signature() const { return _signature; }
+	ZT_ALWAYS_INLINE unsigned int signatureLength() const { return _signatureLength; }
 
 	/**
 	 * Sign this tag
@@ -107,7 +107,7 @@ public:
 		}
 		return false;
 	}
-	
+
 	/**
 	 * Check this tag's signature
 	 *