Face* AsfStrategy::getBestFaceForForwarding(const fib::Entry& fibEntry, const Interest& interest, const Face& inFace) { NFD_LOG_TRACE("Looking for best face for " << fibEntry.getPrefix()); typedef std::function<bool(const FaceStats&, const FaceStats&)> FaceStatsPredicate; typedef std::set<FaceStats, FaceStatsPredicate> FaceStatsSet; FaceStatsSet rankedFaces( [] (const FaceStats& lhs, const FaceStats& rhs) -> bool { // Sort by RTT and then by cost double lhsValue = getValueForSorting(lhs); double rhsValue = getValueForSorting(rhs); if (lhsValue < rhsValue) { return true; } else if (lhsValue == rhsValue) { return lhs.cost < rhs.cost; } else { return false; } }); for (const fib::NextHop& hop : fibEntry.getNextHops()) { Face& hopFace = hop.getFace(); if (hopFace.getId() == inFace.getId() || wouldViolateScope(inFace, interest, hopFace)) { continue; } FaceInfo* info = m_measurements.getFaceInfo(fibEntry, interest, hopFace); if (info == nullptr) { FaceStats stats = {&hopFace, RttStats::RTT_NO_MEASUREMENT, RttStats::RTT_NO_MEASUREMENT, hop.getCost()}; rankedFaces.insert(stats); } else { FaceStats stats = {&hopFace, info->getRtt(), info->getSrtt(), hop.getCost()}; rankedFaces.insert(stats); } } FaceStatsSet::iterator it = rankedFaces.begin(); if (it != rankedFaces.end()) { return it->face; } else { return nullptr; } }
Face* ProbingModule::getFaceToProbe(const Face& inFace, const Interest& interest, const fib::Entry& fibEntry, const Face& faceUsed) { FaceInfoFacePairSet rankedFaces( [] (const auto& pairLhs, const auto& pairRhs) -> bool { // Sort by RTT // If a face has timed-out, rank it behind non-timed-out faces FaceInfo& lhs = *pairLhs.first; FaceInfo& rhs = *pairRhs.first; return (!lhs.isTimeout() && rhs.isTimeout()) || (lhs.isTimeout() == rhs.isTimeout() && lhs.getSrtt() < rhs.getSrtt()); }); // Put eligible faces into rankedFaces. If a face does not have an RTT measurement, // immediately pick the face for probing for (const fib::NextHop& hop : fibEntry.getNextHops()) { Face& hopFace = hop.getFace(); // Don't send probe Interest back to the incoming face or use the same face // as the forwarded Interest or use a face that violates scope if (hopFace.getId() == inFace.getId() || hopFace.getId() == faceUsed.getId() || wouldViolateScope(inFace, interest, hopFace)) { continue; } FaceInfo* info = m_measurements.getFaceInfo(fibEntry, interest, hopFace.getId()); // If no RTT has been recorded, probe this face if (info == nullptr || !info->hasSrttMeasurement()) { return &hopFace; } // Add FaceInfo to container sorted by RTT rankedFaces.insert({info, &hopFace}); } if (rankedFaces.empty()) { // No Face to probe return nullptr; } return getFaceBasedOnProbability(rankedFaces); }
void BestRouteStrategyBase::afterReceiveInterest(const Face& inFace, const Interest& interest, const shared_ptr<pit::Entry>& pitEntry) { if (hasPendingOutRecords(*pitEntry)) { // not a new Interest, don't forward return; } const fib::Entry& fibEntry = this->lookupFib(*pitEntry); for (const auto& nexthop : fibEntry.getNextHops()) { Face& outFace = nexthop.getFace(); if (!wouldViolateScope(inFace, interest, outFace) && canForwardToLegacy(*pitEntry, outFace)) { this->sendInterest(pitEntry, outFace, interest); return; } } this->rejectPendingInterest(pitEntry); }