Browse Source

Make Dictionary templatable so it can be used where we want a higher capacity.

Adam Ierymenko 9 years ago
parent
commit
b2d048aa0e

+ 2 - 2
controller/SqliteNetworkController.cpp

@@ -402,7 +402,7 @@ SqliteNetworkController::~SqliteNetworkController()
 	}
 	}
 }
 }
 
 
-NetworkController::ResultCode SqliteNetworkController::doNetworkConfigRequest(const InetAddress &fromAddr,const Identity &signingId,const Identity &identity,uint64_t nwid,const Dictionary &metaData,NetworkConfig &nc)
+NetworkController::ResultCode SqliteNetworkController::doNetworkConfigRequest(const InetAddress &fromAddr,const Identity &signingId,const Identity &identity,uint64_t nwid,const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &metaData,NetworkConfig &nc)
 {
 {
 	Mutex::Lock _l(_lock);
 	Mutex::Lock _l(_lock);
 	return _doNetworkConfigRequest(fromAddr,signingId,identity,nwid,metaData,nc);
 	return _doNetworkConfigRequest(fromAddr,signingId,identity,nwid,metaData,nc);
@@ -1576,7 +1576,7 @@ unsigned int SqliteNetworkController::_doCPGet(
 	return 404;
 	return 404;
 }
 }
 
 
-NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(const InetAddress &fromAddr,const Identity &signingId,const Identity &identity,uint64_t nwid,const Dictionary &metaData,NetworkConfig &nc)
+NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(const InetAddress &fromAddr,const Identity &signingId,const Identity &identity,uint64_t nwid,const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &metaData,NetworkConfig &nc)
 {
 {
 	// Assumes _lock is locked
 	// Assumes _lock is locked
 
 

+ 2 - 2
controller/SqliteNetworkController.hpp

@@ -62,7 +62,7 @@ public:
 		const Identity &signingId,
 		const Identity &signingId,
 		const Identity &identity,
 		const Identity &identity,
 		uint64_t nwid,
 		uint64_t nwid,
-		const Dictionary &metaData,
+		const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &metaData,
 		NetworkConfig &nc);
 		NetworkConfig &nc);
 
 
 	unsigned int handleControlPlaneHttpGET(
 	unsigned int handleControlPlaneHttpGET(
@@ -113,7 +113,7 @@ private:
 		const Identity &signingId,
 		const Identity &signingId,
 		const Identity &identity,
 		const Identity &identity,
 		uint64_t nwid,
 		uint64_t nwid,
-		const Dictionary &metaData,
+		const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &metaData,
 		NetworkConfig &nc);
 		NetworkConfig &nc);
 
 
 	static void _circuitTestCallback(ZT_Node *node,ZT_CircuitTest *test,const ZT_CircuitTestReport *report);
 	static void _circuitTestCallback(ZT_Node *node,ZT_CircuitTest *test,const ZT_CircuitTestReport *report);

+ 30 - 22
node/Dictionary.hpp

@@ -26,9 +26,6 @@
 
 
 #include <stdint.h>
 #include <stdint.h>
 
 
-// Can be increased if it's ever needed, but not too much.
-#define ZT_DICTIONARY_MAX_SIZE 8194
-
 namespace ZeroTier {
 namespace ZeroTier {
 
 
 /**
 /**
@@ -48,7 +45,10 @@ namespace ZeroTier {
  *
  *
  * There is code to test and fuzz this in selftest.cpp. Fuzzing a blob of
  * There is code to test and fuzz this in selftest.cpp. Fuzzing a blob of
  * pointer tricks like this is important after any modifications.
  * pointer tricks like this is important after any modifications.
+ *
+ * @tparam C Dictionary max capacity in bytes
  */
  */
+template<unsigned int C>
 class Dictionary
 class Dictionary
 {
 {
 public:
 public:
@@ -64,8 +64,8 @@ public:
 
 
 	Dictionary(const char *s,unsigned int len)
 	Dictionary(const char *s,unsigned int len)
 	{
 	{
-		memcpy(_d,s,(len > ZT_DICTIONARY_MAX_SIZE) ? (unsigned int)ZT_DICTIONARY_MAX_SIZE : len);
-		_d[ZT_DICTIONARY_MAX_SIZE-1] = (char)0;
+		memcpy(_d,s,(len > C) ? (unsigned int)C : len);
+		_d[C-1] = (char)0;
 	}
 	}
 
 
 	Dictionary(const Dictionary &d)
 	Dictionary(const Dictionary &d)
@@ -83,7 +83,7 @@ public:
 	 * Load a dictionary from a C-string
 	 * Load a dictionary from a C-string
 	 *
 	 *
 	 * @param s Dictionary in string form
 	 * @param s Dictionary in string form
-	 * @return False if 's' was longer than ZT_DICTIONARY_MAX_SIZE
+	 * @return False if 's' was longer than our capacity
 	 */
 	 */
 	inline bool load(const char *s)
 	inline bool load(const char *s)
 	{
 	{
@@ -103,11 +103,11 @@ public:
 	 */
 	 */
 	inline unsigned int sizeBytes() const
 	inline unsigned int sizeBytes() const
 	{
 	{
-		for(unsigned int i=0;i<ZT_DICTIONARY_MAX_SIZE;++i) {
+		for(unsigned int i=0;i<C;++i) {
 			if (!_d[i])
 			if (!_d[i])
 				return i;
 				return i;
 		}
 		}
-		return ZT_DICTIONARY_MAX_SIZE;
+		return C;
 	}
 	}
 
 
 	/**
 	/**
@@ -194,9 +194,10 @@ public:
 	 * @param key Key to get
 	 * @param key Key to get
 	 * @param dest Destination buffer
 	 * @param dest Destination buffer
 	 * @return True if key was found (if false, dest will be empty)
 	 * @return True if key was found (if false, dest will be empty)
+	 * @tparam BC Buffer capacity (usually inferred)
 	 */
 	 */
-	template<unsigned int C>
-	inline bool get(const char *key,Buffer<C> &dest) const
+	template<unsigned int BC>
+	inline bool get(const char *key,Buffer<BC> &dest) const
 	{
 	{
 		const int r = this->get(key,const_cast<char *>(reinterpret_cast<const char *>(dest.data())),C);
 		const int r = this->get(key,const_cast<char *>(reinterpret_cast<const char *>(dest.data())),C);
 		if (r >= 0) {
 		if (r >= 0) {
@@ -254,13 +255,13 @@ public:
 	 */
 	 */
 	inline bool add(const char *key,const char *value,int vlen = -1)
 	inline bool add(const char *key,const char *value,int vlen = -1)
 	{
 	{
-		for(unsigned int i=0;i<ZT_DICTIONARY_MAX_SIZE;++i) {
+		for(unsigned int i=0;i<C;++i) {
 			if (!_d[i]) {
 			if (!_d[i]) {
 				unsigned int j = i;
 				unsigned int j = i;
 
 
 				if (j > 0) {
 				if (j > 0) {
 					_d[j++] = '\n';
 					_d[j++] = '\n';
-					if (j == ZT_DICTIONARY_MAX_SIZE) {
+					if (j == C) {
 						_d[i] = (char)0;
 						_d[i] = (char)0;
 						return false;
 						return false;
 					}
 					}
@@ -269,14 +270,14 @@ public:
 				const char *p = key;
 				const char *p = key;
 				while (*p) {
 				while (*p) {
 					_d[j++] = *(p++);
 					_d[j++] = *(p++);
-					if (j == ZT_DICTIONARY_MAX_SIZE) {
+					if (j == C) {
 						_d[i] = (char)0;
 						_d[i] = (char)0;
 						return false;
 						return false;
 					}
 					}
 				}
 				}
 
 
 				_d[j++] = '=';
 				_d[j++] = '=';
-				if (j == ZT_DICTIONARY_MAX_SIZE) {
+				if (j == C) {
 					_d[i] = (char)0;
 					_d[i] = (char)0;
 					return false;
 					return false;
 				}
 				}
@@ -291,7 +292,7 @@ public:
 						case '\\':
 						case '\\':
 						case '=':
 						case '=':
 							_d[j++] = '\\';
 							_d[j++] = '\\';
-							if (j == ZT_DICTIONARY_MAX_SIZE) {
+							if (j == C) {
 								_d[i] = (char)0;
 								_d[i] = (char)0;
 								return false;
 								return false;
 							}
 							}
@@ -302,14 +303,14 @@ public:
 								case '\\': _d[j++] = '\\'; break;
 								case '\\': _d[j++] = '\\'; break;
 								case '=': _d[j++] = 'e'; break;
 								case '=': _d[j++] = 'e'; break;
 							}
 							}
-							if (j == ZT_DICTIONARY_MAX_SIZE) {
+							if (j == C) {
 								_d[i] = (char)0;
 								_d[i] = (char)0;
 								return false;
 								return false;
 							}
 							}
 							break;
 							break;
 						default:
 						default:
 							_d[j++] = *p;
 							_d[j++] = *p;
-							if (j == ZT_DICTIONARY_MAX_SIZE) {
+							if (j == C) {
 								_d[i] = (char)0;
 								_d[i] = (char)0;
 								return false;
 								return false;
 							}
 							}
@@ -356,10 +357,12 @@ public:
 	}
 	}
 
 
 	/**
 	/**
-	 * Add a binary buffer
+	 * Add a binary buffer's contents as a value
+	 *
+	 * @tparam BC Buffer capacity (usually inferred)
 	 */
 	 */
-	template<unsigned int C>
-	inline bool add(const char *key,const Buffer<C> &value)
+	template<unsigned int BC>
+	inline bool add(const char *key,const Buffer<BC> &value)
 	{
 	{
 		return this->add(key,(const char *)value.data(),(int)value.size());
 		return this->add(key,(const char *)value.data(),(int)value.size());
 	}
 	}
@@ -385,7 +388,7 @@ public:
 	 */
 	 */
 	inline bool erase(const char *key)
 	inline bool erase(const char *key)
 	{
 	{
-		char d2[ZT_DICTIONARY_MAX_SIZE];
+		char d2[C];
 		char *saveptr = (char *)0;
 		char *saveptr = (char *)0;
 		unsigned int d2ptr = 0;
 		unsigned int d2ptr = 0;
 		bool found = false;
 		bool found = false;
@@ -419,8 +422,13 @@ public:
 	 */
 	 */
 	inline const char *data() const { return _d; }
 	inline const char *data() const { return _d; }
 
 
+	/**
+	 * @return Value of C template parameter
+	 */
+	inline unsigned int capacity() const { return C; }
+
 private:
 private:
-	char _d[ZT_DICTIONARY_MAX_SIZE];
+	char _d[C];
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 3 - 3
node/IncomingPacket.cpp

@@ -403,7 +403,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
 				if ((nw)&&(nw->controller() == peer->address())) {
 				if ((nw)&&(nw->controller() == peer->address())) {
 					const unsigned int nclen = at<uint16_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN);
 					const unsigned int nclen = at<uint16_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN);
 					if (nclen) {
 					if (nclen) {
-						Dictionary dconf((const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT,nclen),nclen);
+						Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> dconf((const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT,nclen),nclen);
 						NetworkConfig nconf;
 						NetworkConfig nconf;
 						if (nconf.fromDictionary(dconf)) {
 						if (nconf.fromDictionary(dconf)) {
 							nw->setConfiguration(nconf,true);
 							nw->setConfiguration(nconf,true);
@@ -684,7 +684,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
 
 
 		const unsigned int metaDataLength = at<uint16_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN);
 		const unsigned int metaDataLength = at<uint16_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN);
 		const char *metaDataBytes = (const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT,metaDataLength);
 		const char *metaDataBytes = (const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT,metaDataLength);
-		const Dictionary metaData(metaDataBytes,metaDataLength);
+		const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> metaData(metaDataBytes,metaDataLength);
 
 
 		//const uint64_t haveRevision = ((ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT + metaDataLength + 8) <= size()) ? at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT + metaDataLength) : 0ULL;
 		//const uint64_t haveRevision = ((ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT + metaDataLength + 8) <= size()) ? at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT + metaDataLength) : 0ULL;
 
 
@@ -697,7 +697,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
 			switch(RR->localNetworkController->doNetworkConfigRequest((h > 0) ? InetAddress() : _remoteAddress,RR->identity,peer->identity(),nwid,metaData,netconf)) {
 			switch(RR->localNetworkController->doNetworkConfigRequest((h > 0) ? InetAddress() : _remoteAddress,RR->identity,peer->identity(),nwid,metaData,netconf)) {
 
 
 				case NetworkController::NETCONF_QUERY_OK: {
 				case NetworkController::NETCONF_QUERY_OK: {
-					Dictionary dconf;
+					Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> dconf;
 					if (netconf.toDictionary(dconf,metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,0) < 6)) {
 					if (netconf.toDictionary(dconf,metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,0) < 6)) {
 						Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
 						Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
 						outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
 						outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);

+ 3 - 3
node/Network.cpp

@@ -64,7 +64,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr) :
 		try {
 		try {
 			std::string conf(RR->node->dataStoreGet(confn));
 			std::string conf(RR->node->dataStoreGet(confn));
 			if (conf.length()) {
 			if (conf.length()) {
-				Dictionary dconf(conf.c_str());
+				Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> dconf(conf.c_str());
 				NetworkConfig nconf;
 				NetworkConfig nconf;
 				if (nconf.fromDictionary(dconf)) {
 				if (nconf.fromDictionary(dconf)) {
 					this->setConfiguration(nconf,false);
 					this->setConfiguration(nconf,false);
@@ -193,7 +193,7 @@ int Network::setConfiguration(const NetworkConfig &nconf,bool saveToDisk)
 			if (saveToDisk) {
 			if (saveToDisk) {
 				char n[64];
 				char n[64];
 				Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id);
 				Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id);
-				Dictionary d;
+				Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> d;
 				if (nconf.toDictionary(d,false))
 				if (nconf.toDictionary(d,false))
 					RR->node->dataStorePut(n,(const void *)d.data(),d.sizeBytes(),true);
 					RR->node->dataStorePut(n,(const void *)d.data(),d.sizeBytes(),true);
 			}
 			}
@@ -210,7 +210,7 @@ void Network::requestConfiguration()
 	if (_id == ZT_TEST_NETWORK_ID) // pseudo-network-ID, uses locally generated static config
 	if (_id == ZT_TEST_NETWORK_ID) // pseudo-network-ID, uses locally generated static config
 		return;
 		return;
 
 
-	Dictionary rmd;
+	Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> rmd;
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION);
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION);
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION);
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION);
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MAJOR);
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MAJOR);

+ 5 - 5
node/NetworkConfig.cpp

@@ -23,9 +23,9 @@
 
 
 namespace ZeroTier {
 namespace ZeroTier {
 
 
-bool NetworkConfig::toDictionary(Dictionary &d,bool includeLegacy) const
+bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,bool includeLegacy) const
 {
 {
-	Buffer<ZT_DICTIONARY_MAX_SIZE> tmp;
+	Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> tmp;
 
 
 	d.clear();
 	d.clear();
 
 
@@ -259,11 +259,11 @@ bool NetworkConfig::toDictionary(Dictionary &d,bool includeLegacy) const
 	return true;
 	return true;
 }
 }
 
 
-bool NetworkConfig::fromDictionary(const Dictionary &d)
+bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d)
 {
 {
 	try {
 	try {
-		Buffer<ZT_DICTIONARY_MAX_SIZE> tmp;
-		char tmp2[ZT_DICTIONARY_MAX_SIZE];
+		Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> tmp;
+		char tmp2[ZT_NETWORKCONFIG_DICT_CAPACITY];
 
 
 		memset(this,0,sizeof(NetworkConfig));
 		memset(this,0,sizeof(NetworkConfig));
 
 

+ 5 - 2
node/NetworkConfig.hpp

@@ -64,6 +64,9 @@
 
 
 namespace ZeroTier {
 namespace ZeroTier {
 
 
+// Maximum size of a network config dictionary (can be increased)
+#define ZT_NETWORKCONFIG_DICT_CAPACITY 8194
+
 // Network config version
 // Network config version
 #define ZT_NETWORKCONFIG_VERSION 6
 #define ZT_NETWORKCONFIG_VERSION 6
 
 
@@ -234,7 +237,7 @@ public:
 	 * @param includeLegacy If true, include legacy fields for old node versions
 	 * @param includeLegacy If true, include legacy fields for old node versions
 	 * @return True if dictionary was successfully created, false if e.g. overflow
 	 * @return True if dictionary was successfully created, false if e.g. overflow
 	 */
 	 */
-	bool toDictionary(Dictionary &d,bool includeLegacy) const;
+	bool toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,bool includeLegacy) const;
 
 
 	/**
 	/**
 	 * Read this network config from a dictionary
 	 * Read this network config from a dictionary
@@ -242,7 +245,7 @@ public:
 	 * @param d Dictionary
 	 * @param d Dictionary
 	 * @return True if dictionary was valid and network config successfully initialized
 	 * @return True if dictionary was valid and network config successfully initialized
 	 */
 	 */
-	bool fromDictionary(const Dictionary &d);
+	bool fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d);
 
 
 	/**
 	/**
 	 * @return True if passive bridging is allowed (experimental)
 	 * @return True if passive bridging is allowed (experimental)

+ 3 - 3
node/NetworkController.hpp

@@ -22,12 +22,12 @@
 #include <stdint.h>
 #include <stdint.h>
 
 
 #include "Constants.hpp"
 #include "Constants.hpp"
+#include "Dictionary.hpp"
+#include "NetworkConfig.hpp"
 
 
 namespace ZeroTier {
 namespace ZeroTier {
 
 
 class RuntimeEnvironment;
 class RuntimeEnvironment;
-class NetworkConfig;
-class Dictionary;
 class Identity;
 class Identity;
 class Address;
 class Address;
 struct InetAddress;
 struct InetAddress;
@@ -75,7 +75,7 @@ public:
 		const Identity &signingId,
 		const Identity &signingId,
 		const Identity &identity,
 		const Identity &identity,
 		uint64_t nwid,
 		uint64_t nwid,
-		const Dictionary &metaData,
+		const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &metaData,
 		NetworkConfig &nc) = 0;
 		NetworkConfig &nc) = 0;
 };
 };
 
 

+ 1 - 1
osdep/LinuxEthernetTap.cpp

@@ -95,7 +95,7 @@ LinuxEthernetTap::LinuxEthernetTap(
 	// Try to recall our last device name, or pick an unused one if that fails.
 	// Try to recall our last device name, or pick an unused one if that fails.
 	bool recalledDevice = false;
 	bool recalledDevice = false;
 	std::string devmapbuf;
 	std::string devmapbuf;
-	Dictionary devmap;
+	Dictionary<8194> devmap;
 	if (OSUtils::readFile((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),devmapbuf)) {
 	if (OSUtils::readFile((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),devmapbuf)) {
 		devmap.load(devmapbuf.c_str());
 		devmap.load(devmapbuf.c_str());
 		char desiredDevice[128];
 		char desiredDevice[128];

+ 1 - 1
osdep/OSXEthernetTap.cpp

@@ -354,7 +354,7 @@ OSXEthernetTap::OSXEthernetTap(
 	// Try to reopen the last device we had, if we had one and it's still unused.
 	// Try to reopen the last device we had, if we had one and it's still unused.
 	bool recalledDevice = false;
 	bool recalledDevice = false;
 	std::string devmapbuf;
 	std::string devmapbuf;
-	Dictionary devmap;
+	Dictionary<8194> devmap;
 	if (OSUtils::readFile((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),devmapbuf)) {
 	if (OSUtils::readFile((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),devmapbuf)) {
 		devmap.load(devmapbuf.c_str());
 		devmap.load(devmapbuf.c_str());
 		char desiredDevice[128];
 		char desiredDevice[128];

+ 4 - 4
selftest.cpp

@@ -766,7 +766,7 @@ static int testOther()
 
 
 	std::cout << "[other] Testing/fuzzing Dictionary... "; std::cout.flush();
 	std::cout << "[other] Testing/fuzzing Dictionary... "; std::cout.flush();
 	for(int k=0;k<1000;++k) {
 	for(int k=0;k<1000;++k) {
-		Dictionary test;
+		Dictionary<8194> test;
 		char key[32][16];
 		char key[32][16];
 		char value[32][128];
 		char value[32][128];
 		for(unsigned int q=0;q<32;++q) {
 		for(unsigned int q=0;q<32;++q) {
@@ -807,12 +807,12 @@ static int testOther()
 	int foo = 0;
 	int foo = 0;
 	volatile int *volatile bar = &foo; // force compiler not to optimize out test.get() below
 	volatile int *volatile bar = &foo; // force compiler not to optimize out test.get() below
 	for(int k=0;k<100;++k) {
 	for(int k=0;k<100;++k) {
-		int r = rand() % ZT_DICTIONARY_MAX_SIZE;
-		unsigned char tmp[ZT_DICTIONARY_MAX_SIZE];
+		int r = rand() % 8194;
+		unsigned char tmp[8194];
 		for(int q=0;q<r;++q)
 		for(int q=0;q<r;++q)
 			tmp[q] = (unsigned char)((rand() % 254) + 1);
 			tmp[q] = (unsigned char)((rand() % 254) + 1);
 		tmp[r] = 0;
 		tmp[r] = 0;
-		Dictionary test((const char *)tmp);
+		Dictionary<8194> test((const char *)tmp);
 		for(unsigned int q=0;q<100;++q) {
 		for(unsigned int q=0;q<100;++q) {
 			char tmp[16];
 			char tmp[16];
 			Utils::snprintf(tmp,16,"%.8lx",(unsigned long)rand());
 			Utils::snprintf(tmp,16,"%.8lx",(unsigned long)rand());

+ 8 - 1
service/OneService.cpp

@@ -1571,6 +1571,7 @@ public:
 	inline int nodePathCheckFunction(const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr)
 	inline int nodePathCheckFunction(const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr)
 	{
 	{
 		Mutex::Lock _l(_nets_m);
 		Mutex::Lock _l(_nets_m);
+	
 		for(std::map<uint64_t,NetworkState>::const_iterator n(_nets.begin());n!=_nets.end();++n) {
 		for(std::map<uint64_t,NetworkState>::const_iterator n(_nets.begin());n!=_nets.end();++n) {
 			if (n->second.tap) {
 			if (n->second.tap) {
 				std::vector<InetAddress> ips(n->second.tap->ips());
 				std::vector<InetAddress> ips(n->second.tap->ips());
@@ -1581,7 +1582,13 @@ public:
 				}
 				}
 			}
 			}
 		}
 		}
-		// TODO: also check routing table for L3 routes via ZeroTier managed devices
+	
+		/* Note: I do not think we need to scan for overlap with managed routes
+		 * because of the "route forking" and interface binding that we do. This
+		 * ensures (we hope) that ZeroTier traffic will still take the physical
+		 * path even if its managed routes override this for other traffic. Will
+		 * revisit if we see problems with this. */
+
 		return 1;
 		return 1;
 	}
 	}