blob: 919ea5d94906da17831ec5ca922d73279536daeb [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 Afanasyevf7ca3202014-02-14 22:28:31 -080027 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080028}
29
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080030Face::Face(const shared_ptr<boost::asio::io_service> &ioService)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080031{
32 construct(shared_ptr<Transport>(new UnixTransport()),
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080033 ioService);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080034}
35
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080036Face::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 Afanasyevf7ca3202014-02-14 22:28:31 -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 Afanasyevf7ca3202014-02-14 22:28:31 -080045 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080046}
47
48Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080049 const shared_ptr<boost::asio::io_service> &ioService)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080050{
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080051 construct(transport, ioService);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080052}
53
54void
55Face::construct(const shared_ptr<Transport>& transport,
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080056 const shared_ptr<boost::asio::io_service> &ioService)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080057{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -080058 m_pitTimeoutCheckTimerActive = false;
59 m_transport = transport;
60 m_ioService = ioService;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080061
Alexander Afanasyevf39c5372014-02-17 19:42:56 -080062 m_pitTimeoutCheckTimer = make_shared<boost::asio::deadline_timer>(boost::ref(*m_ioService));
63 m_processEventsTimeoutTimer = make_shared<boost::asio::deadline_timer>(boost::ref(*m_ioService));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -080064
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080065 if (std::getenv("NFD") != 0)
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -080066 {
67 if (std::getenv("NRD") != 0)
68 m_fwController = make_shared<nrd::Controller>(boost::ref(*this));
69 else
70 m_fwController = make_shared<nfd::Controller>(boost::ref(*this));
71 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070072 else
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080073 m_fwController = make_shared<ndnd::Controller>(boost::ref(*this));
74}
75
76
77const PendingInterestId*
78Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
79{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -080080 if (!m_transport->isConnected())
81 m_transport->connect(*m_ioService,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080082 bind(&Face::onReceiveElement, this, _1));
83
84 shared_ptr<const Interest> interestToExpress(new Interest(interest));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -080085
Alexander Afanasyevf39c5372014-02-17 19:42:56 -080086 m_ioService->post(bind(&Face::asyncExpressInterest, this, interestToExpress, onData, onTimeout));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -080087
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080088 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
89}
90
91const PendingInterestId*
92Face::expressInterest(const Name& name,
93 const Interest &tmpl,
94 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
95{
96 return expressInterest(Interest(name,
97 tmpl.getMinSuffixComponents(),
98 tmpl.getMaxSuffixComponents(),
99 tmpl.getExclude(),
100 tmpl.getChildSelector(),
101 tmpl.getMustBeFresh(),
102 tmpl.getScope(),
103 tmpl.getInterestLifetime()),
104 onData, onTimeout);
105}
106
107void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800108Face::asyncExpressInterest(const shared_ptr<const Interest>& interest,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800109 const OnData& onData, const OnTimeout& onTimeout)
110{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800111 m_pendingInterestTable.push_back(shared_ptr<PendingInterest>(new PendingInterest
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800112 (interest, onData, onTimeout)));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800113
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800114 if (!interest->getLocalControlHeader().empty(false, true))
115 {
116 // encode only NextHopFaceId towards the forwarder
117 m_transport->send(interest->getLocalControlHeader().wireEncode(*interest, false, true),
118 interest->wireEncode());
119 }
120 else
121 {
122 m_transport->send(interest->wireEncode());
123 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800124
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800125 if (!m_pitTimeoutCheckTimerActive) {
126 m_pitTimeoutCheckTimerActive = true;
127 m_pitTimeoutCheckTimer->expires_from_now(boost::posix_time::milliseconds(100));
128 m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire, this));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800129 }
130}
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800131
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800132void
133Face::put(const Data &data)
134{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800135 if (!m_transport->isConnected())
136 m_transport->connect(*m_ioService,
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800137 bind(&Face::onReceiveElement, this, _1));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800138
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800139 if (!data.getLocalControlHeader().empty(false, true))
140 {
Alexander Afanasyev83018352014-02-18 19:52:15 -0800141 m_transport->send(data.getLocalControlHeader().wireEncode(data, false, true),
142 data.wireEncode());
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800143 }
144 else
145 {
Alexander Afanasyev83018352014-02-18 19:52:15 -0800146 m_transport->send(data.wireEncode());
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800147 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800148}
149
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800150void
151Face::removePendingInterest(const PendingInterestId *pendingInterestId)
152{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800153 m_ioService->post(bind(&Face::asyncRemovePendingInterest, this, pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800154}
155
156
157void
158Face::asyncRemovePendingInterest(const PendingInterestId *pendingInterestId)
159{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800160 m_pendingInterestTable.remove_if(MatchPendingInterestId(pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800161}
162
163const RegisteredPrefixId*
164Face::setInterestFilter(const Name& prefix,
165 const OnInterest& onInterest,
166 const OnSetInterestFilterFailed& onSetInterestFilterFailed)
167{
168 shared_ptr<RegisteredPrefix> prefixToRegister(new RegisteredPrefix(prefix, onInterest));
169
170 m_fwController->selfRegisterPrefix(prefixToRegister->getPrefix(),
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800171 bind(&RegisteredPrefixTable::push_back, &m_registeredPrefixTable, prefixToRegister),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800172 bind(onSetInterestFilterFailed, prefixToRegister->getPrefix(), _1));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800173
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800174 return reinterpret_cast<const RegisteredPrefixId*>(prefixToRegister.get());
175}
176
177void
178Face::unsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
179{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800180 m_ioService->post(bind(&Face::asyncUnsetInterestFilter, this, registeredPrefixId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800181}
182
183void
184Face::asyncUnsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
185{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800186 RegisteredPrefixTable::iterator i = std::find_if(m_registeredPrefixTable.begin(), m_registeredPrefixTable.end(),
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800187 MatchRegisteredPrefixId(registeredPrefixId));
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800188 if (i != m_registeredPrefixTable.end())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800189 {
190 m_fwController->selfDeregisterPrefix((*i)->getPrefix(),
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800191 bind(&Face::finalizeUnsertInterestFilter, this, i),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800192 Controller::FailCallback());
193 }
194
195 // there cannot be two registered prefixes with the same id. if there are, then something is broken
196}
197
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800198void
199Face::finalizeUnsertInterestFilter(RegisteredPrefixTable::iterator item)
200{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800201 m_registeredPrefixTable.erase(item);
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800202
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800203 if (!m_pitTimeoutCheckTimerActive && m_registeredPrefixTable.empty())
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800204 {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800205 m_transport->close();
206 if (!m_ioServiceWork) {
207 m_processEventsTimeoutTimer->cancel();
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800208 }
209 }
210}
211
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800212void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800213Face::processEvents(Milliseconds timeout/* = 0 */, bool keepThread/* = false*/)
214{
215 try
216 {
217 if (timeout < 0)
218 {
219 // do not block if timeout is negative, but process pending events
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800220 m_ioService->poll();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800221 return;
222 }
223
224 if (timeout > 0)
225 {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800226 m_processEventsTimeoutTimer->expires_from_now(boost::posix_time::milliseconds(timeout));
227 m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800228 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800229
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800230 if (keepThread) {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800231 // work will ensure that m_ioService is running until work object exists
232 m_ioServiceWork = make_shared<boost::asio::io_service::work>(boost::ref(*m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800233 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800234
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800235 m_ioService->run();
236 m_ioService->reset(); // so it is possible to run processEvents again (if necessary)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800237 }
238 catch(Face::ProcessEventsTimeout &)
239 {
240 // break
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800241 m_ioService->reset();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800242 }
243 catch(const std::exception &)
244 {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800245 m_ioService->reset();
246 m_pendingInterestTable.clear();
247 m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800248 throw;
249 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700250}
251
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800252void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700253Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700254{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800255 m_pendingInterestTable.clear();
256 m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800257
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800258 m_transport->close();
259 m_pitTimeoutCheckTimer->cancel();
260 m_processEventsTimeoutTimer->cancel();
261 m_pitTimeoutCheckTimerActive = false;
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700262}
263
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800264void
265Face::fireProcessEventsTimeout(const boost::system::error_code& error)
266{
267 if (!error) // can fire for some other reason, e.g., cancelled
268 throw Face::ProcessEventsTimeout();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700269}
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800270
271void
272Face::checkPitExpire()
273{
274 // Check for PIT entry timeouts. Go backwards through the list so we can erase entries.
275 MillisecondsSince1970 nowMilliseconds = getNowMilliseconds();
276
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800277 PendingInterestTable::iterator i = m_pendingInterestTable.begin();
278 while (i != m_pendingInterestTable.end())
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800279 {
280 if ((*i)->isTimedOut(nowMilliseconds))
281 {
282 // Save the PendingInterest and remove it from the PIT. Then call the callback.
283 shared_ptr<PendingInterest> pendingInterest = *i;
284
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800285 i = m_pendingInterestTable.erase(i);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800286
287 pendingInterest->callTimeout();
288 }
289 else
290 ++i;
291 }
292
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800293 if (!m_pendingInterestTable.empty()) {
294 m_pitTimeoutCheckTimerActive = true;
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800295
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800296 m_pitTimeoutCheckTimer->expires_from_now(boost::posix_time::milliseconds(100));
297 m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire, this));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800298 }
299 else {
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800300 m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800301
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800302 if (m_registeredPrefixTable.empty()) {
303 m_transport->close();
304 if (!m_ioServiceWork) {
305 m_processEventsTimeoutTimer->cancel();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800306 }
307 }
308 }
309}
310
311
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800312void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800313Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800314{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800315 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
316
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800317 if (block.type() == Tlv::Interest)
318 {
319 shared_ptr<Interest> interest(new Interest());
320 interest->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800321 if (&block != &blockFromDaemon)
322 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800323
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800324 RegisteredPrefixTable::iterator entry = getEntryForRegisteredPrefix(interest->getName());
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800325 if (entry != m_registeredPrefixTable.end()) {
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800326 (*entry)->getOnInterest()((*entry)->getPrefix(), *interest);
327 }
328 }
329 else if (block.type() == Tlv::Data)
330 {
331 shared_ptr<Data> data(new Data());
332 data->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800333 if (&block != &blockFromDaemon)
334 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800335
336 PendingInterestTable::iterator entry = getEntryIndexForExpressedInterest(data->getName());
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800337 if (entry != m_pendingInterestTable.end()) {
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800338 // Copy pointers to the needed objects and remove the PIT entry before the calling the callback.
339 const OnData onData = (*entry)->getOnData();
340 const shared_ptr<const Interest> interest = (*entry)->getInterest();
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800341 m_pendingInterestTable.erase(entry);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800342
343 if (onData) {
344 onData(*interest, *data);
345 }
346
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800347 if (m_pendingInterestTable.empty()) {
348 m_pitTimeoutCheckTimer->cancel(); // this will cause checkPitExpire invocation
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800349 }
350 }
351 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800352 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800353}
354
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800355Face::PendingInterestTable::iterator
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800356Face::getEntryIndexForExpressedInterest(const Name& name)
357{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800358 for (PendingInterestTable::iterator i = m_pendingInterestTable.begin ();
359 i != m_pendingInterestTable.end(); ++i)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800360 {
361 if ((*i)->getInterest()->matchesName(name))
362 {
363 return i;
364 }
365 }
366
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800367 return m_pendingInterestTable.end();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800368}
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800369
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800370Face::RegisteredPrefixTable::iterator
371Face::getEntryForRegisteredPrefix(const Name& name)
372{
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800373 RegisteredPrefixTable::iterator longestPrefix = m_registeredPrefixTable.end();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800374
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800375 for (RegisteredPrefixTable::iterator i = m_registeredPrefixTable.begin();
376 i != m_registeredPrefixTable.end();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800377 ++i)
378 {
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800379 if ((*i)->getPrefix().isPrefixOf(name))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800380 {
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800381
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800382 if (longestPrefix == m_registeredPrefixTable.end() ||
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800383 (*i)->getPrefix().size() > (*longestPrefix)->getPrefix().size())
384 {
385 longestPrefix = i;
386 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800387 }
388 }
389 return longestPrefix;
390}
391
392} // namespace ndn