blob: 04e2570d8becddca592e61201d36a702a1c668b2 [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"
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060016#include "util/config-file.hpp"
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080017#include <cstdlib>
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080018
19#include "management/ndnd-controller.hpp"
20#include "management/nfd-controller.hpp"
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -080021#include "management/nrd-controller.hpp"
Jeff Thompsonb982b6d2013-07-15 18:15:45 -070022
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070023namespace ndn {
Alexander Afanasyevb790d952014-01-24 12:07:53 -080024
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080025Face::Face()
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070026{
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060027 const std::string socketName = UnixTransport::getDefaultSocketName(m_config);
28 construct(shared_ptr<Transport>(new UnixTransport(socketName)),
Alexander Afanasyev505646e2014-02-24 20:13:37 -080029 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080030}
31
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080032Face::Face(const shared_ptr<boost::asio::io_service>& ioService)
33{
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060034 const std::string socketName = UnixTransport::getDefaultSocketName(m_config);
35 construct(shared_ptr<Transport>(new UnixTransport(socketName)),
Alexander Afanasyev505646e2014-02-24 20:13:37 -080036 ioService);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080037}
38
39Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080040{
41 construct(shared_ptr<Transport>(new TcpTransport(host, port)),
Alexander Afanasyev505646e2014-02-24 20:13:37 -080042 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080043}
44
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080045Face::Face(const shared_ptr<Transport>& transport)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080046{
47 construct(transport,
Alexander Afanasyev505646e2014-02-24 20:13:37 -080048 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080049}
50
51Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080052 const shared_ptr<boost::asio::io_service>& ioService)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080053{
Alexander Afanasyev505646e2014-02-24 20:13:37 -080054 construct(transport, ioService);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080055}
56
Alexander Afanasyev505646e2014-02-24 20:13:37 -080057void
58Face::setController(const shared_ptr<Controller>& controller)
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080059{
Alexander Afanasyev505646e2014-02-24 20:13:37 -080060 m_fwController = controller;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080061}
62
63void
64Face::construct(const shared_ptr<Transport>& transport,
Alexander Afanasyev505646e2014-02-24 20:13:37 -080065 const shared_ptr<boost::asio::io_service>& ioService)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080066{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -080067 m_pitTimeoutCheckTimerActive = false;
68 m_transport = transport;
69 m_ioService = ioService;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080070
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070071 m_pitTimeoutCheckTimer = make_shared<monotonic_deadline_timer>(boost::ref(*m_ioService));
72 m_processEventsTimeoutTimer = make_shared<monotonic_deadline_timer>(boost::ref(*m_ioService));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -080073
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060074 std::string protocol = "nrd-0.1";
75
76 try
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -080077 {
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060078 protocol = m_config.getParsedConfiguration().get<std::string>("protocol");
79 }
80 catch (const boost::property_tree::ptree_bad_path& error)
81 {
82 // protocol not specified
83 }
84 catch (const boost::property_tree::ptree_bad_data& error)
85 {
86 throw ConfigFile::Error(error.what());
87 }
88
89 if (isSupportedNrdProtocol(protocol))
90 {
91 m_fwController = make_shared<nrd::Controller>(boost::ref(*this));
92 }
Steve DiBenedettoacab8802014-03-24 11:15:57 -060093 else if (isSupportedNfdProtocol(protocol))
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060094 {
95 m_fwController = make_shared<nfd::Controller>(boost::ref(*this));
96 }
97 else if (isSupportedNdndProtocol(protocol))
98 {
99 m_fwController = make_shared<ndnd::Controller>(boost::ref(*this));
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -0800100 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700101 else
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600102 {
103 throw Face::Error("Cannot create controller for unsupported protocol \"" + protocol + "\"");
104 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800105}
106
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800107const PendingInterestId*
108Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
109{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800110 if (!m_transport->isConnected())
111 m_transport->connect(*m_ioService,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800112 bind(&Face::onReceiveElement, this, _1));
113
114 shared_ptr<const Interest> interestToExpress(new Interest(interest));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800115
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700116 // If the same ioService thread, dispatch directly calls the method
117 m_ioService->dispatch(bind(&Face::asyncExpressInterest, this,
118 interestToExpress, onData, onTimeout));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800119
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800120 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
121}
122
123const PendingInterestId*
124Face::expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800125 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800126 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
127{
128 return expressInterest(Interest(name,
129 tmpl.getMinSuffixComponents(),
130 tmpl.getMaxSuffixComponents(),
131 tmpl.getExclude(),
132 tmpl.getChildSelector(),
133 tmpl.getMustBeFresh(),
134 tmpl.getScope(),
135 tmpl.getInterestLifetime()),
136 onData, onTimeout);
137}
138
139void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800140Face::asyncExpressInterest(const shared_ptr<const Interest>& interest,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800141 const OnData& onData, const OnTimeout& onTimeout)
142{
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700143 if (!m_transport->isExpectingData())
144 m_transport->resume();
145
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800146 m_pendingInterestTable.push_back(shared_ptr<PendingInterest>(new PendingInterest
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800147 (interest, onData, onTimeout)));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800148
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800149 if (!interest->getLocalControlHeader().empty(false, true))
150 {
151 // encode only NextHopFaceId towards the forwarder
152 m_transport->send(interest->getLocalControlHeader().wireEncode(*interest, false, true),
153 interest->wireEncode());
154 }
155 else
156 {
157 m_transport->send(interest->wireEncode());
158 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800159
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800160 if (!m_pitTimeoutCheckTimerActive) {
161 m_pitTimeoutCheckTimerActive = true;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700162 m_pitTimeoutCheckTimer->expires_from_now(time::milliseconds(100));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800163 m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire, this));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800164 }
165}
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800166
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800167void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800168Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800169{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800170 if (!m_transport->isConnected())
171 m_transport->connect(*m_ioService,
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800172 bind(&Face::onReceiveElement, this, _1));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800173
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800174 if (!data.getLocalControlHeader().empty(false, true))
175 {
Alexander Afanasyev83018352014-02-18 19:52:15 -0800176 m_transport->send(data.getLocalControlHeader().wireEncode(data, false, true),
177 data.wireEncode());
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800178 }
179 else
180 {
Alexander Afanasyev83018352014-02-18 19:52:15 -0800181 m_transport->send(data.wireEncode());
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800182 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800183}
184
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800185void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800186Face::removePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800187{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800188 m_ioService->post(bind(&Face::asyncRemovePendingInterest, this, pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800189}
190
191
192void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800193Face::asyncRemovePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800194{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800195 m_pendingInterestTable.remove_if(MatchPendingInterestId(pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800196}
197
198const RegisteredPrefixId*
199Face::setInterestFilter(const Name& prefix,
200 const OnInterest& onInterest,
201 const OnSetInterestFilterFailed& onSetInterestFilterFailed)
202{
203 shared_ptr<RegisteredPrefix> prefixToRegister(new RegisteredPrefix(prefix, onInterest));
204
205 m_fwController->selfRegisterPrefix(prefixToRegister->getPrefix(),
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800206 bind(&RegisteredPrefixTable::push_back, &m_registeredPrefixTable, prefixToRegister),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800207 bind(onSetInterestFilterFailed, prefixToRegister->getPrefix(), _1));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800208
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800209 return reinterpret_cast<const RegisteredPrefixId*>(prefixToRegister.get());
210}
211
212void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800213Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800214{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800215 m_ioService->post(bind(&Face::asyncUnsetInterestFilter, this, registeredPrefixId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800216}
217
218void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800219Face::asyncUnsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800220{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800221 RegisteredPrefixTable::iterator i = std::find_if(m_registeredPrefixTable.begin(), m_registeredPrefixTable.end(),
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800222 MatchRegisteredPrefixId(registeredPrefixId));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800223 if (i != m_registeredPrefixTable.end())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800224 {
225 m_fwController->selfDeregisterPrefix((*i)->getPrefix(),
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000226 bind(&Face::finalizeUnsetInterestFilter, this, i),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800227 Controller::FailCallback());
228 }
229
230 // there cannot be two registered prefixes with the same id. if there are, then something is broken
231}
232
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800233void
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000234Face::finalizeUnsetInterestFilter(RegisteredPrefixTable::iterator item)
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800235{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800236 m_registeredPrefixTable.erase(item);
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800237
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800238 if (!m_pitTimeoutCheckTimerActive && m_registeredPrefixTable.empty())
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800239 {
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000240 m_transport->pause();
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800241 if (!m_ioServiceWork) {
242 m_processEventsTimeoutTimer->cancel();
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800243 }
244 }
245}
246
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800247void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700248Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
249 bool keepThread/* = false*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800250{
251 try
252 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700253 if (timeout < time::milliseconds::zero())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800254 {
255 // do not block if timeout is negative, but process pending events
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800256 m_ioService->poll();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800257 return;
258 }
259
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700260 if (timeout > time::milliseconds::zero())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800261 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700262 m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800263 m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800264 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800265
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800266 if (keepThread) {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800267 // work will ensure that m_ioService is running until work object exists
268 m_ioServiceWork = make_shared<boost::asio::io_service::work>(boost::ref(*m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800269 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800270
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800271 m_ioService->run();
272 m_ioService->reset(); // so it is possible to run processEvents again (if necessary)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800273 }
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800274 catch(Face::ProcessEventsTimeout&)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800275 {
276 // break
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800277 m_ioService->reset();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800278 }
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800279 catch(const std::exception&)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800280 {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800281 m_ioService->reset();
282 m_pendingInterestTable.clear();
283 m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800284 throw;
285 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700286}
287
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800288void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700289Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700290{
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700291 m_ioService->post(bind(&Face::asyncShutdown, this));
292}
293
294void
295Face::asyncShutdown()
296{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800297 m_pendingInterestTable.clear();
298 m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800299
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800300 m_transport->close();
301 m_pitTimeoutCheckTimer->cancel();
302 m_processEventsTimeoutTimer->cancel();
303 m_pitTimeoutCheckTimerActive = false;
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700304}
305
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800306void
307Face::fireProcessEventsTimeout(const boost::system::error_code& error)
308{
309 if (!error) // can fire for some other reason, e.g., cancelled
310 throw Face::ProcessEventsTimeout();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700311}
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800312
313void
314Face::checkPitExpire()
315{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700316 // Check for PIT entry timeouts.
317 time::steady_clock::TimePoint now = time::steady_clock::now();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800318
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800319 PendingInterestTable::iterator i = m_pendingInterestTable.begin();
320 while (i != m_pendingInterestTable.end())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800321 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700322 if ((*i)->isTimedOut(now))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800323 {
324 // Save the PendingInterest and remove it from the PIT. Then call the callback.
325 shared_ptr<PendingInterest> pendingInterest = *i;
326
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800327 i = m_pendingInterestTable.erase(i);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800328
329 pendingInterest->callTimeout();
330 }
331 else
332 ++i;
333 }
334
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800335 if (!m_pendingInterestTable.empty()) {
336 m_pitTimeoutCheckTimerActive = true;
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800337
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700338 m_pitTimeoutCheckTimer->expires_from_now(time::milliseconds(100));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800339 m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire, this));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800340 }
341 else {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800342 m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800343
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800344 if (m_registeredPrefixTable.empty()) {
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000345 m_transport->pause();
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800346 if (!m_ioServiceWork) {
347 m_processEventsTimeoutTimer->cancel();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800348 }
349 }
350 }
351}
352
353
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800354void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800355Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800356{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800357 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
358
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800359 if (block.type() == Tlv::Interest)
360 {
361 shared_ptr<Interest> interest(new Interest());
362 interest->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800363 if (&block != &blockFromDaemon)
364 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800365
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800366 processInterestFilters(*interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800367 }
368 else if (block.type() == Tlv::Data)
369 {
370 shared_ptr<Data> data(new Data());
371 data->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800372 if (&block != &blockFromDaemon)
373 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800374
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800375 satisfyPendingInterests(*data);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800376
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800377 if (m_pendingInterestTable.empty()) {
378 m_pitTimeoutCheckTimer->cancel(); // this will cause checkPitExpire invocation
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800379 }
380 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800381 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800382}
383
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800384void
385Face::satisfyPendingInterests(Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800386{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800387 for (PendingInterestTable::iterator i = m_pendingInterestTable.begin ();
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800388 i != m_pendingInterestTable.end();
389 )
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800390 {
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700391 if ((*i)->getInterest()->matchesData(data))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800392 {
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800393 // Copy pointers to the needed objects and remove the PIT entry before the calling the callback.
394 OnData onData = (*i)->getOnData();
395 shared_ptr<const Interest> interest = (*i)->getInterest();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800396
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800397 PendingInterestTable::iterator next = i;
398 ++next;
399 m_pendingInterestTable.erase(i);
400 i = next;
401
402 if (static_cast<bool>(onData)) {
403 onData(*interest, data);
404 }
405 }
406 else
407 ++i;
408 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800409}
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800410
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800411void
412Face::processInterestFilters(Interest& interest)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800413{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800414 for (RegisteredPrefixTable::iterator i = m_registeredPrefixTable.begin();
415 i != m_registeredPrefixTable.end();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800416 ++i)
417 {
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800418 if ((*i)->getPrefix().isPrefixOf(interest.getName()))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800419 {
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800420 (*i)->getOnInterest()((*i)->getPrefix(), interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800421 }
422 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800423}
424
425} // namespace ndn