Explorar el Código

Permanently retire peers.persist, but make iddb.d always enabled instead since identities are what we really want to cache.

Adam Ierymenko hace 11 años
padre
commit
2416491cbc
Se han modificado 6 ficheros con 72 adiciones y 258 borrados
  1. 6 38
      node/IncomingPacket.cpp
  2. 14 2
      node/Node.cpp
  3. 4 4
      node/Peer.cpp
  4. 2 60
      node/Peer.hpp
  5. 38 127
      node/Topology.cpp
  6. 8 27
      node/Topology.hpp

+ 6 - 38
node/IncomingPacket.cpp

@@ -181,12 +181,8 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
 			return true;
 		}
 
-		// Do we already have this peer?
 		SharedPtr<Peer> peer(RR->topology->getPeer(id.address()));
 		if (peer) {
-			// Check to make sure this isn't a colliding identity (different key,
-			// but same address). The odds are spectacularly low but it could happen.
-			// Could also be a sign of someone doing something nasty.
 			if (peer->identity() != id) {
 				unsigned char key[ZT_PEER_SECRET_KEY_LENGTH];
 				if (RR->identity.agree(id,key,ZT_PEER_SECRET_KEY_LENGTH)) {
@@ -208,33 +204,8 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
 			} else if (!dearmor(peer->key())) {
 				LOG("rejected HELLO from %s(%s): packet failed authentication",source().toString().c_str(),_remoteAddress.toString().c_str());
 				return true;
-			} // else continue and respond
+			}
 		} else {
-			// If we don't have a peer record on file, check the identity cache (if
-			// we have one) to see if we have a cached identity. Then check that for
-			// collision before adding a new peer.
-			Identity alreadyHaveCachedId(RR->topology->getIdentity(id.address()));
-			if ((alreadyHaveCachedId)&&(id != alreadyHaveCachedId)) {
-				unsigned char key[ZT_PEER_SECRET_KEY_LENGTH];
-				if (RR->identity.agree(id,key,ZT_PEER_SECRET_KEY_LENGTH)) {
-					if (dearmor(key)) { // ensure packet is authentic, otherwise drop
-						LOG("rejected HELLO from %s(%s): address already claimed",source().toString().c_str(),_remoteAddress.toString().c_str());
-						Packet outp(source(),RR->identity.address(),Packet::VERB_ERROR);
-						outp.append((unsigned char)Packet::VERB_HELLO);
-						outp.append(packetId());
-						outp.append((unsigned char)Packet::ERROR_IDENTITY_COLLISION);
-						outp.armor(key,true);
-						_fromSock->send(_remoteAddress,outp.data(),outp.size());
-					} else {
-						LOG("rejected HELLO from %s(%s): packet failed authentication",source().toString().c_str(),_remoteAddress.toString().c_str());
-					}
-				} else {
-					LOG("rejected HELLO from %s(%s): key agreement failed",source().toString().c_str(),_remoteAddress.toString().c_str());
-				}
-				return true;
-			} // else continue since identity is already known and matches
-
-			// If this is a new peer, learn it
 			SharedPtr<Peer> newPeer(new Peer(RR->identity,id));
 			if (!dearmor(newPeer->key())) {
 				LOG("rejected HELLO from %s(%s): packet failed authentication",source().toString().c_str(),_remoteAddress.toString().c_str());
@@ -376,29 +347,26 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
 {
 	try {
 		if (payloadLength() == ZT_ADDRESS_LENGTH) {
-			Identity id(RR->topology->getIdentity(Address(payload(),ZT_ADDRESS_LENGTH)));
-			if (id) {
-				Packet outp(source(),RR->identity.address(),Packet::VERB_OK);
+			SharedPtr<Peer> queried(RR->topology->getPeer(Address(payload(),ZT_ADDRESS_LENGTH)));
+			if (queried) {
+				Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
 				outp.append((unsigned char)Packet::VERB_WHOIS);
 				outp.append(packetId());
-				id.serialize(outp,false);
+				queried->identity().serialize(outp,false);
 				outp.armor(peer->key(),true);
 				_fromSock->send(_remoteAddress,outp.data(),outp.size());
-				//TRACE("sent WHOIS response to %s for %s",source().toString().c_str(),Address(payload(),ZT_ADDRESS_LENGTH).toString().c_str());
 			} else {
-				Packet outp(source(),RR->identity.address(),Packet::VERB_ERROR);
+				Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
 				outp.append((unsigned char)Packet::VERB_WHOIS);
 				outp.append(packetId());
 				outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
 				outp.append(payload(),ZT_ADDRESS_LENGTH);
 				outp.armor(peer->key(),true);
 				_fromSock->send(_remoteAddress,outp.data(),outp.size());
-				//TRACE("sent WHOIS ERROR to %s for %s (not found)",source().toString().c_str(),Address(payload(),ZT_ADDRESS_LENGTH).toString().c_str());
 			}
 		} else {
 			TRACE("dropped WHOIS from %s(%s): missing or invalid address",source().toString().c_str(),_remoteAddress.toString().c_str());
 		}
-
 		peer->receive(RR,_fromSock,_remoteAddress,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP,Utils::now());
 	} catch ( ... ) {
 		TRACE("dropped WHOIS from %s(%s): unexpected exception",source().toString().c_str(),_remoteAddress.toString().c_str());

+ 14 - 2
node/Node.cpp

@@ -377,7 +377,7 @@ Node::ReasonForTermination Node::run()
 			Utils::lockDownFile(identitySecretPath.c_str(),false);
 		}
 
-		// Make sure networks.d exists
+		// Make sure networks.d exists (used by NodeConfig to remember networks)
 		{
 			std::string networksDotD(RR->homePath + ZT_PATH_SEPARATOR_S + "networks.d");
 #ifdef __WINDOWS__
@@ -386,13 +386,22 @@ Node::ReasonForTermination Node::run()
 			mkdir(networksDotD.c_str(),0700);
 #endif
 		}
+		// Make sure iddb.d exists (used by Topology to remember identities)
+		{
+			std::string iddbDotD(RR->homePath + ZT_PATH_SEPARATOR_S + "iddb.d");
+#ifdef __WINDOWS__
+			CreateDirectoryA(iddbDotD.c_str(),NULL);
+#else
+			mkdir(iddbDotD.c_str(),0700);
+#endif
+		}
 
 		RR->http = new HttpClient();
 		RR->antiRec = new AntiRecursion();
 		RR->mc = new Multicaster(RR);
 		RR->sw = new Switch(RR);
 		RR->sm = new SocketManager(impl->udpPort,impl->tcpPort,&_CBztTraffic,RR);
-		RR->topology = new Topology(RR,Utils::fileExists((RR->homePath + ZT_PATH_SEPARATOR_S + "iddb.d").c_str()));
+		RR->topology = new Topology(RR);
 		try {
 			RR->nc = new NodeConfig(RR);
 		} catch (std::exception &exc) {
@@ -443,6 +452,9 @@ Node::ReasonForTermination Node::run()
 				return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"invalid root-topology format");
 			}
 		}
+
+		// Delete peers.persist if it exists -- legacy file, just takes up space
+		Utils::rm(std::string(RR->homePath + ZT_PATH_SEPARATOR_S + "peers.persist").c_str());
 	} catch (std::bad_alloc &exc) {
 		return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"memory allocation failure");
 	} catch (std::runtime_error &exc) {

+ 4 - 4
node/Peer.cpp

@@ -42,7 +42,7 @@ Peer::Peer() :
 	_lastReceive(0),
 	_lastUnicastFrame(0),
 	_lastMulticastFrame(0),
-	__lastAnnouncedTo(0),
+	_lastAnnouncedTo(0),
 	_vMajor(0),
 	_vMinor(0),
 	_vRevision(0),
@@ -55,7 +55,7 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity)
 	_lastReceive(0),
 	_lastUnicastFrame(0),
 	_lastMulticastFrame(0),
-	__lastAnnouncedTo(0),
+	_lastAnnouncedTo(0),
 	_vMajor(0),
 	_vMinor(0),
 	_vRevision(0),
@@ -118,8 +118,8 @@ void Peer::receive(
 		 * supernodes and network controllers. The other place this is done
 		 * is in rescanMulticastGroups() in Network, but that only sends something
 		 * if a network's multicast groups change. */
-		if ((now - __lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
-			__lastAnnouncedTo = now;
+		if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
+			_lastAnnouncedTo = now;
 
 			Packet outp(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
 			std::vector< SharedPtr<Network> > networks(RR->nc->networks());

+ 2 - 60
node/Peer.hpp

@@ -50,9 +50,6 @@
 #include "NonCopyable.hpp"
 #include "Mutex.hpp"
 
-// Comment out to disable peers.persist
-//#define ZT_PEER_SERIALIZATION_VERSION 13
-
 namespace ZeroTier {
 
 /**
@@ -248,7 +245,7 @@ public:
 	/**
 	 * @return Time we last announced state TO this peer, such as multicast LIKEs
 	 */
-	inline uint64_t lastAnnouncedTo() const throw() { return __lastAnnouncedTo; }
+	inline uint64_t lastAnnouncedTo() const throw() { return _lastAnnouncedTo; }
 
 	/**
 	 * @param now Current time
@@ -405,61 +402,6 @@ public:
 		else return std::pair<InetAddress,InetAddress>();
 	}
 
-#ifdef ZT_PEER_SERIALIZATION_VERSION
-	template<unsigned int C>
-	inline void serialize(Buffer<C> &b) const
-	{
-		Mutex::Lock _l(_lock);
-
-		b.append((unsigned char)ZT_PEER_SERIALIZATION_VERSION);
-		_id.serialize(b,false);
-		b.append(_key,sizeof(_key));
-		b.append(_lastUsed);
-		b.append(_lastReceive);
-		b.append(_lastUnicastFrame);
-		b.append(_lastMulticastFrame);
-		b.append((uint16_t)_vProto);
-		b.append((uint16_t)_vMajor);
-		b.append((uint16_t)_vMinor);
-		b.append((uint16_t)_vRevision);
-		b.append((uint16_t)_latency);
-		b.append((uint16_t)_paths.size());
-		for(std::vector<Path>::const_iterator p(_paths.begin());p!=_paths.end();++p)
-			p->serialize(b);
-	}
-	template<unsigned int C>
-	inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
-	{
-		unsigned int p = startAt;
-
-		if (b[p++] != ZT_PEER_SERIALIZATION_VERSION)
-			throw std::invalid_argument("Peer: deserialize(): version mismatch");
-
-		Mutex::Lock _l(_lock);
-
-		p += _id.deserialize(b,p);
-		memcpy(_key,b.field(p,sizeof(_key)),sizeof(_key)); p += sizeof(_key);
-		_lastUsed = b.template at<uint64_t>(p); p += sizeof(uint64_t);
-		_lastReceive = b.template at<uint64_t>(p); p += sizeof(uint64_t);
-		_lastUnicastFrame = b.template at<uint64_t>(p); p += sizeof(uint64_t);
-		_lastMulticastFrame = b.template at<uint64_t>(p); p += sizeof(uint64_t);
-		__lastAnnouncedTo = 0;
-		_vProto = b.template at<uint16_t>(p); p += sizeof(uint16_t);
-		_vMajor = b.template at<uint16_t>(p); p += sizeof(uint16_t);
-		_vMinor = b.template at<uint16_t>(p); p += sizeof(uint16_t);
-		_vRevision = b.template at<uint16_t>(p); p += sizeof(uint16_t);
-		_latency = b.template at<uint16_t>(p); p += sizeof(uint16_t);
-		unsigned int npaths = (unsigned int)b.template at<uint16_t>(p); p += sizeof(uint16_t);
-		_paths.clear();
-		for(unsigned int i=0;i<npaths;++i) {
-			_paths.push_back(Path());
-			p += _paths.back().deserialize(b,p);
-		}
-
-		return (p - startAt);
-	}
-#endif // ZT_PEER_SERIALIZATION_VERSION
-
 private:
 	void _announceMulticastGroups(const RuntimeEnvironment *RR,uint64_t now);
 
@@ -472,7 +414,7 @@ private:
 	volatile uint64_t _lastReceive; // direct or indirect
 	volatile uint64_t _lastUnicastFrame;
 	volatile uint64_t _lastMulticastFrame;
-	volatile uint64_t __lastAnnouncedTo; // not persisted -- shouldn't be unless Multicaster state is also persisted
+	volatile uint64_t _lastAnnouncedTo;
 	volatile uint16_t _vProto;
 	volatile uint16_t _vMajor;
 	volatile uint16_t _vMinor;

+ 38 - 127
node/Topology.cpp

@@ -38,19 +38,15 @@
 
 namespace ZeroTier {
 
-Topology::Topology(const RuntimeEnvironment *renv,bool enablePermanentIdCaching) :
+Topology::Topology(const RuntimeEnvironment *renv) :
 	RR(renv),
+	_idCacheBase(renv->homePath + ZT_PATH_SEPARATOR_S + "iddb.d"),
 	_amSupernode(false)
 {
-	if (enablePermanentIdCaching)
-		_idCacheBase = (RR->homePath + ZT_PATH_SEPARATOR_S + "iddb.d");
-	_loadPeers();
 }
 
 Topology::~Topology()
 {
-	clean(Utils::now());
-	_dumpPeers();
 }
 
 void Topology::setSupernodes(const std::map< Identity,std::vector< std::pair<InetAddress,bool> > > &sn)
@@ -108,57 +104,49 @@ SharedPtr<Peer> Topology::addPeer(const SharedPtr<Peer> &peer)
 		TRACE("BUG: addNewPeer() caught and ignored attempt to add peer for self");
 		throw std::logic_error("cannot add peer for self");
 	}
+
 	uint64_t now = Utils::now();
 	Mutex::Lock _l(_activePeers_m);
+
 	SharedPtr<Peer> p(_activePeers.insert(std::pair< Address,SharedPtr<Peer> >(peer->address(),peer)).first->second);
 	p->use(now);
-	saveIdentity(p->identity());
+	_saveIdentity(p->identity());
+
 	return p;
 }
 
-SharedPtr<Peer> Topology::getPeer(const Address &zta) const
+SharedPtr<Peer> Topology::getPeer(const Address &zta)
 {
 	if (zta == RR->identity.address()) {
 		TRACE("BUG: ignored attempt to getPeer() for self, returned NULL");
 		return SharedPtr<Peer>();
 	}
+
 	uint64_t now = Utils::now();
 	Mutex::Lock _l(_activePeers_m);
-	std::map< Address,SharedPtr<Peer> >::const_iterator ap(_activePeers.find(zta));
-	if ((ap != _activePeers.end())&&(ap->second)) {
-		ap->second->use(now);
-		return ap->second;
-	}
-	return SharedPtr<Peer>();
-}
 
-Identity Topology::getIdentity(const Address &zta)
-{
-	SharedPtr<Peer> p(getPeer(zta));
-	if (p)
-		return p->identity();
-	if (_idCacheBase.length()) {
-		std::string idcPath(_idCacheBase + ZT_PATH_SEPARATOR_S + zta.toString());
-		std::string ids;
-		if (Utils::readFile(idcPath.c_str(),ids)) {
-			try {
-				return Identity(ids);
-			} catch ( ... ) {} // ignore invalid IDs
-		}
+	SharedPtr<Peer> &ap = _activePeers[zta];
+
+	if (ap) {
+		ap->use(now);
+		return ap;
 	}
-	return Identity();
-}
 
-void Topology::saveIdentity(const Identity &id)
-{
-	if ((id)&&(_idCacheBase.length())) {
-		std::string idcPath(_idCacheBase + ZT_PATH_SEPARATOR_S + id.address().toString());
-		if (!Utils::fileExists(idcPath.c_str()))
-			Utils::writeFile(idcPath.c_str(),id.toString(false));
+	Identity id(_getIdentity(zta));
+	if (id) {
+		try {
+			ap = SharedPtr<Peer>(new Peer(RR->identity,id));
+			ap->use(now);
+			return ap;
+		} catch ( ... ) {} // invalid identity?
 	}
+
+	_activePeers.erase(zta);
+
+	return SharedPtr<Peer>();
 }
 
-SharedPtr<Peer> Topology::getBestSupernode(const Address *avoid,unsigned int avoidCount,bool strictAvoid) const
+SharedPtr<Peer> Topology::getBestSupernode(const Address *avoid,unsigned int avoidCount,bool strictAvoid)
 {
 	SharedPtr<Peer> bestSupernode;
 	uint64_t now = Utils::now();
@@ -261,9 +249,9 @@ void Topology::clean(uint64_t now)
 	Mutex::Lock _l(_activePeers_m);
 	Mutex::Lock _l2(_supernodes_m);
 	for(std::map< Address,SharedPtr<Peer> >::iterator p(_activePeers.begin());p!=_activePeers.end();) {
-		if (((now - p->second->lastUsed()) >= ZT_PEER_IN_MEMORY_EXPIRATION)&&(!_supernodeAddresses.count(p->second->address())))
+		if (((now - p->second->lastUsed()) >= ZT_PEER_IN_MEMORY_EXPIRATION)&&(!_supernodeAddresses.count(p->second->address()))) {
 			_activePeers.erase(p++);
-		else {
+		} else {
 			p->second->clean(now);
 			++p;
 		}
@@ -288,101 +276,24 @@ bool Topology::authenticateRootTopology(const Dictionary &rt)
 	}
 }
 
-void Topology::_dumpPeers()
+Identity Topology::_getIdentity(const Address &zta)
 {
-#ifdef ZT_PEER_SERIALIZATION_VERSION
-	Buffer<ZT_PEER_WRITE_BUF_SIZE> buf;
-	std::string pdpath(RR->homePath + ZT_PATH_SEPARATOR_S + "peers.persist");
-	Mutex::Lock _l(_activePeers_m);
-
-	FILE *pd = fopen(pdpath.c_str(),"wb");
-	if (!pd)
-		return;
-	if (fwrite("ZTPD0",5,1,pd) != 1) {
-		fclose(pd);
-		Utils::rm(pdpath);
-		return;
-	}
-
-	for(std::map< Address,SharedPtr<Peer> >::iterator p(_activePeers.begin());p!=_activePeers.end();++p) {
+	std::string idcPath(_idCacheBase + ZT_PATH_SEPARATOR_S + zta.toString());
+	std::string ids;
+	if (Utils::readFile(idcPath.c_str(),ids)) {
 		try {
-			p->second->serialize(buf);
-			if (buf.size() >= (ZT_PEER_WRITE_BUF_SIZE / 2)) {
-				if (fwrite(buf.data(),buf.size(),1,pd) != 1) {
-					fclose(pd);
-					Utils::rm(pdpath);
-					buf.burn();
-					return;
-				}
-				buf.clear();
-				buf.burn();
-			}
-		} catch ( ... ) {
-			fclose(pd);
-			Utils::rm(pdpath);
-			buf.burn();
-			return;
-		}
+			return Identity(ids);
+		} catch ( ... ) {} // ignore invalid IDs
 	}
-
-	if (buf.size()) {
-		if (fwrite(buf.data(),buf.size(),1,pd) != 1) {
-			fclose(pd);
-			Utils::rm(pdpath);
-			buf.burn();
-			return;
-		}
-		buf.burn();
-	}
-
-	fclose(pd);
-	buf.burn();
-
-	Utils::lockDownFile(pdpath.c_str(),false);
-#endif // ZT_PEER_SERIALIZATION_VERSION
+	return Identity();
 }
 
-void Topology::_loadPeers()
+void Topology::_saveIdentity(const Identity &id)
 {
-	std::string pdpath(RR->homePath + ZT_PATH_SEPARATOR_S + "peers.persist");
-
-#ifdef ZT_PEER_SERIALIZATION_VERSION
-	Buffer<ZT_PEER_WRITE_BUF_SIZE> buf;
-	Mutex::Lock _l(_activePeers_m);
-
-	_activePeers.clear();
-
-	FILE *pd = fopen(pdpath.c_str(),"rb");
-	if (!pd)
-		return;
-
-	try {
-		char magic[5];
-		if ((fread(magic,5,1,pd) == 1)&&(!memcmp("ZTPD0",magic,5))) {
-			long rlen = 0;
-			do {
-				long rlen = (long)fread(const_cast<char *>(static_cast<const char *>(buf.data())) + buf.size(),1,ZT_PEER_WRITE_BUF_SIZE - buf.size(),pd);
-				if (rlen < 0) rlen = 0;
-				buf.setSize(buf.size() + (unsigned int)rlen);
-				unsigned int ptr = 0;
-				while ((ptr < (ZT_PEER_WRITE_BUF_SIZE / 2))&&(ptr < buf.size())) {
-					SharedPtr<Peer> p(new Peer());
-					ptr += p->deserialize(buf,ptr);
-					_activePeers[p->address()] = p;
-					saveIdentity(p->identity());
-				}
-				buf.behead(ptr);
-			} while (rlen > 0);
-		}
-	} catch ( ... ) {
-		_activePeers.clear();
+	if (id) {
+		std::string idcPath(_idCacheBase + ZT_PATH_SEPARATOR_S + id.address().toString());
+		Utils::writeFile(idcPath.c_str(),id.toString(false));
 	}
-
-	fclose(pd);
-	buf.burn();
-#endif // ZT_PEER_SERIALIZATION_VERSION
-
-	Utils::rm(pdpath);
 }
 
 } // namespace ZeroTier

+ 8 - 27
node/Topology.hpp

@@ -58,7 +58,7 @@ class RuntimeEnvironment;
 class Topology
 {
 public:
-	Topology(const RuntimeEnvironment *renv,bool enablePermanentIdCaching);
+	Topology(const RuntimeEnvironment *renv);
 	~Topology();
 
 	/**
@@ -95,26 +95,7 @@ public:
 	 * @param zta ZeroTier address of peer
 	 * @return Peer or NULL if not found
 	 */
-	SharedPtr<Peer> getPeer(const Address &zta) const;
-
-	/**
-	 * Get an identity if cached or available in a peer record
-	 *
-	 * @param zta ZeroTier address
-	 * @return Identity or NULL-identity if not found
-	 */
-	Identity getIdentity(const Address &zta);
-
-	/**
-	 * Save identity in permanent store, or do nothing if disabled
-	 *
-	 * This is called automatically by addPeer(), so it should not need to be
-	 * called manually anywhere else. The private part of the identity, if
-	 * present, is NOT cached by this.
-	 *
-	 * @param id Identity to save
-	 */
-	void saveIdentity(const Identity &id);
+	SharedPtr<Peer> getPeer(const Address &zta);
 
 	/**
 	 * @return Vector of peers that are supernodes
@@ -139,7 +120,7 @@ public:
 	 * 
 	 * @return Supernode with lowest latency or NULL if none
 	 */
-	inline SharedPtr<Peer> getBestSupernode() const
+	inline SharedPtr<Peer> getBestSupernode()
 	{
 		return getBestSupernode((const Address *)0,0,false);
 	}
@@ -156,7 +137,7 @@ public:
 	 * @param strictAvoid If false, consider avoided supernodes anyway if no non-avoid supernodes are available
 	 * @return Supernode or NULL if none
 	 */
-	SharedPtr<Peer> getBestSupernode(const Address *avoid,unsigned int avoidCount,bool strictAvoid) const;
+	SharedPtr<Peer> getBestSupernode(const Address *avoid,unsigned int avoidCount,bool strictAvoid);
 
 	/**
 	 * @param zta ZeroTier address
@@ -373,12 +354,12 @@ public:
 	static bool authenticateRootTopology(const Dictionary &rt);
 
 private:
-	const RuntimeEnvironment *RR;
+	Identity _getIdentity(const Address &zta);
+	void _saveIdentity(const Identity &id);
 
-	void _dumpPeers();
-	void _loadPeers();
+	const RuntimeEnvironment *RR;
 
-	std::string _idCacheBase; // empty if identity caching disabled
+	std::string _idCacheBase;
 
 	std::map< Address,SharedPtr<Peer> > _activePeers;
 	Mutex _activePeers_m;