void Node::expressInterestHelper (uint64_t pendingInterestId, const ptr_lib::shared_ptr<const Interest>& interestCopy, const OnData& onData, const OnTimeout& onTimeout, WireFormat* wireFormat, Face* face) { ptr_lib::shared_ptr<PendingInterest> pendingInterest(new PendingInterest (pendingInterestId, interestCopy, onData, onTimeout)); pendingInterestTable_.push_back(pendingInterest); if (interestCopy->getInterestLifetimeMilliseconds() >= 0.0) // Set up the timeout. face->callLater (interestCopy->getInterestLifetimeMilliseconds(), bind(&Node::processInterestTimeout, this, pendingInterest)); // Special case: For timeoutPrefix_ we don't actually send the interest. if (!timeoutPrefix_.match(interestCopy->getName())) { Blob encoding = interestCopy->wireEncode(*wireFormat); if (encoding.size() > getMaxNdnPacketSize()) throw runtime_error ("The encoded interest size exceeds the maximum limit getMaxNdnPacketSize()"); transport_->send(*encoding); } }
void Chat::onData (const ptr_lib::shared_ptr<const Interest>& interest, const ptr_lib::shared_ptr<Data>& data) { SyncDemo::ChatMessage content; content.ParseFromArray(data->getContent().buf(), data->getContent().size()); if (getNowMilliseconds() - content.timestamp() * 1000.0 < 120000.0) { string name = content.from(); string prefix = data->getName().getPrefix(-2).toUri(); int sessionNo = ::atoi(data->getName().get(-2).toEscapedString().c_str()); int sequenceNo = ::atoi(data->getName().get(-1).toEscapedString().c_str()); ostringstream tempStream; tempStream << name << sessionNo; string nameAndSession = tempStream.str(); size_t l = 0; //update roster while (l < roster_.size()) { string tempName2 = roster_[l].substr(0, roster_[l].size() - 10); int tempSessionNo = ::atoi(roster_[l].substr(roster_[l].size() - 10, 10).c_str()); if (name != tempName2 && content.type() != SyncDemo::ChatMessage_ChatMessageType_LEAVE) ++l; else { if (name == tempName2 && sessionNo > tempSessionNo) roster_[l] = nameAndSession; break; } } if (l == roster_.size()) { roster_.push_back(nameAndSession); cout << name << ": Join" << endl; } // Set the alive timeout using the Interest timeout mechanism. // TODO: Are we sure using a "/local/timeout" interest is the best future call approach? Interest timeout("/local/timeout"); timeout.setInterestLifetimeMilliseconds(120000); face_.expressInterest (timeout, dummyOnData, bind(&Chat::alive, shared_from_this(), _1, sequenceNo, name, sessionNo, prefix)); // isRecoverySyncState_ was set by sendInterest. // TODO: If isRecoverySyncState_ changed, this assumes that we won't get // data from an interest sent before it changed. if (content.type() == SyncDemo::ChatMessage_ChatMessageType_CHAT && !isRecoverySyncState_ && content.from() != screenName_) cout << content.from() << ": " << content.data() << endl; else if (content.type() == SyncDemo::ChatMessage_ChatMessageType_LEAVE) { // leave message int n = rosterFind(nameAndSession); if (n >= 0 && name != screenName_) { roster_.erase(roster_.begin() + n); cout << name << ": Leave" << endl; } } } }
void onData(const ptr_lib::shared_ptr<const Interest>& interest, const ptr_lib::shared_ptr<Data>& data) { ++callbackCount_; cout << "Got data packet with name " << data->getName().toUri() << endl; for (size_t i = 0; i < data->getContent().size(); ++i) cout << (*data->getContent())[i]; cout << endl; }
void NdndIdFetcher::operator()(const ptr_lib::shared_ptr<const Interest>& interest, const ptr_lib::shared_ptr<Data>& ndndIdData) { if (ndndIdData->getSignature().getType() == Signature::Sha256WithRsa) { ndndId_.resize(32); ndn_digestSha256(ndndIdData->getContent().value(), ndndIdData->getContent().value_size(), ndndId_.buf()); onSuccess_(); } else onFailure_(); }
ptr_lib::shared_ptr<ValidationRequest> SelfVerifyPolicyManager::checkVerificationPolicy (const ptr_lib::shared_ptr<Data>& data, int stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed) { // wireEncode returns the cached encoding if available. if (verify(data->getSignature(), data->wireEncode())) onVerified(data); else onVerifyFailed(data); // No more steps, so return a null ValidationRequest. return ptr_lib::shared_ptr<ValidationRequest>(); }
/** * This is called when the face create command responds to decode the * encodedControlResonse as a TLV ControlResponse message containing one * ControlParameters. Get the face ID and call registerRoute(). * @param expressedInterest The interest given to expressInterest. * @param responseData The response Data packet whose content is the * TLV-encoded ControlResponse. * @param prefix The prefix name to register. * @param face The Face which is used to sign the command interest and call * expressInterest. * @param enabled On success or error, set *enabled = false. */ static void processCreateFaceResponse (const ptr_lib::shared_ptr<const Interest>& expressedInterest, const ptr_lib::shared_ptr<Data>& responseData, const Name& prefix, Face* face, bool* enabled) { ndn_message::ControlParametersTypes_ControlParametersResponseMessage controlResponseMessage; ProtobufTlv::decode(controlResponseMessage, responseData->getContent()); const ndn_message::ControlParametersTypes_ControlParametersResponse& controlResponse = controlResponseMessage.control_response(); const int lowestErrorCode = 400; if (controlResponse.status_code() >= lowestErrorCode) { cout << "Face create command got error, code " << controlResponse.status_code() << ": " + controlResponse.status_text() << endl; *enabled = false; return; } if (controlResponse.control_parameters_size() != 1) { cout << "Face create command response does not have one ControlParameters" << endl; *enabled = false; return; } boost::uint64_t faceId = controlResponse.control_parameters(0).face_id(); cout << "Created face ID " << faceId << endl; registerRoute(prefix, faceId, face, enabled); }
void PrivateKeyStorage::decodeEcPrivateKey (const ptr_lib::shared_ptr<DerNode>& algorithmParameters, const Blob& privateKeyDer, EcPrivateKeyLite& privateKey) { // Find the curveId in EC_KEY_INFO. int curveId = -1; string oidString = algorithmParameters->toVal().toRawStr(); for (size_t i = 0 ; i < ndn_getEcKeyInfoCount(); ++i) { const struct ndn_EcKeyInfo *info = ndn_getEcKeyInfo(i); OID curveOid(info->oidIntegerList, info->oidIntegerListLength); if (curveOid.toString() == oidString) { curveId = info->curveId; break; } } if (curveId == -1) throw SecurityException ("FilePrivateKeyStorage::decodeEcPrivateKey: Unrecognized EC algorithm parameters"); // Get the value in the octet string. ptr_lib::shared_ptr<DerNode> parsedNode = DerNode::parse(privateKeyDer.buf(), 0); DerNode::DerOctetString* octetString = dynamic_cast<DerNode::DerOctetString*> (parsedNode->getChildren()[1].get()); if (!octetString) throw SecurityException ("FilePrivateKeyStorage::decodeEcPrivateKey: Can't get the private key octet string"); Blob octetStringValue = octetString->toVal(); ndn_Error error; if ((error = privateKey.setByCurve(curveId, octetStringValue))) throw SecurityException (string("PrivateKeyStorage::decodeEcPrivateKey ") + ndn_getErrorString(error)); }
/** * This is called when a new prefix list (or the first list) is reported by the * local NFD. * @param prefix The new prefix list. */ static void onPrefixes(const ptr_lib::shared_ptr<vector<Name> >& prefixes) { cout << "Got prefix(es):"; for (size_t i = 0; i < prefixes->size(); ++i) cout << " " << (*prefixes)[i].toUri(); cout << endl; }
/** * Create a new Entry with the given values. * @param interestFilterId The ID from Node::getNextEntryId(). * @param filter A shared_ptr for the InterestFilter for this entry. * @param onInterest A function object to call when a matching data packet * is received. * @param face The face on which was called registerPrefix or * setInterestFilter which is passed to the onInterest callback. */ Entry (uint64_t interestFilterId, const ptr_lib::shared_ptr<const InterestFilter>& filter, const OnInterestCallback& onInterest, Face* face) : interestFilterId_(interestFilterId), filter_(filter), prefix_(new Name(filter->getPrefix())), onInterest_(onInterest), face_(face) { }
void Chat::messageCacheAppend(int messageType, const string& message) { messageCache_.push_back(ptr_lib::make_shared<CachedMessage> (sync_->getSequenceNo(), messageType, message, getNowMilliseconds())); while (messageCache_.size() > maxMessageCacheLength_) messageCache_.erase(messageCache_.begin()); }
void SecPublicInfo::refreshDefaultCertificate() { Name certName = getDefaultCertificateNameForIdentity(getDefaultIdentity()); if(certName.empty()) defaultCertificate_.reset(); else defaultCertificate_ = getCertificate(certName); }
void Chat::onInterest (const ptr_lib::shared_ptr<const Name>& prefix, const ptr_lib::shared_ptr<const Interest>& interest, Face& face, uint64_t interestFilterId, const ptr_lib::shared_ptr<const InterestFilter>& filter) { SyncDemo::ChatMessage content; int sequenceNo = ::atoi(interest->getName().get(chatPrefix_.size() + 1).toEscapedString().c_str()); for (int i = messageCache_.size() - 1; i >= 0; --i) { if (messageCache_[i]->getSequenceNo() == sequenceNo) { if (messageCache_[i]->getMessageType() != SyncDemo::ChatMessage_ChatMessageType_CHAT) { content.set_from(screenName_); content.set_to(chatRoom_); content.set_type((SyncDemo::ChatMessage_ChatMessageType)messageCache_[i]->getMessageType()); content.set_timestamp(::round(messageCache_[i]->getTime() / 1000.0)); } else { content.set_from(screenName_); content.set_to(chatRoom_); content.set_type((SyncDemo::ChatMessage_ChatMessageType)messageCache_[i]->getMessageType()); content.set_data(messageCache_[i]->getMessage()); content.set_timestamp(::round(messageCache_[i]->getTime() / 1000.0)); } break; } } if (content.from().size() != 0) { ptr_lib::shared_ptr<vector<uint8_t> > array(new vector<uint8_t>(content.ByteSize())); content.SerializeToArray(&array->front(), array->size()); Data data(interest->getName()); data.setContent(Blob(array, false)); keyChain_.sign(data, certificateName_); try { face.putData(data); } catch (std::exception& e) { cout << "Error sending the chat data " << e.what() << endl; } } }
Name SecPublicInfo::getDefaultCertificateName() { if(!static_cast<bool>(defaultCertificate_)) refreshDefaultCertificate(); if(!static_cast<bool>(defaultCertificate_)) return Name(); return defaultCertificate_->getName(); }
void Node::RegisterResponse::operator()(const ptr_lib::shared_ptr<const Interest>& interest, const ptr_lib::shared_ptr<Data>& responseData) { // Decode responseData->getContent() and check for a success code. // TODO: Move this into the TLV code. struct ndn_TlvDecoder decoder; ndn_TlvDecoder_initialize (&decoder, responseData->getContent().buf(), responseData->getContent().size()); ndn_Error error; size_t endOffset; if ((error = ndn_TlvDecoder_readNestedTlvsStart (&decoder, ndn_Tlv_NfdCommand_ControlResponse, &endOffset))) { _LOG_DEBUG ("Register prefix failed: Error decoding the NFD response: " << ndn_getErrorString(error)); info_->onRegisterFailed_(info_->prefix_); return; } uint64_t statusCode; if ((error = ndn_TlvDecoder_readNonNegativeIntegerTlv (&decoder, ndn_Tlv_NfdCommand_StatusCode, &statusCode))) { _LOG_DEBUG ("Register prefix failed: Error decoding the NFD response: " << ndn_getErrorString(error)); info_->onRegisterFailed_(info_->prefix_); return; } // Status code 200 is "OK". if (statusCode != 200) { _LOG_DEBUG ("Register prefix failed: Expected NFD status code 200, got: " << statusCode); info_->onRegisterFailed_(info_->prefix_); return; } _LOG_DEBUG("Register prefix succeeded with the NFD forwarder for prefix " << info_->prefix_->toUri()); }
void Node::processInterestTimeout(ptr_lib::shared_ptr<PendingInterest> pendingInterest) { if (pendingInterest->getIsRemoved()) // extractEntriesForExpressedInterest or removePendingInterest has removed // pendingInterest from pendingInterestTable_, so we don't need to look for // it. Do nothing. return; // Find the entry. for (vector<ptr_lib::shared_ptr<PendingInterest> >::iterator entry = pendingInterestTable_.begin(); entry != pendingInterestTable_.end(); ++entry) { if (entry->get() == pendingInterest.get()) { pendingInterestTable_.erase(entry); pendingInterest->callTimeout(); return; } } // The pending interest has been removed. Do nothing. }
ptr_lib::shared_ptr<ValidationRequest> SelfVerifyPolicyManager::checkVerificationPolicy (const ptr_lib::shared_ptr<Interest>& interest, int stepCount, const OnVerifiedInterest& onVerified, const OnVerifyInterestFailed& onVerifyFailed, WireFormat& wireFormat) { // Decode the last two name components of the signed interest ptr_lib::shared_ptr<Signature> signature = wireFormat.decodeSignatureInfoAndValue (interest->getName().get(-2).getValue().buf(), interest->getName().get(-2).getValue().size(), interest->getName().get(-1).getValue().buf(), interest->getName().get(-1).getValue().size()); // wireEncode returns the cached encoding if available. if (verify(signature.get(), interest->wireEncode())) onVerified(interest); else onVerifyFailed(interest); // No more steps, so return a null ValidationRequest. return ptr_lib::shared_ptr<ValidationRequest>(); }
void Chat::sendMessage(const string& chatMessage) { if (messageCache_.size() == 0) messageCacheAppend(SyncDemo::ChatMessage_ChatMessageType_JOIN, "xxx"); // Ignore an empty message. // forming Sync Data Packet. if (chatMessage != "") { sync_->publishNextSequenceNo(); messageCacheAppend(SyncDemo::ChatMessage_ChatMessageType_CHAT, chatMessage); cout << screenName_ << ": " << chatMessage << endl; } }
void onInterest(const ptr_lib::shared_ptr<const Name> &name, const ptr_lib::shared_ptr<const Interest> &interest) { std::cout << "<< I: " << *interest << std::endl; ndn::Data data(ndn::Name(interest->getName()).append("testApp").appendVersion()); data.setFreshnessPeriod(1000); // 10 sec data.setContent((const uint8_t*)"HELLO KITTY", sizeof("HELLO KITTY")); keyChain_.sign(data); std::cout << ">> D: " << data << std::endl; face_.put(data); }
void Chat::heartbeat(const ptr_lib::shared_ptr<const Interest> &interest) { if (messageCache_.size() == 0) messageCacheAppend(SyncDemo::ChatMessage_ChatMessageType_JOIN, "xxx"); sync_->publishNextSequenceNo(); messageCacheAppend(SyncDemo::ChatMessage_ChatMessageType_HELLO, "xxx"); // Call again. // TODO: Are we sure using a "/local/timeout" interest is the best future call approach? Interest timeout("/local/timeout"); timeout.setInterestLifetimeMilliseconds(60000); face_.expressInterest(timeout, dummyOnData, bind(&Chat::heartbeat, shared_from_this(), _1)); }
void checkEncryptionKeys (const vector<ptr_lib::shared_ptr<Data> >& result, MillisecondsSince1970 testTime, const Name::Component roundedTime, int expectedExpressInterestCallCount, const int* expressInterestCallCount, Blob* contentKey, Name cKeyName, ptr_lib::shared_ptr<ProducerDb> testDb) { ASSERT_EQ(expectedExpressInterestCallCount, *expressInterestCallCount); ASSERT_EQ(true, testDb->hasContentKey(testTime)); (*contentKey) = testDb->getContentKey(testTime); EncryptParams params(ndn_EncryptAlgorithmType_RsaOaep); for (size_t i = 0; i < result.size(); ++i) { const Data& key = *result[i]; const Name& keyName = key.getName(); ASSERT_EQ(cKeyName, keyName.getSubName(0, 6)); ASSERT_EQ(keyName.get(6), roundedTime); ASSERT_EQ(keyName.get(7), Encryptor::getNAME_COMPONENT_FOR()); ASSERT_EQ(true, decryptionKeys.find(keyName.getSubName(8)) != decryptionKeys.end()); Blob decryptionKey = decryptionKeys[keyName.getSubName(8)]; ASSERT_EQ(true, decryptionKey.size() != 0); const Blob& encryptedKeyEncoding = key.getContent(); EncryptedContent content; content.wireDecode(encryptedKeyEncoding); Blob encryptedKey = content.getPayload(); Blob retrievedKey = RsaAlgorithm::decrypt (decryptionKey, encryptedKey, params); ASSERT_TRUE(contentKey->equals(retrievedKey)); } ASSERT_EQ(3, result.size()); }
void BoostInfoTree::addSubtree (const string& treeName, ptr_lib::shared_ptr<BoostInfoTree> newTree) { vector<ptr_lib::shared_ptr<BoostInfoTree> >* subtreeList = find(treeName); if (subtreeList) subtreeList->push_back(newTree); else { subtrees_.push_back(make_pair (treeName, vector<ptr_lib::shared_ptr<BoostInfoTree> >())); subtrees_.back().second.push_back(newTree); } newTree->parent_ = this; lastChild_ = newTree.get(); }
void Chat::alive (const ptr_lib::shared_ptr<const Interest> &interest, int tempSequenceNo, const string& name, int sessionNo, const string& prefix) { int sequenceNo = sync_->getProducerSequenceNo(prefix, sessionNo); ostringstream tempStream; tempStream << name << sessionNo; string nameAndSession = tempStream.str(); int n = rosterFind(nameAndSession); if (sequenceNo != -1 && n >= 0) { if (tempSequenceNo == sequenceNo){ roster_.erase(roster_.begin() + n); cout << name << ": Leave" << endl; } } }
/** * This is called when the register route command responds to decode the * encodedControlResponse as a TLV ControlParametersResponse message * containing one ControlParameters. On success, print the ControlParameters * values which should be the same as requested. * @param expressedInterest The interest given to expressInterest. * @param responseData The response Data packet whose content is the TLV-encoded * ControlParametersResponse. * @param enabled On success or error, set *enabled = false. */ static void processRegisterResponse (const ptr_lib::shared_ptr<const Interest>& expressedInterest, const ptr_lib::shared_ptr<Data>& responseData, bool* enabled) { // We are finished in all cases. *enabled = false; ndn_message::ControlParametersTypes_ControlParametersResponseMessage decodedControlResponse; ProtobufTlv::decode(decodedControlResponse, responseData->getContent()); const ndn_message::ControlParametersTypes_ControlParametersResponse& controlResponse = decodedControlResponse.control_response(); const boost::uint64_t lowestErrorCode = 400; if (controlResponse.status_code() >= lowestErrorCode) { cout << "Face create command got error, code " << controlResponse.status_code() <<": " + controlResponse.status_text(); return; } if (controlResponse.control_parameters_size() != 1) { cout << "Face create command response does not have one ControlParameters"; return; } // Success. Print the ControlParameters response. const ndn_message::ControlParametersTypes_ControlParameters& controlParameters = controlResponse.control_parameters(0); string name = ""; for (size_t i = 0; i < controlParameters.name().component_size(); ++i) name += "/" + controlParameters.name().component(i); cout << "Successful in name registration: ControlParameters(Name: " << name << ", FaceId: " << controlParameters.face_id() << ", Origin: " << controlParameters.origin() << ", Cost: " << controlParameters.cost() << ", Flags: " << controlParameters.flags() << ")" << endl; }
static void onRegisterFailed(const ptr_lib::shared_ptr<const Name>& prefix) { cout << "Register failed for prefix " << prefix->toUri() << endl; }
void Chat::leave() { sync_->publishNextSequenceNo(); messageCacheAppend(SyncDemo::ChatMessage_ChatMessageType_LEAVE, "xxx"); }
void MemoryContentCache::operator() (const ptr_lib::shared_ptr<const Name>& prefix, const ptr_lib::shared_ptr<const Interest>& interest, Face& face, boost::uint64_t interestFilterId, const ptr_lib::shared_ptr<const InterestFilter>& filter) { doCleanup(); const Name::Component* selectedComponent = 0; Blob selectedEncoding; // We need to iterate over both arrays. size_t totalSize = staleTimeCache_.size() + noStaleTimeCache_.size(); for (size_t i = 0; i < totalSize; ++i) { const Content* content; if (i < staleTimeCache_.size()) content = staleTimeCache_[i].get(); else // We have iterated over the first array. Get from the second. content = noStaleTimeCache_[i - staleTimeCache_.size()].get(); if (interest->matchesName(content->getName())) { if (interest->getChildSelector() < 0) { // No child selector, so send the first match that we have found. face.send(*content->getDataEncoding()); return; } else { // Update selectedEncoding based on the child selector. const Name::Component* component; if (content->getName().size() > interest->getName().size()) component = &content->getName().get(interest->getName().size()); else component = &emptyComponent_; bool gotBetterMatch = false; if (!selectedEncoding) // Save the first match. gotBetterMatch = true; else { if (interest->getChildSelector() == 0) { // Leftmost child. if (*component < *selectedComponent) gotBetterMatch = true; } else { // Rightmost child. if (*component > *selectedComponent) gotBetterMatch = true; } } if (gotBetterMatch) { selectedComponent = component; selectedEncoding = content->getDataEncoding(); } } } } if (selectedEncoding) // We found the leftmost or rightmost child. face.send(*selectedEncoding); else { // Call the onDataNotFound callback (if defined). map<string, OnInterestCallback>::iterator onDataNotFound = onDataNotFoundForPrefix_.find(prefix->toUri()); if (onDataNotFound != onDataNotFoundForPrefix_.end() && onDataNotFound->second) onDataNotFound->second(prefix, interest, face, interestFilterId, filter); } }
void onTimeout(const ptr_lib::shared_ptr<const Interest>& interest) { ++callbackCount_; cout << "Time out for interest " << interest->getName().toUri() << endl; }