mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-01 23:10:52 +00:00
Implement peer serialization and deserialization.
This commit is contained in:
parent
4352202349
commit
64758c46b6
@ -369,7 +369,7 @@ void Peer::tryMemorizedPath(void *tPtr,uint64_t now)
|
|||||||
_lastTriedMemorizedPath = now;
|
_lastTriedMemorizedPath = now;
|
||||||
InetAddress mp;
|
InetAddress mp;
|
||||||
if (RR->node->externalPathLookup(tPtr,_id.address(),-1,mp))
|
if (RR->node->externalPathLookup(tPtr,_id.address(),-1,mp))
|
||||||
attemptToContactAt(tPtr,InetAddress(),mp,now,true,0);
|
attemptToContactAt(tPtr,-1,mp,now,true,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,6 +439,90 @@ public:
|
|||||||
return false;
|
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:
|
private:
|
||||||
struct _PeerPath
|
struct _PeerPath
|
||||||
{
|
{
|
||||||
|
@ -88,6 +88,15 @@ Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
|
|||||||
addWorld(tPtr,defaultPlanet,false);
|
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> Topology::addPeer(void *tPtr,const SharedPtr<Peer> &peer)
|
||||||
{
|
{
|
||||||
SharedPtr<Peer> np;
|
SharedPtr<Peer> np;
|
||||||
@ -113,23 +122,21 @@ SharedPtr<Peer> Topology::getPeer(void *tPtr,const Address &zta)
|
|||||||
return *ap;
|
return *ap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
try {
|
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;
|
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) {
|
if (len > 0) {
|
||||||
Mutex::Lock _l(_peers_m);
|
Mutex::Lock _l(_peers_m);
|
||||||
SharedPtr<Peer> &ap = _peers[zta];
|
SharedPtr<Peer> &ap = _peers[zta];
|
||||||
if (ap)
|
if (ap)
|
||||||
return ap;
|
return ap;
|
||||||
ap = Peer::createFromStateUpdate(RR,tPtr,buf,len);
|
ap = Peer::deserializeFromCache(RR->node->now(),tPtr,buf,RR);
|
||||||
if (!ap)
|
if (!ap)
|
||||||
_peers.erase(zta);
|
_peers.erase(zta);
|
||||||
return ap;
|
return ap;
|
||||||
}
|
}
|
||||||
} catch ( ... ) {} // ignore invalid identities or other strage failures
|
} catch ( ... ) {} // ignore invalid identities or other strage failures
|
||||||
*/
|
|
||||||
|
|
||||||
return SharedPtr<Peer>();
|
return SharedPtr<Peer>();
|
||||||
}
|
}
|
||||||
@ -383,8 +390,10 @@ void Topology::doPeriodicTasks(void *tPtr,uint64_t now)
|
|||||||
Address *a = (Address *)0;
|
Address *a = (Address *)0;
|
||||||
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
|
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
|
||||||
while (i.next(a,p)) {
|
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);
|
_peers.erase(*a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,4 +449,14 @@ void Topology::_memoizeUpstreams(void *tPtr)
|
|||||||
_cor.sign(RR->identity,RR->node->now());
|
_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
|
} // namespace ZeroTier
|
||||||
|
@ -59,6 +59,7 @@ class Topology
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Topology(const RuntimeEnvironment *renv,void *tPtr);
|
Topology(const RuntimeEnvironment *renv,void *tPtr);
|
||||||
|
~Topology();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a peer to database
|
* Add a peer to database
|
||||||
@ -419,6 +420,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
Identity _getIdentity(void *tPtr,const Address &zta);
|
Identity _getIdentity(void *tPtr,const Address &zta);
|
||||||
void _memoizeUpstreams(void *tPtr);
|
void _memoizeUpstreams(void *tPtr);
|
||||||
|
void _savePeer(void *tPtr,const SharedPtr<Peer> &peer);
|
||||||
|
|
||||||
const RuntimeEnvironment *const RR;
|
const RuntimeEnvironment *const RR;
|
||||||
|
|
||||||
|
@ -2047,6 +2047,8 @@ public:
|
|||||||
char p[1024];
|
char p[1024];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
bool secure = false;
|
bool secure = false;
|
||||||
|
char dirname[1024];
|
||||||
|
dirname[0] = 0;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case ZT_STATE_OBJECT_IDENTITY_PUBLIC:
|
case ZT_STATE_OBJECT_IDENTITY_PUBLIC:
|
||||||
@ -2060,12 +2062,18 @@ public:
|
|||||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str());
|
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str());
|
||||||
break;
|
break;
|
||||||
case ZT_STATE_OBJECT_MOON:
|
case ZT_STATE_OBJECT_MOON:
|
||||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "moons.d/%.16llx.moon",_homePath.c_str(),(unsigned long long)id[0]);
|
OSUtils::ztsnprintf(dirname,sizeof(dirname),"%s" ZT_PATH_SEPARATOR_S "moons.d",_homePath.c_str());
|
||||||
|
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.moon",dirname,(unsigned long long)id[0]);
|
||||||
break;
|
break;
|
||||||
case ZT_STATE_OBJECT_NETWORK_CONFIG:
|
case ZT_STATE_OBJECT_NETWORK_CONFIG:
|
||||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "networks.d/%.16llx.conf",_homePath.c_str(),(unsigned long long)id[0]);
|
OSUtils::ztsnprintf(dirname,sizeof(dirname),"%s" ZT_PATH_SEPARATOR_S "networks.d",_homePath.c_str());
|
||||||
|
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.conf",dirname,(unsigned long long)id[0]);
|
||||||
secure = true;
|
secure = true;
|
||||||
break;
|
break;
|
||||||
|
case ZT_STATE_OBJECT_PEER:
|
||||||
|
OSUtils::ztsnprintf(dirname,sizeof(dirname),"%s" ZT_PATH_SEPARATOR_S "peers.d",_homePath.c_str());
|
||||||
|
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.10llx.peer",dirname,(unsigned long long)id[0]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2084,6 +2092,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
f = fopen(p,"w");
|
f = fopen(p,"w");
|
||||||
|
if ((!f)&&(dirname[0])) { // create subdirectory if it does not exist
|
||||||
|
OSUtils::mkdir(dirname);
|
||||||
|
f = fopen(p,"w");
|
||||||
|
}
|
||||||
if (f) {
|
if (f) {
|
||||||
if (fwrite(data,len,1,f) != 1)
|
if (fwrite(data,len,1,f) != 1)
|
||||||
fprintf(stderr,"WARNING: unable to write to file: %s (I/O error)" ZT_EOL_S,p);
|
fprintf(stderr,"WARNING: unable to write to file: %s (I/O error)" ZT_EOL_S,p);
|
||||||
@ -2108,15 +2120,18 @@ public:
|
|||||||
case ZT_STATE_OBJECT_IDENTITY_SECRET:
|
case ZT_STATE_OBJECT_IDENTITY_SECRET:
|
||||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str());
|
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str());
|
||||||
break;
|
break;
|
||||||
case ZT_STATE_OBJECT_NETWORK_CONFIG:
|
|
||||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "networks.d/%.16llx.conf",_homePath.c_str(),(unsigned long long)id);
|
|
||||||
break;
|
|
||||||
case ZT_STATE_OBJECT_PLANET:
|
case ZT_STATE_OBJECT_PLANET:
|
||||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str());
|
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str());
|
||||||
break;
|
break;
|
||||||
case ZT_STATE_OBJECT_MOON:
|
case ZT_STATE_OBJECT_MOON:
|
||||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "moons.d/%.16llx.moon",_homePath.c_str(),(unsigned long long)id);
|
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "moons.d/%.16llx.moon",_homePath.c_str(),(unsigned long long)id);
|
||||||
break;
|
break;
|
||||||
|
case ZT_STATE_OBJECT_NETWORK_CONFIG:
|
||||||
|
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "networks.d/%.16llx.conf",_homePath.c_str(),(unsigned long long)id);
|
||||||
|
break;
|
||||||
|
case ZT_STATE_OBJECT_PEER:
|
||||||
|
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "peers.d/%.10llx.conf",_homePath.c_str(),(unsigned long long)id[0]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user