diff options
| -rw-r--r-- | controller/EmbeddedNetworkController.cpp | 173 | ||||
| -rw-r--r-- | controller/EmbeddedNetworkController.hpp | 10 | ||||
| -rw-r--r-- | controller/JSONDB.cpp | 236 | ||||
| -rw-r--r-- | controller/JSONDB.hpp | 9 | ||||
| -rw-r--r-- | make-linux.mk | 9 | ||||
| -rw-r--r-- | node/AtomicCounter.hpp | 9 | ||||
| -rw-r--r-- | node/IncomingPacket.cpp | 13 | ||||
| -rw-r--r-- | node/Membership.cpp | 3 | ||||
| -rw-r--r-- | node/Node.cpp | 27 | ||||
| -rw-r--r-- | node/Switch.cpp | 37 | ||||
| -rw-r--r-- | node/Switch.hpp | 27 | ||||
| -rw-r--r-- | node/Trace.cpp | 79 | ||||
| -rw-r--r-- | node/Trace.hpp | 9 | ||||
| -rw-r--r-- | osdep/Binder.hpp | 6 | ||||
| -rw-r--r-- | service/OneService.cpp | 30 | ||||
| -rw-r--r-- | service/OneService.hpp | 7 |
16 files changed, 257 insertions, 427 deletions
diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 72d47622..0f342fa5 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -35,6 +35,7 @@ #include <memory> #include "../include/ZeroTierOne.h" +#include "../version.h" #include "../node/Constants.hpp" #include "EmbeddedNetworkController.hpp" @@ -430,7 +431,7 @@ EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *dbPa _startTime(OSUtils::now()), _running(true), _lastDumpedStatus(0), - _db(dbPath), + _db(dbPath,this), _node(node) { } @@ -638,26 +639,14 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST( if (newAuth != OSUtils::jsonBool(member["authorized"],false)) { member["authorized"] = newAuth; member[((newAuth) ? "lastAuthorizedTime" : "lastDeauthorizedTime")] = now; - - json ah; - ah["a"] = newAuth; - ah["by"] = "api"; - ah["ts"] = now; - ah["ct"] = json(); - ah["c"] = json(); - member["authHistory"].push_back(ah); + if (newAuth) { + member["lastAuthorizedCredentialType"] = "api"; + member["lastAuthorizedCredential"] = json(); + } // Member is being de-authorized, so spray Revocation objects to all online members - if (!newAuth) { - Revocation rev((uint32_t)_node->prng(),nwid,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(address),Revocation::CREDENTIAL_TYPE_COM); - rev.sign(_signingId); - - Mutex::Lock _l(_memberStatus_m); - for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) { - if ((i->first.networkId == nwid)&&(i->second.online(now))) - _node->ncSendRevocation(Address(i->first.nodeId),rev); - } - } + if (!newAuth) + onNetworkMemberDeauthorize(nwid,address); } } @@ -724,14 +713,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST( json &revj = member["revision"]; member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL); _db.saveNetworkMember(nwid,address,member); - - // Push update to member if online - try { - Mutex::Lock _l(_memberStatus_m); - _MemberStatus &ms = _memberStatus[_MemberStatusKey(nwid,address)]; - if ((ms.online(now))&&(ms.lastRequestMetaData)) - request(nwid,InetAddress(),0,ms.identity,ms.lastRequestMetaData); - } catch ( ... ) {} + onNetworkMemberUpdate(nwid,address); } _addMemberNonPersistedFields(nwid,address,member,now); @@ -896,22 +878,15 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST( if (b.count("authTokens")) { json &authTokens = b["authTokens"]; - if (authTokens.is_array()) { - json nat = json::array(); - for(unsigned long i=0;i<authTokens.size();++i) { - json &token = authTokens[i]; - if (token.is_object()) { - std::string tstr = token["token"]; - if (tstr.length() > 0) { - json t = json::object(); - t["token"] = tstr; - t["expires"] = OSUtils::jsonInt(token["expires"],0ULL); - t["maxUsesPerMember"] = OSUtils::jsonInt(token["maxUsesPerMember"],0ULL); - nat.push_back(t); - } - } + if (authTokens.is_object()) { + json nat; + for(json::iterator t(authTokens.begin());t!=authTokens.end();++t) { + if ((t.value().is_number())&&(t.value() >= 0)) + nat[t.key()] = t.value(); } network["authTokens"] = nat; + } else { + network["authTokens"] = {{}}; } } @@ -991,13 +966,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST( json &revj = network["revision"]; network["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL); _db.saveNetwork(nwid,network); - - // Send an update to all members of the network that are online - Mutex::Lock _l(_memberStatus_m); - for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) { - if ((i->first.networkId == nwid)&&(i->second.online(now))&&(i->second.lastRequestMetaData)) - request(nwid,InetAddress(),0,i->second.identity,i->second.lastRequestMetaData); - } + onNetworkUpdate(nwid); } JSONDB::NetworkSummaryInfo ns; @@ -1155,6 +1124,42 @@ void EmbeddedNetworkController::handleRemoteTrace(const ZT_RemoteTrace &rt) } } +void EmbeddedNetworkController::onNetworkUpdate(const uint64_t networkId) +{ + // Send an update to all members of the network that are online + const uint64_t now = OSUtils::now(); + Mutex::Lock _l(_memberStatus_m); + for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) { + if ((i->first.networkId == networkId)&&(i->second.online(now))&&(i->second.lastRequestMetaData)) + request(networkId,InetAddress(),0,i->second.identity,i->second.lastRequestMetaData); + } +} + +void EmbeddedNetworkController::onNetworkMemberUpdate(const uint64_t networkId,const uint64_t memberId) +{ + // Push update to member if online + try { + Mutex::Lock _l(_memberStatus_m); + _MemberStatus &ms = _memberStatus[_MemberStatusKey(networkId,memberId)]; + if ((ms.online(OSUtils::now()))&&(ms.lastRequestMetaData)) + request(networkId,InetAddress(),0,ms.identity,ms.lastRequestMetaData); + } catch ( ... ) {} +} + +void EmbeddedNetworkController::onNetworkMemberDeauthorize(const uint64_t networkId,const uint64_t memberId) +{ + const uint64_t now = OSUtils::now(); + Revocation rev((uint32_t)_node->prng(),networkId,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(memberId),Revocation::CREDENTIAL_TYPE_COM); + rev.sign(_signingId); + { + Mutex::Lock _l(_memberStatus_m); + for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) { + if ((i->first.networkId == networkId)&&(i->second.online(now))) + _node->ncSendRevocation(Address(i->first.nodeId),rev); + } + } +} + void EmbeddedNetworkController::threadMain() throw() { @@ -1195,7 +1200,7 @@ void EmbeddedNetworkController::threadMain() first = false; }); } - OSUtils::ztsnprintf(tmp,sizeof(tmp),"],\"clock\":%llu,\"startTime\":%llu,\"uptime\":%llu}",(unsigned long long)now,(unsigned long long)_startTime,(unsigned long long)(now - _startTime)); + OSUtils::ztsnprintf(tmp,sizeof(tmp),"],\"clock\":%llu,\"startTime\":%llu,\"uptime\":%llu,\"vMajor\":%d,\"vMinor\":%d,\"vRev\":%d}",(unsigned long long)now,(unsigned long long)_startTime,(unsigned long long)(now - _startTime),ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION); st.append(tmp); _db.writeRaw("status",st); } @@ -1268,56 +1273,29 @@ void EmbeddedNetworkController::_request( } // Determine whether and how member is authorized - const char *authorizedBy = (const char *)0; + bool authorized = false; bool autoAuthorized = false; json autoAuthCredentialType,autoAuthCredential; if (OSUtils::jsonBool(member["authorized"],false)) { - authorizedBy = "memberIsAuthorized"; + authorized = true; } else if (!OSUtils::jsonBool(network["private"],true)) { - authorizedBy = "networkIsPublic"; - json &ahist = member["authHistory"]; - if ((!ahist.is_array())||(ahist.size() == 0)) - autoAuthorized = true; + authorized = true; + autoAuthorized = true; + autoAuthCredentialType = "public"; } else { char presentedAuth[512]; if (metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH,presentedAuth,sizeof(presentedAuth)) > 0) { presentedAuth[511] = (char)0; // sanity check - - // Check for bearer token presented by member if ((strlen(presentedAuth) > 6)&&(!strncmp(presentedAuth,"token:",6))) { const char *const presentedToken = presentedAuth + 6; - - json &authTokens = network["authTokens"]; - if (authTokens.is_array()) { - for(unsigned long i=0;i<authTokens.size();++i) { - json &token = authTokens[i]; - if (token.is_object()) { - const uint64_t expires = OSUtils::jsonInt(token["expires"],0ULL); - const uint64_t maxUses = OSUtils::jsonInt(token["maxUsesPerMember"],0ULL); - std::string tstr = OSUtils::jsonString(token["token"],""); - - if (((expires == 0ULL)||(expires > now))&&(tstr == presentedToken)) { - bool usable = (maxUses == 0); - if (!usable) { - uint64_t useCount = 0; - json &ahist = member["authHistory"]; - if (ahist.is_array()) { - for(unsigned long j=0;j<ahist.size();++j) { - json &ah = ahist[j]; - if ((OSUtils::jsonString(ah["ct"],"") == "token")&&(OSUtils::jsonString(ah["c"],"") == tstr)&&(OSUtils::jsonBool(ah["a"],false))) - ++useCount; - } - } - usable = (useCount < maxUses); - } - if (usable) { - authorizedBy = "token"; - autoAuthorized = true; - autoAuthCredentialType = "token"; - autoAuthCredential = tstr; - } - } - } + json authTokens(network["authTokens"]); + json &tokenExpires = authTokens[presentedToken]; + if (tokenExpires.is_number()) { + if ((tokenExpires == 0)||(tokenExpires > now)) { + authorized = true; + autoAuthorized = true; + autoAuthCredentialType = "token"; + autoAuthCredential = presentedToken; } } } @@ -1325,23 +1303,16 @@ void EmbeddedNetworkController::_request( } // If we auto-authorized, update member record - if ((autoAuthorized)&&(authorizedBy)) { + if ((autoAuthorized)&&(authorized)) { member["authorized"] = true; member["lastAuthorizedTime"] = now; - - json ah; - ah["a"] = true; - ah["by"] = authorizedBy; - ah["ts"] = now; - ah["ct"] = autoAuthCredentialType; - ah["c"] = autoAuthCredential; - member["authHistory"].push_back(ah); - + member["lastAuthorizedCredentialType"] = autoAuthCredentialType; + member["lastAuthorizedCredential"] = autoAuthCredential; json &revj = member["revision"]; member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL); } - if (authorizedBy) { + if (authorized) { // Update version info and meta-data if authorized and if this is a genuine request if (requestPacketId) { const uint64_t vMajor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,0); @@ -1420,7 +1391,7 @@ void EmbeddedNetworkController::_request( if (rtt.length() == 10) { nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str())); } else { - nc->remoteTraceTarget = _signingId.address(); + nc->remoteTraceTarget.zero(); } } diff --git a/controller/EmbeddedNetworkController.hpp b/controller/EmbeddedNetworkController.hpp index 8752922e..d1217d60 100644 --- a/controller/EmbeddedNetworkController.hpp +++ b/controller/EmbeddedNetworkController.hpp @@ -93,6 +93,11 @@ public: void handleRemoteTrace(const ZT_RemoteTrace &rt); + // Called on update via POST or by JSONDB on external update of network or network member records + void onNetworkUpdate(const uint64_t networkId); + void onNetworkMemberUpdate(const uint64_t networkId,const uint64_t memberId); + void onNetworkMemberDeauthorize(const uint64_t networkId,const uint64_t memberId); + void threadMain() throw(); @@ -129,7 +134,6 @@ private: inline void _initMember(nlohmann::json &member) { if (!member.count("authorized")) member["authorized"] = false; - if (!member.count("authHistory")) member["authHistory"] = nlohmann::json::array(); if (!member.count("ipAssignments")) member["ipAssignments"] = nlohmann::json::array(); if (!member.count("activeBridge")) member["activeBridge"] = false; if (!member.count("tags")) member["tags"] = nlohmann::json::array(); @@ -139,6 +143,8 @@ private: if (!member.count("revision")) member["revision"] = 0ULL; if (!member.count("lastDeauthorizedTime")) member["lastDeauthorizedTime"] = 0ULL; if (!member.count("lastAuthorizedTime")) member["lastAuthorizedTime"] = 0ULL; + if (!member.count("lastAuthorizedCredentialType")) member["lastAuthorizedCredentialType"] = nlohmann::json(); + if (!member.count("lastAuthorizedCredential")) member["lastAuthorizedCredential"] = nlohmann::json(); if (!member.count("vMajor")) member["vMajor"] = -1; if (!member.count("vMinor")) member["vMinor"] = -1; if (!member.count("vRev")) member["vRev"] = -1; @@ -156,7 +162,7 @@ private: if (!network.count("enableBroadcast")) network["enableBroadcast"] = true; if (!network.count("v4AssignMode")) network["v4AssignMode"] = {{"zt",false}}; if (!network.count("v6AssignMode")) network["v6AssignMode"] = {{"rfc4193",false},{"zt",false},{"6plane",false}}; - if (!network.count("authTokens")) network["authTokens"] = nlohmann::json::array(); + if (!network.count("authTokens")) network["authTokens"] = {{}}; if (!network.count("capabilities")) network["capabilities"] = nlohmann::json::array(); if (!network.count("tags")) network["tags"] = nlohmann::json::array(); if (!network.count("routes")) network["routes"] = nlohmann::json::array(); diff --git a/controller/JSONDB.cpp b/controller/JSONDB.cpp index 4b6824c2..f362acf3 100644 --- a/controller/JSONDB.cpp +++ b/controller/JSONDB.cpp @@ -29,75 +29,44 @@ #endif #include "JSONDB.hpp" - -#define ZT_JSONDB_HTTP_TIMEOUT 60000 +#include "EmbeddedNetworkController.hpp" namespace ZeroTier { static const nlohmann::json _EMPTY_JSON(nlohmann::json::object()); -static const std::map<std::string,std::string> _ZT_JSONDB_GET_HEADERS; -JSONDB::JSONDB(const std::string &basePath) : +JSONDB::JSONDB(const std::string &basePath,EmbeddedNetworkController *parent) : + _parent(parent), _basePath(basePath), _rawInput(-1), _rawOutput(-1), _summaryThreadRun(true), _dataReady(false) { - if ((_basePath.length() > 7)&&(_basePath.substr(0,7) == "http://")) { - // If base path is http:// we run in HTTP mode - // TODO: this doesn't yet support IPv6 since bracketed address notiation isn't supported. - // Typically it's just used with 127.0.0.1 anyway. - std::string hn = _basePath.substr(7); - std::size_t hnend = hn.find_first_of('/'); - if (hnend != std::string::npos) - hn = hn.substr(0,hnend); - std::size_t hnsep = hn.find_last_of(':'); - if (hnsep != std::string::npos) - hn[hnsep] = '/'; - _httpAddr.fromString(hn.c_str()); - if (hnend != std::string::npos) - _basePath = _basePath.substr(7 + hnend); - if (_basePath.length() == 0) - _basePath = "/"; - if (_basePath[0] != '/') - _basePath = std::string("/") + _basePath; #ifndef __WINDOWS__ - } else if (_basePath == "-") { - // If base path is "-" we run in stdin/stdout mode and expect our database to be populated on startup via stdin - // Not supported on Windows + if (_basePath == "-") { + // If base path is "-" we run in Central harnessed mode. We read pseudo-http-requests from stdin and write + // them to stdout. _rawInput = STDIN_FILENO; _rawOutput = STDOUT_FILENO; fcntl(_rawInput,F_SETFL,O_NONBLOCK); -#endif } else { +#endif // Default mode of operation is to store files in the filesystem OSUtils::mkdir(_basePath.c_str()); OSUtils::lockDownFile(_basePath.c_str(),true); // networks might contain auth tokens, etc., so restrict directory permissions +#ifndef __WINDOWS__ } +#endif _networks_m.lock(); // locked until data is loaded, etc. if (_rawInput < 0) { - unsigned int cnt = 0; - while (!_load(_basePath)) { - if ((++cnt & 7) == 0) - fprintf(stderr,"WARNING: controller still waiting to read '%s'..." ZT_EOL_S,_basePath.c_str()); - Thread::sleep(250); - } - - for(std::unordered_map<uint64_t,_NW>::iterator n(_networks.begin());n!=_networks.end();++n) - _summaryThreadToDo.push_back(n->first); - - if (_summaryThreadToDo.size() > 0) { - _summaryThread = Thread::start(this); - } else { - _dataReady = true; - _networks_m.unlock(); - } + _load(basePath); + _dataReady = true; + _networks_m.unlock(); } else { - // In IPC mode we wait for the first message to start, and we start - // this thread since this thread is responsible for reading from stdin. + // In harnessed mode we leave the lock locked and wait for our initial DB from Central. _summaryThread = Thread::start(this); } } @@ -128,16 +97,6 @@ bool JSONDB::writeRaw(const std::string &n,const std::string &obj) } else return true; #endif return false; - } else if (_httpAddr) { - std::map<std::string,std::string> headers; - std::string body; - std::map<std::string,std::string> reqHeaders; - char tmp[64]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%lu",(unsigned long)obj.length()); - reqHeaders["Content-Length"] = tmp; - reqHeaders["Content-Type"] = "application/json"; - const unsigned int sc = Http::PUT(0,ZT_JSONDB_HTTP_TIMEOUT,reinterpret_cast<const struct sockaddr *>(&_httpAddr),(_basePath+"/"+n).c_str(),reqHeaders,obj.data(),(unsigned long)obj.length(),headers,body); - return (sc == 200); } else { const std::string path(_genPath(n,true)); if (!path.length()) @@ -207,7 +166,8 @@ void JSONDB::saveNetwork(const uint64_t networkId,const nlohmann::json &networkC writeRaw(n,OSUtils::jsonDump(networkConfig,-1)); { Mutex::Lock _l(_networks_m); - _networks[networkId].config = nlohmann::json::to_msgpack(networkConfig); + _NW &nw = _networks[networkId]; + nw.config = nlohmann::json::to_msgpack(networkConfig); } _recomputeSummaryInfo(networkId); } @@ -219,7 +179,8 @@ void JSONDB::saveNetworkMember(const uint64_t networkId,const uint64_t nodeId,co writeRaw(n,OSUtils::jsonDump(memberConfig,-1)); { Mutex::Lock _l(_networks_m); - _networks[networkId].members[nodeId] = nlohmann::json::to_msgpack(memberConfig); + std::vector<uint8_t> &m = _networks[networkId].members[nodeId]; + m = nlohmann::json::to_msgpack(memberConfig); _members[nodeId].insert(networkId); } _recomputeSummaryInfo(networkId); @@ -227,7 +188,10 @@ void JSONDB::saveNetworkMember(const uint64_t networkId,const uint64_t nodeId,co nlohmann::json JSONDB::eraseNetwork(const uint64_t networkId) { - if (!_httpAddr) { // Member deletion is done by Central in harnessed mode, and deleting the cache network entry also deletes all members + if (_rawOutput >= 0) { + // In harnessed mode, DB deletes occur in the Central database and we do + // not need to erase files. + } else { std::vector<uint64_t> memberIds; { Mutex::Lock _l(_networks_m); @@ -239,24 +203,15 @@ nlohmann::json JSONDB::eraseNetwork(const uint64_t networkId) } for(std::vector<uint64_t>::iterator m(memberIds.begin());m!=memberIds.end();++m) eraseNetworkMember(networkId,*m,false); - } - char n[256]; - OSUtils::ztsnprintf(n,sizeof(n),"network/%.16llx",(unsigned long long)networkId); - - if (_rawOutput >= 0) { - // In harnessed mode, deletes occur in Central or other management - // software and do not need to be executed this way. - } else if (_httpAddr) { - std::map<std::string,std::string> headers; - std::string body; - Http::DEL(0,ZT_JSONDB_HTTP_TIMEOUT,reinterpret_cast<const struct sockaddr *>(&_httpAddr),(_basePath+"/"+n).c_str(),_ZT_JSONDB_GET_HEADERS,headers,body); - } else { + char n[256]; + OSUtils::ztsnprintf(n,sizeof(n),"network/%.16llx",(unsigned long long)networkId); const std::string path(_genPath(n,false)); if (path.length()) OSUtils::rm(path.c_str()); } + // This also erases all members from the memory cache { Mutex::Lock _l(_networks_m); std::unordered_map<uint64_t,_NW>::iterator i(_networks.find(networkId)); @@ -270,17 +225,11 @@ nlohmann::json JSONDB::eraseNetwork(const uint64_t networkId) nlohmann::json JSONDB::eraseNetworkMember(const uint64_t networkId,const uint64_t nodeId,bool recomputeSummaryInfo) { - char n[256]; - OSUtils::ztsnprintf(n,sizeof(n),"network/%.16llx/member/%.10llx",(unsigned long long)networkId,(unsigned long long)nodeId); - if (_rawOutput >= 0) { - // In harnessed mode, deletes occur in Central or other management - // software and do not need to be executed this way. - } else if (_httpAddr) { - std::map<std::string,std::string> headers; - std::string body; - Http::DEL(0,ZT_JSONDB_HTTP_TIMEOUT,reinterpret_cast<const struct sockaddr *>(&_httpAddr),(_basePath+"/"+n).c_str(),_ZT_JSONDB_GET_HEADERS,headers,body); + // In harnessed mode, DB deletes occur in Central and we do not remove files. } else { + char n[256]; + OSUtils::ztsnprintf(n,sizeof(n),"network/%.16llx/member/%.10llx",(unsigned long long)networkId,(unsigned long long)nodeId); const std::string path(_genPath(n,false)); if (path.length()) OSUtils::rm(path.c_str()); @@ -320,7 +269,6 @@ void JSONDB::threadMain() while (_summaryThreadRun) { #ifndef __WINDOWS__ if (_rawInput < 0) { - // In HTTP and filesystem mode we just wait for summary to-do items Thread::sleep(25); } else { // In IPC mode we wait but also select() on STDIN to read database updates @@ -337,8 +285,8 @@ void JSONDB::threadMain() } else if (rawInputBuf.length() > 0) { try { const nlohmann::json obj(OSUtils::jsonParse(rawInputBuf)); - gotMessage = true; + if (!_dataReady) { _dataReady = true; _networks_m.unlock(); @@ -346,11 +294,12 @@ void JSONDB::threadMain() if (obj.is_array()) { for(unsigned long i=0;i<obj.size();++i) - _add(obj[i]); + _addOrUpdate(obj[i]); } else if (obj.is_object()) { - _add(obj); + _addOrUpdate(obj); } } catch ( ... ) {} // ignore malformed JSON + rawInputBuf.clear(); } } @@ -369,7 +318,7 @@ void JSONDB::threadMain() else _summaryThreadToDo.swap(todo); } - if (!_dataReady) { + if (!_dataReady) { // sanity check _dataReady = true; _networks_m.unlock(); } @@ -450,29 +399,71 @@ void JSONDB::threadMain() #endif } -bool JSONDB::_add(const nlohmann::json &j) +bool JSONDB::_addOrUpdate(const nlohmann::json &j) { try { if (j.is_object()) { std::string id(OSUtils::jsonString(j["id"],"0")); - std::string objtype(OSUtils::jsonString(j["objtype"],"")); - + const std::string objtype(OSUtils::jsonString(j["objtype"],"")); if ((id.length() == 16)&&(objtype == "network")) { + const uint64_t nwid = Utils::hexStrToU64(id.c_str()); if (nwid) { - Mutex::Lock _l(_networks_m); - _networks[nwid].config = nlohmann::json::to_msgpack(j); + bool update; + { + Mutex::Lock _l(_networks_m); + _NW &nw = _networks[nwid]; + update = !nw.config.empty(); + nw.config = nlohmann::json::to_msgpack(j); + } + if (update) + _parent->onNetworkUpdate(nwid); + _recomputeSummaryInfo(nwid); return true; } + } else if ((id.length() == 10)&&(objtype == "member")) { + const uint64_t mid = Utils::hexStrToU64(id.c_str()); const uint64_t nwid = Utils::hexStrToU64(OSUtils::jsonString(j["nwid"],"0").c_str()); if ((mid)&&(nwid)) { - Mutex::Lock _l(_networks_m); - _networks[nwid].members[mid] = nlohmann::json::to_msgpack(j); - _members[mid].insert(nwid); + bool update = false; + bool deauth = false; + { + Mutex::Lock _l(_networks_m); + std::vector<uint8_t> &m = _networks[nwid].members[mid]; + if (!m.empty()) { + update = true; + nlohmann::json oldm(nlohmann::json::from_msgpack(m)); + deauth = ((OSUtils::jsonBool(oldm["authorized"],false))&&(!OSUtils::jsonBool(j["authorized"],false))); + } + m = nlohmann::json::to_msgpack(j); + _members[mid].insert(nwid); + } + if (update) { + _parent->onNetworkMemberUpdate(nwid,mid); + if (deauth) + _parent->onNetworkMemberDeauthorize(nwid,mid); + } + _recomputeSummaryInfo(nwid); return true; } + + } else if (objtype == "_delete") { // pseudo-object-type, only used in Central harnessed mode + + const std::string deleteType(OSUtils::jsonString(j["deleteType"],"")); + id = OSUtils::jsonString(j["deleteId"],""); + if ((deleteType == "network")&&(id.length() == 16)) { + eraseNetwork(Utils::hexStrToU64(id.c_str())); + } else if ((deleteType == "member")&&(id.length() == 10)) { + const std::string networkId(OSUtils::jsonString(j["deleteNetworkId"],"")); + const uint64_t nwid = Utils::hexStrToU64(networkId.c_str()); + const uint64_t mid = Utils::hexStrToU64(id.c_str()); + if (networkId.length() == 16) + eraseNetworkMember(nwid,mid,true); + _parent->onNetworkMemberDeauthorize(nwid,mid); + } + } } } catch ( ... ) {} @@ -484,48 +475,21 @@ bool JSONDB::_load(const std::string &p) // This is not used in stdin/stdout mode. Instead data is populated by // sending it all to stdin. - if (_httpAddr) { - // In HTTP harnessed mode we download our entire working data set on startup. - - std::string body; - std::map<std::string,std::string> headers; - const unsigned int sc = Http::GET(0,ZT_JSONDB_HTTP_TIMEOUT,reinterpret_cast<const struct sockaddr *>(&_httpAddr),_basePath.c_str(),_ZT_JSONDB_GET_HEADERS,headers,body); - if (sc == 200) { - try { - nlohmann::json dbImg(OSUtils::jsonParse(body)); - std::string tmp; - if (dbImg.is_object()) { - Mutex::Lock _l(_networks_m); - for(nlohmann::json::iterator i(dbImg.begin());i!=dbImg.end();++i) { - try { - _add(i.value()); - } catch ( ... ) {} - } - return true; - } - } catch ( ... ) {} // invalid JSON, so maybe incomplete request - } - return false; - - } else { - // In regular mode we recursively read it from controller.d/ on disk - - std::vector<std::string> dl(OSUtils::listDirectory(p.c_str(),true)); - for(std::vector<std::string>::const_iterator di(dl.begin());di!=dl.end();++di) { - if ((di->length() > 5)&&(di->substr(di->length() - 5) == ".json")) { - std::string buf; - if (OSUtils::readFile((p + ZT_PATH_SEPARATOR_S + *di).c_str(),buf)) { - try { - _add(OSUtils::jsonParse(buf)); - } catch ( ... ) {} - } - } else { - this->_load((p + ZT_PATH_SEPARATOR_S + *di)); + std::vector<std::string> dl(OSUtils::listDirectory(p.c_str(),true)); + for(std::vector<std::string>::const_iterator di(dl.begin());di!=dl.end();++di) { + if ((di->length() > 5)&&(di->substr(di->length() - 5) == ".json")) { + std::string buf; + if (OSUtils::readFile((p + ZT_PATH_SEPARATOR_S + *di).c_str(),buf)) { + try { + _addOrUpdate(OSUtils::jsonParse(buf)); + } catch ( ... ) {} } + } else { + this->_load((p + ZT_PATH_SEPARATOR_S + *di)); } - return true; - } + + return true; } void JSONDB::_recomputeSummaryInfo(const uint64_t networkId) @@ -543,23 +507,15 @@ std::string JSONDB::_genPath(const std::string &n,bool create) if (pt.size() == 0) return std::string(); - char sep; - if (_httpAddr) { - sep = '/'; - create = false; - } else { - sep = ZT_PATH_SEPARATOR; - } - std::string p(_basePath); if (create) OSUtils::mkdir(p.c_str()); for(unsigned long i=0,j=(unsigned long)(pt.size()-1);i<j;++i) { - p.push_back(sep); + p.push_back(ZT_PATH_SEPARATOR); p.append(pt[i]); if (create) OSUtils::mkdir(p.c_str()); } - p.push_back(sep); + p.push_back(ZT_PATH_SEPARATOR); p.append(pt[pt.size()-1]); p.append(".json"); diff --git a/controller/JSONDB.hpp b/controller/JSONDB.hpp index 7131b0c1..44f4d7f5 100644 --- a/controller/JSONDB.hpp +++ b/controller/JSONDB.hpp @@ -37,11 +37,12 @@ #include "../node/Mutex.hpp" #include "../ext/json/json.hpp" #include "../osdep/OSUtils.hpp" -#include "../osdep/Http.hpp" #include "../osdep/Thread.hpp" namespace ZeroTier { +class EmbeddedNetworkController; + /** * Hierarchical JSON store that persists into the filesystem or via HTTP */ @@ -59,7 +60,7 @@ public: uint64_t mostRecentDeauthTime; }; - JSONDB(const std::string &basePath); + JSONDB(const std::string &basePath,EmbeddedNetworkController *parent); ~JSONDB(); /** @@ -156,13 +157,13 @@ public: throw(); private: - bool _add(const nlohmann::json &j); + bool _addOrUpdate(const nlohmann::json &j); bool _load(const std::string &p); void _recomputeSummaryInfo(const uint64_t networkId); std::string _genPath(const std::string &n,bool create); + EmbeddedNetworkController *const _parent; std::string _basePath; - InetAddress _httpAddr; int _rawInput,_rawOutput; Mutex _rawLock; diff --git a/make-linux.mk b/make-linux.mk index 8b0082aa..4ef590a4 100644 --- a/make-linux.mk +++ b/make-linux.mk @@ -213,12 +213,6 @@ endif all: one -#ext/x64-salsa2012-asm/salsa2012.o: -# $(CC) -c ext/x64-salsa2012-asm/salsa2012.s -o ext/x64-salsa2012-asm/salsa2012.o - -#ext/arm32-neon-salsa2012-asm/salsa2012.o: -# $(CC) -c ext/arm32-neon-salsa2012-asm/salsa2012.s -o ext/arm32-neon-salsa2012-asm/salsa2012.o - one: $(CORE_OBJS) $(ONE_OBJS) one.o $(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(CORE_OBJS) $(ONE_OBJS) one.o $(LDLIBS) $(STRIP) zerotier-one @@ -255,6 +249,9 @@ distclean: clean realclean: distclean +official-static: FORCE + make -j4 ZT_STATIC=1 LDLIBS=/usr/lib/libjemalloc.a all selftest + debug: FORCE make ZT_DEBUG=1 one make ZT_DEBUG=1 selftest diff --git a/node/AtomicCounter.hpp b/node/AtomicCounter.hpp index e1864db8..34b58e91 100644 --- a/node/AtomicCounter.hpp +++ b/node/AtomicCounter.hpp @@ -47,6 +47,15 @@ public: _v = 0; } + inline int load() const + { +#ifdef __GNUC__ + return __sync_or_and_fetch(const_cast<int *>(&_v),0); +#else + return _v.load(); +#endif + } + inline int operator++() { #ifdef __GNUC__ diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index e5e10476..3788708d 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -66,10 +66,9 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr) // packets are dropped on the floor. const uint64_t tpid = trustedPathId(); if (RR->topology->shouldInboundPathBeTrusted(_path->address(),tpid)) { - RR->t->incomingPacketTrustedPath(tPtr,_path,packetId(),sourceAddress,tpid,true); trusted = true; } else { - RR->t->incomingPacketTrustedPath(tPtr,_path,packetId(),sourceAddress,tpid,false); + RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,packetId(),sourceAddress,hops(),"path not trusted"); return true; } } else if ((c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)&&(verb() == Packet::VERB_HELLO)) { @@ -81,7 +80,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr) if (peer) { if (!trusted) { if (!dearmor(peer->key())) { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,packetId(),sourceAddress,hops()); + RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,packetId(),sourceAddress,hops(),"invalid MAC"); return true; } } @@ -246,10 +245,10 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool outp.armor(key,true,_path->nextOutgoingCounter()); _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); } else { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops()); + RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid MAC"); } } else { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops()); + RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid identity"); } return true; @@ -257,7 +256,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool // Identity is the same as the one we already have -- check packet integrity if (!dearmor(peer->key())) { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops()); + RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid MAC"); return true; } @@ -282,7 +281,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool // Check packet integrity and MAC (this is faster than locallyValidate() so do it first to filter out total crap) SharedPtr<Peer> newPeer(new Peer(RR,RR->identity,id)); if (!dearmor(newPeer->key())) { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops()); + RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid MAC"); return true; } diff --git a/node/Membership.cpp b/node/Membership.cpp index a1453307..17de6554 100644 --- a/node/Membership.cpp +++ b/node/Membership.cpp @@ -147,7 +147,6 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme return ADD_REJECTED; case 0: _com = com; - RR->t->credentialAccepted(tPtr,com); return ADD_ACCEPTED_NEW; case 1: return ADD_DEFERRED_FOR_WHOIS; @@ -179,7 +178,6 @@ static Membership::AddCredentialResult _addCredImpl(Hashtable<uint32_t,C> &remot RR->t->credentialRejected(tPtr,cred,"invalid"); return Membership::ADD_REJECTED; case 0: - RR->t->credentialAccepted(tPtr,cred); if (!rc) rc = &(remoteCreds[cred.id()]); *rc = cred; @@ -205,7 +203,6 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme switch(ct) { case Credential::CREDENTIAL_TYPE_COM: if (rev.threshold() > _comRevocationThreshold) { - RR->t->credentialAccepted(tPtr,rev); _comRevocationThreshold = rev.threshold(); return ADD_ACCEPTED_NEW; } diff --git a/node/Node.cpp b/node/Node.cpp index f3339068..366ddbf0 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -100,7 +100,7 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint6 } else { idtmp[0] = RR->identity.address().toInt(); idtmp[1] = 0; n = stateObjectGet(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,tmp,sizeof(tmp) - 1); - if ((n > 0)&&(n < sizeof(RR->publicIdentityStr))&&(n < sizeof(tmp))) { + if ((n > 0)&&(n < (int)sizeof(RR->publicIdentityStr))&&(n < (int)sizeof(tmp))) { if (memcmp(tmp,RR->publicIdentityStr,n)) stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr,(unsigned int)strlen(RR->publicIdentityStr)); } @@ -250,20 +250,23 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,uint64_t now,volatile uint _lastPingCheck = now; // Get networks that need config without leaving mutex locked - std::vector< SharedPtr<Network> > needConfig; { - Mutex::Lock _l(_networks_m); - Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(_networks); - uint64_t *k = (uint64_t *)0; - SharedPtr<Network> *v = (SharedPtr<Network> *)0; - while (i.next(k,v)) { - if (((now - (*v)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!(*v)->hasConfig())) - needConfig.push_back(*v); - (*v)->sendUpdatesToMembers(tptr); + std::vector< std::pair< SharedPtr<Network>,bool > > nwl; + { + Mutex::Lock _l(_networks_m); + nwl.reserve(_networks.size()+1); + Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(_networks); + uint64_t *k = (uint64_t *)0; + SharedPtr<Network> *v = (SharedPtr<Network> *)0; + while (i.next(k,v)) + nwl.push_back( std::pair< SharedPtr<Network>,bool >(*v,(((now - (*v)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!(*v)->hasConfig()))) ); + } + for(std::vector< std::pair< SharedPtr<Network>,bool > >::const_iterator n(nwl.begin());n!=nwl.end();++n) { + if (n->second) + n->first->requestConfiguration(tptr); + n->first->sendUpdatesToMembers(tptr); } } - for(std::vector< SharedPtr<Network> >::const_iterator n(needConfig.begin());n!=needConfig.end();++n) - (*n)->requestConfiguration(tptr); // Do pings and keepalives Hashtable< Address,std::vector<InetAddress> > upstreamsToContact; diff --git a/node/Switch.cpp b/node/Switch.cpp index 9c9daac9..053f793e 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -120,10 +120,8 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre // Total fragments must be more than 1, otherwise why are we // seeing a Packet::Fragment? - Mutex::Lock _l(_rxQueue_m); - RXQueueEntry *const rq = _findRXQueueEntry(now,fragmentPacketId); - - if ((!rq->timestamp)||(rq->packetId != fragmentPacketId)) { + RXQueueEntry *const rq = _findRXQueueEntry(fragmentPacketId); + if (rq->packetId != fragmentPacketId) { // No packet found, so we received a fragment without its head. rq->timestamp = now; @@ -250,10 +248,8 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre ((uint64_t)reinterpret_cast<const uint8_t *>(data)[7]) ); - Mutex::Lock _l(_rxQueue_m); - RXQueueEntry *const rq = _findRXQueueEntry(now,packetId); - - if ((!rq->timestamp)||(rq->packetId != packetId)) { + RXQueueEntry *const rq = _findRXQueueEntry(packetId); + if (rq->packetId != packetId) { // If we have no other fragments yet, create an entry and save the head rq->timestamp = now; @@ -286,14 +282,7 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre // Packet is unfragmented, so just process it IncomingPacket packet(data,len,path,now); if (!packet.tryDecode(RR,tPtr)) { - Mutex::Lock _l(_rxQueue_m); - RXQueueEntry *rq = &(_rxQueue[ZT_RX_QUEUE_SIZE - 1]); - unsigned long i = ZT_RX_QUEUE_SIZE - 1; - while ((i)&&(rq->timestamp)) { - RXQueueEntry *tmp = &(_rxQueue[--i]); - if (tmp->timestamp < rq->timestamp) - rq = tmp; - } + RXQueueEntry *const rq = _nextRXQueueEntry(); rq->timestamp = now; rq->packetId = packet.packetId(); rq->frag0 = packet; @@ -590,15 +579,13 @@ void Switch::doAnythingWaitingForPeer(void *tPtr,const SharedPtr<Peer> &peer) _outstandingWhoisRequests.erase(peer->address()); } - { // finish processing any packets waiting on peer's public key / identity - Mutex::Lock _l(_rxQueue_m); - unsigned long i = ZT_RX_QUEUE_SIZE; - while (i) { - RXQueueEntry *rq = &(_rxQueue[--i]); - if ((rq->timestamp)&&(rq->complete)) { - if (rq->frag0.tryDecode(RR,tPtr)) - rq->timestamp = 0; - } + // finish processing any packets waiting on peer's public key / identity + const uint64_t now = RR->node->now(); + for(unsigned int ptr=0;ptr<ZT_RX_QUEUE_SIZE;++ptr) { + RXQueueEntry *const rq = &(_rxQueue[ptr]); + if ((rq->timestamp)&&(rq->complete)) { + if ((rq->frag0.tryDecode(RR,tPtr))||((now - rq->timestamp) > ZT_RECEIVE_QUEUE_TIMEOUT)) + rq->timestamp = 0; } } diff --git a/node/Switch.hpp b/node/Switch.hpp index 346aaca3..114bc5e1 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -169,25 +169,24 @@ private: bool complete; // if true, packet is complete }; RXQueueEntry _rxQueue[ZT_RX_QUEUE_SIZE]; - Mutex _rxQueue_m; + AtomicCounter _rxQueuePtr; - /* Returns the matching or oldest entry. Caller must check timestamp and - * packet ID to determine which. */ - inline RXQueueEntry *_findRXQueueEntry(uint64_t now,uint64_t packetId) + // Returns matching or next available RX queue entry + inline RXQueueEntry *_findRXQueueEntry(uint64_t packetId) { - RXQueueEntry *rq; - RXQueueEntry *oldest = &(_rxQueue[ZT_RX_QUEUE_SIZE - 1]); - unsigned long i = ZT_RX_QUEUE_SIZE; - while (i) { - rq = &(_rxQueue[--i]); + unsigned int ptr = static_cast<unsigned int>(_rxQueuePtr.load()); + for(unsigned int k=0;k<ZT_RX_QUEUE_SIZE;++k) { + RXQueueEntry *rq = &(_rxQueue[--ptr % ZT_RX_QUEUE_SIZE]); if ((rq->packetId == packetId)&&(rq->timestamp)) return rq; - if ((now - rq->timestamp) >= ZT_RX_QUEUE_EXPIRE) - rq->timestamp = 0; - if (rq->timestamp < oldest->timestamp) - oldest = rq; } - return oldest; + return &(_rxQueue[static_cast<unsigned int>(++_rxQueuePtr) % ZT_RX_QUEUE_SIZE]); + } + + // Returns next RX queue entry in ring buffer and increments ring counter + inline RXQueueEntry *_nextRXQueueEntry() + { + return &(_rxQueue[static_cast<unsigned int>(++_rxQueuePtr) % ZT_RX_QUEUE_SIZE]); } // ZeroTier-layer TX queue entry diff --git a/node/Trace.cpp b/node/Trace.cpp index 98a4adcb..8e78b676 100644 --- a/node/Trace.cpp +++ b/node/Trace.cpp @@ -164,12 +164,7 @@ void Trace::incomingNetworkFrameDropped(void *const tPtr,const SharedPtr<Network _send(tPtr,d,*network); } -void Trace::incomingPacketTrustedPath(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const uint64_t trustedPathId,bool approved) -{ - // TODO -} - -void Trace::incomingPacketMessageAuthenticationFailure(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const unsigned int hops) +void Trace::incomingPacketMessageAuthenticationFailure(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const unsigned int hops,const char *reason) { char tmp[128]; Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d; @@ -179,6 +174,8 @@ void Trace::incomingPacketMessageAuthenticationFailure(void *const tPtr,const Sh d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source); d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp)); d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket()); + if (reason) + d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason); _send(tPtr,d,0); } @@ -344,76 +341,6 @@ void Trace::credentialRejected(void *const tPtr,const Revocation &c,const char * _send(tPtr,d,c.networkId()); } -void Trace::credentialAccepted(void *const tPtr,const CertificateOfMembership &c) -{ - Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP,c.timestamp()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo()); - _send(tPtr,d,c.networkId()); -} - -void Trace::credentialAccepted(void *const tPtr,const CertificateOfOwnership &c) -{ - Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP,c.timestamp()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo()); - _send(tPtr,d,c.networkId()); -} - -void Trace::credentialAccepted(void *const tPtr,const CertificateOfRepresentation &c) -{ - Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP,c.timestamp()); - _send(tPtr,d,0); -} - -void Trace::credentialAccepted(void *const tPtr,const Capability &c) -{ - Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP,c.timestamp()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo()); - _send(tPtr,d,c.networkId()); -} - -void Trace::credentialAccepted(void *const tPtr,const Tag &c) -{ - Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP,c.timestamp()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_INFO,(uint64_t)c.value()); - _send(tPtr,d,c.networkId()); -} - -void Trace::credentialAccepted(void *const tPtr,const Revocation &c) -{ - Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_REVOCATION_TARGET,c.target()); - _send(tPtr,d,c.networkId()); -} - void Trace::_send(void *const tPtr,const Dictionary<ZT_MAX_REMOTE_TRACE_SIZE> &d) { #ifdef ZT_TRACE diff --git a/node/Trace.hpp b/node/Trace.hpp index d66d0871..a7b2b194 100644 --- a/node/Trace.hpp +++ b/node/Trace.hpp @@ -108,8 +108,7 @@ public: void peerLearnedNewPath(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr<Path> &oldPath,const SharedPtr<Path> &newPath,const uint64_t packetId); void peerRedirected(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr<Path> &oldPath,const SharedPtr<Path> &newPath); - void incomingPacketTrustedPath(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const uint64_t trustedPathId,bool approved); - void incomingPacketMessageAuthenticationFailure(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const unsigned int hops); + void incomingPacketMessageAuthenticationFailure(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const unsigned int hops,const char *reason); void incomingPacketInvalid(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const unsigned int hops,const Packet::Verb verb,const char *reason); void incomingPacketDroppedHELLO(void *const tPtr,const SharedPtr<Path> &path,const uint64_t packetId,const Address &source,const char *reason); @@ -142,12 +141,6 @@ public: void credentialRejected(void *const tPtr,const Capability &c,const char *reason); void credentialRejected(void *const tPtr,const Tag &c,const char *reason); void credentialRejected(void *const tPtr,const Revocation &c,const char *reason); - void credentialAccepted(void *const tPtr,const CertificateOfMembership &c); - void credentialAccepted(void *const tPtr,const CertificateOfOwnership &c); - void credentialAccepted(void *const tPtr,const CertificateOfRepresentation &c); - void credentialAccepted(void *const tPtr,const Capability &c); - void credentialAccepted(void *const tPtr,const Tag &c); - void credentialAccepted(void *const tPtr,const Revocation &c); private: const RuntimeEnvironment *const RR; diff --git a/osdep/Binder.hpp b/osdep/Binder.hpp index 17a0fbf6..e3c2dc02 100644 --- a/osdep/Binder.hpp +++ b/osdep/Binder.hpp @@ -227,7 +227,7 @@ public: case InetAddress::IP_SCOPE_GLOBAL: case InetAddress::IP_SCOPE_SHARED: case InetAddress::IP_SCOPE_PRIVATE: - for(int x=0;x<portCount;++x) { + for(int x=0;x<(int)portCount;++x) { ip.setPort(ports[x]); localIfAddrs.insert(std::pair<InetAddress,std::string>(ip,std::string(devname))); } @@ -268,7 +268,7 @@ public: case InetAddress::IP_SCOPE_GLOBAL: case InetAddress::IP_SCOPE_SHARED: case InetAddress::IP_SCOPE_PRIVATE: - for(int x=0;x<portCount;++x) { + for(int x=0;x<(int)portCount;++x) { ip.setPort(ports[x]); localIfAddrs.insert(std::pair<InetAddress,std::string>(ip,ifname)); } @@ -302,7 +302,7 @@ public: case InetAddress::IP_SCOPE_GLOBAL: case InetAddress::IP_SCOPE_SHARED: case InetAddress::IP_SCOPE_PRIVATE: - for(int x=0;x<portCount;++x) { + for(int x=0;x<(int)portCount;++x) { ip.setPort(ports[x]); localIfAddrs.insert(std::pair<InetAddress,std::string>(ip,std::string(ifa->ifa_name))); } diff --git a/service/OneService.cpp b/service/OneService.cpp index 27f2ef3c..c3bf9fee 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -99,8 +99,8 @@ namespace ZeroTier { typedef TestEthernetTap EthernetTap; } #include "../controller/EmbeddedNetworkController.hpp" #include "../node/Node.hpp" // Use the virtual netcon endpoint instead of a tun/tap port driver -#include "../src/SocketTap.hpp" -namespace ZeroTier { typedef SocketTap EthernetTap; } +#include "../src/VirtualTap.hpp" +namespace ZeroTier { typedef VirtualTap EthernetTap; } #else @@ -925,29 +925,15 @@ public: return _homePath; } - virtual EthernetTap * getTap(uint64_t nwid) + std::vector<ZT_VirtualNetworkRoute> *getRoutes(uint64_t nwid) { Mutex::Lock _l(_nets_m); - std::map<uint64_t,NetworkState>::const_iterator n(_nets.find(nwid)); - if (n == _nets.end()) - return NULL; - return n->second.tap; - } - - virtual EthernetTap *getTap(InetAddress &addr) - { - Mutex::Lock _l(_nets_m); - std::map<uint64_t,NetworkState>::iterator it; - for(it = _nets.begin(); it != _nets.end(); it++) { - if(it->second.tap) { - for(int j=0; j<it->second.tap->_ips.size(); j++) { - if(it->second.tap->_ips[j].isEqualPrefix(addr) || it->second.tap->_ips[j].ipsEqual(addr) || it->second.tap->_ips[j].containsAddress(addr)) { - return it->second.tap; - } - } - } + NetworkState &n = _nets[nwid]; + std::vector<ZT_VirtualNetworkRoute> *routes = new std::vector<ZT_VirtualNetworkRoute>(); + for(int i=0; i<ZT_MAX_NETWORK_ROUTES; i++) { + routes->push_back(n.config.routes[i]); } - return NULL; + return routes; } virtual Node *getNode() diff --git a/service/OneService.hpp b/service/OneService.hpp index eba10ca0..b0467419 100644 --- a/service/OneService.hpp +++ b/service/OneService.hpp @@ -35,8 +35,8 @@ #ifdef ZT_SDK #include "../node/Node.hpp" // Use the virtual netcon endpoint instead of a tun/tap port driver -#include "../src/SocketTap.hpp" -namespace ZeroTier { typedef SocketTap EthernetTap; } +#include "../src/VirtualTap.hpp" +namespace ZeroTier { typedef VirtualTap EthernetTap; } #endif namespace ZeroTier { @@ -150,10 +150,9 @@ public: virtual void leave(const char *hp) = 0; virtual void join(const char *hp) = 0; virtual std::string givenHomePath() = 0; - virtual EthernetTap * getTap(uint64_t nwid) = 0; - virtual EthernetTap * getTap(InetAddress &addr) = 0; virtual Node * getNode() = 0; virtual void removeNets() = 0; + virtual std::vector<ZT_VirtualNetworkRoute> *getRoutes(uint64_t nwid) = 0; #endif /** |
