summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2019-06-25 13:42:20 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2019-06-25 13:42:20 -0700
commita019c3dd5d141d07a1554e36b6b4c942edfc4d70 (patch)
tree745e76548d3d51277bf6a42534f13d10d058ccec
parenta3ef9b8a15554326aaffdf14ebcf7795e5b73aff (diff)
downloadinfinitytier-a019c3dd5d141d07a1554e36b6b4c942edfc4d70.tar.gz
infinitytier-a019c3dd5d141d07a1554e36b6b4c942edfc4d70.zip
Tighten up credential push just a bit for faster up-time with older nodes, should not have significant impact on bandwidth. Also some cleanup and push direct path timing fixes.
-rw-r--r--node/Constants.hpp9
-rw-r--r--node/InetAddress.cpp3
-rw-r--r--node/Membership.cpp3
-rw-r--r--node/Membership.hpp11
-rw-r--r--node/Network.hpp15
-rw-r--r--node/OutboundMulticast.cpp7
-rw-r--r--node/Peer.cpp21
-rw-r--r--node/Switch.cpp3
8 files changed, 52 insertions, 20 deletions
diff --git a/node/Constants.hpp b/node/Constants.hpp
index a51d378e..98df998d 100644
--- a/node/Constants.hpp
+++ b/node/Constants.hpp
@@ -530,14 +530,19 @@
#define ZT_MAX_BRIDGE_ROUTES 67108864
/**
- * If there is no known route, spam to up to this many active bridges
+ * If there is no known L2 bridging route, spam to up to this many active bridges
*/
#define ZT_MAX_BRIDGE_SPAM 32
/**
* Interval between direct path pushes in milliseconds
*/
-#define ZT_DIRECT_PATH_PUSH_INTERVAL 120000
+#define ZT_DIRECT_PATH_PUSH_INTERVAL 15000
+
+/**
+ * Interval between direct path pushes in milliseconds if we already have a path
+ */
+#define ZT_DIRECT_PATH_PUSH_INTERVAL_HAVEPATH 120000
/**
* Time horizon for push direct paths cutoff
diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp
index 35457dc6..9207613e 100644
--- a/node/InetAddress.cpp
+++ b/node/InetAddress.cpp
@@ -185,15 +185,12 @@ bool InetAddress::fromString(const char *ipSlashPort)
inet_pton(AF_INET6, buf, &in6->sin6_addr.s6_addr);
in6->sin6_family = AF_INET6;
in6->sin6_port = Utils::hton((uint16_t)port);
-
-
return true;
} else if (strchr(buf,'.')) {
struct sockaddr_in *const in = reinterpret_cast<struct sockaddr_in *>(this);
inet_pton(AF_INET, buf, &in->sin_addr.s_addr);
in->sin_family = AF_INET;
in->sin_port = Utils::hton((uint16_t)port);
-
return true;
} else {
return false;
diff --git a/node/Membership.cpp b/node/Membership.cpp
index aa6d4359..92dd30cb 100644
--- a/node/Membership.cpp
+++ b/node/Membership.cpp
@@ -40,6 +40,7 @@ namespace ZeroTier {
Membership::Membership() :
_lastUpdatedMulticast(0),
_comRevocationThreshold(0),
+ _lastPushedCredentials(0),
_revocations(4),
_remoteTags(4),
_remoteCaps(4),
@@ -103,6 +104,8 @@ void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const i
outp.compress();
RR->sw->send(tPtr,outp,true);
}
+
+ _lastPushedCredentials = now;
}
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfMembership &com)
diff --git a/node/Membership.hpp b/node/Membership.hpp
index 90b6be6a..6f2d0339 100644
--- a/node/Membership.hpp
+++ b/node/Membership.hpp
@@ -79,6 +79,14 @@ public:
void pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const int64_t now,const Address &peerAddress,const NetworkConfig &nconf,int localCapabilityIndex);
/**
+ * @return True if we haven't pushed credentials in a long time (to cause proactive credential push)
+ */
+ inline bool shouldPushCredentials(const int64_t now) const
+ {
+ return ((now - _lastPushedCredentials) > ZT_PEER_ACTIVITY_TIMEOUT);
+ }
+
+ /**
* Check whether we should push MULTICAST_LIKEs to this peer, and update last sent time if true
*
* @param now Current time
@@ -213,6 +221,9 @@ private:
// Revocation threshold for COM or 0 if none
int64_t _comRevocationThreshold;
+ // Time we last pushed credentials
+ int64_t _lastPushedCredentials;
+
// Remote member's latest network COM
CertificateOfMembership _com;
diff --git a/node/Network.hpp b/node/Network.hpp
index 9350b3b5..969e1f14 100644
--- a/node/Network.hpp
+++ b/node/Network.hpp
@@ -369,6 +369,21 @@ public:
}
/**
+ * Push credentials if we haven't done so in a very long time
+ *
+ * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
+ * @param to Destination peer address
+ * @param now Current time
+ */
+ inline void pushCredentialsIfNeeded(void *tPtr,const Address &to,const int64_t now)
+ {
+ Mutex::Lock _l(_lock);
+ Membership &m = _membership(to);
+ if (m.shouldPushCredentials(now))
+ m.pushCredentials(RR,tPtr,now,to,_config,-1);
+ }
+
+ /**
* Destroy this network
*
* This sets the network to completely remove itself on delete. This also prevents the
diff --git a/node/OutboundMulticast.cpp b/node/OutboundMulticast.cpp
index 5b5b726b..a162c8a5 100644
--- a/node/OutboundMulticast.cpp
+++ b/node/OutboundMulticast.cpp
@@ -84,13 +84,12 @@ void OutboundMulticast::init(
void OutboundMulticast::sendOnly(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr)
{
const SharedPtr<Network> nw(RR->node->network(_nwid));
- const Address toAddr2(toAddr);
uint8_t QoSBucket = 255; // Dummy value
- if ((nw)&&(nw->filterOutgoingPacket(tPtr,true,RR->identity.address(),toAddr2,_macSrc,_macDest,_frameData,_frameLen,_etherType,0,QoSBucket))) {
+ if ((nw)&&(nw->filterOutgoingPacket(tPtr,true,RR->identity.address(),toAddr,_macSrc,_macDest,_frameData,_frameLen,_etherType,0,QoSBucket))) {
+ nw->pushCredentialsIfNeeded(tPtr,toAddr,RR->node->now());
_packet.newInitializationVector();
- _packet.setDestination(toAddr2);
+ _packet.setDestination(toAddr);
RR->node->expectReplyTo(_packet.packetId());
-
_tmp = _packet;
RR->sw->send(tPtr,_tmp,true);
}
diff --git a/node/Peer.cpp b/node/Peer.cpp
index cbd07799..5f5d1462 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -39,6 +39,8 @@
namespace ZeroTier {
+static unsigned char s_freeRandomByteCounter = 0;
+
Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Identity &peerIdentity) :
RR(renv),
_lastReceive(0),
@@ -55,7 +57,7 @@ Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Ident
_lastACKWindowReset(0),
_lastQoSWindowReset(0),
_lastMultipathCompatibilityCheck(0),
- _freeRandomByte(0),
+ _freeRandomByte((unsigned char)((uintptr_t)this >> 4) ^ ++s_freeRandomByteCounter),
_uniqueAlivePathCount(0),
_localMultipathSupported(false),
_remoteMultipathSupported(false),
@@ -73,7 +75,6 @@ Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Ident
_lastAggregateStatsReport(0),
_lastAggregateAllocation(0)
{
- Utils::getSecureRandom(&_freeRandomByte, 1);
if (!myIdentity.agree(peerIdentity,_key,ZT_PEER_SECRET_KEY_LENGTH))
throw ZT_EXCEPTION_INVALID_ARGUMENT;
}
@@ -101,7 +102,8 @@ void Peer::received(
case Packet::VERB_MULTICAST_FRAME:
_lastNontrivialReceive = now;
break;
- default: break;
+ default:
+ break;
}
if (trustEstablished) {
@@ -202,17 +204,17 @@ void Peer::received(
}
// If we have a trust relationship periodically push a message enumerating
- // all known external addresses for ourselves. We now do this even if we
- // have a current path since we'll want to use new ones too.
+ // all known external addresses for ourselves. If we already have a path this
+ // is done less frequently.
if (this->trustEstablished(now)) {
- const uint64_t sinceLastPush = now - _lastDirectPathPushSent;
- if (sinceLastPush >= ZT_DIRECT_PATH_PUSH_INTERVAL) {
+ const int64_t sinceLastPush = now - _lastDirectPathPushSent;
+ if (sinceLastPush >= ((hops == 0) ? ZT_DIRECT_PATH_PUSH_INTERVAL_HAVEPATH : ZT_DIRECT_PATH_PUSH_INTERVAL)) {
_lastDirectPathPushSent = now;
std::vector<InetAddress> pathsToPush(RR->node->directPaths());
if (pathsToPush.size() > 0) {
std::vector<InetAddress>::const_iterator p(pathsToPush.begin());
while (p != pathsToPush.end()) {
- Packet *outp = new Packet(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS);
+ Packet *const outp = new Packet(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS);
outp->addSize(2); // leave room for count
unsigned int count = 0;
while ((p != pathsToPush.end())&&((outp->size() + 24) < 1200)) {
@@ -254,8 +256,7 @@ void Peer::received(
void Peer::recordOutgoingPacket(const SharedPtr<Path> &path, const uint64_t packetId,
uint16_t payloadLength, const Packet::Verb verb, int64_t now)
{
- // Grab second byte from packetId to use as a source of entropy in the next path selection
- _freeRandomByte = (packetId & 0xFF00) >> 8;
+ _freeRandomByte += (unsigned char)(packetId >> 8); // grab entropy to use in path selection logic for multipath
if (_canUseMultipath) {
path->recordOutgoingPacket(now, packetId, payloadLength, verb);
}
diff --git a/node/Switch.cpp b/node/Switch.cpp
index a9c882fb..a6852d9f 100644
--- a/node/Switch.cpp
+++ b/node/Switch.cpp
@@ -417,6 +417,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
return;
}
+ network->pushCredentialsIfNeeded(tPtr,toZT,RR->node->now());
+
if (fromBridged) {
Packet outp(toZT,RR->identity.address(),Packet::VERB_EXT_FRAME);
outp.append(network->id());
@@ -437,7 +439,6 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
outp.compress();
aqm_enqueue(tPtr,network,outp,true,qosBucket);
}
-
} else {
// Destination is bridged behind a remote peer