bool OverlayManagerImpl::isPeerPreferred(Peer::pointer peer) { std::string pstr = peer->toString(); if (mPreferredPeers.find(pstr) != mPreferredPeers.end()) { CLOG(DEBUG, "Overlay") << "Peer " << pstr << " is preferred"; return true; } if (peer->isAuthenticated()) { std::string kstr = PubKeyUtils::toStrKey(peer->getPeerID()); std::vector<std::string> const& pk = mApp.getConfig().PREFERRED_PEER_KEYS; if (std::find(pk.begin(), pk.end(), kstr) != pk.end()) { CLOG(DEBUG, "Overlay") << "Peer key " << mApp.getConfig().toStrKey(peer->getPeerID()) << " is preferred"; return true; } } CLOG(DEBUG, "Overlay") << "Peer " << pstr << " is not preferred"; return false; }
bool OverlayManagerImpl::isPeerAccepted(Peer::pointer peer) { if (isPeerPreferred(peer)) { if (mPeers.size() < mApp.getConfig().MAX_PEER_CONNECTIONS) { return true; } for (auto victim : mPeers) { if (!isPeerPreferred(victim)) { CLOG(INFO, "Overlay") << "Evicting non-preferred peer " << victim->toString() << " for preferred peer " << peer->toString(); dropPeer(victim); return true; } } } if (!mApp.getConfig().PREFERRED_PEERS_ONLY && mPeers.size() < mApp.getConfig().MAX_PEER_CONNECTIONS) return true; mConnectionsRejected.Mark(); return false; }
void OverlayManagerImpl::dropPeer(Peer::pointer peer) { mConnectionsDropped.Mark(); CLOG(DEBUG, "Overlay") << "Dropping peer " << peer->toString(); auto iter = find(mPeers.begin(), mPeers.end(), peer); if (iter != mPeers.end()) mPeers.erase(iter); else CLOG(WARNING, "Overlay") << "Dropping unlisted peer"; mPeersSize.set_count(mPeers.size()); }
void OverlayManagerImpl::addConnectedPeer(Peer::pointer peer) { if (mShuttingDown) { peer->drop(); return; } CLOG(INFO, "Overlay") << "New connected peer " << peer->toString(); mConnectionsEstablished.Mark(); mPeers.push_back(peer); mPeersSize.set_count(mPeers.size()); }
void Tracker::tryNextPeer() { // will be called by some timer or when we get a // response saying they don't have it Peer::pointer peer; CLOG(TRACE, "Overlay") << "tryNextPeer " << hexAbbrev(mItemHash) << " last: " << (mLastAskedPeer ? mLastAskedPeer->toString() : "<none>"); // if we don't have a list of peers to ask and we're not // currently asking peers, build a new list if (mPeersToAsk.empty() && !mLastAskedPeer) { std::set<std::shared_ptr<Peer>> peersWithEnvelope; for (auto const& e : mWaitingEnvelopes) { auto const& s = mApp.getOverlayManager().getPeersKnows(e.first); peersWithEnvelope.insert(s.begin(), s.end()); } // move the peers that have the envelope to the back, // to be processed first for (auto const& p : mApp.getOverlayManager().getRandomPeers()) { if (peersWithEnvelope.find(p) != peersWithEnvelope.end()) { mPeersToAsk.emplace_back(p); } else { mPeersToAsk.emplace_front(p); } } mNumListRebuild++; CLOG(TRACE, "Overlay") << "tryNextPeer " << hexAbbrev(mItemHash) << " attempt " << mNumListRebuild << " reset to #" << mPeersToAsk.size(); mTryNextPeerReset.Mark(); } while (!peer && !mPeersToAsk.empty()) { peer = mPeersToAsk.back(); if (!peer->isAuthenticated()) { peer.reset(); } mPeersToAsk.pop_back(); } std::chrono::milliseconds nextTry; if (!peer) { // we have asked all our peers // clear mLastAskedPeer so that we rebuild a new list mLastAskedPeer.reset(); if (mNumListRebuild > MAX_REBUILD_FETCH_LIST) { nextTry = MS_TO_WAIT_FOR_FETCH_REPLY * MAX_REBUILD_FETCH_LIST; } else { nextTry = MS_TO_WAIT_FOR_FETCH_REPLY * mNumListRebuild; } } else { mLastAskedPeer = peer; CLOG(TRACE, "Overlay") << "Asking for " << hexAbbrev(mItemHash) << " to " << peer->toString(); mTryNextPeer.Mark(); mAskPeer(peer, mItemHash); nextTry = MS_TO_WAIT_FOR_FETCH_REPLY; } mTimer.expires_from_now(nextTry); mTimer.async_wait([this]() { this->tryNextPeer(); }, VirtualTimer::onFailureNoop); }