Always ping / contact network preferred relays (if any).

This commit is contained in:
Adam Ierymenko 2015-06-01 16:53:58 -07:00
parent 229195166a
commit 5bc89034bc
3 changed files with 37 additions and 5 deletions

View File

@ -188,24 +188,53 @@ public:
lastReceiveFromUpstream(0), lastReceiveFromUpstream(0),
RR(renv), RR(renv),
_now(now), _now(now),
_supernodes(RR->topology->supernodeAddresses()) {} _supernodes(RR->topology->supernodeAddresses()),
_networkRelays()
{
std::vector< SharedPtr<Network> > nws(renv->node->allNetworks());
for(std::vector< SharedPtr<Network> >::const_iterator nw(nws.begin());nw!=nws.end();++nw) {
SharedPtr<NetworkConfig> nc((*nw)->config2());
if (nc)
_networkRelays.insert(_networkRelays.end(),nc->relays().begin(),nc->relays().end());
}
std::sort(_networkRelays.begin(),_networkRelays.end());
std::unique(_networkRelays.begin(),_networkRelays.end());
}
uint64_t lastReceiveFromUpstream; uint64_t lastReceiveFromUpstream;
inline void operator()(Topology &t,const SharedPtr<Peer> &p) inline void operator()(Topology &t,const SharedPtr<Peer> &p)
{ {
if (std::find(_supernodes.begin(),_supernodes.end(),p->address()) != _supernodes.end()) { if (std::find(_supernodes.begin(),_supernodes.end(),p->address()) != _supernodes.end()) {
// Supernodes have fixed addresses and are always pinged
p->doPingAndKeepalive(RR,_now); p->doPingAndKeepalive(RR,_now);
if (p->lastReceive() > lastReceiveFromUpstream) if (p->lastReceive() > lastReceiveFromUpstream)
lastReceiveFromUpstream = p->lastReceive(); lastReceiveFromUpstream = p->lastReceive();
} else if (p->alive(_now)) { } else {
p->doPingAndKeepalive(RR,_now); // Ping regular peers if they are alive, or if they are network
// designated relays with suggested IP address endpoints in a
// network config.
bool ison;
if (p->alive(_now))
ison = p->doPingAndKeepalive(RR,_now);
else ison = false;
if (!ison) {
// Note that multiple networks might designate the same peer as
// a preferred relay, so try all suggested endpoints.
for(std::vector< std::pair<Address,InetAddress> >::const_iterator r(_networkRelays.begin());r!=_networkRelays.end();++r) {
if (r->first == p->address())
p->attemptToContactAt(RR,r->second,_now);
}
}
} }
} }
private: private:
const RuntimeEnvironment *RR; const RuntimeEnvironment *RR;
uint64_t _now; uint64_t _now;
std::vector<Address> _supernodes; std::vector<Address> _supernodes;
std::vector< std::pair<Address,InetAddress> > _networkRelays;
}; };
ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline) ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline)

View File

@ -191,7 +191,7 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &at
RR->node->putPacket(atAddress,outp.data(),outp.size()); RR->node->putPacket(atAddress,outp.data(),outp.size());
} }
void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) bool Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
{ {
Path *const bestPath = getBestPath(now); Path *const bestPath = getBestPath(now);
if ((bestPath)&&(bestPath->active(now))) { if ((bestPath)&&(bestPath->active(now))) {
@ -204,7 +204,9 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
RR->node->putPacket(bestPath->address(),"",0); RR->node->putPacket(bestPath->address(),"",0);
bestPath->sent(now); bestPath->sent(now);
} }
return true;
} }
return false;
} }
void Peer::addPath(const Path &newp) void Peer::addPath(const Path &newp)

View File

@ -179,8 +179,9 @@ public:
* *
* @param RR Runtime environment * @param RR Runtime environment
* @param now Current time * @param now Current time
* @return True if there is an active best path (regardless of whether it needed a ping or keepalive), false if no paths
*/ */
void doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now); bool doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now);
/** /**
* @return All known direct paths to this peer * @return All known direct paths to this peer