Browse Source

Fix evil bug, and instrument/assert on some other stuff, and a bit of cleanup.

Adam Ierymenko 9 năm trước cách đây
mục cha
commit
1b4cc4af5c
5 tập tin đã thay đổi với 46 bổ sung35 xóa
  1. 1 1
      node/Cluster.cpp
  2. 0 2
      node/Hashtable.hpp
  3. 18 15
      node/Topology.cpp
  4. 2 14
      node/Topology.hpp
  5. 25 3
      selftest.cpp

+ 1 - 1
node/Cluster.cpp

@@ -476,7 +476,7 @@ struct _ClusterAnnouncePeers
 	_ClusterAnnouncePeers(const uint64_t now_,Cluster *parent_) : now(now_),parent(parent_) {}
 	const uint64_t now;
 	Cluster *const parent;
-	inline void operator()(const Topology &t,const SharedPtr<Peer> &peer)
+	inline void operator()(const Topology &t,const SharedPtr<Peer> &peer) const
 	{
 		Path *p = peer->getBestPath(now);
 		if (p)

+ 0 - 2
node/Hashtable.hpp

@@ -322,7 +322,6 @@ public:
 		b->next = _t[bidx];
 		_t[bidx] = b;
 		++_s;
-
 		return b->v;
 	}
 
@@ -351,7 +350,6 @@ public:
 		b->next = _t[bidx];
 		_t[bidx] = b;
 		++_s;
-
 		return b->v;
 	}
 

+ 18 - 15
node/Topology.cpp

@@ -65,7 +65,7 @@ Topology::Topology(const RuntimeEnvironment *renv) :
 			if (!p)
 				break; // stop if invalid records
 			if (p->address() != RR->identity.address())
-				_peers[p->address()] = p;
+				_peers.set(p->address(),p);
 		} catch ( ... ) {
 			break; // stop if invalid records
 		}
@@ -122,7 +122,9 @@ SharedPtr<Peer> Topology::addPeer(const SharedPtr<Peer> &peer)
 {
 #ifdef ZT_TRACE
 	if ((!peer)||(peer->address() == RR->identity.address())) {
-		TRACE("BUG: addPeer() caught and ignored attempt to add peer for self or add a NULL peer");
+		if (!peer)
+			fprintf(stderr,"FATAL BUG: addPeer() caught attempt to add NULL peer"ZT_EOL_S);
+		else fprintf(stderr,"FATAL BUG: addPeer() caught attempt to add peer for self"ZT_EOL_S);
 		abort();
 	}
 #endif
@@ -171,7 +173,10 @@ SharedPtr<Peer> Topology::getPeer(const Address &zta)
 				return ap;
 			}
 		}
-	} catch ( ... ) {} // invalid identity on disk?
+	} catch ( ... ) {
+		fprintf(stderr,"EXCEPTION in getPeer() part 2\n");
+		abort();
+	} // invalid identity on disk?
 
 	return SharedPtr<Peer>();
 }
@@ -180,9 +185,9 @@ Identity Topology::getIdentity(const Address &zta)
 {
 	{
 		Mutex::Lock _l(_lock);
-		SharedPtr<Peer> &ap = _peers[zta];
+		const SharedPtr<Peer> *const ap = _peers.get(zta);
 		if (ap)
-			return ap->identity();
+			return (*ap)->identity();
 	}
 	return _getIdentity(zta);
 }
@@ -207,18 +212,16 @@ SharedPtr<Peer> Topology::getBestRoot(const Address *avoid,unsigned int avoidCou
 		 * causes packets searching for a route to pretty much literally
 		 * circumnavigate the globe rather than bouncing between just two. */
 
-		if (_rootAddresses.size() > 1) { // gotta be one other than me for this to work
-			for(unsigned long p=0;p<_rootAddresses.size();++p) {
-				if (_rootAddresses[p] == RR->identity.address()) {
-					for(unsigned long q=1;q<_rootAddresses.size();++q) {
-						SharedPtr<Peer> *nextsn = _peers.get(_rootAddresses[(p + q) % _rootAddresses.size()]);
-						if ((nextsn)&&((*nextsn)->hasActiveDirectPath(now))) {
-							(*nextsn)->use(now);
-							return *nextsn;
-						}
+		for(unsigned long p=0;p<_rootAddresses.size();++p) {
+			if (_rootAddresses[p] == RR->identity.address()) {
+				for(unsigned long q=1;q<_rootAddresses.size();++q) {
+					const SharedPtr<Peer> *const nextsn = _peers.get(_rootAddresses[(p + q) % _rootAddresses.size()]);
+					if ((nextsn)&&((*nextsn)->hasActiveDirectPath(now))) {
+						(*nextsn)->use(now);
+						return *nextsn;
 					}
-					break;
 				}
+				break;
 			}
 		}
 

+ 2 - 14
node/Topology.hpp

@@ -113,24 +113,12 @@ public:
 	 */
 	void saveIdentity(const Identity &id);
 
-	/**
-	 * @return Vector of peers that are root servers
-	 */
-	inline std::vector< SharedPtr<Peer> > rootPeers() const
-	{
-		Mutex::Lock _l(_lock);
-		return _rootPeers;
-	}
-
 	/**
 	 * Get the current favorite root server
 	 *
 	 * @return Root server with lowest latency or NULL if none
 	 */
-	inline SharedPtr<Peer> getBestRoot()
-	{
-		return getBestRoot((const Address *)0,0,false);
-	}
+	inline SharedPtr<Peer> getBestRoot() { return getBestRoot((const Address *)0,0,false); }
 
 	/**
 	 * Get the best root server, avoiding root servers listed in an array
@@ -237,7 +225,7 @@ public:
 		while (i.next(a,p)) {
 #ifdef ZT_TRACE
 			if (!(*p)) {
-				fprintf(stderr,"FATAL BUG: eachPeer() caught NULL peer for %s -- peer pointers in Topology should NEVER be NULL",a->toString().c_str());
+				fprintf(stderr,"FATAL BUG: eachPeer() caught NULL peer for %s -- peer pointers in Topology should NEVER be NULL"ZT_EOL_S,a->toString().c_str());
 				abort();
 			}
 #endif

+ 25 - 3
selftest.cpp

@@ -593,23 +593,44 @@ static int testOther()
 	std::cout << "[other] Testing Hashtable... "; std::cout.flush();
 	{
 		Hashtable<uint64_t,std::string> ht;
-		Hashtable<uint64_t,std::string> ht2;
 		std::map<uint64_t,std::string> ref; // assume std::map works correctly :)
 		for(int x=0;x<2;++x) {
-			for(int i=0;i<25000;++i) {
+			for(int i=0;i<77777;++i) {
 				uint64_t k = rand();
 				while ((k == 0)||(ref.count(k) > 0))
 					++k;
 				std::string v("!");
 				for(int j=0;j<(int)(k % 64);++j)
 					v.push_back("0123456789"[rand() % 10]);
-				ht.set(k,v);
 				ref[k] = v;
+				ht.set(0xffffffffffffffffULL,v);
+				std::string &vref = ht[k];
+				vref = v;
+				ht.erase(0xffffffffffffffffULL);
 			}
 			if (ht.size() != ref.size()) {
 				std::cout << "FAILED! (size mismatch, original)" << std::endl;
 				return -1;
 			}
+			{
+				Hashtable<uint64_t,std::string>::Iterator i(ht);
+				uint64_t *k = (uint64_t *)0;
+				std::string *v = (std::string *)0;
+				while(i.next(k,v)) {
+					if (ref.find(*k)->second != *v) {
+						std::cout << "FAILED! (data mismatch!)" << std::endl;
+						return -1;
+					}
+				}
+			}
+			for(std::map<uint64_t,std::string>::const_iterator i(ref.begin());i!=ref.end();++i) {
+				if (ht[i->first] != i->second) {
+					std::cout << "FAILED! (data mismatch!)" << std::endl;
+					return -1;
+				}
+			}
+
+			Hashtable<uint64_t,std::string> ht2;
 			ht2 = ht;
 			Hashtable<uint64_t,std::string> ht3(ht2);
 			if (ht2.size() != ref.size()) {
@@ -620,6 +641,7 @@ static int testOther()
 				std::cout << "FAILED! (size mismatch, copied)" << std::endl;
 				return -1;
 			}
+
 			for(std::map<uint64_t,std::string>::iterator i(ref.begin());i!=ref.end();++i) {
 				std::string *v = ht.get(i->first);
 				if (!v) {