blob: d227199f14436b24a59608e0ae6d87342d431c67 [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -07002/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07003 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -07005 * See COPYING for copyright and distribution information.
6 */
7
Jeff Thompsonea141d72013-09-19 14:40:10 -07008#include <stdexcept>
Jeff Thompson9ae4d782013-10-17 10:25:54 -07009#include "c/util/time.h"
Alexander Afanasyev96d914f2014-01-02 22:24:29 -080010
Yingdi Yu61ec2722014-01-20 14:22:32 -080011#include <ndn-cpp-dev/forwarding-entry.hpp>
12#include <ndn-cpp-dev/face-instance.hpp>
13#include <ndn-cpp-dev/node.hpp>
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070014
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080015#include "util/ndnd-id-fetcher.hpp"
Alexander Afanasyev96d914f2014-01-02 22:24:29 -080016
Yingdi Yu61ec2722014-01-20 14:22:32 -080017#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
18#include <ndn-cpp-dev/status-response.hpp>
Alexander Afanasyev18371872014-01-05 23:00:26 -080019
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070020using namespace std;
Alexander Afanasyev6be1a6a2014-01-06 00:08:14 -080021#if NDN_CPP_HAVE_CXX11
22// In the std library, the placeholders are in a different namespace than boost.
23using namespace ndn::func_lib::placeholders;
24#endif
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070025
26namespace ndn {
27
Jeff Thompson62992e42013-10-07 18:50:51 -070028uint64_t Node::PendingInterest::lastPendingInterestId_ = 0;
29uint64_t Node::RegisteredPrefix::lastRegisteredPrefixId_ = 0;
Jeff Thompson11095142013-10-01 16:20:28 -070030
Alexander Afanasyev0b688dc2013-12-18 16:43:37 -080031Node::Node(const ptr_lib::shared_ptr<Transport>& transport)
Alexander Afanasyevbf082112014-01-09 14:27:55 -080032 : pitTimeoutCheckTimerActive_(false)
33 , transport_(transport)
Alexander Afanasyeve1b7a5d2013-12-29 16:23:52 -080034 , ndndIdFetcherInterest_(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"), 4000.0)
35{
36 ioService_ = ptr_lib::make_shared<boost::asio::io_service>();
37 pitTimeoutCheckTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
38 processEventsTimeoutTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
Alexander Afanasyeve1b7a5d2013-12-29 16:23:52 -080039}
40
41Node::Node(const ptr_lib::shared_ptr<Transport>& transport, const ptr_lib::shared_ptr<boost::asio::io_service> &ioService)
42 : ioService_(ioService)
Alexander Afanasyevbf082112014-01-09 14:27:55 -080043 , pitTimeoutCheckTimerActive_(false)
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080044 , transport_(transport)
45 , ndndIdFetcherInterest_(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"), 4000.0)
Jeff Thompson557b81e2013-08-21 15:13:51 -070046{
Alexander Afanasyeve1b7a5d2013-12-29 16:23:52 -080047 pitTimeoutCheckTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
48 processEventsTimeoutTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
Jeff Thompson557b81e2013-08-21 15:13:51 -070049}
50
Jeff Thompson62992e42013-10-07 18:50:51 -070051uint64_t
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080052Node::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070053{
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080054 if (!transport_->isConnected())
Alexander Afanasyeve1b7a5d2013-12-29 16:23:52 -080055 transport_->connect(*ioService_,
Alexander Afanasyev3ae2da22013-12-29 15:50:04 -080056 ptr_lib::bind(&Node::onReceiveElement, this, _1));
Jeff Thompson86507bc2013-08-23 20:51:38 -070057
Jeff Thompson62992e42013-10-07 18:50:51 -070058 uint64_t pendingInterestId = PendingInterest::getNextPendingInterestId();
Jeff Thompsonce115762013-12-18 14:59:56 -080059 pendingInterestTable_.push_back(ptr_lib::shared_ptr<PendingInterest>(new PendingInterest
60 (pendingInterestId, ptr_lib::shared_ptr<const Interest>(new Interest(interest)), onData, onTimeout)));
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080061
62 transport_->send(interest.wireEncode());
Alexander Afanasyevbf082112014-01-09 14:27:55 -080063
64 if (!pitTimeoutCheckTimerActive_) {
65 pitTimeoutCheckTimerActive_ = true;
66 pitTimeoutCheckTimer_->expires_from_now(boost::posix_time::milliseconds(100));
67 pitTimeoutCheckTimer_->async_wait(func_lib::bind(&Node::checkPitExpire, this));
68 }
Jeff Thompson11095142013-10-01 16:20:28 -070069
70 return pendingInterestId;
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070071}
72
Jeff Thompson11095142013-10-01 16:20:28 -070073void
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -080074Node::put(const Data &data)
75{
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -080076 if (!transport_->isConnected())
Alexander Afanasyeve1b7a5d2013-12-29 16:23:52 -080077 transport_->connect(*ioService_,
Alexander Afanasyev3ae2da22013-12-29 15:50:04 -080078 ptr_lib::bind(&Node::onReceiveElement, this, _1));
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -080079
80 transport_->send(data.wireEncode());
81}
82
83
84void
Jeff Thompson62992e42013-10-07 18:50:51 -070085Node::removePendingInterest(uint64_t pendingInterestId)
Jeff Thompson11095142013-10-01 16:20:28 -070086{
87 // Go backwards through the list so we can erase entries.
88 // Remove all entries even though pendingInterestId should be unique.
89 for (int i = (int)pendingInterestTable_.size() - 1; i >= 0; --i) {
90 if (pendingInterestTable_[i]->getPendingInterestId() == pendingInterestId)
91 pendingInterestTable_.erase(pendingInterestTable_.begin() + i);
92 }
93}
94
Jeff Thompson62992e42013-10-07 18:50:51 -070095uint64_t
Jeff Thompson590ec232013-09-18 15:55:56 -070096Node::registerPrefix
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080097 (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags)
Jeff Thompson86507bc2013-08-23 20:51:38 -070098{
Jeff Thompson11095142013-10-01 16:20:28 -070099 // Get the registeredPrefixId now so we can return it to the caller.
Jeff Thompson62992e42013-10-07 18:50:51 -0700100 uint64_t registeredPrefixId = RegisteredPrefix::getNextRegisteredPrefixId();
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800101 ptr_lib::shared_ptr<const Name> prefixPtr = ptr_lib::make_shared<const Name>(prefix);
102
Jeff Thompson86507bc2013-08-23 20:51:38 -0700103 if (ndndId_.size() == 0) {
104 // First fetch the ndndId of the connected hub.
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800105 NdndIdFetcher fetcher(ndndId_,
106 func_lib::bind(&Node::registerPrefixHelper, this,
107 registeredPrefixId, prefixPtr, onInterest, onRegisterFailed, flags),
108 func_lib::bind(onRegisterFailed, prefixPtr));
109
110 // @todo: Check if this crash
Jeff Thompsonce115762013-12-18 14:59:56 -0800111 // It is OK for func_lib::function make a copy of the function object because the Info is in a ptr_lib::shared_ptr.
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800112 expressInterest(ndndIdFetcherInterest_, fetcher, fetcher);
Jeff Thompson86507bc2013-08-23 20:51:38 -0700113 }
114 else
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800115 registerPrefixHelper(registeredPrefixId, prefixPtr, onInterest, onRegisterFailed, flags);
Jeff Thompson11095142013-10-01 16:20:28 -0700116
117 return registeredPrefixId;
118}
119
120void
Jeff Thompson62992e42013-10-07 18:50:51 -0700121Node::removeRegisteredPrefix(uint64_t registeredPrefixId)
Jeff Thompson11095142013-10-01 16:20:28 -0700122{
123 // Go backwards through the list so we can erase entries.
124 // Remove all entries even though pendingInterestId should be unique.
Alexander Afanasyevbc343ef2014-01-09 22:36:20 -0800125
126 for (RegisteredPrefixTable::iterator i = registeredPrefixTable_.begin();
127 i != registeredPrefixTable_.end();
128 ++i)
129 {
130 if ((*i)->getRegisteredPrefixId() == registeredPrefixId) {
131 ForwardingEntry forwardingEntry("unreg", *(*i)->getPrefix(), faceId_);
132 Data data;
133 data.setContent(forwardingEntry.wireEncode());
134
135 SignatureSha256WithRsa signature;
136 signature.setValue(Block(Tlv::SignatureValue, ptr_lib::make_shared<Buffer>()));
137 data.setSignature(signature);
138
139 // Create an interest where the name has the encoded Data packet.
140 Name interestName;
141 interestName.append("ndnx");
142 interestName.append(ndndId_);
143 interestName.append("unreg");
144 interestName.append(data.wireEncode());
145
146 Interest interest(interestName);
147 interest.setScope(1);
148 interest.setInterestLifetime(1000);
149
150 expressInterest(interest, OnData(), OnTimeout());
151
152 registeredPrefixTable_.erase(i);
153 break;
154 }
155 }
Jeff Thompson86507bc2013-08-23 20:51:38 -0700156}
157
Jeff Thompson0050abe2013-09-17 12:50:25 -0700158void
Alexander Afanasyev79100492014-01-03 15:35:38 -0800159Node::registerPrefixHelper(uint64_t registeredPrefixId,
160 const ptr_lib::shared_ptr<const Name>& prefix,
161 const OnInterest& onInterest,
162 const OnRegisterFailed& onRegisterFailed,
163 const ForwardingFlags& flags)
Jeff Thompson86507bc2013-08-23 20:51:38 -0700164{
Jeff Thompson9cc4be42013-08-27 18:12:41 -0700165 // Create a ForwardingEntry.
Alexander Afanasyevfbdfa092013-12-28 20:44:49 -0800166
167 // AlexA: ndnd ignores any freshness that is larger than 3600 sec and sets 300 sec instead
168 // to register "forever" (=2000000000 sec), freshnessPeriod must be omitted
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800169 ForwardingEntry forwardingEntry("selfreg", *prefix, -1, flags, -1);
170 Block content = forwardingEntry.wireEncode();
Jeff Thompson9cc4be42013-08-27 18:12:41 -0700171
172 // Set the ForwardingEntry as the content of a Data packet and sign.
173 Data data;
Jeff Thompsonc2b7b142013-09-12 15:29:04 -0700174 data.setContent(content);
Jeff Thompson9cc4be42013-08-27 18:12:41 -0700175
Alexander Afanasyev79100492014-01-03 15:35:38 -0800176 // Create an empty signature, since nobody going to verify it for now
177 // @todo In the future, we may require real signatures to do the registration
178 SignatureSha256WithRsa signature;
179 signature.setValue(Block(Tlv::SignatureValue, ptr_lib::make_shared<Buffer>()));
180 data.setSignature(signature);
181
Jeff Thompson9cc4be42013-08-27 18:12:41 -0700182 // Create an interest where the name has the encoded Data packet.
183 Name interestName;
Alexander Afanasyev18371872014-01-05 23:00:26 -0800184 interestName.append("ndnx");
Jeff Thompson3a715632013-10-31 11:36:35 -0700185 interestName.append(ndndId_);
Alexander Afanasyev18371872014-01-05 23:00:26 -0800186 interestName.append("selfreg");
Alexander Afanasyev79100492014-01-03 15:35:38 -0800187 interestName.append(data.wireEncode());
Alexander Afanasyev18371872014-01-05 23:00:26 -0800188
Jeff Thompson9cc4be42013-08-27 18:12:41 -0700189 Interest interest(interestName);
190 interest.setScope(1);
Alexander Afanasyev18371872014-01-05 23:00:26 -0800191 interest.setInterestLifetime(1000);
192
193 expressInterest(interest,
194 func_lib::bind(&Node::registerPrefixFinal, this,
195 registeredPrefixId, prefix, onInterest, onRegisterFailed, _1, _2),
196 func_lib::bind(onRegisterFailed, prefix));
197}
198
199void
200Node::registerPrefixFinal(uint64_t registeredPrefixId,
201 const ptr_lib::shared_ptr<const Name>& prefix,
202 const OnInterest& onInterest,
203 const OnRegisterFailed& onRegisterFailed,
204 const ptr_lib::shared_ptr<const Interest>&, const ptr_lib::shared_ptr<Data>&data)
205{
206 Block content = data->getContent();
207 content.parse();
208
209 if (content.getAll().empty())
210 {
211 onRegisterFailed(prefix);
212 return;
213 }
214
Alexander Afanasyeve0c02f52013-12-28 20:44:25 -0800215 Block::element_iterator val = content.getAll().begin();
216
217 switch(val->type())
Alexander Afanasyev18371872014-01-05 23:00:26 -0800218 {
219 case Tlv::FaceManagement::ForwardingEntry:
220 {
Alexander Afanasyeve0c02f52013-12-28 20:44:25 -0800221 ForwardingEntry entry;
222 entry.wireDecode(*val);
223
224 // Save the onInterest callback and send the registration interest.
225 registeredPrefixTable_.push_back(ptr_lib::make_shared<RegisteredPrefix>(registeredPrefixId, prefix, onInterest));
226
227 /// @todo Notify user about successful registration
228
Alexander Afanasyev18371872014-01-05 23:00:26 -0800229 // succeeded
Alexander Afanasyeve0c02f52013-12-28 20:44:25 -0800230 return;
Alexander Afanasyev18371872014-01-05 23:00:26 -0800231 }
232 case Tlv::FaceManagement::StatusResponse:
233 {
234 // failed :(
235 StatusResponse resp;
Alexander Afanasyeve0c02f52013-12-28 20:44:25 -0800236 resp.wireDecode(*val);
Alexander Afanasyev18371872014-01-05 23:00:26 -0800237
Alexander Afanasyevbc343ef2014-01-09 22:36:20 -0800238 // std::cerr << "StatusReponse: " << resp << std::endl;
Alexander Afanasyev18371872014-01-05 23:00:26 -0800239
240 onRegisterFailed(prefix);
241 return;
Alexander Afanasyev18371872014-01-05 23:00:26 -0800242 }
243 default:
244 {
245 // failed :(
246
247 onRegisterFailed(prefix);
248 return;
Alexander Afanasyev18371872014-01-05 23:00:26 -0800249 }
250 }
Jeff Thompson86507bc2013-08-23 20:51:38 -0700251}
252
Jeff Thompson0050abe2013-09-17 12:50:25 -0700253void
Alexander Afanasyevf75a0aa2014-01-09 14:29:22 -0800254Node::processEvents(Milliseconds timeout/* = 0 */, bool keepThread/* = false*/)
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700255{
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800256 try
257 {
Alexander Afanasyevf75a0aa2014-01-09 14:29:22 -0800258 if (timeout < 0)
259 {
260 // do not block if timeout is negative, but process pending events
261 ioService_->poll();
262 return;
263 }
264
265 if (timeout > 0)
266 {
267 processEventsTimeoutTimer_->expires_from_now(boost::posix_time::milliseconds(timeout));
Jeff Thompson6e9fc182014-01-23 13:04:08 -0800268 processEventsTimeoutTimer_->async_wait(&fireProcessEventsTimeout);
Alexander Afanasyevf75a0aa2014-01-09 14:29:22 -0800269 }
270
271 if (keepThread) {
272 // work will ensure that ioService_ is running until work object exists
273 ioServiceWork_ = ptr_lib::make_shared<boost::asio::io_service::work>(boost::ref(*ioService_));
274 }
275
Alexander Afanasyeve1b7a5d2013-12-29 16:23:52 -0800276 ioService_->run();
Alexander Afanasyev8995f542014-01-17 15:33:44 -0800277 ioService_->reset(); // so it is possible to run processEvents again (if necessary)
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800278 }
Alexander Afanasyev3ae2da22013-12-29 15:50:04 -0800279 catch(Node::ProcessEventsTimeout &)
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800280 {
Alexander Afanasyev3ae2da22013-12-29 15:50:04 -0800281 // break
Alexander Afanasyevf75a0aa2014-01-09 14:29:22 -0800282 ioService_->reset();
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800283 }
Alexander Afanasyev8995f542014-01-17 15:33:44 -0800284 catch(const std::exception &)
285 {
286 ioService_->reset();
287 pendingInterestTable_.clear();
288 registeredPrefixTable_.clear();
289 throw;
290 }
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800291}
292
293void
Alexander Afanasyev3ae2da22013-12-29 15:50:04 -0800294Node::fireProcessEventsTimeout(const boost::system::error_code& error)
295{
296 if (!error) // can fire for some other reason, e.g., cancelled
297 throw Node::ProcessEventsTimeout();
298}
299
300void
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800301Node::checkPitExpire()
302{
Jeff Thompson48917f02013-08-21 17:12:45 -0700303 // Check for PIT entry timeouts. Go backwards through the list so we can erase entries.
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700304 MillisecondsSince1970 nowMilliseconds = ndn_getNowMilliseconds();
Jeff Thompson11095142013-10-01 16:20:28 -0700305 for (int i = (int)pendingInterestTable_.size() - 1; i >= 0; --i) {
Jeff Thompson3b0ed532013-11-05 13:43:40 -0800306 if (pendingInterestTable_[i]->isTimedOut(nowMilliseconds)) {
307 // Save the PendingInterest and remove it from the PIT. Then call the callback.
Jeff Thompsonce115762013-12-18 14:59:56 -0800308 ptr_lib::shared_ptr<PendingInterest> pendingInterest = pendingInterestTable_[i];
Jeff Thompson11095142013-10-01 16:20:28 -0700309 pendingInterestTable_.erase(pendingInterestTable_.begin() + i);
Jeff Thompson3b0ed532013-11-05 13:43:40 -0800310 pendingInterest->callTimeout();
Jeff Thompson48917f02013-08-21 17:12:45 -0700311
312 // Refresh now since the timeout callback might have delayed.
Jeff Thompson9ae4d782013-10-17 10:25:54 -0700313 nowMilliseconds = ndn_getNowMilliseconds();
Jeff Thompson48917f02013-08-21 17:12:45 -0700314 }
315 }
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800316
Alexander Afanasyevbf082112014-01-09 14:27:55 -0800317 if (!pendingInterestTable_.empty()) {
Alexander Afanasyevbc343ef2014-01-09 22:36:20 -0800318 pitTimeoutCheckTimerActive_ = true;
319
Alexander Afanasyevbf082112014-01-09 14:27:55 -0800320 pitTimeoutCheckTimer_->expires_from_now(boost::posix_time::milliseconds(100));
321 pitTimeoutCheckTimer_->async_wait(func_lib::bind(&Node::checkPitExpire, this));
322 }
323 else {
324 pitTimeoutCheckTimerActive_ = false;
325
326 if (registeredPrefixTable_.empty()) {
327 transport_->close();
Alexander Afanasyevf75a0aa2014-01-09 14:29:22 -0800328 if (!ioServiceWork_) {
329 processEventsTimeoutTimer_->cancel();
330 }
Alexander Afanasyevbf082112014-01-09 14:27:55 -0800331 }
332 }
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700333}
334
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800335
Jeff Thompson0050abe2013-09-17 12:50:25 -0700336void
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800337Node::onReceiveElement(const Block &block)
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700338{
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800339 if (block.type() == Tlv::Interest)
Alexander Afanasyev96d914f2014-01-02 22:24:29 -0800340 {
341 ptr_lib::shared_ptr<Interest> interest(new Interest());
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800342 interest->wireDecode(block);
Jeff Thompson9cc4be42013-08-27 18:12:41 -0700343
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800344 RegisteredPrefixTable::iterator entry = getEntryForRegisteredPrefix(interest->getName());
345 if (entry != registeredPrefixTable_.end()) {
346 (*entry)->getOnInterest()((*entry)->getPrefix(), interest, *transport_, (*entry)->getRegisteredPrefixId());
347 }
Jeff Thompson557b81e2013-08-21 15:13:51 -0700348 }
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800349 else if (block.type() == Tlv::Data)
Alexander Afanasyev96d914f2014-01-02 22:24:29 -0800350 {
351 ptr_lib::shared_ptr<Data> data(new Data());
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800352 data->wireDecode(block);
353
354 PendingInterestTable::iterator entry = getEntryIndexForExpressedInterest(data->getName());
355 if (entry != pendingInterestTable_.end()) {
Alexander Afanasyev96d914f2014-01-02 22:24:29 -0800356 // Copy pointers to the needed objects and remove the PIT entry before the calling the callback.
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800357 const OnData onData = (*entry)->getOnData();
358 const ptr_lib::shared_ptr<const Interest> interest = (*entry)->getInterest();
359 pendingInterestTable_.erase(entry);
Alexander Afanasyevbc343ef2014-01-09 22:36:20 -0800360
361 if (onData) {
362 onData(interest, data);
363 }
364
365 if (pendingInterestTable_.empty()) {
366 pitTimeoutCheckTimer_->cancel(); // this will cause checkPitExpire invocation
367 }
Alexander Afanasyev96d914f2014-01-02 22:24:29 -0800368 }
369 }
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700370}
371
Jeff Thompson0050abe2013-09-17 12:50:25 -0700372void
373Node::shutdown()
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700374{
Alexander Afanasyev8995f542014-01-17 15:33:44 -0800375 pendingInterestTable_.clear();
376 registeredPrefixTable_.clear();
377
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700378 transport_->close();
Alexander Afanasyevbf082112014-01-09 14:27:55 -0800379 pitTimeoutCheckTimer_->cancel();
380 processEventsTimeoutTimer_->cancel();
381 pitTimeoutCheckTimerActive_ = false;
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700382}
383
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800384Node::PendingInterestTable::iterator
Jeff Thompson0050abe2013-09-17 12:50:25 -0700385Node::getEntryIndexForExpressedInterest(const Name& name)
Jeff Thompson557b81e2013-08-21 15:13:51 -0700386{
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800387 for (PendingInterestTable::iterator i = pendingInterestTable_.begin ();
388 i != pendingInterestTable_.end(); ++i)
389 {
390 if ((*i)->getInterest()->matchesName(name))
391 {
392 return i;
393 }
Jeff Thompson557b81e2013-08-21 15:13:51 -0700394 }
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800395
396 return pendingInterestTable_.end();
Jeff Thompson557b81e2013-08-21 15:13:51 -0700397}
Jeff Thompson86507bc2013-08-23 20:51:38 -0700398
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800399Node::RegisteredPrefixTable::iterator
Jeff Thompson0050abe2013-09-17 12:50:25 -0700400Node::getEntryForRegisteredPrefix(const Name& name)
Jeff Thompson9cc4be42013-08-27 18:12:41 -0700401{
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800402 RegisteredPrefixTable::iterator longestPrefix = registeredPrefixTable_.end();
403
404 for (RegisteredPrefixTable::iterator i = registeredPrefixTable_.begin();
405 i != registeredPrefixTable_.end();
406 ++i)
407 {
408 if (longestPrefix == registeredPrefixTable_.end() ||
409 (*i)->getPrefix()->size() > (*longestPrefix)->getPrefix()->size())
410 {
411 longestPrefix = i;
412 }
Jeff Thompson9cc4be42013-08-27 18:12:41 -0700413 }
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800414 return longestPrefix;
Jeff Thompson9cc4be42013-08-27 18:12:41 -0700415}
416
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800417Node::PendingInterest::PendingInterest(uint64_t pendingInterestId,
418 const ptr_lib::shared_ptr<const Interest>& interest,
419 const OnData& onData, const OnTimeout& onTimeout)
420: pendingInterestId_(pendingInterestId),
421 interest_(interest),
422 onData_(onData), onTimeout_(onTimeout)
Jeff Thompson86507bc2013-08-23 20:51:38 -0700423{
424 // Set up timeoutTime_.
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800425 if (interest_->getInterestLifetime() >= 0)
426 timeoutTimeMilliseconds_ = ndn_getNowMilliseconds() + interest_->getInterestLifetime();
Jeff Thompson86507bc2013-08-23 20:51:38 -0700427 else
428 // No timeout.
Alexander Afanasyevb24a68a2013-12-28 16:53:21 -0800429 /**
430 * @todo Set more meaningful default timeout. This timeout MUST exist.
431 */
432 timeoutTimeMilliseconds_ = ndn_getNowMilliseconds() + 4000;
Jeff Thompson86507bc2013-08-23 20:51:38 -0700433}
434
Jeff Thompson3b0ed532013-11-05 13:43:40 -0800435void
436Node::PendingInterest::callTimeout()
Jeff Thompson86507bc2013-08-23 20:51:38 -0700437{
Jeff Thompson3b0ed532013-11-05 13:43:40 -0800438 if (onTimeout_) {
Alexander Afanasyevbc343ef2014-01-09 22:36:20 -0800439 onTimeout_(interest_);
Jeff Thompson86507bc2013-08-23 20:51:38 -0700440 }
Jeff Thompson86507bc2013-08-23 20:51:38 -0700441}
Jeff Thompson557b81e2013-08-21 15:13:51 -0700442
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700443}