void MulticastStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest, shared_ptr<fib::Entry> fibEntry, shared_ptr<pit::Entry> pitEntry) { std::string interest_name = interest.getName().toUri(); if (my_panini_fib::has_prefix(interest_name, "/nac")) { return; } else if (my_panini_fib::has_prefix(interest_name, "/nam_msg")) { return; } else if (my_panini_fib::has_prefix(interest_name, "/panini")) { m_my_logger.log("panini", "afterRecvInterest", interest_name, 0); } const fib::NextHopList& nexthops = fibEntry->getNextHops(); for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) { shared_ptr<Face> outFace = it->getFace(); if (pitEntry->canForwardTo(*outFace)) { this->sendInterest(pitEntry, outFace); m_my_logger.log("panini", "afterSendBroadcastInterest", interest_name); } } if (!pitEntry->hasUnexpiredOutRecords()) { this->rejectPendingInterest(pitEntry); } }
bool Validator::verifySignature(const Interest& interest, const v1::PublicKey& key) { const Name& name = interest.getName(); if (name.size() < signed_interest::MIN_LENGTH_SIG_ONLY) return false; Signature sig; try { sig.setInfo(name[signed_interest::POS_SIG_INFO].blockFromValue()); sig.setValue(name[signed_interest::POS_SIG_VALUE].blockFromValue()); } catch (const tlv::Error&) { return false; } if (!sig.hasKeyLocator()) return false; const Block& nameWire = name.wireEncode(); return verifySignature(nameWire.value(), nameWire.value_size() - name[signed_interest::POS_SIG_VALUE].size(), sig, key); }
virtual uint64_t expressInterest (const Interest& interest, const OnData& onData, const OnTimeout& onTimeout, const OnNetworkNack& onNetworkNack, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) { if (expectedInterest_ != interest.getName()) throw runtime_error("TestFace::expressInterest: Not the expectedInterest_"); if (interest.getLink()->getDelegations().size() != 3) throw runtime_error ("TestFace::expressInterest: The Interest link does not the expected number of delegates"); ++(*timeoutCount_); onTimeout(ptr_lib::make_shared<Interest>(interest)); return 0; }
void StrategyChoiceManager::onStrategyChoiceRequest(const Interest& request) { const Name& command = request.getName(); const size_t commandNComps = command.size(); if (command == LIST_DATASET_PREFIX) { listStrategies(request); return; } if (COMMAND_UNSIGNED_NCOMPS <= commandNComps && commandNComps < COMMAND_SIGNED_NCOMPS) { NFD_LOG_DEBUG("command result: unsigned verb: " << command); sendResponse(command, 401, "Signature required"); return; } else if (commandNComps < COMMAND_SIGNED_NCOMPS || !COMMAND_PREFIX.isPrefixOf(command)) { NFD_LOG_DEBUG("command result: malformed"); sendResponse(command, 400, "Malformed command"); return; } validate(request, bind(&StrategyChoiceManager::onValidatedStrategyChoiceRequest, this, _1), bind(&ManagerBase::onCommandValidationFailed, this, _1, _2)); }
void MadmStrategy::probeInterests(const shared_ptr<Face> outFace, const Interest& interest, StrategyRequirements &requirements, const fib::NextHopList& nexthops, shared_ptr<pit::Entry> pitEntry) { for (auto n : nexthops) { const shared_ptr<Face>& thisFace = n.getFace(); bool costTooHigh = false; if (requirements.getLimits(RequirementType::COST).second != -1) { costTooHigh = costMap[thisFace->getId()].getCost() > (requirements.getLimits(RequirementType::COST)).second; if (costTooHigh) { NFD_LOG_DEBUG( "Cost too high: " << costMap[thisFace->getId()].getCost() << " > " << (requirements.getLimits(RequirementType::COST)).second); } } if (thisFace != outFace && !costTooHigh) { NFD_LOG_TRACE("Probing face: " << thisFace->getId()); faceInfoTable[thisFace->getId()].addSentInterest(interest.getName().toUri()); this->sendInterest(pitEntry, thisFace, true); } } }
void ClientFace::request(const Interest& interest, const OnData& onData, const OnNack& onNack, const OnTimeout& onTimeout, const time::milliseconds& timeoutOverride) { PendingInterestList::iterator it = m_pendingInterests.insert(m_pendingInterests.end(), PendingInterest()); PendingInterest& pi = *it; pi.interest = interest; pi.onData = onData; pi.onNack = onNack; pi.onTimeout = onTimeout; time::milliseconds timeout = interest.getInterestLifetime(); if (timeout < time::milliseconds::zero()) { timeout = time::duration_cast<time::milliseconds>(DEFAULT_INTEREST_LIFETIME); } if (timeoutOverride > time::milliseconds::zero() && timeoutOverride < timeout) { // XXX hack! allow library and network use different timeout, // so that caller doesn't have to manage retx timeout = timeoutOverride; } pi.timeoutEvent = this->getScheduler().schedule(timeout, bind(&ClientFace::onInterestTimeout, this, it)); this->sendInterest(interest); this->trace(TraceEventKind::INTEREST_TO, interest, Nack::NONE); }
iterator Cs::findRightmost(const Interest& interest, iterator first, iterator last) const { // Each loop visits a sub-namespace under a prefix one component longer than Interest Name. // If there is a match in that sub-namespace, the leftmost match is returned; // otherwise, loop continues. size_t interestNameLength = interest.getName().size(); for (iterator right = last; right != first;) { iterator prev = std::prev(right); // special case: [first,prev] have exact Names if (prev->getName().size() == interestNameLength) { NFD_LOG_TRACE(" find-among-exact " << prev->getName()); iterator matchExact = this->findRightmostAmongExact(interest, first, right); return matchExact == right ? last : matchExact; } Name prefix = prev->getName().getPrefix(interestNameLength + 1); iterator left = m_table.lower_bound(prefix); // normal case: [left,right) are under one-component-longer prefix NFD_LOG_TRACE(" find-under-prefix " << prefix); iterator match = this->findLeftmost(interest, left, right); if (match != right) { return match; } right = left; } return last; }
void onInterest(const Name& name, const Interest& interest) { std::cout << "<< I: " << interest << std::endl; // Create new name, based on Interest's name Name dataName(interest.getName()); dataName .append("testApp") // add "testApp" component to Interest name .appendVersion(); // add "version" component (current UNIX timestamp in milliseconds) static const std::string content = "HELLO KITTY"; // Create Data packet Data data; data.setName(dataName); data.setFreshnessPeriod(time::seconds(10)); data.setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.size()); // Sign Data packet with default identity m_keyChain.sign(data); // m_keyChain.sign(data, <identityName>); // m_keyChain.sign(data, <certificate>); // Return Data packet to the requester std::cout << ">> D: " << data << std::endl; m_face.put(data); }
void Tlv0_2WireFormat::decodeInterest (Interest& interest, const uint8_t *input, size_t inputLength, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset) { struct ndn_NameComponent nameComponents[100]; struct ndn_ExcludeEntry excludeEntries[100]; struct ndn_NameComponent keyNameComponents[100]; InterestLite interestLite (nameComponents, sizeof(nameComponents) / sizeof(nameComponents[0]), excludeEntries, sizeof(excludeEntries) / sizeof(excludeEntries[0]), keyNameComponents, sizeof(keyNameComponents) / sizeof(keyNameComponents[0])); ndn_Error error; if ((error = Tlv0_2WireFormatLite::decodeInterest (interestLite, input, inputLength, signedPortionBeginOffset, signedPortionEndOffset))) throw runtime_error(ndn_getErrorString(error)); if (interestLite.getForwardingHintWireEncoding().buf()) { // Throw any decoding exceptions now before calling set. DelegationSet delegationSet; decodeDelegationSet (delegationSet, interestLite.getForwardingHintWireEncoding().buf(), interestLite.getForwardingHintWireEncoding().size()); } interest.set(interestLite, *this); }
void Pib::processCommand(Processor& process, const Interest& interest) { std::pair<bool, Block> result = process(interest); if (result.first) returnResult(Name(interest.getName()).appendVersion(), result.second); }
void PipelineInterests::handleLifeTimeExpiration(const Interest& interest) { uint64_t segno = interest.getName()[-1].toSegment(); m_retxQueue.push(segno); // put on retx queue m_segmentInfoMap[segno]->state = inRetxQueue; // update state handleTimeout(1); }
/** * @brief Send Interest towards application */ virtual void sendInterest(const Interest& interest) { NS_LOG_DEBUG("<< Interest " << interest); shared_ptr<const Interest> interestPtr = interest.shared_from_this(); m_appFaceImpl.m_scheduler.scheduleEvent(time::seconds(0), [this, interestPtr] { m_appFaceImpl.processInterestFilters(*interestPtr); }); }
void processInterestFilters(const Interest& interest) { for (const auto& filter : m_interestFilterTable) { if (filter->doesMatch(interest.getName())) { filter->invokeInterestCallback(interest); } } }
void GenericLinkService::doSendInterest(const Interest& interest, const EndpointId& endpointId) { lp::Packet lpPacket(interest.wireEncode()); encodeLpFields(interest, lpPacket); this->sendNetPacket(std::move(lpPacket), endpointId, true); }
void Forwarder::onInterestLoop(Face& inFace, const Interest& interest, shared_ptr<pit::Entry> pitEntry) { NFD_LOG_DEBUG("onInterestLoop face=" << inFace.getId() << " interest=" << interest.getName()); // (drop) }
// on receipt of Data 2, send Data 1 back void onData(const Interest& interest, const Data& data2, const time::steady_clock::TimePoint& sendI2Time) { // store time that received Data 2 const time::steady_clock::TimePoint& receiveD2Time = time::steady_clock::now(); std::string i2Name = interest.getName().toUri(); size_t delimiter2 = i2Name.find_last_of("/"); std::string prefix2 = i2Name.substr(0,delimiter2); std::string seq2 = i2Name.substr(delimiter2+1); std::cout << "Received Data 2 : " << prefix2 << " - Ping Reference = " << seq2 << std::endl; // *** V2 *** uncomment these lines // get data out of array here // shared_ptr<Data> data1 = arr[currentDataNum]; // ++currentDataNum; // *** V2 *** comment next 15 lines out if making data in advance Name dataName = m_interestName; dataName .append("testApp") // add "testApp" component to interest name .appendVersion(); // add "version" component (current UNIX timestamp in milliseconds) // dummy content static const std::string content = "HELLO KITTY"; // create data packet shared_ptr<Data> data1 = make_shared<Data>(); data1->setName(dataName); data1->setFreshnessPeriod(time::seconds(10)); data1->setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.size()); m_keyChain.sign(*data1); // *** V2 *** comment out to here if making data in advance // store time that sent Data 1 const time::steady_clock::TimePoint& sendD1Time = time::steady_clock::now(); // return data packet to requester m_face.put(*data1); std::string i1Name = m_interestName.toUri(); size_t delimiter1 = i1Name.find_last_of("/"); std::string prefix1 = i1Name.substr(0,delimiter1); std::string seq1 = i1Name.substr(delimiter1+1); std::cout << "Sending Data 1 : " << prefix1 << " - Ping Reference = " << seq1 << std::endl; // store time to write to file auto receiveD2_se = receiveD2Time.time_since_epoch(); m_receiveD2 = time::duration_cast<time::microseconds>(receiveD2_se).count(); auto sendD1_se = sendD1Time.time_since_epoch(); m_sendD1 = time::duration_cast<time::microseconds>(sendD1_se).count(); writeToFile(); }
void AppFace::sendInterest(const Interest& interest) { NS_LOG_FUNCTION(this << &interest); this->emitSignal(onSendInterest, interest); // to decouple callbacks Simulator::ScheduleNow(&App::OnInterest, m_app, interest.shared_from_this()); }
void InternalFace::sendInterest(const Interest& interest) { this->emitSignal(onSendInterest, interest); // Invoke .processInterest a bit later, // to avoid potential problems in forwarding pipelines. scheduler::schedule(time::seconds(0), bind(&InternalFace::processInterest, this, interest.shared_from_this())); }
void Forwarder::onIncomingInterest(Face& inFace, const Interest& interest) { // receive Interest NFD_LOG_DEBUG("onIncomingInterest face=" << inFace.getId() << " interest=" << interest.getName()); const_cast<Interest&>(interest).setIncomingFaceId(inFace.getId()); ++m_counters.getNInInterests(); // /localhost scope control bool isViolatingLocalhost = !inFace.isLocal() && LOCALHOST_NAME.isPrefixOf(interest.getName()); if (isViolatingLocalhost) { NFD_LOG_DEBUG("onIncomingInterest face=" << inFace.getId() << " interest=" << interest.getName() << " violates /localhost"); // (drop) return; } // PIT insert shared_ptr<pit::Entry> pitEntry = m_pit.insert(interest).first; // detect duplicate Nonce int dnw = pitEntry->findNonce(interest.getNonce(), inFace); bool hasDuplicateNonce = (dnw != pit::DUPLICATE_NONCE_NONE) || m_deadNonceList.has(interest.getName(), interest.getNonce()); if (hasDuplicateNonce) { // goto Interest loop pipeline this->onInterestLoop(inFace, interest, pitEntry); return; } // cancel unsatisfy & straggler timer this->cancelUnsatisfyAndStragglerTimer(pitEntry); // is pending? const pit::InRecordCollection& inRecords = pitEntry->getInRecords(); bool isPending = inRecords.begin() != inRecords.end(); if (!isPending) { if (m_csFromNdnSim == nullptr) { m_cs.find(interest, bind(&Forwarder::onContentStoreHit, this, ref(inFace), pitEntry, _1, _2), bind(&Forwarder::onContentStoreMiss, this, ref(inFace), pitEntry, _1)); } else { shared_ptr<Data> match = m_csFromNdnSim->Lookup(interest.shared_from_this()); if (match != nullptr) { this->onContentStoreHit(inFace, pitEntry, interest, *match); } else { this->onContentStoreMiss(inFace, pitEntry, interest); } } } else { this->onContentStoreMiss(inFace, pitEntry, interest); } }
virtual void checkPolicy(const Interest& interest, int stepCount, const ndn::OnInterestValidated& onValidated, const ndn::OnInterestValidationFailed& onValidationFailed, std::vector<shared_ptr<ndn::ValidationRequest> >& nextSteps) { onValidationFailed(interest.shared_from_this(), "No rules for interest."); }
void PipelineInterests::handleData(const Interest& interest, const Data& data) { BOOST_ASSERT(data.getName().equals(interest.getName())); uint64_t recv_segno = data.getName()[-1].toSegment(); if (m_highData < recv_segno) { m_highData = recv_segno; } shared_ptr<SegmentInfo> seg_info = m_segmentInfoMap[recv_segno]; BOOST_ASSERT(seg_info != nullptr); if (seg_info->state == retransmitReceived) { m_segmentInfoMap.erase(recv_segno); return; // ignore already-received segment } if (m_options.isVerbose) { duration_in_ms rtt = time::steady_clock::now() - seg_info->timeSent; std::cerr << "Received the segment #" << recv_segno << ", rtt=" << rtt.count() << "ms" << ", rto=" << seg_info->rto << "ms" << std::endl; } // for segments in retransmission queue, no need to decrement m_inFligh since // it's already been decremented when segments timed out. if (seg_info->state != inRetxQueue && m_inFlight > 0) { m_inFlight--; } m_numOfSegmentReceived++; adjustCwnd(); m_onData(interest, data); if (seg_info->state == firstTimeSent || seg_info->state == inRetxQueue) { // donot sample RTT for retransmitted segments m_rttEstimator.rttMeasurement(recv_segno, seg_info->timeSent, seg_info->rto); m_segmentInfoMap.erase(recv_segno); // remove the entry associated with the received segment } else { // retransmission seg_info->state = retransmitReceived; } if (allSegmentsReceived() == true) { printSummary(); if (m_options.keepStats) { writeStats(); m_rttEstimator.writeStats(); } cancel(); } else { schedulePackets(); } }
void ValidatorConfig::checkPolicy(const Interest& interest, int nSteps, const OnInterestValidated& onValidated, const OnInterestValidationFailed& onValidationFailed, std::vector<shared_ptr<ValidationRequest> >& nextSteps) { if (!m_shouldValidate) return onValidated(interest.shared_from_this()); if (m_stepLimit == nSteps) return onValidationFailed(interest.shared_from_this(), "Maximum steps of validation reached"); bool isMatched = false; int8_t checkResult = -1; for (InterestRuleList::iterator it = m_interestRules.begin(); it != m_interestRules.end(); it++) { if ((*it)->match(interest)) { isMatched = true; checkResult = (*it)->check(interest, onValidated, onValidationFailed); break; } } if (!isMatched) return onValidationFailed(interest.shared_from_this(), "No rule matched!"); if (checkResult == 0) { const Name& interestName = interest.getName(); Name signedName = interestName.getPrefix(-2); Signature signature(interestName[-2].blockFromValue(), interestName[-1].blockFromValue()); checkSignature(interest, signature, nSteps, onValidated, onValidationFailed, nextSteps); } }
void Producer::onInterest(const Interest& interest) { BOOST_ASSERT(m_segments.size() > 0); // std::cout << "Interest: " << interest << std::endl; const Name& name = interest.getName(); shared_ptr<Data> data; // is this a discovery Interest or a sequence retrieval? // if (name.size() == m_prefix.size() + 1 && m_prefix.isPrefixOf(name) && // name[-1].isSegment()) { // const auto segmentNo = static_cast<size_t>(interest.getName()[-1].toSegment()); // // specific segment retrieval // if (segmentNo < m_segments.size()) { // data = m_segments[segmentNo]; // } // } // else if (interest.matchesData(*m_segments[0])) { // // Interest has version and is looking for the first segment or has no version // data = m_segments[0]; // } if (m_prefix.isPrefixOf(name) && name[-1].isSegment()) { const auto segmentNo = static_cast<size_t>(interest.getName()[-1].toSegment()); // specific segment retrieval if (segmentNo < m_segments.size()) { data = m_segments[segmentNo]; } } else if (interest.matchesData(*m_segments[0])) { // Interest has version and is looking for the first segment or has no version data = m_segments[0]; } if (data != nullptr) { // std::cout << "Data: " << *data << std::endl; m_face.put(*data); } }
void DummyClientFace::receive(const Interest& interest) { lp::Packet lpPacket(interest.wireEncode()); addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, interest); addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest); addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest); static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode()); }
void AsfStrategy::forwardInterest(const Interest& interest, const fib::Entry& fibEntry, const shared_ptr<pit::Entry>& pitEntry, Face& outFace, bool wantNewNonce) { if (wantNewNonce) { //Send probe: interest with new Nonce Interest probeInterest(interest); probeInterest.refreshNonce(); NFD_LOG_TRACE("Sending probe for " << probeInterest << probeInterest.getNonce() << " to FaceId: " << outFace.getId()); this->sendInterest(pitEntry, outFace, probeInterest); } else { this->sendInterest(pitEntry, outFace, interest); } FaceInfo& faceInfo = m_measurements.getOrCreateFaceInfo(fibEntry, interest, outFace); // Refresh measurements since Face is being used for forwarding NamespaceInfo& namespaceInfo = m_measurements.getOrCreateNamespaceInfo(fibEntry, interest); namespaceInfo.extendFaceInfoLifetime(faceInfo, outFace); if (!faceInfo.isTimeoutScheduled()) { // Estimate and schedule timeout RttEstimator::Duration timeout = faceInfo.computeRto(); NFD_LOG_TRACE("Scheduling timeout for " << fibEntry.getPrefix() << " FaceId: " << outFace.getId() << " in " << time::duration_cast<time::milliseconds>(timeout) << " ms"); scheduler::EventId id = scheduler::schedule(timeout, bind(&AsfStrategy::onTimeout, this, interest.getName(), outFace.getId())); faceInfo.setTimeoutEvent(id, interest.getName()); } }
virtual uint64_t expressInterest (const Interest& interest, const OnData& onData, const OnTimeout& onTimeout, const OnNetworkNack& onNetworkNack, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) { if (expectedInterest_ != interest.getName()) throw runtime_error("TestFace::expressInterest: Not the expectedInterest_"); ++(*timeoutCount_); onTimeout(ptr_lib::make_shared<Interest>(interest)); return 0; }
ssize_t RepoStorage::deleteData(const Interest& interest) { Interest interestDelete = interest; interestDelete.setChildSelector(0); //to disable the child selector in delete handle int64_t count = 0; bool hasError = false; std::pair<int64_t,ndn::Name> idName = m_index.find(interestDelete); while (idName.first != 0) { bool resultDb = m_storage.erase(idName.first); bool resultIndex = m_index.erase(idName.second); //full name if (resultDb && resultIndex) count++; else hasError = true; idName = m_index.find(interestDelete); } if (hasError) return -1; else return count; }
void Validator::onTimeout(const Interest& interest, int remainingRetries, const OnFailure& onFailure, const shared_ptr<ValidationRequest>& validationRequest) { if (remainingRetries > 0) { Interest newInterest = Interest(interest); newInterest.refreshNonce(); // Express the same interest with different nonce and decremented remainingRetries. m_face->expressInterest(newInterest, bind(&Validator::onData, this, _1, _2, validationRequest), bind(&Validator::onNack, this, _1, _2, remainingRetries - 1, onFailure, validationRequest), bind(&Validator::onTimeout, this, _1, remainingRetries - 1, onFailure, validationRequest)); } else { onFailure("Cannot fetch cert: " + interest.getName().toUri()); } }
/** \brief respond to specific FaceQuery requests * \retval true the Interest matches one of the defined patterns and is responded * \retval false the Interest is not responded */ bool respondFaceQuery(const Interest& interest) { using ndn::nfd::FacePersistency; using ndn::nfd::FaceQueryFilter; using ndn::nfd::FaceStatus; if (!Name("/localhost/nfd/faces/query").isPrefixOf(interest.getName())) { return false; } BOOST_CHECK_EQUAL(interest.getName().size(), 5); FaceQueryFilter filter(interest.getName().at(4).blockFromValue()); if (filter == FaceQueryFilter().setFaceId(10156)) { FaceStatus faceStatus; faceStatus.setFaceId(10156) .setLocalUri("tcp4://151.26.163.27:22967") .setRemoteUri("tcp4://198.57.27.40:6363") .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT); this->sendDataset(interest.getName(), faceStatus); return true; } if (filter == FaceQueryFilter().setRemoteUri("tcp4://32.121.182.82:6363")) { FaceStatus faceStatus; faceStatus.setFaceId(2249) .setLocalUri("tcp4://30.99.87.98:31414") .setRemoteUri("tcp4://32.121.182.82:6363") .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT); this->sendDataset(interest.getName(), faceStatus); return true; } if (filter == FaceQueryFilter().setFaceId(23728)) { this->sendEmptyDataset(interest.getName()); return true; } if (filter == FaceQueryFilter().setRemoteUri("udp4://225.131.75.231:56363")) { FaceStatus faceStatus1, faceStatus2; faceStatus1.setFaceId(6720) .setLocalUri("udp4://202.83.168.28:56363") .setRemoteUri("udp4://225.131.75.231:56363") .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERMANENT); faceStatus2.setFaceId(31066) .setLocalUri("udp4://25.90.26.32:56363") .setRemoteUri("udp4://225.131.75.231:56363") .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERMANENT); this->sendDataset(interest.getName(), faceStatus1, faceStatus2); return true; } return false; }
void KeyChain::sign (Interest& interest, const Name& certificateName, WireFormat& wireFormat) { // TODO: Handle signature algorithms other than Sha256WithRsa. Sha256WithRsaSignature signature; signature.getKeyLocator().setType(ndn_KeyLocatorType_KEYNAME); signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1)); // Append the encoded SignatureInfo. interest.getName().append(wireFormat.encodeSignatureInfo(signature)); // Append an empty signature so that the "signedPortion" is correct. interest.getName().append(Name::Component()); // Encode once to get the signed portion, and sign. SignedBlob encoding = interest.wireEncode(wireFormat); ptr_lib::shared_ptr<Signature> signedSignature = sign (encoding.signedBuf(), encoding.signedSize(), certificateName); // Remove the empty signature and append the real one. interest.setName(interest.getName().getPrefix(-1).append (wireFormat.encodeSignatureValue(*signedSignature))); }