summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.linux2
-rw-r--r--node/Constants.hpp5
-rw-r--r--node/Network.cpp3
-rw-r--r--node/Peer.hpp2
-rw-r--r--node/Topology.cpp102
-rw-r--r--node/Topology.hpp3
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;