blob: fa0f24d52a1ad71df6f394f7d83379b891b87d00 [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -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 Thompsonaa4e6db2013-07-15 17:25:23 -07005 * See COPYING for copyright and distribution information.
6 */
7
Alexander Afanasyev0222fba2014-02-09 23:16:02 -08008#include "common.hpp"
9
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080010#include "face.hpp"
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070011
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080012#include "security/signature-sha256-with-rsa.hpp"
13
14#include "util/time.hpp"
15#include "util/random.hpp"
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080016#include <cstdlib>
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080017
18#include "management/ndnd-controller.hpp"
19#include "management/nfd-controller.hpp"
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -080020#include "management/nrd-controller.hpp"
Jeff Thompsonb982b6d2013-07-15 18:15:45 -070021
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070022namespace ndn {
Alexander Afanasyevb790d952014-01-24 12:07:53 -080023
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080024Face::Face()
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070025{
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080026 construct(shared_ptr<Transport>(new UnixTransport()),
Alexander Afanasyev505646e2014-02-24 20:13:37 -080027 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080028}
29
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080030Face::Face(const shared_ptr<boost::asio::io_service>& ioService)
31{
32 construct(shared_ptr<Transport>(new UnixTransport()),
Alexander Afanasyev505646e2014-02-24 20:13:37 -080033 ioService);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080034}
35
36Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080037{
38 construct(shared_ptr<Transport>(new TcpTransport(host, port)),
Alexander Afanasyev505646e2014-02-24 20:13:37 -080039 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080040}
41
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080042Face::Face(const shared_ptr<Transport>& transport)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080043{
44 construct(transport,
Alexander Afanasyev505646e2014-02-24 20:13:37 -080045 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080046}
47
48Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080049 const shared_ptr<boost::asio::io_service>& ioService)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080050{
Alexander Afanasyev505646e2014-02-24 20:13:37 -080051 construct(transport, ioService);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080052}
53
Alexander Afanasyev505646e2014-02-24 20:13:37 -080054void
55Face::setController(const shared_ptr<Controller>& controller)
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080056{
Alexander Afanasyev505646e2014-02-24 20:13:37 -080057 m_fwController = controller;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080058}
59
60void
61Face::construct(const shared_ptr<Transport>& transport,
Alexander Afanasyev505646e2014-02-24 20:13:37 -080062 const shared_ptr<boost::asio::io_service>& ioService)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080063{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -080064 m_pitTimeoutCheckTimerActive = false;
65 m_transport = transport;
66 m_ioService = ioService;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080067
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070068 m_pitTimeoutCheckTimer = make_shared<monotonic_deadline_timer>(boost::ref(*m_ioService));
69 m_processEventsTimeoutTimer = make_shared<monotonic_deadline_timer>(boost::ref(*m_ioService));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -080070
Alexander Afanasyev505646e2014-02-24 20:13:37 -080071 if (std::getenv("NFD") != 0)
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -080072 {
Alexander Afanasyev505646e2014-02-24 20:13:37 -080073 if (std::getenv("NRD") != 0)
74 m_fwController = make_shared<nrd::Controller>(boost::ref(*this));
75 else
76 m_fwController = make_shared<nfd::Controller>(boost::ref(*this));
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -080077 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070078 else
Alexander Afanasyev505646e2014-02-24 20:13:37 -080079 m_fwController = make_shared<ndnd::Controller>(boost::ref(*this));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080080}
81
82
83const PendingInterestId*
84Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
85{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -080086 if (!m_transport->isConnected())
87 m_transport->connect(*m_ioService,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080088 bind(&Face::onReceiveElement, this, _1));
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +000089 else if (!m_transport->isExpectingData())
90 m_transport->resume();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080091
92 shared_ptr<const Interest> interestToExpress(new Interest(interest));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -080093
Alexander Afanasyevf39c5372014-02-17 19:42:56 -080094 m_ioService->post(bind(&Face::asyncExpressInterest, this, interestToExpress, onData, onTimeout));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -080095
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080096 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
97}
98
99const PendingInterestId*
100Face::expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800101 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800102 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
103{
104 return expressInterest(Interest(name,
105 tmpl.getMinSuffixComponents(),
106 tmpl.getMaxSuffixComponents(),
107 tmpl.getExclude(),
108 tmpl.getChildSelector(),
109 tmpl.getMustBeFresh(),
110 tmpl.getScope(),
111 tmpl.getInterestLifetime()),
112 onData, onTimeout);
113}
114
115void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800116Face::asyncExpressInterest(const shared_ptr<const Interest>& interest,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800117 const OnData& onData, const OnTimeout& onTimeout)
118{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800119 m_pendingInterestTable.push_back(shared_ptr<PendingInterest>(new PendingInterest
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800120 (interest, onData, onTimeout)));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800121
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800122 if (!interest->getLocalControlHeader().empty(false, true))
123 {
124 // encode only NextHopFaceId towards the forwarder
125 m_transport->send(interest->getLocalControlHeader().wireEncode(*interest, false, true),
126 interest->wireEncode());
127 }
128 else
129 {
130 m_transport->send(interest->wireEncode());
131 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800132
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800133 if (!m_pitTimeoutCheckTimerActive) {
134 m_pitTimeoutCheckTimerActive = true;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700135 m_pitTimeoutCheckTimer->expires_from_now(time::milliseconds(100));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800136 m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire, this));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800137 }
138}
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800139
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800140void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800141Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800142{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800143 if (!m_transport->isConnected())
144 m_transport->connect(*m_ioService,
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800145 bind(&Face::onReceiveElement, this, _1));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800146
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800147 if (!data.getLocalControlHeader().empty(false, true))
148 {
Alexander Afanasyev83018352014-02-18 19:52:15 -0800149 m_transport->send(data.getLocalControlHeader().wireEncode(data, false, true),
150 data.wireEncode());
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800151 }
152 else
153 {
Alexander Afanasyev83018352014-02-18 19:52:15 -0800154 m_transport->send(data.wireEncode());
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800155 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800156}
157
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800158void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800159Face::removePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800160{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800161 m_ioService->post(bind(&Face::asyncRemovePendingInterest, this, pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800162}
163
164
165void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800166Face::asyncRemovePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800167{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800168 m_pendingInterestTable.remove_if(MatchPendingInterestId(pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800169}
170
171const RegisteredPrefixId*
172Face::setInterestFilter(const Name& prefix,
173 const OnInterest& onInterest,
174 const OnSetInterestFilterFailed& onSetInterestFilterFailed)
175{
176 shared_ptr<RegisteredPrefix> prefixToRegister(new RegisteredPrefix(prefix, onInterest));
177
178 m_fwController->selfRegisterPrefix(prefixToRegister->getPrefix(),
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800179 bind(&RegisteredPrefixTable::push_back, &m_registeredPrefixTable, prefixToRegister),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800180 bind(onSetInterestFilterFailed, prefixToRegister->getPrefix(), _1));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800181
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800182 return reinterpret_cast<const RegisteredPrefixId*>(prefixToRegister.get());
183}
184
185void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800186Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800187{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800188 m_ioService->post(bind(&Face::asyncUnsetInterestFilter, this, registeredPrefixId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800189}
190
191void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800192Face::asyncUnsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800193{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800194 RegisteredPrefixTable::iterator i = std::find_if(m_registeredPrefixTable.begin(), m_registeredPrefixTable.end(),
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800195 MatchRegisteredPrefixId(registeredPrefixId));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800196 if (i != m_registeredPrefixTable.end())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800197 {
198 m_fwController->selfDeregisterPrefix((*i)->getPrefix(),
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000199 bind(&Face::finalizeUnsetInterestFilter, this, i),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800200 Controller::FailCallback());
201 }
202
203 // there cannot be two registered prefixes with the same id. if there are, then something is broken
204}
205
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800206void
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000207Face::finalizeUnsetInterestFilter(RegisteredPrefixTable::iterator item)
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800208{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800209 m_registeredPrefixTable.erase(item);
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800210
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800211 if (!m_pitTimeoutCheckTimerActive && m_registeredPrefixTable.empty())
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800212 {
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000213 m_transport->pause();
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800214 if (!m_ioServiceWork) {
215 m_processEventsTimeoutTimer->cancel();
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800216 }
217 }
218}
219
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800220void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700221Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
222 bool keepThread/* = false*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800223{
224 try
225 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700226 if (timeout < time::milliseconds::zero())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800227 {
228 // do not block if timeout is negative, but process pending events
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800229 m_ioService->poll();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800230 return;
231 }
232
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700233 if (timeout > time::milliseconds::zero())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800234 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700235 m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800236 m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800237 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800238
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800239 if (keepThread) {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800240 // work will ensure that m_ioService is running until work object exists
241 m_ioServiceWork = make_shared<boost::asio::io_service::work>(boost::ref(*m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800242 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800243
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800244 m_ioService->run();
245 m_ioService->reset(); // so it is possible to run processEvents again (if necessary)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800246 }
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800247 catch(Face::ProcessEventsTimeout&)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800248 {
249 // break
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800250 m_ioService->reset();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800251 }
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800252 catch(const std::exception&)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800253 {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800254 m_ioService->reset();
255 m_pendingInterestTable.clear();
256 m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800257 throw;
258 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700259}
260
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800261void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700262Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700263{
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700264 m_ioService->post(bind(&Face::asyncShutdown, this));
265}
266
267void
268Face::asyncShutdown()
269{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800270 m_pendingInterestTable.clear();
271 m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800272
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800273 m_transport->close();
274 m_pitTimeoutCheckTimer->cancel();
275 m_processEventsTimeoutTimer->cancel();
276 m_pitTimeoutCheckTimerActive = false;
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700277}
278
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800279void
280Face::fireProcessEventsTimeout(const boost::system::error_code& error)
281{
282 if (!error) // can fire for some other reason, e.g., cancelled
283 throw Face::ProcessEventsTimeout();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700284}
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800285
286void
287Face::checkPitExpire()
288{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700289 // Check for PIT entry timeouts.
290 time::steady_clock::TimePoint now = time::steady_clock::now();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800291
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800292 PendingInterestTable::iterator i = m_pendingInterestTable.begin();
293 while (i != m_pendingInterestTable.end())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800294 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700295 if ((*i)->isTimedOut(now))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800296 {
297 // Save the PendingInterest and remove it from the PIT. Then call the callback.
298 shared_ptr<PendingInterest> pendingInterest = *i;
299
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800300 i = m_pendingInterestTable.erase(i);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800301
302 pendingInterest->callTimeout();
303 }
304 else
305 ++i;
306 }
307
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800308 if (!m_pendingInterestTable.empty()) {
309 m_pitTimeoutCheckTimerActive = true;
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800310
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700311 m_pitTimeoutCheckTimer->expires_from_now(time::milliseconds(100));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800312 m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire, this));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800313 }
314 else {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800315 m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800316
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800317 if (m_registeredPrefixTable.empty()) {
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000318 m_transport->pause();
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800319 if (!m_ioServiceWork) {
320 m_processEventsTimeoutTimer->cancel();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800321 }
322 }
323 }
324}
325
326
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800327void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800328Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800329{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800330 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
331
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800332 if (block.type() == Tlv::Interest)
333 {
334 shared_ptr<Interest> interest(new Interest());
335 interest->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800336 if (&block != &blockFromDaemon)
337 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800338
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800339 processInterestFilters(*interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800340 }
341 else if (block.type() == Tlv::Data)
342 {
343 shared_ptr<Data> data(new Data());
344 data->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800345 if (&block != &blockFromDaemon)
346 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800347
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800348 satisfyPendingInterests(*data);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800349
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800350 if (m_pendingInterestTable.empty()) {
351 m_pitTimeoutCheckTimer->cancel(); // this will cause checkPitExpire invocation
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800352 }
353 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800354 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800355}
356
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800357void
358Face::satisfyPendingInterests(Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800359{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800360 for (PendingInterestTable::iterator i = m_pendingInterestTable.begin ();
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800361 i != m_pendingInterestTable.end();
362 )
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800363 {
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800364 if ((*i)->getInterest()->matchesName(data.getName()))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800365 {
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800366 // Copy pointers to the needed objects and remove the PIT entry before the calling the callback.
367 OnData onData = (*i)->getOnData();
368 shared_ptr<const Interest> interest = (*i)->getInterest();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800369
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800370 PendingInterestTable::iterator next = i;
371 ++next;
372 m_pendingInterestTable.erase(i);
373 i = next;
374
375 if (static_cast<bool>(onData)) {
376 onData(*interest, data);
377 }
378 }
379 else
380 ++i;
381 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800382}
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800383
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800384void
385Face::processInterestFilters(Interest& interest)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800386{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800387 for (RegisteredPrefixTable::iterator i = m_registeredPrefixTable.begin();
388 i != m_registeredPrefixTable.end();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800389 ++i)
390 {
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800391 if ((*i)->getPrefix().isPrefixOf(interest.getName()))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800392 {
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800393 (*i)->getOnInterest()((*i)->getPrefix(), interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800394 }
395 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800396}
397
398} // namespace ndn