Browse Source

Add remoteTraceTarget to network and member configs in controller.

Adam Ierymenko 8 years ago
parent
commit
d9552fb120

+ 80 - 39
controller/EmbeddedNetworkController.cpp

@@ -453,6 +453,8 @@ void EmbeddedNetworkController::init(const Identity &signingId,Sender *sender)
 {
 {
 	this->_sender = sender;
 	this->_sender = sender;
 	this->_signingId = signingId;
 	this->_signingId = signingId;
+	char tmp[64];
+	this->_signingIdAddressString = signingId.address().toString(tmp);
 }
 }
 
 
 void EmbeddedNetworkController::request(
 void EmbeddedNetworkController::request(
@@ -1085,51 +1087,80 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpDELETE(
 
 
 void EmbeddedNetworkController::handleRemoteTrace(const ZT_RemoteTrace &rt)
 void EmbeddedNetworkController::handleRemoteTrace(const ZT_RemoteTrace &rt)
 {
 {
-	// Convert Dictionary into JSON object
-	json d;
-	char *saveptr = (char *)0;
-	for(char *l=Utils::stok(rt.data,"\n",&saveptr);(l);l=Utils::stok((char *)0,"\n",&saveptr)) {
-		char *eq = strchr(l,'=');
-		if (eq > l) {
-			std::string k(l,(unsigned long)(eq - l));
-			std::string v;
-			++eq;
-			while (*eq) {
-				if (*eq == '\\') {
-					++eq;
-					if (*eq) {
-						switch(*eq) {
-							case 'r':
-								v.push_back('\r');
-								break;
-							case 'n':
-								v.push_back('\n');
-								break;
-							case '0':
-								v.push_back((char)0);
-								break;
-							case 'e':
-								v.push_back('=');
-								break;
-							default:
-								v.push_back(*eq);
-								break;
-						}
+	try {
+		std::vector<uint64_t> nw4m(_db.networksForMember(rt.origin));
+		if (nw4m.empty()) // ignore these for unknown members
+			return;
+
+		// Convert Dictionary into JSON object
+		json d;
+		char *saveptr = (char *)0;
+		for(char *l=Utils::stok(rt.data,"\n",&saveptr);(l);l=Utils::stok((char *)0,"\n",&saveptr)) {
+			char *eq = strchr(l,'=');
+			if (eq > l) {
+				std::string k(l,(unsigned long)(eq - l));
+				std::string v;
+				++eq;
+				while (*eq) {
+					if (*eq == '\\') {
 						++eq;
 						++eq;
+						if (*eq) {
+							switch(*eq) {
+								case 'r':
+									v.push_back('\r');
+									break;
+								case 'n':
+									v.push_back('\n');
+									break;
+								case '0':
+									v.push_back((char)0);
+									break;
+								case 'e':
+									v.push_back('=');
+									break;
+								default:
+									v.push_back(*eq);
+									break;
+							}
+							++eq;
+						}
+					} else {
+						v.push_back(*(eq++));
 					}
 					}
-				} else {
-					v.push_back(*(eq++));
 				}
 				}
+				if (v.length() > 0)
+					d[k] = v;
 			}
 			}
-			if (v.length() > 0)
-				d[k] = v;
 		}
 		}
-	}
 
 
-	char p[128];
-	OSUtils::ztsnprintf(p,sizeof(p),"trace/%.10llx_%.16llx.json",rt.origin,OSUtils::now());
-	_db.writeRaw(p,OSUtils::jsonDump(d));
-	//fprintf(stdout,"%s\n",OSUtils::jsonDump(d).c_str()); fflush(stdout);
+		bool accept = false;
+		for(std::vector<uint64_t>::const_iterator nwid(nw4m.begin());nwid!=nw4m.end();++nwid) {
+			json nconf;
+			if (_db.getNetwork(*nwid,nconf)) {
+				try {
+					if (OSUtils::jsonString(nconf["remoteTraceTarget"],"") == _signingIdAddressString) {
+						accept = true;
+						break;
+					}
+				} catch ( ... ) {} // ignore missing fields or other errors, drop trace message
+			}
+			if (_db.getNetworkMember(*nwid,rt.origin,nconf)) {
+				try {
+					if (OSUtils::jsonString(nconf["remoteTraceTarget"],"") == _signingIdAddressString) {
+						accept = true;
+						break;
+					}
+				} catch ( ... ) {} // ignore missing fields or other errors, drop trace message
+			}
+		}
+		if (accept) {
+			char p[128];
+			OSUtils::ztsnprintf(p,sizeof(p),"trace/%.10llx_%.16llx.json",rt.origin,OSUtils::now());
+			_db.writeRaw(p,OSUtils::jsonDump(d));
+		}
+	} catch ( ... ) {
+		// drop invalid trace messages if an error occurs
+	}
 }
 }
 
 
 void EmbeddedNetworkController::threadMain()
 void EmbeddedNetworkController::threadMain()
@@ -1381,6 +1412,16 @@ void EmbeddedNetworkController::_request(
 	nc->mtu = std::max(std::min((unsigned int)OSUtils::jsonInt(network["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU);
 	nc->mtu = std::max(std::min((unsigned int)OSUtils::jsonInt(network["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU);
 	nc->multicastLimit = (unsigned int)OSUtils::jsonInt(network["multicastLimit"],32ULL);
 	nc->multicastLimit = (unsigned int)OSUtils::jsonInt(network["multicastLimit"],32ULL);
 
 
+	std::string rtt(OSUtils::jsonString(member["remoteTraceTarget"],""));
+	if (rtt.length() == 10) {
+		nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str()));
+	} else {
+		rtt = OSUtils::jsonString(network["remoteTraceTarget"],"");
+		if (rtt.length() == 10) {
+			nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str()));
+		}
+	}
+
 	for(std::vector<Address>::const_iterator ab(ns.activeBridges.begin());ab!=ns.activeBridges.end();++ab)
 	for(std::vector<Address>::const_iterator ab(ns.activeBridges.begin());ab!=ns.activeBridges.end();++ab)
 		nc->addSpecialist(*ab,ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE);
 		nc->addSpecialist(*ab,ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE);
 
 

+ 2 - 0
controller/EmbeddedNetworkController.hpp

@@ -27,6 +27,7 @@
 #include <set>
 #include <set>
 #include <list>
 #include <list>
 #include <thread>
 #include <thread>
+#include <unordered_map>
 
 
 #include "../node/Constants.hpp"
 #include "../node/Constants.hpp"
 
 
@@ -218,6 +219,7 @@ private:
 
 
 	NetworkController::Sender *_sender;
 	NetworkController::Sender *_sender;
 	Identity _signingId;
 	Identity _signingId;
+	std::string _signingIdAddressString;
 
 
 	struct _MemberStatusKey
 	struct _MemberStatusKey
 	{
 	{

+ 6 - 1
controller/JSONDB.cpp

@@ -181,6 +181,7 @@ void JSONDB::saveNetworkMember(const uint64_t networkId,const uint64_t nodeId,co
 	{
 	{
 		Mutex::Lock _l(_networks_m);
 		Mutex::Lock _l(_networks_m);
 		_networks[networkId].members[nodeId] = nlohmann::json::to_msgpack(memberConfig);
 		_networks[networkId].members[nodeId] = nlohmann::json::to_msgpack(memberConfig);
+		_members[nodeId].insert(networkId);
 	}
 	}
 	_recomputeSummaryInfo(networkId);
 	_recomputeSummaryInfo(networkId);
 }
 }
@@ -244,6 +245,7 @@ nlohmann::json JSONDB::eraseNetworkMember(const uint64_t networkId,const uint64_
 
 
 	{
 	{
 		Mutex::Lock _l(_networks_m);
 		Mutex::Lock _l(_networks_m);
+		_members[nodeId].erase(networkId);
 		std::unordered_map<uint64_t,_NW>::iterator i(_networks.find(networkId));
 		std::unordered_map<uint64_t,_NW>::iterator i(_networks.find(networkId));
 		if (i == _networks.end())
 		if (i == _networks.end())
 			return _EMPTY_JSON;
 			return _EMPTY_JSON;
@@ -367,8 +369,10 @@ bool JSONDB::_load(const std::string &p)
 							} else if ((id.length() == 10)&&(objtype == "member")) {
 							} else if ((id.length() == 10)&&(objtype == "member")) {
 								const uint64_t mid = Utils::hexStrToU64(id.c_str());
 								const uint64_t mid = Utils::hexStrToU64(id.c_str());
 								const uint64_t nwid = Utils::hexStrToU64(OSUtils::jsonString(j["nwid"],"0").c_str());
 								const uint64_t nwid = Utils::hexStrToU64(OSUtils::jsonString(j["nwid"],"0").c_str());
-								if ((mid)&&(nwid))
+								if ((mid)&&(nwid)) {
 									_networks[nwid].members[mid] = nlohmann::json::to_msgpack(j);
 									_networks[nwid].members[mid] = nlohmann::json::to_msgpack(j);
+									_members[mid].insert(nwid);
+								}
 							}
 							}
 						}
 						}
 					}
 					}
@@ -403,6 +407,7 @@ bool JSONDB::_load(const std::string &p)
 							if ((mid)&&(nwid)) {
 							if ((mid)&&(nwid)) {
 								Mutex::Lock _l(_networks_m);
 								Mutex::Lock _l(_networks_m);
 								_networks[nwid].members[mid] = nlohmann::json::to_msgpack(j);
 								_networks[nwid].members[mid] = nlohmann::json::to_msgpack(j);
+								_members[mid].insert(nwid);
 							}
 							}
 						}
 						}
 					} catch ( ... ) {}
 					} catch ( ... ) {}

+ 14 - 1
controller/JSONDB.hpp

@@ -29,6 +29,7 @@
 #include <vector>
 #include <vector>
 #include <algorithm>
 #include <algorithm>
 #include <unordered_map>
 #include <unordered_map>
+#include <unordered_set>
 
 
 #include "../node/Constants.hpp"
 #include "../node/Constants.hpp"
 #include "../node/Utils.hpp"
 #include "../node/Utils.hpp"
@@ -129,6 +130,17 @@ public:
 		}
 		}
 	}
 	}
 
 
+	inline std::vector<uint64_t> networksForMember(const uint64_t nodeId)
+	{
+		Mutex::Lock _l(_networks_m);
+		std::unordered_map< uint64_t,std::unordered_set< uint64_t > >::const_iterator m(_members.find(nodeId));
+		if (m != _members.end()) {
+			return std::vector<uint64_t>(m->second.begin(),m->second.end());
+		} else {
+			return std::vector<uint64_t>();
+		}
+	}
+
 	void threadMain()
 	void threadMain()
 		throw();
 		throw();
 
 
@@ -154,7 +166,8 @@ private:
 		std::unordered_map< uint64_t,std::vector<uint8_t> > members;
 		std::unordered_map< uint64_t,std::vector<uint8_t> > members;
 	};
 	};
 
 
-	std::unordered_map<uint64_t,_NW> _networks;
+	std::unordered_map< uint64_t,_NW > _networks;
+	std::unordered_map< uint64_t,std::unordered_set< uint64_t > > _members;
 	Mutex _networks_m;
 	Mutex _networks_m;
 };
 };