void
PipelineInterests::handleNack(const Interest& interest, const lp::Nack& nack)
{
  if (m_options.isVerbose)
    std::cerr << "Received Nack with reason " << nack.getReason()
              << " for Interest " << interest << std::endl;

  switch (nack.getReason()) {
  case lp::NackReason::DUPLICATE: {
    break; // ignore duplicates
  }
  case lp::NackReason::CONGESTION: { // treated the same as timeout for now
    uint64_t segno = interest.getName()[-1].toSegment();
    m_segmentInfoMap[segno]->state = inRetxQueue; // update state
    handleTimeout(1);
    break;
  }
  default: {
    m_hasError = true;
    fail("Could not retrieve data for " + interest.getName().toUri() +
         ", reason: " + boost::lexical_cast<std::string>(nack.getReason()));
    break;
  }
  }
}
예제 #2
0
bool
OutRecord::setIncomingNack(const lp::Nack& nack)
{
  if (nack.getInterest().getNonce() != this->getLastNonce()) {
    return false;
  }

  m_incomingNack.reset(new lp::NackHeader(nack.getHeader()));
  return true;
}
예제 #3
0
void
GenericLinkService::doSendNack(const lp::Nack& nack, const EndpointId& endpointId)
{
  lp::Packet lpPacket(nack.getInterest().wireEncode());
  lpPacket.add<lp::NackField>(nack.getHeader());

  encodeLpFields(nack, lpPacket);

  this->sendNetPacket(std::move(lpPacket), endpointId, false);
}
예제 #4
0
void
DummyClientFace::receive(const lp::Nack& nack)
{
  lp::Packet lpPacket;
  lpPacket.add<lp::NackField>(nack.getHeader());
  Block interest = nack.getInterest().wireEncode();
  lpPacket.add<lp::FragmentField>(make_pair(interest.begin(), interest.end()));

  addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, nack);
  addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, nack);

  static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
}
예제 #5
0
void
AsfStrategy::afterReceiveNack(const Face& inFace, const lp::Nack& nack,
                              const shared_ptr<pit::Entry>& pitEntry)
{
  NFD_LOG_DEBUG("Nack for " << nack.getInterest() << " from=" << inFace.getId() << ": " << nack.getReason());
  onTimeout(pitEntry->getName(), inFace.getId());
}
예제 #6
0
void
DummyClientFace::receive<lp::Nack>(const lp::Nack& nack)
{
  lp::Packet lpPacket;
  lpPacket.add<lp::NackField>(nack.getHeader());
  Block interest = nack.getInterest().wireEncode();
  lpPacket.add<lp::FragmentField>(make_pair(interest.begin(), interest.end()));

  nfd::LocalControlHeader localControlHeader = nack.getLocalControlHeader();

  if (localControlHeader.hasIncomingFaceId()) {
    lpPacket.add<lp::IncomingFaceIdField>(localControlHeader.getIncomingFaceId());
  }

  m_transport->receive(lpPacket.wireEncode());
}
예제 #7
0
 void
 nackPendingInterests(const lp::Nack& nack)
 {
   for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
     const Interest& pendingInterest = *(*entry)->getInterest();
     if (nack.getInterest().matchesInterest(pendingInterest)) {
       shared_ptr<PendingInterest> matchedEntry = *entry;
       entry = m_pendingInterestTable.erase(entry);
       matchedEntry->invokeNackCallback(nack);
     }
     else {
       ++entry;
     }
   }
 }
void
CertificateFetcherFromNetwork::nackCallback(const lp::Nack& nack,
                                            const shared_ptr<CertificateRequest>& certRequest,
                                            const shared_ptr<ValidationState>& state,
                                            const ValidationContinuation& continueValidation)
{
  NDN_LOG_DEBUG_DEPTH("NACK (" << nack.getReason() <<  ") while fetching certificate "
                      << certRequest->interest.getName());

  --certRequest->nRetriesLeft;
  if (certRequest->nRetriesLeft >= 0) {
    m_scheduler.schedule(certRequest->waitAfterNack,
                         [=] { fetch(certRequest, state, continueValidation); });
    certRequest->waitAfterNack *= 2;
  }
  else {
    state->fail({ValidationError::Code::CANNOT_RETRIEVE_CERT, "Cannot fetch certificate after all "
                 "retries `" + certRequest->interest.getName().toUri() + "`"});
  }
}
예제 #9
0
void
SegmentFetcher::afterNackReceivedCb(const Interest& origInterest, const lp::Nack& nack,
                                    const weak_ptr<SegmentFetcher>& weakSelf)
{
  if (shouldStop(weakSelf))
    return;

  afterSegmentNacked();

  BOOST_ASSERT(m_nSegmentsInFlight > 0);
  m_nSegmentsInFlight--;

  switch (nack.getReason()) {
    case lp::NackReason::DUPLICATE:
    case lp::NackReason::CONGESTION:
      afterNackOrTimeout(origInterest);
      break;
    default:
      signalError(NACK_ERROR, "Nack Error");
      break;
  }
}
  time::milliseconds
  exponentialBackoff(lp::Nack nack)
  {
    uint64_t nackSequenceNo;

    try {
      nackSequenceNo = nack.getInterest().getName().get(-1).toSequenceNumber();
    }
    catch (name::Component::Error&) {
      nackSequenceNo = 0;
    }

    if (m_lastNackSequenceNo ==  nackSequenceNo) {
      ++m_attempts;
    } else {
      m_attempts = 1;
    }

    time::milliseconds delayTime =
      time::milliseconds (static_cast<uint32_t>( pow(2, m_attempts) * 100 + random::generateWord32() % 100));

    m_lastNackSequenceNo = nackSequenceNo;
    return delayTime;
  }