void PipelineInterests::schedulePackets() { int available_window_size = static_cast<int>(floor(m_cwnd - m_inFlight)); while (available_window_size > 0) { if (m_retxQueue.size()) { // do retransmission first uint64_t retx_segno = m_retxQueue.front(); m_retxQueue.pop(); auto it = m_segmentInfoMap.find(retx_segno); if (it != m_segmentInfoMap.end()) { // the segment is still in the map, it means that it needs to be retransmitted sendInterest(retx_segno, true); } else { continue; } } else { // send next segment sendInterest(m_nextSegmentNo, false); m_nextSegmentNo++; } available_window_size--; } }
void SegmentFetcher::fetchFirstSegment(const Interest& baseInterest, bool isRetransmission) { Interest interest(baseInterest); interest.setCanBePrefix(true); interest.setMustBeFresh(true); interest.setInterestLifetime(m_options.interestLifetime); if (isRetransmission) { interest.refreshNonce(); } sendInterest(0, interest, isRetransmission); }
void SegmentFetcher::fetchSegmentsInWindow(const Interest& origInterest) { if (checkAllSegmentsReceived()) { // All segments have been retrieved return finalizeFetch(); } int64_t availableWindowSize = static_cast<int64_t>(m_cwnd) - m_nSegmentsInFlight; std::vector<std::pair<uint64_t, bool>> segmentsToRequest; // The boolean indicates whether a retx or not while (availableWindowSize > 0) { if (!m_retxQueue.empty()) { auto pendingSegmentIt = m_pendingSegments.find(m_retxQueue.front()); m_retxQueue.pop(); if (pendingSegmentIt == m_pendingSegments.end()) { // Skip re-requesting this segment, since it was received after RTO timeout continue; } BOOST_ASSERT(pendingSegmentIt->second.state == SegmentState::InRetxQueue); segmentsToRequest.emplace_back(pendingSegmentIt->first, true); } else if (m_nSegments == 0 || m_nextSegmentNum < static_cast<uint64_t>(m_nSegments)) { if (m_receivedSegments.count(m_nextSegmentNum) > 0) { // Don't request a segment a second time if received in response to first "discovery" Interest m_nextSegmentNum++; continue; } segmentsToRequest.emplace_back(m_nextSegmentNum++, false); } else { break; } availableWindowSize--; } for (const auto& segment : segmentsToRequest) { Interest interest(origInterest); // to preserve Interest elements interest.setName(Name(m_versionedDataName).appendSegment(segment.first)); interest.setCanBePrefix(false); interest.setMustBeFresh(false); interest.setInterestLifetime(m_options.interestLifetime); interest.refreshNonce(); sendInterest(segment.first, interest, segment.second); } }
void WeightedLoadBalancerStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest, shared_ptr<fib::Entry> fibEntry, shared_ptr<pit::Entry> pitEntry) { NFD_LOG_TRACE("Received Interest: " << interest.getName()); const auto suppression = m_retxSuppression.decide(inFace, interest, *pitEntry); NFD_LOG_DEBUG("retx decision: " << suppression); if (suppression == RetxSuppression::FORWARD || suppression == RetxSuppression::SUPPRESS) { demoteFace(pitEntry); } // create timer information and attach to PIT entry auto pitEntryInfo = myGetOrCreateMyPitInfo(pitEntry); auto measurementsEntryInfo = myGetOrCreateMyMeasurementInfo(fibEntry); // reconcile differences between incoming nexthops and those stored // on our custom measurement entry info measurementsEntryInfo->updateStoredNextHops(fibEntry->getNextHops()); auto selectedFace = selectOutgoingFace(inFace, interest, measurementsEntryInfo, pitEntry); if (selectedFace == nullptr) { rejectPendingInterest(pitEntry); return; } sendInterest(pitEntry, selectedFace); }
void SimpleDataRetrieval::start() { m_isRunning = true; sendInterest(); }
scheduler::EventId sendInterest(time::nanoseconds delay, const Interest& interest) { static char ignoredOutcome; return sendInterest(delay, interest, ignoredOutcome); }