RR->antiRec->logOutgoingZT(outp.data(),outp.size());
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
} else {
- Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
- outp.append((unsigned char)Packet::VERB_WHOIS);
- outp.append(packetId());
- outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
- outp.append(payload(),ZT_ADDRESS_LENGTH);
- outp.armor(peer->key(),true);
- RR->antiRec->logOutgoingZT(outp.data(),outp.size());
- RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
+#ifdef ZT_ENABLE_CLUSTER
+ if (RR->cluster)
+ RR->cluster->sendDistributedQuery(*this);
+#endif
}
} else {
TRACE("dropped WHOIS from %s(%s): missing or invalid address",source().toString().c_str(),_remoteAddress.toString().c_str());
@@ -585,10 +574,6 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtrvalidateAndSetNetworkMembershipCertificate(RR,network->id(),com);
-#ifdef ZT_ENABLE_CLUSTER
- if (RR->cluster)
- RR->cluster->replicateCertificateOfNetworkMembership(com);
-#endif
}
if (!network->isAllowed(peer)) {
@@ -674,10 +659,6 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,const Shared
const uint64_t nwid = at(ptr);
const MulticastGroup group(MAC(field(ptr + 8,6),6),at(ptr + 14));
RR->mc->add(now,nwid,group,peer->address());
-#ifdef ZT_ENABLE_CLUSTER
- if (RR->cluster)
- RR->cluster->replicateMulticastLike(nwid,peer->address(),group);
-#endif
}
peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP);
@@ -696,10 +677,6 @@ bool IncomingPacket::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment
while (ptr < size()) {
ptr += com.deserialize(*this,ptr);
peer->validateAndSetNetworkMembershipCertificate(RR,com.networkId(),com);
-#ifdef ZT_ENABLE_CLUSTER
- if (RR->cluster)
- RR->cluster->replicateCertificateOfNetworkMembership(com);
-#endif
}
peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP);
@@ -831,11 +808,17 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar
outp.append(nwid);
mg.mac().appendTo(outp);
outp.append((uint32_t)mg.adi());
- if (RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit)) {
+ const unsigned int gatheredLocally = RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit);
+ if (gatheredLocally) {
outp.armor(peer->key(),true);
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
}
+
+#ifdef ZT_ENABLE_CLUSTER
+ if ((RR->cluster)&&(gatheredLocally < gatherLimit))
+ RR->cluster->sendDistributedQuery(*this);
+#endif
}
peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP);
@@ -860,10 +843,6 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
CertificateOfMembership com;
offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM);
peer->validateAndSetNetworkMembershipCertificate(RR,nwid,com);
-#ifdef ZT_ENABLE_CLUSTER
- if (RR->cluster)
- RR->cluster->replicateCertificateOfNetworkMembership(com);
-#endif
}
// Check membership after we've read any included COM, since
diff --git a/node/Packet.hpp b/node/Packet.hpp
index 63c49ce33..ef0251e33 100644
--- a/node/Packet.hpp
+++ b/node/Packet.hpp
@@ -322,8 +322,6 @@
#define ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY (ZT_PROTO_VERB_OK_IDX_PAYLOAD)
-#define ZT_PROTO_VERB_WHOIS__ERROR__IDX_ZTADDRESS (ZT_PROTO_VERB_ERROR_IDX_PAYLOAD)
-
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID (ZT_PROTO_VERB_OK_IDX_PAYLOAD)
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID + 8)
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN + 2)
@@ -599,8 +597,11 @@ public:
* OK response payload:
* <[...] binary serialized identity>
*
- * ERROR response payload:
- * <[5] address>
+ * If querying a cluster, duplicate OK responses may occasionally occur.
+ * These should be discarded.
+ *
+ * If the address is not found, no response is generated. WHOIS requests
+ * will time out much like ARP requests and similar do in L2.
*/
VERB_WHOIS = 4,
@@ -785,6 +786,9 @@ public:
* to send multicast but does not have the desired number of recipient
* peers.
*
+ * More than one OK response can occur if the response is broken up across
+ * multiple packets or if querying a clustered node.
+ *
* OK response payload:
* <[8] 64-bit network ID>
* <[6] MAC address of multicast group being queried>
@@ -794,16 +798,7 @@ public:
* <[2] 16-bit number of members enumerated in this packet>
* <[...] series of 5-byte ZeroTier addresses of enumerated members>
*
- * If no endpoints are known, OK and ERROR are both optional. It's okay
- * to return nothing in that case since gathering is "lazy."
- *
- * ERROR response payload:
- * <[8] 64-bit network ID>
- * <[6] MAC address of multicast group being queried>
- * <[4] 32-bit ADI for multicast group being queried>
- *
- * ERRORs are optional and are only generated if permission is denied,
- * certificate of membership is out of date, etc.
+ * ERROR is not generated; queries that return no response are dropped.
*/
VERB_MULTICAST_GATHER = 13,
@@ -1118,7 +1113,7 @@ public:
/* Bad/unsupported protocol version */
ERROR_BAD_PROTOCOL_VERSION = 2,
- /* Unknown object queried (e.g. with WHOIS) */
+ /* Unknown object queried */
ERROR_OBJ_NOT_FOUND = 3,
/* HELLO pushed an identity whose address is already claimed */
diff --git a/node/Peer.cpp b/node/Peer.cpp
index 52727c78f..6f987da2f 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -156,14 +156,7 @@ void Peer::received(
}
}
- if (pathIsConfirmed) {
-
-#ifdef ZT_ENABLE_CLUSTER
- if ((RR->cluster)&&(verb == Packet::VERB_HELLO))
- RR->cluster->replicateHavePeer(_id);
-#endif
-
- } else {
+ if (!pathIsConfirmed) {
if (verb == Packet::VERB_OK) {
Path *slot = (Path *)0;
@@ -186,11 +179,6 @@ void Peer::received(
_sortPaths(now);
}
-#ifdef ZT_ENABLE_CLUSTER
- if (RR->cluster)
- RR->cluster->replicateHavePeer(_id);
-#endif
-
} else {
/* If this path is not known, send a HELLO. We don't learn