summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2014-10-11 16:26:02 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2014-10-11 16:26:02 -0700
commit0d017c043f67bcdcbe7c52a1ee34c29215c2852e (patch)
treecb21f24dfa1901a9a8da8d93a28cb3ee1daf13e8
parentc2aac69a9f982954caf519082192bb98173d8484 (diff)
downloadinfinitytier-0d017c043f67bcdcbe7c52a1ee34c29215c2852e.tar.gz
infinitytier-0d017c043f67bcdcbe7c52a1ee34c29215c2852e.zip
Stop persisting last announcement time since Multicaster is volatile. Also some more legacy multicast fixes.
-rw-r--r--node/IncomingPacket.cpp28
-rw-r--r--node/Peer.cpp8
-rw-r--r--node/Peer.hpp9
3 files changed, 28 insertions, 17 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index 2753aa7c..7ac19ca3 100644
--- a/node/IncomingPacket.cpp
+++ b/node/IncomingPacket.cpp
@@ -563,13 +563,9 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
{
- /* This handles the old deprecated "P5" multicast frame, and will
- * go away once there are no longer nodes using this on the network.
- * We handle these old nodes by accepting these as simple multicasts
- * and if we are a supernode performing individual relaying of them
- * to all older nodes that expect them. This won't be too expensive
- * though since there aren't likely to be many older nodes left after
- * we do a software update. */
+ /* This code is a bit of a hack to handle compatibility with <1.0.0 peers
+ * and will go away once there's no longer any left (to speak of) on the
+ * network. */
// Quick and dirty dedup -- this is all condemned code in any case
static uint64_t p5MulticastDedupBuffer[1024];
@@ -577,6 +573,7 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
static Mutex p5MulticastDedupBuffer_m;
try {
+ unsigned int depth = at<uint16_t>(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH);
Address origin(Address(field(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ORIGIN,ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_ORIGIN),ZT_ADDRESS_LENGTH));
const unsigned int flags = (*this)[ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FLAGS];
const uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_NETWORK_ID);
@@ -608,8 +605,8 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
// If the sending peer is >=1.0.0, they only go to legacy peers. Otherwise they go to all
// peers.
+ const bool senderIsLegacy = ((peer->remoteVersionMajor() < 1)||(depth == 0xbeef));
const unsigned int limit = 128; // use a fairly generous limit since we want legacy peers to always work until they go away
- const bool senderIsLegacy = (peer->remoteVersionMajor() < 1);
std::vector<Address> members(RR->mc->getMembers(nwid,dest,limit));
@@ -624,6 +621,21 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
RR->sw->send(*this,true);
}
}
+ } else if (!RR->topology->isSupernode(peer->address())) {
+ // If we received this from a non-supernode, this must be a legacy peer. In that
+ // case relay it up to our supernode so it can get broadcast since there are now
+ // going to be too few legacy peers to form a mesh for the old style of propagation.
+
+ SharedPtr<Peer> sn(RR->topology->getBestSupernode());
+ if (sn) {
+ setAt(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH,(uint16_t)0xbeef); // magic number means "relayed on behalf of legacy peer"
+ newInitializationVector();
+ setDestination(sn->address());
+ setSource(RR->identity.address());
+ compress();
+ armor(sn->key(),true);
+ sn->send(RR,data(),size(),Utils::now());
+ }
}
SharedPtr<Network> network(RR->nc->network(nwid));
diff --git a/node/Peer.cpp b/node/Peer.cpp
index 540a83a1..94b8f29a 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -42,7 +42,7 @@ Peer::Peer() :
_lastReceive(0),
_lastUnicastFrame(0),
_lastMulticastFrame(0),
- _lastAnnouncedTo(0),
+ __lastAnnouncedTo(0),
_vMajor(0),
_vMinor(0),
_vRevision(0),
@@ -55,7 +55,7 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity)
_lastReceive(0),
_lastUnicastFrame(0),
_lastMulticastFrame(0),
- _lastAnnouncedTo(0),
+ __lastAnnouncedTo(0),
_vMajor(0),
_vMinor(0),
_vRevision(0),
@@ -118,8 +118,8 @@ void Peer::receive(
* supernodes and network controllers. The other place this is done
* is in rescanMulticastGroups() in Network, but that only sends something
* if a network's multicast groups change. */
- if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
- _lastAnnouncedTo = now;
+ if ((now - __lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
+ __lastAnnouncedTo = now;
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
std::vector< SharedPtr<Network> > networks(RR->nc->networks());
diff --git a/node/Peer.hpp b/node/Peer.hpp
index deb15ac9..a24fb7b2 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -50,7 +50,7 @@
#include "NonCopyable.hpp"
#include "Mutex.hpp"
-#define ZT_PEER_SERIALIZATION_VERSION 12
+#define ZT_PEER_SERIALIZATION_VERSION 13
namespace ZeroTier {
@@ -247,7 +247,7 @@ public:
/**
* @return Time we last announced state TO this peer, such as multicast LIKEs
*/
- inline uint64_t lastAnnouncedTo() const throw() { return _lastAnnouncedTo; }
+ inline uint64_t lastAnnouncedTo() const throw() { return __lastAnnouncedTo; }
/**
* @param now Current time
@@ -416,7 +416,6 @@ public:
b.append(_lastReceive);
b.append(_lastUnicastFrame);
b.append(_lastMulticastFrame);
- b.append(_lastAnnouncedTo);
b.append((uint16_t)_vProto);
b.append((uint16_t)_vMajor);
b.append((uint16_t)_vMinor);
@@ -442,7 +441,7 @@ public:
_lastReceive = b.template at<uint64_t>(p); p += sizeof(uint64_t);
_lastUnicastFrame = b.template at<uint64_t>(p); p += sizeof(uint64_t);
_lastMulticastFrame = b.template at<uint64_t>(p); p += sizeof(uint64_t);
- _lastAnnouncedTo = b.template at<uint64_t>(p); p += sizeof(uint64_t);
+ __lastAnnouncedTo = 0;
_vProto = b.template at<uint16_t>(p); p += sizeof(uint16_t);
_vMajor = b.template at<uint16_t>(p); p += sizeof(uint16_t);
_vMinor = b.template at<uint16_t>(p); p += sizeof(uint16_t);
@@ -470,7 +469,7 @@ private:
volatile uint64_t _lastReceive; // direct or indirect
volatile uint64_t _lastUnicastFrame;
volatile uint64_t _lastMulticastFrame;
- volatile uint64_t _lastAnnouncedTo;
+ volatile uint64_t __lastAnnouncedTo; // not persisted -- shouldn't be unless Multicaster state is also persisted
volatile uint16_t _vProto;
volatile uint16_t _vMajor;
volatile uint16_t _vMinor;