blob: 4f89c2eb9800c534bd0feb33985e030ab9611571 [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
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070039class NullIoDeleter
40{
41public:
42 void
43 operator()(boost::asio::io_service*)
44 {
45 }
46};
47
48Face::Face(boost::asio::io_service& ioService)
49{
50 const std::string socketName = UnixTransport::getDefaultSocketName(m_config);
51 construct(shared_ptr<Transport>(new UnixTransport(socketName)),
52 shared_ptr<boost::asio::io_service>(&ioService, NullIoDeleter()));
53}
54
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080055Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080056{
57 construct(shared_ptr<Transport>(new TcpTransport(host, port)),
Alexander Afanasyev505646e2014-02-24 20:13:37 -080058 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080059}
60
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080061Face::Face(const shared_ptr<Transport>& transport)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080062{
63 construct(transport,
Alexander Afanasyev505646e2014-02-24 20:13:37 -080064 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080065}
66
67Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070068 boost::asio::io_service& ioService)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080069{
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070070 construct(transport,
71 shared_ptr<boost::asio::io_service>(&ioService, NullIoDeleter()));
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080072}
73
Alexander Afanasyev505646e2014-02-24 20:13:37 -080074void
75Face::setController(const shared_ptr<Controller>& controller)
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080076{
Alexander Afanasyev505646e2014-02-24 20:13:37 -080077 m_fwController = controller;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080078}
79
80void
81Face::construct(const shared_ptr<Transport>& transport,
Alexander Afanasyev505646e2014-02-24 20:13:37 -080082 const shared_ptr<boost::asio::io_service>& ioService)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080083{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -080084 m_pitTimeoutCheckTimerActive = false;
85 m_transport = transport;
86 m_ioService = ioService;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080087
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070088 m_pitTimeoutCheckTimer = make_shared<monotonic_deadline_timer>(boost::ref(*m_ioService));
89 m_processEventsTimeoutTimer = make_shared<monotonic_deadline_timer>(boost::ref(*m_ioService));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -080090
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060091 std::string protocol = "nrd-0.1";
92
93 try
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -080094 {
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060095 protocol = m_config.getParsedConfiguration().get<std::string>("protocol");
96 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070097 catch (boost::property_tree::ptree_bad_path& error)
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060098 {
99 // protocol not specified
100 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700101 catch (boost::property_tree::ptree_bad_data& error)
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600102 {
103 throw ConfigFile::Error(error.what());
104 }
105
106 if (isSupportedNrdProtocol(protocol))
107 {
108 m_fwController = make_shared<nrd::Controller>(boost::ref(*this));
109 }
Steve DiBenedettoacab8802014-03-24 11:15:57 -0600110 else if (isSupportedNfdProtocol(protocol))
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600111 {
112 m_fwController = make_shared<nfd::Controller>(boost::ref(*this));
113 }
114 else if (isSupportedNdndProtocol(protocol))
115 {
116 m_fwController = make_shared<ndnd::Controller>(boost::ref(*this));
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -0800117 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700118 else
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600119 {
120 throw Face::Error("Cannot create controller for unsupported protocol \"" + protocol + "\"");
121 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800122}
123
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800124const PendingInterestId*
125Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
126{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800127 if (!m_transport->isConnected())
128 m_transport->connect(*m_ioService,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800129 bind(&Face::onReceiveElement, this, _1));
130
131 shared_ptr<const Interest> interestToExpress(new Interest(interest));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800132
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700133 // If the same ioService thread, dispatch directly calls the method
134 m_ioService->dispatch(bind(&Face::asyncExpressInterest, this,
135 interestToExpress, onData, onTimeout));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800136
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800137 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
138}
139
140const PendingInterestId*
141Face::expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800142 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800143 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
144{
145 return expressInterest(Interest(name,
146 tmpl.getMinSuffixComponents(),
147 tmpl.getMaxSuffixComponents(),
148 tmpl.getExclude(),
149 tmpl.getChildSelector(),
150 tmpl.getMustBeFresh(),
151 tmpl.getScope(),
152 tmpl.getInterestLifetime()),
153 onData, onTimeout);
154}
155
156void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800157Face::asyncExpressInterest(const shared_ptr<const Interest>& interest,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800158 const OnData& onData, const OnTimeout& onTimeout)
159{
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700160 if (!m_transport->isExpectingData())
161 m_transport->resume();
162
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800163 m_pendingInterestTable.push_back(shared_ptr<PendingInterest>(new PendingInterest
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800164 (interest, onData, onTimeout)));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800165
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800166 if (!interest->getLocalControlHeader().empty(false, true))
167 {
168 // encode only NextHopFaceId towards the forwarder
169 m_transport->send(interest->getLocalControlHeader().wireEncode(*interest, false, true),
170 interest->wireEncode());
171 }
172 else
173 {
174 m_transport->send(interest->wireEncode());
175 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800176
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800177 if (!m_pitTimeoutCheckTimerActive) {
178 m_pitTimeoutCheckTimerActive = true;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700179 m_pitTimeoutCheckTimer->expires_from_now(time::milliseconds(100));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800180 m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire, this));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800181 }
182}
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800183
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800184void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800185Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800186{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800187 if (!m_transport->isConnected())
188 m_transport->connect(*m_ioService,
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800189 bind(&Face::onReceiveElement, this, _1));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800190
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800191 if (!data.getLocalControlHeader().empty(false, true))
192 {
Alexander Afanasyev83018352014-02-18 19:52:15 -0800193 m_transport->send(data.getLocalControlHeader().wireEncode(data, false, true),
194 data.wireEncode());
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800195 }
196 else
197 {
Alexander Afanasyev83018352014-02-18 19:52:15 -0800198 m_transport->send(data.wireEncode());
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800199 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800200}
201
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800202void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800203Face::removePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800204{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800205 m_ioService->post(bind(&Face::asyncRemovePendingInterest, this, pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800206}
207
208
209void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800210Face::asyncRemovePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800211{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800212 m_pendingInterestTable.remove_if(MatchPendingInterestId(pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800213}
214
215const RegisteredPrefixId*
216Face::setInterestFilter(const Name& prefix,
217 const OnInterest& onInterest,
218 const OnSetInterestFilterFailed& onSetInterestFilterFailed)
219{
220 shared_ptr<RegisteredPrefix> prefixToRegister(new RegisteredPrefix(prefix, onInterest));
221
222 m_fwController->selfRegisterPrefix(prefixToRegister->getPrefix(),
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -0700223 bind(&RegisteredPrefixTable::push_back,
224 &m_registeredPrefixTable, prefixToRegister),
225 bind(onSetInterestFilterFailed,
226 prefixToRegister->getPrefix(), _1));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800227
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800228 return reinterpret_cast<const RegisteredPrefixId*>(prefixToRegister.get());
229}
230
231void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800232Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800233{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800234 m_ioService->post(bind(&Face::asyncUnsetInterestFilter, this, registeredPrefixId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800235}
236
237void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800238Face::asyncUnsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800239{
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -0700240 RegisteredPrefixTable::iterator i = std::find_if(m_registeredPrefixTable.begin(),
241 m_registeredPrefixTable.end(),
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800242 MatchRegisteredPrefixId(registeredPrefixId));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800243 if (i != m_registeredPrefixTable.end())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800244 {
245 m_fwController->selfDeregisterPrefix((*i)->getPrefix(),
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000246 bind(&Face::finalizeUnsetInterestFilter, this, i),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800247 Controller::FailCallback());
248 }
249
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -0700250 // there cannot be two registered prefixes with the same id
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800251}
252
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800253void
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000254Face::finalizeUnsetInterestFilter(RegisteredPrefixTable::iterator item)
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800255{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800256 m_registeredPrefixTable.erase(item);
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800257
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800258 if (!m_pitTimeoutCheckTimerActive && m_registeredPrefixTable.empty())
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800259 {
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000260 m_transport->pause();
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800261 if (!m_ioServiceWork) {
262 m_processEventsTimeoutTimer->cancel();
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800263 }
264 }
265}
266
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800267void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700268Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
269 bool keepThread/* = false*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800270{
271 try
272 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700273 if (timeout < time::milliseconds::zero())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800274 {
275 // do not block if timeout is negative, but process pending events
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800276 m_ioService->poll();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800277 return;
278 }
279
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700280 if (timeout > time::milliseconds::zero())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800281 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700282 m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800283 m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800284 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800285
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800286 if (keepThread) {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800287 // work will ensure that m_ioService is running until work object exists
288 m_ioServiceWork = make_shared<boost::asio::io_service::work>(boost::ref(*m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800289 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800290
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800291 m_ioService->run();
292 m_ioService->reset(); // so it is possible to run processEvents again (if necessary)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800293 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700294 catch (Face::ProcessEventsTimeout&)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800295 {
296 // break
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800297 m_ioService->reset();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800298 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700299 catch (std::exception&)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800300 {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800301 m_ioService->reset();
302 m_pendingInterestTable.clear();
303 m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800304 throw;
305 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700306}
307
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800308void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700309Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700310{
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700311 m_ioService->post(bind(&Face::asyncShutdown, this));
312}
313
314void
315Face::asyncShutdown()
316{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800317 m_pendingInterestTable.clear();
318 m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800319
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800320 m_transport->close();
321 m_pitTimeoutCheckTimer->cancel();
322 m_processEventsTimeoutTimer->cancel();
323 m_pitTimeoutCheckTimerActive = false;
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700324}
325
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800326void
327Face::fireProcessEventsTimeout(const boost::system::error_code& error)
328{
329 if (!error) // can fire for some other reason, e.g., cancelled
330 throw Face::ProcessEventsTimeout();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700331}
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800332
333void
334Face::checkPitExpire()
335{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700336 // Check for PIT entry timeouts.
337 time::steady_clock::TimePoint now = time::steady_clock::now();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800338
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800339 PendingInterestTable::iterator i = m_pendingInterestTable.begin();
340 while (i != m_pendingInterestTable.end())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800341 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700342 if ((*i)->isTimedOut(now))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800343 {
344 // Save the PendingInterest and remove it from the PIT. Then call the callback.
345 shared_ptr<PendingInterest> pendingInterest = *i;
346
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800347 i = m_pendingInterestTable.erase(i);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800348
349 pendingInterest->callTimeout();
350 }
351 else
352 ++i;
353 }
354
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800355 if (!m_pendingInterestTable.empty()) {
356 m_pitTimeoutCheckTimerActive = true;
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800357
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700358 m_pitTimeoutCheckTimer->expires_from_now(time::milliseconds(100));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800359 m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire, this));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800360 }
361 else {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800362 m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800363
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800364 if (m_registeredPrefixTable.empty()) {
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000365 m_transport->pause();
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800366 if (!m_ioServiceWork) {
367 m_processEventsTimeoutTimer->cancel();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800368 }
369 }
370 }
371}
372
373
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800374void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800375Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800376{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800377 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
378
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800379 if (block.type() == Tlv::Interest)
380 {
381 shared_ptr<Interest> interest(new Interest());
382 interest->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800383 if (&block != &blockFromDaemon)
384 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800385
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800386 processInterestFilters(*interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800387 }
388 else if (block.type() == Tlv::Data)
389 {
390 shared_ptr<Data> data(new Data());
391 data->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800392 if (&block != &blockFromDaemon)
393 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800394
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800395 satisfyPendingInterests(*data);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800396
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800397 if (m_pendingInterestTable.empty()) {
398 m_pitTimeoutCheckTimer->cancel(); // this will cause checkPitExpire invocation
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800399 }
400 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800401 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800402}
403
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800404void
405Face::satisfyPendingInterests(Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800406{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800407 for (PendingInterestTable::iterator i = m_pendingInterestTable.begin ();
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800408 i != m_pendingInterestTable.end();
409 )
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800410 {
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700411 if ((*i)->getInterest()->matchesData(data))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800412 {
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -0700413 // Copy pointers to the objects and remove the PIT entry before calling the callback.
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800414 OnData onData = (*i)->getOnData();
415 shared_ptr<const Interest> interest = (*i)->getInterest();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800416
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800417 PendingInterestTable::iterator next = i;
418 ++next;
419 m_pendingInterestTable.erase(i);
420 i = next;
421
422 if (static_cast<bool>(onData)) {
423 onData(*interest, data);
424 }
425 }
426 else
427 ++i;
428 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800429}
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800430
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800431void
432Face::processInterestFilters(Interest& interest)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800433{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800434 for (RegisteredPrefixTable::iterator i = m_registeredPrefixTable.begin();
435 i != m_registeredPrefixTable.end();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800436 ++i)
437 {
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800438 if ((*i)->getPrefix().isPrefixOf(interest.getName()))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800439 {
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800440 (*i)->getOnInterest()((*i)->getPrefix(), interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800441 }
442 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800443}
444
445} // namespace ndn