summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2017-01-27 13:50:56 -0800
committerAdam Ierymenko <adam.ierymenko@gmail.com>2017-01-27 13:50:56 -0800
commitf102fd7f92225fbe39ae69dda716530a4e5457e9 (patch)
tree87ca67ce754085992dd6de8b31858dd38b529750
parent64774d0d4f552b2864abd969c6bc69c0ced3b2e1 (diff)
downloadinfinitytier-f102fd7f92225fbe39ae69dda716530a4e5457e9.tar.gz
infinitytier-f102fd7f92225fbe39ae69dda716530a4e5457e9.zip
Extend in-band world updates to handle moons too.
-rw-r--r--node/IncomingPacket.cpp40
-rw-r--r--node/Packet.hpp13
-rw-r--r--node/Peer.cpp11
-rw-r--r--node/Topology.hpp9
-rw-r--r--node/World.hpp4
5 files changed, 63 insertions, 14 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index 2487a8aa..1a60d13a 100644
--- a/node/IncomingPacket.cpp
+++ b/node/IncomingPacket.cpp
@@ -216,6 +216,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
InetAddress externalSurfaceAddress;
uint64_t planetWorldId = 0;
uint64_t planetWorldTimestamp = 0;
+ std::vector< std::pair<uint64_t,uint64_t> > moonIdsAndTimestamps;
{
unsigned int ptr = ZT_PROTO_VERB_HELLO_IDX_IDENTITY + id.deserialize(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY);
@@ -228,6 +229,16 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
planetWorldId = at<uint64_t>(ptr); ptr += 8;
planetWorldTimestamp = at<uint64_t>(ptr);
}
+
+ // Get moon IDs and timestamps if present
+ if ((ptr + 2) <= size()) {
+ unsigned int numMoons = at<uint16_t>(ptr); ptr += 2;
+ for(unsigned int i=0;i<numMoons;++i) {
+ if ((World::Type)(*this)[ptr++] == World::TYPE_MOON)
+ moonIdsAndTimestamps.push_back(std::pair<uint64_t,uint64_t>(at<uint64_t>(ptr),at<uint64_t>(ptr + 8)));
+ ptr += 16;
+ }
+ }
}
if (fromAddress != id.address()) {
@@ -356,15 +367,24 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
tmpa.serialize(outp);
}
+ const unsigned int worldUpdateSizeAt = outp.size();
+ outp.addSize(2); // make room for 16-bit size field
if ((planetWorldId)&&(RR->topology->planetWorldTimestamp() > planetWorldTimestamp)&&(planetWorldId == RR->topology->planetWorldId())) {
- World w(RR->topology->planet());
- const unsigned int sizeAt = outp.size();
- outp.addSize(2); // make room for 16-bit size field
- w.serialize(outp,false);
- outp.setAt<uint16_t>(sizeAt,(uint16_t)(outp.size() - (sizeAt + 2)));
- } else {
- outp.append((uint16_t)0); // no planet update needed
+ RR->topology->planet().serialize(outp,false);
+ }
+ if (moonIdsAndTimestamps.size() > 0) {
+ std::vector<World> moons(RR->topology->moons());
+ for(std::vector<World>::const_iterator m(moons.begin());m!=moons.end();++m) {
+ for(std::vector< std::pair<uint64_t,uint64_t> >::const_iterator i(moonIdsAndTimestamps.begin());i!=moonIdsAndTimestamps.end();++i) {
+ if (i->first == m->id()) {
+ if (m->timestamp() > i->second)
+ m->serialize(outp,false);
+ break;
+ }
+ }
+ }
}
+ outp.setAt<uint16_t>(worldUpdateSizeAt,(uint16_t)(outp.size() - (worldUpdateSizeAt + 2)));
outp.armor(peer->key(),true);
_path->send(RR,outp.data(),outp.size(),now);
@@ -411,11 +431,11 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
if (ptr < size())
ptr += externalSurfaceAddress.deserialize(*this,ptr);
- // Handle planet or moon updates
+ // Handle planet or moon updates if present (older versions don't send this)
if ((ptr + 2) <= size()) {
- World worldUpdate;
const unsigned int worldLen = at<uint16_t>(ptr); ptr += 2;
- if (worldLen > 0) {
+ const unsigned int endOfWorlds = ptr + worldLen;
+ while (ptr < endOfWorlds) {
World w;
w.deserialize(*this,ptr);
RR->topology->addWorld(w,true);
diff --git a/node/Packet.hpp b/node/Packet.hpp
index 0be19f8a..26e87af8 100644
--- a/node/Packet.hpp
+++ b/node/Packet.hpp
@@ -536,12 +536,17 @@ public:
* <[1] software major version>
* <[1] software minor version>
* <[2] software revision>
- * <[8] timestamp (ms since epoch)>
+ * <[8] timestamp for determining latench>
* <[...] binary serialized identity (see Identity)>
* <[1] destination address type>
* [<[...] destination address to which packet was sent>]
- * <[8] 64-bit world ID of current world>
- * <[8] 64-bit timestamp of current world>
+ * <[8] 64-bit world ID of current planet>
+ * <[8] 64-bit timestamp of current planet>
+ * <[2] 16-bit number of moons>
+ * [<[1] 8-bit type ID of moon>]
+ * [<[8] 64-bit world ID of moon>]
+ * [<[8] 64-bit timestamp of moon>]
+ * [... additional moons ...]
*
* This is the only message that ever must be sent in the clear, since it
* is used to push an identity to a new peer.
@@ -567,7 +572,7 @@ public:
* <[1] destination address type (for this OK, not copied from HELLO)>
* [<[...] destination address>]
* <[2] 16-bit length of world update or 0 if none>
- * [[...] world update]
+ * [[...] updates to planets and/or moons]
*
* ERROR has no payload.
*/
diff --git a/node/Peer.cpp b/node/Peer.cpp
index 40356034..441a5b33 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -345,6 +345,7 @@ SharedPtr<Path> Peer::getBestPath(uint64_t now,bool includeExpired)
void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now)
{
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO);
+
outp.append((unsigned char)ZT_PROTO_VERSION);
outp.append((unsigned char)ZEROTIER_ONE_VERSION_MAJOR);
outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR);
@@ -352,8 +353,18 @@ void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,u
outp.append(now);
RR->identity.serialize(outp,false);
atAddress.serialize(outp);
+
outp.append((uint64_t)RR->topology->planetWorldId());
outp.append((uint64_t)RR->topology->planetWorldTimestamp());
+
+ std::vector<World> moons(RR->topology->moons());
+ outp.append((uint16_t)moons.size());
+ for(std::vector<World>::const_iterator m(moons.begin());m!=moons.end();++m) {
+ outp.append((uint8_t)m->type());
+ outp.append((uint64_t)m->id());
+ outp.append((uint64_t)m->timestamp());
+ }
+
RR->node->expectReplyTo(outp.packetId());
outp.armor(_key,false); // HELLO is sent in the clear
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size());
diff --git a/node/Topology.hpp b/node/Topology.hpp
index 47981248..6369c5cd 100644
--- a/node/Topology.hpp
+++ b/node/Topology.hpp
@@ -202,6 +202,15 @@ public:
}
/**
+ * @return Current moons
+ */
+ inline std::vector<World> moons() const
+ {
+ Mutex::Lock _l(_lock);
+ return _moons;
+ }
+
+ /**
* @return Current planet
*/
inline World planet() const
diff --git a/node/World.hpp b/node/World.hpp
index c4682a69..06dcb981 100644
--- a/node/World.hpp
+++ b/node/World.hpp
@@ -176,6 +176,8 @@ public:
for(std::vector<InetAddress>::const_iterator ep(r->stableEndpoints.begin());ep!=r->stableEndpoints.end();++ep)
ep->serialize(b);
}
+ if (_type == TYPE_MOON)
+ b.append((uint16_t)0); // no attached dictionary (for future use)
if (forSign) b.append((uint64_t)0xf7f7f7f7f7f7f7f7ULL);
}
@@ -214,6 +216,8 @@ public:
p += r.stableEndpoints.back().deserialize(b,p);
}
}
+ if (_type == TYPE_MOON)
+ p += b.template at<uint16_t>(p) + 2;
return (p - startAt);
}