summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2017-08-23 13:40:51 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2017-08-23 13:40:51 -0700
commit64758c46b672f8b3182c370aed6b81a07780c093 (patch)
treea54729fc85ef374fda98f5203a48c0825dd02f77 /node
parent4352202349a9059d4cd1fbad7e148ed047d8e47d (diff)
downloadinfinitytier-64758c46b672f8b3182c370aed6b81a07780c093.tar.gz
infinitytier-64758c46b672f8b3182c370aed6b81a07780c093.zip
Implement peer serialization and deserialization.
Diffstat (limited to 'node')
-rw-r--r--node/Peer.cpp2
-rw-r--r--node/Peer.hpp84
-rw-r--r--node/Topology.cpp31
-rw-r--r--node/Topology.hpp2
4 files changed, 112 insertions, 7 deletions
diff --git a/node/Peer.cpp b/node/Peer.cpp
index 986e52ef..127f222c 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -369,7 +369,7 @@ void Peer::tryMemorizedPath(void *tPtr,uint64_t now)
_lastTriedMemorizedPath = now;
InetAddress mp;
if (RR->node->externalPathLookup(tPtr,_id.address(),-1,mp))
- attemptToContactAt(tPtr,InetAddress(),mp,now,true,0);
+ attemptToContactAt(tPtr,-1,mp,now,true,0);
}
}
diff --git a/node/Peer.hpp b/node/Peer.hpp
index c6423a59..af9163a5 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -439,6 +439,90 @@ public:
return false;
}
+ /**
+ * Serialize a peer for storage in local cache
+ *
+ * This does not serialize everything, just identity and addresses where the peer
+ * may be reached.
+ */
+ template<unsigned int C>
+ inline void serialize(Buffer<C> &b) const
+ {
+ b.append((uint8_t)0);
+
+ _id.serialize(b);
+
+ b.append(_lastReceive);
+ b.append(_lastNontrivialReceive);
+ b.append(_lastTriedMemorizedPath);
+ b.append(_lastDirectPathPushSent);
+ b.append(_lastDirectPathPushReceive);
+ b.append(_lastCredentialRequestSent);
+ b.append(_lastWhoisRequestReceived);
+ b.append(_lastEchoRequestReceived);
+ b.append(_lastComRequestReceived);
+ b.append(_lastComRequestSent);
+ b.append(_lastCredentialsReceived);
+ b.append(_lastTrustEstablishedPacketReceived);
+
+ b.append((uint16_t)_vProto);
+ b.append((uint16_t)_vMajor);
+ b.append((uint16_t)_vMinor);
+ b.append((uint16_t)_vRevision);
+
+ {
+ Mutex::Lock _l(_paths_m);
+ unsigned int pcount = 0;
+ if (_v4Path.p) ++pcount;
+ if (_v6Path.p) ++pcount;
+ b.append((uint8_t)pcount);
+ if (_v4Path.p) _v4Path.p->address().serialize(b);
+ if (_v6Path.p) _v6Path.p->address().serialize(b);
+ }
+
+ b.append((uint16_t)0);
+ }
+
+ template<unsigned int C>
+ inline static SharedPtr<Peer> deserializeFromCache(uint64_t now,void *tPtr,Buffer<C> &b,const RuntimeEnvironment *renv)
+ {
+ try {
+ unsigned int ptr = 0;
+ if (b[ptr++] != 0)
+ return SharedPtr<Peer>();
+
+ Identity id;
+ ptr += id.deserialize(b,ptr);
+ if (!id)
+ return SharedPtr<Peer>();
+
+ SharedPtr<Peer> p(new Peer(renv,renv->identity,id));
+
+ ptr += 12 * 8; // skip deserializing ephemeral state in this case
+
+ p->_vProto = b.template at<uint16_t>(ptr); ptr += 2;
+ p->_vMajor = b.template at<uint16_t>(ptr); ptr += 2;
+ p->_vMinor = b.template at<uint16_t>(ptr); ptr += 2;
+ p->_vRevision = b.template at<uint16_t>(ptr); ptr += 2;
+
+ const unsigned int pcount = (unsigned int)b[ptr++];
+ for(unsigned int i=0;i<pcount;++i) {
+ InetAddress inaddr;
+ try {
+ ptr += inaddr.deserialize(b,ptr);
+ if (inaddr)
+ p->attemptToContactAt(tPtr,-1,inaddr,now,true,0);
+ } catch ( ... ) {
+ break;
+ }
+ }
+
+ return p;
+ } catch ( ... ) {
+ return SharedPtr<Peer>();
+ }
+ }
+
private:
struct _PeerPath
{
diff --git a/node/Topology.cpp b/node/Topology.cpp
index edca0180..aeca59a7 100644
--- a/node/Topology.cpp
+++ b/node/Topology.cpp
@@ -88,6 +88,15 @@ Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
addWorld(tPtr,defaultPlanet,false);
}
+Topology::~Topology()
+{
+ Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
+ Address *a = (Address *)0;
+ SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
+ while (i.next(a,p))
+ _savePeer((void *)0,*p);
+}
+
SharedPtr<Peer> Topology::addPeer(void *tPtr,const SharedPtr<Peer> &peer)
{
SharedPtr<Peer> np;
@@ -113,23 +122,21 @@ SharedPtr<Peer> Topology::getPeer(void *tPtr,const Address &zta)
return *ap;
}
- /*
try {
- char buf[ZT_PEER_MAX_SERIALIZED_STATE_SIZE];
+ Buffer<ZT_PEER_MAX_SERIALIZED_STATE_SIZE> buf;
uint64_t idbuf[2]; idbuf[0] = zta.toInt(); idbuf[1] = 0;
- int len = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_PEER,idbuf,buf,(unsigned int)sizeof(buf));
+ int len = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_PEER,idbuf,buf.unsafeData(),ZT_PEER_MAX_SERIALIZED_STATE_SIZE);
if (len > 0) {
Mutex::Lock _l(_peers_m);
SharedPtr<Peer> &ap = _peers[zta];
if (ap)
return ap;
- ap = Peer::createFromStateUpdate(RR,tPtr,buf,len);
+ ap = Peer::deserializeFromCache(RR->node->now(),tPtr,buf,RR);
if (!ap)
_peers.erase(zta);
return ap;
}
} catch ( ... ) {} // ignore invalid identities or other strage failures
- */
return SharedPtr<Peer>();
}
@@ -383,8 +390,10 @@ void Topology::doPeriodicTasks(void *tPtr,uint64_t now)
Address *a = (Address *)0;
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
while (i.next(a,p)) {
- if ( (!(*p)->isAlive(now)) && (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),*a) == _upstreamAddresses.end()) )
+ if ( (!(*p)->isAlive(now)) && (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),*a) == _upstreamAddresses.end()) ) {
+ _savePeer(tPtr,*p);
_peers.erase(*a);
+ }
}
}
@@ -440,4 +449,14 @@ void Topology::_memoizeUpstreams(void *tPtr)
_cor.sign(RR->identity,RR->node->now());
}
+void Topology::_savePeer(void *tPtr,const SharedPtr<Peer> &peer)
+{
+ try {
+ Buffer<ZT_PEER_MAX_SERIALIZED_STATE_SIZE> buf;
+ peer->serialize(buf);
+ uint64_t tmpid[2]; tmpid[0] = peer->address().toInt(); tmpid[1] = 0;
+ RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_PEER,tmpid,buf.data(),buf.size());
+ } catch ( ... ) {} // sanity check, discard invalid entries
+}
+
} // namespace ZeroTier
diff --git a/node/Topology.hpp b/node/Topology.hpp
index 30e58abc..04dfb1cc 100644
--- a/node/Topology.hpp
+++ b/node/Topology.hpp
@@ -59,6 +59,7 @@ class Topology
{
public:
Topology(const RuntimeEnvironment *renv,void *tPtr);
+ ~Topology();
/**
* Add a peer to database
@@ -419,6 +420,7 @@ public:
private:
Identity _getIdentity(void *tPtr,const Address &zta);
void _memoizeUpstreams(void *tPtr);
+ void _savePeer(void *tPtr,const SharedPtr<Peer> &peer);
const RuntimeEnvironment *const RR;