From 7bae95836c8824a76e0299df776a708eb3e58576 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 19 Jun 2015 10:23:25 -0700 Subject: Root server terminology cleanup, and tighten up a security check by checking full identity of peers instead of just address. --- node/Node.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'node/Node.cpp') diff --git a/node/Node.cpp b/node/Node.cpp index 1f6d474c..45e2463c 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -133,9 +133,7 @@ Node::Node( if (!rt.size()) rt.fromString(ZT_DEFAULTS.defaultRootTopology); } - Dictionary rootservers(rt.get("rootservers","")); - rootservers.update(rt.get("supernodes","")); - RR->topology->setRootservers(rootservers); + RR->topology->setRootServers(Dictionary(rt.get("rootservers",""))); postEvent(ZT1_EVENT_UP); } @@ -191,7 +189,7 @@ public: RR(renv), _now(now), _relays(relays), - _rootservers(RR->topology->rootserverAddresses()) + _rootAddresses(RR->topology->rootAddresses()) { } @@ -207,7 +205,7 @@ public: } } - if ((isRelay)||(std::find(_rootservers.begin(),_rootservers.end(),p->address()) != _rootservers.end())) { + if ((isRelay)||(std::find(_rootAddresses.begin(),_rootAddresses.end(),p->address()) != _rootAddresses.end())) { p->doPingAndKeepalive(RR,_now); if (p->lastReceive() > lastReceiveFromUpstream) lastReceiveFromUpstream = p->lastReceive(); @@ -221,7 +219,7 @@ private: const RuntimeEnvironment *RR; uint64_t _now; const std::vector< std::pair > &_relays; - std::vector
_rootservers; + std::vector
_rootAddresses; }; ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline) @@ -262,7 +260,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next } } - // Ping living or rootserver/relay peers + // Ping living or root server/relay peers _PingPeersThatNeedPing pfunc(RR,now,networkRelays); RR->topology->eachPeer<_PingPeersThatNeedPing &>(pfunc); @@ -386,7 +384,7 @@ ZT1_PeerList *Node::peers() const p->versionRev = -1; } p->latency = pi->second->latency(); - p->role = RR->topology->isRootserver(pi->second->address()) ? ZT1_PEER_ROLE_ROOTSERVER : ZT1_PEER_ROLE_LEAF; + p->role = RR->topology->isRoot(pi->second->identity()) ? ZT1_PEER_ROLE_ROOT : ZT1_PEER_ROLE_LEAF; std::vector paths(pi->second->paths()); Path *bestPath = pi->second->getBestPath(_now); -- cgit v1.2.3 From 2b04ac5e9b8be8bd1cc1263755a55a579f28009e Mon Sep 17 00:00:00 2001 From: Moritz Warning Date: Sat, 20 Jun 2015 09:36:51 +0200 Subject: replace _networks map by vector _networks is usually quite small, using binary search on a vector might be faster comapred to std::map. This is especially true when using uClibc++, which uses a list. --- node/Node.cpp | 38 ++++++++++++++++++++++---------------- node/Node.hpp | 23 ++++++++++++++++------- 2 files changed, 38 insertions(+), 23 deletions(-) (limited to 'node/Node.cpp') diff --git a/node/Node.cpp b/node/Node.cpp index 9f195a10..8e00071f 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -236,13 +236,14 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next std::vector< SharedPtr > needConfig; { Mutex::Lock _l(_networks_m); - for(std::map< uint64_t,SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) { - SharedPtr nc(n->second->config2()); - if (((now - n->second->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!nc)) - needConfig.push_back(n->second); + for(std::vector< SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) { + SharedPtr nc((*n)->config2()); + if (((now - (*n)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!nc)) + needConfig.push_back(*n); if (nc) networkRelays.insert(networkRelays.end(),nc->relays().begin(),nc->relays().end()); } + std::sort(_networks.begin(),_networks.end()); } // Request updated configuration for networks that need it @@ -310,19 +311,24 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next ZT1_ResultCode Node::join(uint64_t nwid) { Mutex::Lock _l(_networks_m); - SharedPtr &nwe = _networks[nwid]; - if (!nwe) - nwe = SharedPtr(new Network(RR,nwid)); + std::vector< SharedPtr >::const_iterator nwi = std::lower_bound(_networks.begin(), _networks.end(), nwid, NetworkComparator()); + if(nwi == _networks.end() || (*nwi)->id() != nwid) { + _networks.push_back(SharedPtr(new Network(RR,nwid))); + std::sort(_networks.begin(),_networks.end()); + } return ZT1_RESULT_OK; } ZT1_ResultCode Node::leave(uint64_t nwid) { Mutex::Lock _l(_networks_m); - std::map< uint64_t,SharedPtr >::iterator nw(_networks.find(nwid)); - if (nw != _networks.end()) { - nw->second->destroy(); - _networks.erase(nw); + std::vector< SharedPtr >::iterator nwi = std::lower_bound(_networks.begin(), _networks.end(), nwid, NetworkComparator()); + if(nwi != _networks.end() && (*nwi)->id() == nwid) { + (*nwi)->destroy(); + // erase element (replace by last) + *nwi = _networks.back(); + _networks.pop_back(); + std::sort(_networks.begin(),_networks.end()); } return ZT1_RESULT_OK; } @@ -406,10 +412,10 @@ ZT1_PeerList *Node::peers() const ZT1_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const { Mutex::Lock _l(_networks_m); - std::map< uint64_t,SharedPtr >::const_iterator nw(_networks.find(nwid)); - if (nw != _networks.end()) { + std::vector< SharedPtr >::const_iterator nwi = std::lower_bound(_networks.begin(), _networks.end(), nwid, NetworkComparator()); + if(nwi != _networks.end() && (*nwi)->id() == nwid) { ZT1_VirtualNetworkConfig *nc = (ZT1_VirtualNetworkConfig *)::malloc(sizeof(ZT1_VirtualNetworkConfig)); - nw->second->externalConfig(nc); + (*nwi)->externalConfig(nc); return nc; } return (ZT1_VirtualNetworkConfig *)0; @@ -426,8 +432,8 @@ ZT1_VirtualNetworkList *Node::networks() const nl->networks = (ZT1_VirtualNetworkConfig *)(buf + sizeof(ZT1_VirtualNetworkList)); nl->networkCount = 0; - for(std::map< uint64_t,SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) - n->second->externalConfig(&(nl->networks[nl->networkCount++])); + for(std::vector< SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) + (*n)->externalConfig(&(nl->networks[nl->networkCount++])); return nl; } diff --git a/node/Node.hpp b/node/Node.hpp index 1d9372e4..6ef306eb 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -155,19 +155,21 @@ public: len); } - inline SharedPtr network(uint64_t nwid) + inline SharedPtr network(uint64_t nwid) const { Mutex::Lock _l(_networks_m); - std::map< uint64_t,SharedPtr >::iterator nw(_networks.find(nwid)); - return ((nw == _networks.end()) ? SharedPtr() : nw->second); + std::vector< SharedPtr >::const_iterator iter = std::lower_bound(_networks.begin(), _networks.end(), nwid, NetworkComparator()); + if(iter != _networks.end() && (*iter)->id() == nwid) { + return *iter; + } else { + return SharedPtr(); + } } inline std::vector< SharedPtr > allNetworks() const { Mutex::Lock _l(_networks_m); - std::vector< SharedPtr > nw; - for(std::map< uint64_t,SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) - nw.push_back(n->second); + std::vector< SharedPtr > nw(_networks); return nw; } @@ -208,6 +210,13 @@ public: #endif private: + // for binary search on _networks + struct NetworkComparator { + bool operator()(const SharedPtr &n,uint64_t nwid) const { + return n->id() < nwid; + } + }; + RuntimeEnvironment _RR; RuntimeEnvironment *RR; @@ -223,7 +232,7 @@ private: //Dictionary _localConfig; // persisted as local.conf //Mutex _localConfig_m; - std::map< uint64_t,SharedPtr > _networks; + std::vector< SharedPtr > _networks; Mutex _networks_m; Mutex _backgroundTasksLock; -- cgit v1.2.3 From 787608b5683eb5df2a8ca0d365438234b5497c60 Mon Sep 17 00:00:00 2001 From: Moritz Warning Date: Sat, 20 Jun 2015 16:32:48 +0200 Subject: use _network function to reduce source code complexity --- node/Node.cpp | 10 +++++----- node/Node.hpp | 17 +++++++++++------ 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'node/Node.cpp') diff --git a/node/Node.cpp b/node/Node.cpp index 8e00071f..1dbb6d19 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -311,8 +311,8 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next ZT1_ResultCode Node::join(uint64_t nwid) { Mutex::Lock _l(_networks_m); - std::vector< SharedPtr >::const_iterator nwi = std::lower_bound(_networks.begin(), _networks.end(), nwid, NetworkComparator()); - if(nwi == _networks.end() || (*nwi)->id() != nwid) { + SharedPtr nw = _network(nwid); + if(!nw) { _networks.push_back(SharedPtr(new Network(RR,nwid))); std::sort(_networks.begin(),_networks.end()); } @@ -412,10 +412,10 @@ ZT1_PeerList *Node::peers() const ZT1_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const { Mutex::Lock _l(_networks_m); - std::vector< SharedPtr >::const_iterator nwi = std::lower_bound(_networks.begin(), _networks.end(), nwid, NetworkComparator()); - if(nwi != _networks.end() && (*nwi)->id() == nwid) { + SharedPtr nw = _network(nwid); + if(nw) { ZT1_VirtualNetworkConfig *nc = (ZT1_VirtualNetworkConfig *)::malloc(sizeof(ZT1_VirtualNetworkConfig)); - (*nwi)->externalConfig(nc); + nw->externalConfig(nc); return nc; } return (ZT1_VirtualNetworkConfig *)0; diff --git a/node/Node.hpp b/node/Node.hpp index 6ef306eb..b0f4ab22 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -158,12 +158,7 @@ public: inline SharedPtr network(uint64_t nwid) const { Mutex::Lock _l(_networks_m); - std::vector< SharedPtr >::const_iterator iter = std::lower_bound(_networks.begin(), _networks.end(), nwid, NetworkComparator()); - if(iter != _networks.end() && (*iter)->id() == nwid) { - return *iter; - } else { - return SharedPtr(); - } + return _network(nwid); } inline std::vector< SharedPtr > allNetworks() const @@ -217,6 +212,16 @@ private: } }; + inline SharedPtr _network(uint64_t nwid) const + { + std::vector< SharedPtr >::const_iterator iter = std::lower_bound(_networks.begin(), _networks.end(), nwid, NetworkComparator()); + if(iter != _networks.end() && (*iter)->id() == nwid) { + return *iter; + } else { + return SharedPtr(); + } + } + RuntimeEnvironment _RR; RuntimeEnvironment *RR; -- cgit v1.2.3 From c287ae4d1d0cb6448e556dda2c5c98eee4898cfe Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 26 Jun 2015 11:38:31 -0700 Subject: Redo conversion of _networks to a vector. Just use a simple linear search and put the nwid in a pair with the pointer so linear search can be done without pointer chasing. This should be the fastest option for anything less than dozens of networks, and should save memory over the old map. --- node/Node.cpp | 34 +++++++++++++++------------------- node/Node.hpp | 24 ++++++++++-------------- 2 files changed, 25 insertions(+), 33 deletions(-) (limited to 'node/Node.cpp') diff --git a/node/Node.cpp b/node/Node.cpp index 60aeff1f..85011434 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -141,7 +141,7 @@ Node::Node( Node::~Node() { Mutex::Lock _l(_networks_m); - _networks.clear(); + _networks.clear(); // ensure that networks are destroyed before shutdown delete RR->sa; delete RR->topology; delete RR->antiRec; @@ -236,14 +236,13 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next std::vector< SharedPtr > needConfig; { Mutex::Lock _l(_networks_m); - for(std::vector< SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) { - SharedPtr nc((*n)->config2()); - if (((now - (*n)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!nc)) - needConfig.push_back(*n); + for(std::vector< std::pair< uint64_t,SharedPtr > >::const_iterator n(_networks.begin());n!=_networks.end();++n) { + SharedPtr nc(n->second->config2()); + if (((now - n->second->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!nc)) + needConfig.push_back(n->second); if (nc) networkRelays.insert(networkRelays.end(),nc->relays().begin(),nc->relays().end()); } - std::sort(_networks.begin(),_networks.end()); } // Request updated configuration for networks that need it @@ -312,24 +311,21 @@ ZT1_ResultCode Node::join(uint64_t nwid) { Mutex::Lock _l(_networks_m); SharedPtr nw = _network(nwid); - if(!nw) { - _networks.push_back(SharedPtr(new Network(RR,nwid))); - std::sort(_networks.begin(),_networks.end()); - } + if(!nw) + _networks.push_back(std::pair< uint64_t,SharedPtr >(nwid,SharedPtr(new Network(RR,nwid)))); + std::sort(_networks.begin(),_networks.end()); // will sort by nwid since it's the first in a pair<> return ZT1_RESULT_OK; } ZT1_ResultCode Node::leave(uint64_t nwid) { + std::vector< std::pair< uint64_t,SharedPtr > > newn; Mutex::Lock _l(_networks_m); - std::vector< SharedPtr >::iterator nwi = std::lower_bound(_networks.begin(), _networks.end(), nwid, NetworkComparator()); - if(nwi != _networks.end() && (*nwi)->id() == nwid) { - (*nwi)->destroy(); - // erase element (replace by last) - *nwi = _networks.back(); - _networks.pop_back(); - std::sort(_networks.begin(),_networks.end()); + for(std::vector< std::pair< uint64_t,SharedPtr > >::const_iterator n(_networks.begin());n!=_networks.end();++n) { + if (n->first != nwid) + newn.push_back(*n); } + _networks.swap(newn); return ZT1_RESULT_OK; } @@ -432,8 +428,8 @@ ZT1_VirtualNetworkList *Node::networks() const nl->networks = (ZT1_VirtualNetworkConfig *)(buf + sizeof(ZT1_VirtualNetworkList)); nl->networkCount = 0; - for(std::vector< SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) - (*n)->externalConfig(&(nl->networks[nl->networkCount++])); + for(std::vector< std::pair< uint64_t,SharedPtr > >::const_iterator n(_networks.begin());n!=_networks.end();++n) + n->second->externalConfig(&(nl->networks[nl->networkCount++])); return nl; } diff --git a/node/Node.hpp b/node/Node.hpp index b0f4ab22..2d2898b5 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -163,8 +163,11 @@ public: inline std::vector< SharedPtr > allNetworks() const { + std::vector< SharedPtr > nw; Mutex::Lock _l(_networks_m); - std::vector< SharedPtr > nw(_networks); + nw.reserve(_networks.size()); + for(std::vector< std::pair< uint64_t, SharedPtr > >::const_iterator i=_networks.begin();i!=_networks.end();++i) + nw.push_back(i->second); return nw; } @@ -205,21 +208,14 @@ public: #endif private: - // for binary search on _networks - struct NetworkComparator { - bool operator()(const SharedPtr &n,uint64_t nwid) const { - return n->id() < nwid; - } - }; - inline SharedPtr _network(uint64_t nwid) const { - std::vector< SharedPtr >::const_iterator iter = std::lower_bound(_networks.begin(), _networks.end(), nwid, NetworkComparator()); - if(iter != _networks.end() && (*iter)->id() == nwid) { - return *iter; - } else { - return SharedPtr(); + // assumes _networks_m is locked + for(std::vector< std::pair< uint64_t, SharedPtr > >::const_iterator i=_networks.begin();i!=_networks.end();++i) { + if (i->first == nwid) + return i->second; } + return SharedPtr(); } RuntimeEnvironment _RR; @@ -237,7 +233,7 @@ private: //Dictionary _localConfig; // persisted as local.conf //Mutex _localConfig_m; - std::vector< SharedPtr > _networks; + std::vector< std::pair< uint64_t, SharedPtr > > _networks; Mutex _networks_m; Mutex _backgroundTasksLock; -- cgit v1.2.3