blob: 7e1a7cad31414ebdcd79c3099074e52ca86f3680 [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
8#ifndef NDN_NODE_HPP
9#define NDN_NODE_HPP
10
Jeff Thompson7aec0252013-08-22 17:29:57 -070011#include "common.hpp"
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070012#include "interest.hpp"
Jeff Thompson86507bc2013-08-23 20:51:38 -070013#include "data.hpp"
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080014#include "transport/transport.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070015
Alexander Afanasyeve289b532014-02-09 22:14:44 -080016#include "management/controller.hpp"
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080017
18#include "detail/registered-prefix.hpp"
19#include "detail/pending-interest.hpp"
20
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070021namespace ndn {
22
Alexander Afanasyevb790d952014-01-24 12:07:53 -080023struct PendingInterestId;
24struct RegisteredPrefixId;
25
Jeff Thompson7aec0252013-08-22 17:29:57 -070026/**
27 * An OnData function object is used to pass a callback to expressInterest.
28 */
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080029typedef function<void(const shared_ptr<const Interest>&, const shared_ptr<Data>&)> OnData;
Jeff Thompson7aec0252013-08-22 17:29:57 -070030
31/**
32 * An OnTimeout function object is used to pass a callback to expressInterest.
33 */
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080034typedef function<void(const shared_ptr<const Interest>&)> OnTimeout;
Jeff Thompson7aec0252013-08-22 17:29:57 -070035
Jeff Thompson86507bc2013-08-23 20:51:38 -070036/**
37 * An OnInterest function object is used to pass a callback to registerPrefix.
38 */
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080039typedef function<void
40 (const shared_ptr<const Name>&, const shared_ptr<const Interest>&)> OnInterest;
Jeff Thompson86507bc2013-08-23 20:51:38 -070041
Jeff Thompson590ec232013-09-18 15:55:56 -070042/**
43 * An OnRegisterFailed function object is used to report when registerPrefix fails.
44 */
Alexander Afanasyeve289b532014-02-09 22:14:44 -080045typedef function<void(const Name&, const std::string&)> OnSetInterestFilterFailed;
Jeff Thompson590ec232013-09-18 15:55:56 -070046
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080047class Node {
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070048public:
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -080049 struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
50
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070051 /**
Jeff Thompson10e34382013-08-22 13:34:46 -070052 * Create a new Node for communication with an NDN hub with the given Transport object and connectionInfo.
53 * @param transport A shared_ptr to a Transport object used for communication.
54 * @param transport A shared_ptr to a Transport::ConnectionInfo to be used to connect to the transport.
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070055 */
Alexander Afanasyeve289b532014-02-09 22:14:44 -080056 Node(const shared_ptr<Transport>& transport, bool nfdMode = false);
Alexander Afanasyeve1b7a5d2013-12-29 16:23:52 -080057
58 /**
59 * @brief Alternative (special use case) version of the constructor, can be used to aggregate
60 * several Faces within one processing thread
61 *
62 * <code>
63 * Face face1(...);
64 * Face face2(..., face1.getAsyncService());
65 *
66 * // Now the following ensures that events on both faces are processed
67 * face1.processEvents();
68 * </code>
69 */
Alexander Afanasyeve289b532014-02-09 22:14:44 -080070 Node(const shared_ptr<Transport>& transport, const shared_ptr<boost::asio::io_service> &ioService, bool nfdMode = false);
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -070071
72 /**
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080073 * @brief Send the Interest through the transport, read the entire response and call onData(interest, data).
74 *
75 * @param interest A reference to the Interest. This copies the Interest.
76 * @param onData A function object to call when a matching data packet is received.
77 * @param onTimeout A function object to call if the interest times out.
78 * If onTimeout is an empty OnTimeout(), this does not use it.
79 *
Jeff Thompson11095142013-10-01 16:20:28 -070080 * @return The pending interest ID which can be used with removePendingInterest.
Jeff Thompson4fe45512013-08-23 14:06:38 -070081 */
Alexander Afanasyevb790d952014-01-24 12:07:53 -080082 const PendingInterestId*
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080083 expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout);
Jeff Thompson7aec0252013-08-22 17:29:57 -070084
85 /**
Jeff Thompson11095142013-10-01 16:20:28 -070086 * Remove the pending interest entry with the pendingInterestId from the pending interest table.
87 * This does not affect another pending interest with a different pendingInterestId, even it if has the same interest name.
88 * If there is no entry with the pendingInterestId, do nothing.
89 * @param pendingInterestId The ID returned from expressInterest.
90 */
91 void
Alexander Afanasyevb790d952014-01-24 12:07:53 -080092 removePendingInterest(const PendingInterestId *pendingInterestId);
Jeff Thompson11095142013-10-01 16:20:28 -070093
94 /**
Jeff Thompson86507bc2013-08-23 20:51:38 -070095 * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
96 * @param prefix A reference to a Name for the prefix to register. This copies the Name.
97 * @param onInterest A function object to call when a matching interest is received. This copies the function object, so you may need to
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080098 * use ref() as appropriate.
Jeff Thompson590ec232013-09-18 15:55:56 -070099 * @param onRegisterFailed A function object to call if failed to retrieve the connected hub’s ID or failed to register the prefix.
100 * This calls onRegisterFailed(prefix) where prefix is the prefix given to registerPrefix.
Jeff Thompson86507bc2013-08-23 20:51:38 -0700101 * @param flags The flags for finer control of which interests are forward to the application.
Jeff Thompson11095142013-10-01 16:20:28 -0700102 * @return The registered prefix ID which can be used with removeRegisteredPrefix.
Jeff Thompson86507bc2013-08-23 20:51:38 -0700103 */
Alexander Afanasyevb790d952014-01-24 12:07:53 -0800104 const RegisteredPrefixId*
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800105 setInterestFilter(const Name& prefix,
106 const OnInterest& onInterest,
107 const OnSetInterestFilterFailed& onSetInterestFilterFailed);
Jeff Thompson86507bc2013-08-23 20:51:38 -0700108
109 /**
Jeff Thompson11095142013-10-01 16:20:28 -0700110 * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.
111 * This does not affect another registered prefix with a different registeredPrefixId, even it if has the same prefix name.
112 * If there is no entry with the registeredPrefixId, do nothing.
113 * @param registeredPrefixId The ID returned from registerPrefix.
114 */
115 void
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800116 unsetInterestFilter(const RegisteredPrefixId *registeredPrefixId);
Jeff Thompson11095142013-10-01 16:20:28 -0700117
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800118 /**
119 * @brief Publish data packet
120 *
121 * This method can be called to satisfy the incoming Interest or to put Data packet into the cache
122 * of the local NDN forwarder
123 */
124 void
125 put(const Data &data);
126
Jeff Thompson11095142013-10-01 16:20:28 -0700127 /**
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800128 * Process any data to receive or call timeout callbacks.
129 *
130 * This call will block forever (default timeout == 0) to process IO on the face.
131 * To exit, one expected to call face.shutdown() from one of the callback methods.
132 *
Alexander Afanasyevf75a0aa2014-01-09 14:29:22 -0800133 * If positive timeout is specified, then processEvents will exit after this timeout,
134 * if not stopped earlier with face.shutdown() or when all active events finish.
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800135 * The call can be called repeatedly, if desired.
136 *
Alexander Afanasyevf75a0aa2014-01-09 14:29:22 -0800137 * If negative timeout is specified, then processEvents will not block and process only pending
138 * events.
139 *
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700140 * @throw This may throw an exception for reading data or in the callback for processing the data. If you
141 * call this from an main event loop, you may want to catch and log/disregard all exceptions.
142 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700143 void
Alexander Afanasyevf75a0aa2014-01-09 14:29:22 -0800144 processEvents(Milliseconds timeout = 0, bool keepThread = false);
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800145
Jeff Thompson0050abe2013-09-17 12:50:25 -0700146 void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700147 shutdown();
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700148
Yingdi Yu0d920812014-01-30 14:50:57 -0800149 shared_ptr<boost::asio::io_service>
150 ioService() { return ioService_; }
151
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700152private:
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800153 void
154 construct(const shared_ptr<Transport>& transport, const shared_ptr<boost::asio::io_service> &ioService, bool nfdMode);
155
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800156 struct ProcessEventsTimeout {};
157 typedef std::list<shared_ptr<PendingInterest> > PendingInterestTable;
158 typedef std::list<shared_ptr<RegisteredPrefix> > RegisteredPrefixTable;
159
Alexander Afanasyevb790d952014-01-24 12:07:53 -0800160 void
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800161 asyncExpressInterest(const shared_ptr<const Interest> &interest,
Alexander Afanasyevb790d952014-01-24 12:07:53 -0800162 const OnData& onData, const OnTimeout& onTimeout);
163
164 void
165 asyncRemovePendingInterest(const PendingInterestId *pendingInterestId);
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800166
167 void
168 asyncUnsetInterestFilter(const RegisteredPrefixId *registeredPrefixId);
Alexander Afanasyevb790d952014-01-24 12:07:53 -0800169
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800170 void
171 onReceiveElement(const Block &wire);
172
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800173
Alexander Afanasyev3ae2da22013-12-29 15:50:04 -0800174 static void
175 fireProcessEventsTimeout(const boost::system::error_code& error);
176
Jeff Thompson86507bc2013-08-23 20:51:38 -0700177 /**
Jeff Thompson557b81e2013-08-21 15:13:51 -0700178 * Find the entry from the pit_ where the name conforms to the entry's interest selectors, and
179 * the entry interest name is the longest that matches name.
180 * @param name The name to find the interest for (from the incoming data packet).
181 * @return The index in pit_ of the pit entry, or -1 if not found.
182 */
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800183 PendingInterestTable::iterator
Jeff Thompson590ec232013-09-18 15:55:56 -0700184 getEntryIndexForExpressedInterest(const Name& name);
Jeff Thompson557b81e2013-08-21 15:13:51 -0700185
Jeff Thompson86507bc2013-08-23 20:51:38 -0700186 /**
Jeff Thompson9cc4be42013-08-27 18:12:41 -0700187 * Find the first entry from the registeredPrefixTable_ where the entry prefix is the longest that matches name.
188 * @param name The name to find the PrefixEntry for (from the incoming interest packet).
189 * @return A pointer to the entry, or 0 if not found.
190 */
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800191 RegisteredPrefixTable::iterator
Jeff Thompson0050abe2013-09-17 12:50:25 -0700192 getEntryForRegisteredPrefix(const Name& name);
Jeff Thompson590ec232013-09-18 15:55:56 -0700193
Alexander Afanasyev18371872014-01-05 23:00:26 -0800194
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800195 void
196 checkPitExpire();
197
198private:
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800199 shared_ptr<boost::asio::io_service> ioService_;
200 shared_ptr<boost::asio::io_service::work> ioServiceWork_; // needed if thread needs to be preserved
201 shared_ptr<boost::asio::deadline_timer> pitTimeoutCheckTimer_;
Alexander Afanasyevbf082112014-01-09 14:27:55 -0800202 bool pitTimeoutCheckTimerActive_;
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800203 shared_ptr<boost::asio::deadline_timer> processEventsTimeoutTimer_;
Jeff Thompson86507bc2013-08-23 20:51:38 -0700204
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800205 shared_ptr<Transport> transport_;
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800206
207 PendingInterestTable pendingInterestTable_;
208 RegisteredPrefixTable registeredPrefixTable_;
Alexander Afanasyevbc343ef2014-01-09 22:36:20 -0800209
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800210 shared_ptr<Controller> m_fwController;
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700211};
212
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -0800213} // namespace ndn
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700214
215#endif