summaryrefslogtreecommitdiff
path: root/node/Node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/Node.cpp')
-rw-r--r--node/Node.cpp24
1 files changed, 15 insertions, 9 deletions
diff --git a/node/Node.cpp b/node/Node.cpp
index 31ee8f19..b7dbffc3 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -191,12 +191,13 @@ public:
{
const std::vector<InetAddress> *const upstreamStableEndpoints = _upstreamsToContact.get(p->address());
if (upstreamStableEndpoints) {
- bool contacted = false;
-
// Upstreams must be pinged constantly over both IPv4 and IPv6 to allow
// them to perform three way handshake introductions for both stacks.
- if (!p->doPingAndKeepalive(_tPtr,_now,AF_INET)) {
+ const unsigned int sent = p->doPingAndKeepalive(_tPtr,_now);
+ bool contacted = (sent != 0);
+
+ if ((sent & 0x1) == 0) { // bit 0x1 == IPv4 sent
for(unsigned long k=0,ptr=(unsigned long)RR->node->prng();k<(unsigned long)upstreamStableEndpoints->size();++k) {
const InetAddress &addr = (*upstreamStableEndpoints)[ptr++ % upstreamStableEndpoints->size()];
if (addr.ss_family == AF_INET) {
@@ -205,8 +206,9 @@ public:
break;
}
}
- } else contacted = true;
- if (!p->doPingAndKeepalive(_tPtr,_now,AF_INET6)) {
+ }
+
+ if ((sent & 0x2) == 0) { // bit 0x2 == IPv6 sent
for(unsigned long k=0,ptr=(unsigned long)RR->node->prng();k<(unsigned long)upstreamStableEndpoints->size();++k) {
const InetAddress &addr = (*upstreamStableEndpoints)[ptr++ % upstreamStableEndpoints->size()];
if (addr.ss_family == AF_INET6) {
@@ -215,8 +217,10 @@ public:
break;
}
}
- } else contacted = true;
+ }
+ // If we have no memoized addresses for this upstream peer, attempt to contact
+ // it indirectly so we will be introduced.
if ((!contacted)&&(_bestCurrentUpstream)) {
const SharedPtr<Path> up(_bestCurrentUpstream->getBestPath(_now,true));
if (up)
@@ -224,9 +228,11 @@ public:
}
lastReceiveFromUpstream = std::max(p->lastReceive(),lastReceiveFromUpstream);
- _upstreamsToContact.erase(p->address()); // erase from upstreams to contact so that we can WHOIS those that remain
+
+ _upstreamsToContact.erase(p->address()); // after this we'll WHOIS all upstreams that remain
} else if (p->isActive(_now)) {
- p->doPingAndKeepalive(_tPtr,_now,-1);
+ // Regular non-upstream nodes get pinged if they appear active.
+ p->doPingAndKeepalive(_tPtr,_now);
}
}
@@ -420,7 +426,7 @@ ZT_PeerList *Node::peers() const
p->versionMinor = -1;
p->versionRev = -1;
}
- p->latency = pi->second->latency();
+ p->latency = pi->second->latency(_now);
p->role = RR->topology->role(pi->second->identity().address());
std::vector< SharedPtr<Path> > paths(pi->second->paths(_now));