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);
  }
}
예제 #2
0
파일: face.cpp 프로젝트: nnaren1902/ndn-cxx
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);
}
예제 #3
0
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);
}
예제 #6
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));
}
예제 #8
0
  /**
   * 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"));
}
예제 #11
0
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;
}