diff options
-rw-r--r-- | Makefile.linux | 2 | ||||
-rw-r--r-- | node/Constants.hpp | 5 | ||||
-rw-r--r-- | node/Network.cpp | 3 | ||||
-rw-r--r-- | node/Peer.hpp | 2 | ||||
-rw-r--r-- | node/Topology.cpp | 102 | ||||
-rw-r--r-- | node/Topology.hpp | 3 |
6 files changed, 113 insertions, 4 deletions
diff --git a/Makefile.linux b/Makefile.linux index 794de5e3..7bacec73 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -3,7 +3,7 @@ CXX=g++ INCLUDES= ARCH=$(shell uname -m) -DEFS=-DZT_ARCH="$(ARCH)" -DZT_OSNAME="linux" -DZT_TRACE +DEFS=-DZT_ARCH="$(ARCH)" -DZT_OSNAME="linux" LIBS= # Uncomment for a release optimized build diff --git a/node/Constants.hpp b/node/Constants.hpp index 5b6fa92b..23dd5e48 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -209,6 +209,11 @@ error_no_ZT_ARCH_defined; #define ZT_DB_CLEAN_PERIOD 300000 /** + * How long to remember peers in RAM if they haven't been used + */ +#define ZT_PEER_IN_MEMORY_EXPIRATION 600000 + +/** * Delay between WHOIS retries in ms */ #define ZT_WHOIS_RETRY_DELAY 350 diff --git a/node/Network.cpp b/node/Network.cpp index 991842e4..acc2588d 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -37,7 +37,7 @@ #include "Packet.hpp" #include "Buffer.hpp" -#define ZT_NETWORK_CERT_WRITE_BUF_SIZE 524288 +#define ZT_NETWORK_CERT_WRITE_BUF_SIZE 131072 namespace ZeroTier { @@ -324,6 +324,7 @@ void Network::_dumpMulticastCerts() if (!mcdb) return; if (fwrite("ZTMCD0",6,1,mcdb) != 1) { + fclose(mcdb); Utils::rm(mcdbPath); return; } diff --git a/node/Peer.hpp b/node/Peer.hpp index 6c123746..0a8a7b57 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -349,7 +349,6 @@ public: template<unsigned int C> inline void serialize(Buffer<C> &b) - throw(std::out_of_range) { b.append((unsigned char)4); // version b.append(_key,sizeof(_key)); @@ -367,7 +366,6 @@ public: template<unsigned int C> inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0) - throw(std::out_of_range,std::invalid_argument) { unsigned int p = startAt; diff --git a/node/Topology.cpp b/node/Topology.cpp index 8add2f4e..18432f25 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -31,16 +31,21 @@ #include "NodeConfig.hpp" #include "CMWC4096.hpp" +#define ZT_PEER_WRITE_BUF_SIZE 131072 + namespace ZeroTier { Topology::Topology(const RuntimeEnvironment *renv) : _r(renv), _amSupernode(false) { + _loadPeers(); } Topology::~Topology() { + clean(); + _dumpPeers(); } void Topology::setSupernodes(const std::map< Identity,std::vector<InetAddress> > &sn) @@ -159,6 +164,103 @@ skip_and_try_next_supernode: void Topology::clean() { + uint64_t now = Utils::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()))) + _activePeers.erase(p++); + else ++p; + } +} + +void Topology::_dumpPeers() +{ + Buffer<ZT_PEER_WRITE_BUF_SIZE> buf; + std::string pdpath(_r->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) { + 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); + return; + } + buf.clear(); + } + } catch ( ... ) { + fclose(pd); + Utils::rm(pdpath); + return; + } + } + + if (buf.size()) { + if (fwrite(buf.data(),buf.size(),1,pd) != 1) { + fclose(pd); + Utils::rm(pdpath); + return; + } + } + + fclose(pd); + Utils::lockDownFile(pdpath.c_str(),false); +} + +void Topology::_loadPeers() +{ + Buffer<ZT_PEER_WRITE_BUF_SIZE> buf; + std::string pdpath(_r->homePath + ZT_PATH_SEPARATOR_S + "peers.persist"); + 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(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; + } + if (ptr) { + memmove(buf.data(),buf.data() + ptr,buf.size() - ptr); + buf.setSize(buf.size() - ptr); + } + } while (rlen > 0); + fclose(pd); + } else { + fclose(pd); + Utils::rm(pdpath); + } + } catch ( ... ) { + // Membership cert dump file invalid. We'll re-learn them off the net. + _activePeers.clear(); + fclose(pd); + Utils::rm(pdpath); + } } } // namespace ZeroTier diff --git a/node/Topology.hpp b/node/Topology.hpp index ac143b04..efb03dbe 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -271,6 +271,9 @@ public: private: const RuntimeEnvironment *const _r; + void _dumpPeers(); + void _loadPeers(); + std::map< Address,SharedPtr<Peer> > _activePeers; Mutex _activePeers_m; |