BOOST_FIXTURE_TEST_CASE(TripleWithInitialSegmentFetching, Fixture) { ValidatorNull nullValidator; SegmentFetcher::fetch(face, Interest("/hello/world", time::seconds(1000)), nullValidator, bind(&Fixture::onComplete, this, _1), bind(&Fixture::onError, this, _1)); advanceClocks(time::milliseconds(1), 10); face.receive(*makeDataSegment("/hello/world/version0", 1, false)); advanceClocks(time::milliseconds(1), 10); face.receive(*makeDataSegment("/hello/world/version0", 0, false)); advanceClocks(time::milliseconds(1), 10); face.receive(*makeDataSegment("/hello/world/version0", 1, false)); advanceClocks(time::milliseconds(1), 10); face.receive(*makeDataSegment("/hello/world/version0", 2, true)); advanceClocks(time::milliseconds(1), 10); BOOST_CHECK_EQUAL(nErrors, 0); BOOST_CHECK_EQUAL(nDatas, 1); BOOST_CHECK_EQUAL(dataSize, 42); BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 4); BOOST_CHECK_EQUAL(face.sentData.size(), 0); { const Interest& interest = face.sentInterests[0]; BOOST_CHECK_EQUAL(interest.getName(), "/hello/world"); BOOST_CHECK_EQUAL(interest.getMustBeFresh(), true); BOOST_CHECK_EQUAL(interest.getChildSelector(), 1); } { const Interest& interest = face.sentInterests[1]; BOOST_CHECK_EQUAL(interest.getName(), "/hello/world/version0/%00%00"); BOOST_CHECK_EQUAL(interest.getMustBeFresh(), false); BOOST_CHECK_EQUAL(interest.getChildSelector(), 0); } { const Interest& interest = face.sentInterests[2]; BOOST_CHECK_EQUAL(interest.getName(), "/hello/world/version0/%00%01"); BOOST_CHECK_EQUAL(interest.getMustBeFresh(), false); BOOST_CHECK_EQUAL(interest.getChildSelector(), 0); } { const Interest& interest = face.sentInterests[3]; BOOST_CHECK_EQUAL(interest.getName(), "/hello/world/version0/%00%02"); BOOST_CHECK_EQUAL(interest.getMustBeFresh(), false); BOOST_CHECK_EQUAL(interest.getChildSelector(), 0); } }
const PendingInterestId* Face::expressInterest(const Name& name, const Interest& tmpl, const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/) { return expressInterest(Interest(tmpl) .setName(name) .setNonce(0), onData, onTimeout); }
void MulticastDiscovery::start() { std::cerr << "Trying multicast discovery..." << std::endl; util::SegmentFetcher::fetch(m_face, Interest("/localhost/nfd/faces/list"), m_validator, [this] (const ConstBufferPtr& data) { registerHubDiscoveryPrefix(data); }, [this] (uint32_t code, const std::string& msg) { m_nextStageOnFailure(msg); }); }
BOOST_FIXTURE_TEST_CASE(ZeroComponentName, Fixture) { SegmentFetcher::fetch(face, Interest("ndn:/"), make_shared<ValidatorNull>(), bind(&Fixture::onComplete, this, _1), bind(&Fixture::onError, this, _1)); advanceClocks(time::milliseconds(10)); nackLastInterest(lp::NackReason::DUPLICATE); face.receive(*makeDataSegment("/hello/world", 0, true)); BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2); BOOST_CHECK_EQUAL(face.sentInterests[0].getName(), ndn::Name("ndn:/")); BOOST_CHECK_EQUAL(face.sentInterests[1].getName(), ndn::Name("ndn:/")); BOOST_REQUIRE_EQUAL(nData, 1); }
BOOST_FIXTURE_TEST_CASE(SegmentValidationFailure, Fixture) { ValidatorFailed failedValidator; SegmentFetcher::fetch(face, Interest("/hello/world", time::seconds(1000)), failedValidator, bind(&Fixture::onComplete, this, _1), bind(&Fixture::onError, this, _1)); advanceClocks(time::milliseconds(1), 10); face.receive(*makeDataSegment("/hello/world/version0", 0, true)); advanceClocks(time::milliseconds(1), 10); BOOST_CHECK_EQUAL(nErrors, 1); BOOST_CHECK_EQUAL(lastError, static_cast<uint32_t>(SegmentFetcher::SEGMENT_VALIDATION_FAIL)); BOOST_CHECK_EQUAL(nDatas, 0); }
void GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId) { BOOST_ASSERT(netPkt.type() == tlv::Interest); BOOST_ASSERT(firstPkt.has<lp::NackField>()); lp::Nack nack((Interest(netPkt))); nack.setHeader(firstPkt.get<lp::NackField>()); if (firstPkt.has<lp::NextHopFaceIdField>()) { ++this->nInNetInvalid; NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP"); return; } if (firstPkt.has<lp::CachePolicyField>()) { ++this->nInNetInvalid; NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP"); return; } if (firstPkt.has<lp::IncomingFaceIdField>()) { NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE"); } if (firstPkt.has<lp::CongestionMarkField>()) { nack.setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>())); } if (firstPkt.has<lp::NonDiscoveryField>()) { ++this->nInNetInvalid; NFD_LOG_FACE_WARN("received NonDiscovery with Nack: DROP"); return; } if (firstPkt.has<lp::PrefixAnnouncementField>()) { ++this->nInNetInvalid; NFD_LOG_FACE_WARN("received PrefixAnnouncement with Nack: DROP"); return; } this->receiveNack(nack, endpointId); }
BOOST_FIXTURE_TEST_CASE(SegmentFetcherCongestionNack, Fixture) { SegmentFetcher::fetch(face, Interest("/hello/world", time::seconds(1000)), make_shared<ValidatorNull>(), bind(&Fixture::onComplete, this, _1), bind(&Fixture::onError, this, _1)); advanceClocks(time::milliseconds(1), 10); // receive nack for the original interest nackLastInterest(lp::NackReason::CONGESTION); // receive nack due to Congestion for the reexpressed interests for (uint32_t i = 1; i <= SegmentFetcher::MAX_INTEREST_REEXPRESS; ++i) { nackLastInterest(lp::NackReason::CONGESTION); } BOOST_CHECK_EQUAL(face.sentInterests.size(), (SegmentFetcher::MAX_INTEREST_REEXPRESS + 1)); BOOST_CHECK_EQUAL(lastError, static_cast<uint32_t>(SegmentFetcher::NACK_ERROR)); }
/** * Walk the pattern chip through the search chip to find the best interest * * @param cube [in] The Isis::Cube to look for an interesting area in * @param sample [in] The sample postion in the cube where the chip is located * @param line [in] The line postion in the cube where the chip is located * * @return Returns the status of the operation. The following conditions can * occur true=Success, false=Failed */ bool InterestOperator::Operate(Cube &cube, int sample, int line) { int pad = Padding(); Chip chip(2*p_deltaSamp + p_samples + pad, 2*p_deltaLine + p_lines + pad); chip.TackCube(sample, line); if (p_clipPolygon != NULL) chip.SetClipPolygon(*p_clipPolygon); chip.Load(cube); // Walk the search chip and find the best interest int bestSamp = 0; int bestLine = 0; double smallestDist = DBL_MAX; double bestInterest = Isis::Null; for (int lin=p_lines/2 + 1; lin<=2*p_deltaLine+p_lines/2 + 1; lin++) { for (int samp=p_samples/2 + 1; samp<=2*p_deltaSamp+p_samples/2 + 1; samp++) { Chip subChip = chip.Extract(p_samples+pad, p_lines+pad, samp, lin); double interest = Interest(subChip); if (interest != Isis::Null) { if ((bestInterest == Isis::Null) || CompareInterests(interest,bestInterest)) { double dist = std::sqrt(std::pow(sample-samp,2.0)+std::pow(line-lin,2.0)); if (interest == bestInterest && dist>smallestDist) { continue; } else { bestInterest = interest; bestSamp = samp; bestLine = lin; smallestDist = dist; } } } } } // Check to see if we went through the interest chip and never got a interest at // any location. if (bestInterest == Isis::Null || bestInterest<p_minimumInterest) return false; p_interestAmount = bestInterest; chip.SetChipPosition(bestSamp, bestLine); p_cubeSample = chip.CubeSample(); p_cubeLine = chip.CubeLine(); return true; }
BOOST_FIXTURE_TEST_CASE(MultipleSegmentFetching, Fixture) { ValidatorNull nullValidator; SegmentFetcher::fetch(face, Interest("/hello/world", time::seconds(1000)), nullValidator, bind(&Fixture::onComplete, this, _1), bind(&Fixture::onError, this, _1)); advanceClocks(time::milliseconds(1), 10); for (uint64_t i = 0; i < 400; i++) { advanceClocks(time::milliseconds(1), 10); face.receive(*makeDataSegment("/hello/world/version0", i, false)); } advanceClocks(time::milliseconds(1), 10); face.receive(*makeDataSegment("/hello/world/version0", 400, true)); advanceClocks(time::milliseconds(1), 10); BOOST_CHECK_EQUAL(nErrors, 0); BOOST_CHECK_EQUAL(nDatas, 1); }
BOOST_FIXTURE_TEST_CASE(SegmentZero, Fixture) { int nNacks = 2; ndn::Name interestName("ndn:/A"); SegmentFetcher::fetch(face, Interest(interestName), make_shared<ValidatorNull>(), bind(&Fixture::onComplete, this, _1), bind(&Fixture::onError, this, _1)); advanceClocks(time::milliseconds(1000)); for (uint64_t segmentNo = 0; segmentNo <= 3; segmentNo++) { if (segmentNo == 1) { while (nNacks--) { nackLastInterest(lp::NackReason::CONGESTION); advanceClocks(time::milliseconds(10)); } } auto data = makeDataSegment(interestName, segmentNo, segmentNo == 3); face.receive(*data); advanceClocks(time::milliseconds(10)); } // Total number of sent interests should be 6: one interest for segment zero and segment one each, // two re-expressed interests for segment one after getting nack twice, and two interests for // segment two and three BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 6); BOOST_CHECK_EQUAL(face.sentInterests[0].getName(), ndn::Name("ndn:/A")); BOOST_CHECK_EQUAL(face.sentInterests[1].getName(), ndn::Name("ndn:/A/%00%01")); BOOST_CHECK_EQUAL(face.sentInterests[2].getName(), ndn::Name("ndn:/A/%00%01")); BOOST_CHECK_EQUAL(face.sentInterests[3].getName(), ndn::Name("ndn:/A/%00%01")); BOOST_CHECK_EQUAL(face.sentInterests[4].getName(), ndn::Name("ndn:/A/%00%02")); BOOST_CHECK_EQUAL(face.sentInterests[5].getName(), ndn::Name("ndn:/A/%00%03")); }
std::vector<lp::Sequence> LpReliability::onLpPacketLost(lp::Sequence txSeq) { BOOST_ASSERT(m_unackedFrags.count(txSeq) > 0); auto txSeqIt = m_unackedFrags.find(txSeq); auto& txFrag = txSeqIt->second; txFrag.rtoTimer.cancel(); auto netPkt = txFrag.netPkt; std::vector<lp::Sequence> removedThisTxSeq; // Check if maximum number of retransmissions exceeded if (txFrag.retxCount >= m_options.maxRetx) { // Delete all LpPackets of NetPkt from m_unackedFrags (except this one) for (size_t i = 0; i < netPkt->unackedFrags.size(); i++) { if (netPkt->unackedFrags[i] != txSeqIt) { removedThisTxSeq.push_back(netPkt->unackedFrags[i]->first); deleteUnackedFrag(netPkt->unackedFrags[i]); } } ++m_linkService->nRetxExhausted; // Notify strategy of dropped Interest (if any) if (netPkt->isInterest) { BOOST_ASSERT(netPkt->pkt.has<lp::FragmentField>()); ndn::Buffer::const_iterator fragBegin, fragEnd; std::tie(fragBegin, fragEnd) = netPkt->pkt.get<lp::FragmentField>(); Block frag(&*fragBegin, std::distance(fragBegin, fragEnd)); onDroppedInterest(Interest(frag)); } removedThisTxSeq.push_back(txSeqIt->first); deleteUnackedFrag(txSeqIt); } else { // Assign new TxSequence lp::Sequence newTxSeq = assignTxSequence(txFrag.pkt); netPkt->didRetx = true; // Move fragment to new TxSequence mapping auto newTxFragIt = m_unackedFrags.emplace_hint( m_firstUnackedFrag != m_unackedFrags.end() && m_firstUnackedFrag->first > newTxSeq ? m_firstUnackedFrag : m_unackedFrags.end(), std::piecewise_construct, std::forward_as_tuple(newTxSeq), std::forward_as_tuple(txFrag.pkt)); auto& newTxFrag = newTxFragIt->second; newTxFrag.retxCount = txFrag.retxCount + 1; newTxFrag.netPkt = netPkt; // Update associated NetPkt auto fragInNetPkt = std::find(netPkt->unackedFrags.begin(), netPkt->unackedFrags.end(), txSeqIt); BOOST_ASSERT(fragInNetPkt != netPkt->unackedFrags.end()); *fragInNetPkt = newTxFragIt; removedThisTxSeq.push_back(txSeqIt->first); deleteUnackedFrag(txSeqIt); // Retransmit fragment m_linkService->sendLpPacket(lp::Packet(newTxFrag.pkt)); // Start RTO timer for this sequence newTxFrag.rtoTimer = scheduler::schedule(m_rto.computeRto(), [=] { onLpPacketLost(newTxSeq); }); } return removedThisTxSeq; }