blob: 2920a7da3b2d6b628506a7eed9bb1deed3ebb1df [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.
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -07004 * See COPYING for copyright and distribution information.
5 */
6
Jeff Thompsonb9e3c8e2013-08-02 11:42:51 -07007#ifndef NDN_FACE_HPP
Jeff Thompsona0d18c92013-08-06 13:55:32 -07008#define NDN_FACE_HPP
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -07009
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080010#include "common.hpp"
11#include "interest.hpp"
12#include "data.hpp"
13
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080014#include "transport/transport.hpp"
15#include "transport/unix-transport.hpp"
Alexander Afanasyev20d2c582014-01-26 15:32:51 -080016#include "transport/tcp-transport.hpp"
Jeff Thompsonbeb8b7d2013-07-16 15:49:21 -070017
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080018#include "management/controller.hpp"
19
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070020#include "util/scheduler.hpp"
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080021#include "detail/registered-prefix.hpp"
22#include "detail/pending-interest.hpp"
23
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070024namespace ndn {
25
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080026struct PendingInterestId;
27struct RegisteredPrefixId;
28
Jeff Thompsonfe08e5a2013-08-13 11:15:59 -070029/**
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080030 * An OnData function object is used to pass a callback to expressInterest.
31 */
32typedef function<void(const Interest&, Data&)> OnData;
33
34/**
35 * An OnTimeout function object is used to pass a callback to expressInterest.
36 */
37typedef function<void(const Interest&)> OnTimeout;
38
39/**
40 * An OnInterest function object is used to pass a callback to registerPrefix.
41 */
42typedef function<void (const Name&, const Interest&)> OnInterest;
43
44/**
45 * An OnRegisterFailed function object is used to report when registerPrefix fails.
46 */
47typedef function<void(const Name&, const std::string&)> OnSetInterestFilterFailed;
48
49
50
51/**
52 * @brief Abstraction to communicate with local or remote NDN forwarder
Jeff Thompsonfe08e5a2013-08-13 11:15:59 -070053 */
Alexander Afanasyev8460afb2014-02-15 20:31:42 -080054class Face : noncopyable
55{
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070056public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070057 class Error : public std::runtime_error
58 {
59 public:
60 explicit
61 Error(const std::string& what)
62 : std::runtime_error(what)
63 {
64 }
65 };
Alexander Afanasyevb790d952014-01-24 12:07:53 -080066
67 /**
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080068 * @brief Create a new Face for communication with an NDN Forwarder using the default UnixTransport.
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060069 * @throws ConfigFile::Error on configuration file parse failure
70 * @throws Face::Error on unsupported protocol
Alexander Afanasyevb790d952014-01-24 12:07:53 -080071 */
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080072 Face();
Alexander Afanasyeve2e0d752014-01-03 13:30:30 -080073
74 /**
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080075 * @brief Create a new Face for communication with an NDN Forwarder using the default UnixTransport.
Alexander Afanasyevb790d952014-01-24 12:07:53 -080076 * @param ioService A shared pointer to boost::io_service object that should control all IO operations
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060077 * @throws ConfigFile::Error on configuration file parse failure
78 * @throws Face::Error on unsupported protocol
Jeff Thompsonfe08e5a2013-08-13 11:15:59 -070079 */
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080080 explicit
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080081 Face(const shared_ptr<boost::asio::io_service>& ioService);
82
Jeff Thompsonfe08e5a2013-08-13 11:15:59 -070083 /**
Jeff Thompson86507bc2013-08-23 20:51:38 -070084 * Create a new Face for communication with an NDN hub at host:port using the default TcpTransport.
Jeff Thompsonfe08e5a2013-08-13 11:15:59 -070085 * @param host The host of the NDN hub.
Alexander Afanasyev20d2c582014-01-26 15:32:51 -080086 * @param port The port or service name of the NDN hub. If omitted. use 6363.
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060087 * @throws Face::Error on unsupported protocol
Jeff Thompsonfe08e5a2013-08-13 11:15:59 -070088 */
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080089 Face(const std::string& host, const std::string& port = "6363");
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080090
91 /**
92 * Create a new Face for communication with an NDN hub with the given Transport object and connectionInfo.
93 * @param transport A shared_ptr to a Transport object used for communication.
94 * @param transport A shared_ptr to a Transport::ConnectionInfo to be used to connect to the transport.
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -060095 * @throws Face::Error on unsupported protocol
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080096 */
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080097 explicit
98 Face(const shared_ptr<Transport>& transport);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080099
100 /**
101 * @brief Alternative (special use case) version of the constructor, can be used to aggregate
102 * several Faces within one processing thread
103 *
104 * <code>
105 * Face face1(...);
106 * Face face2(..., face1.getAsyncService());
107 *
108 * // Now the following ensures that events on both faces are processed
109 * face1.processEvents();
110 * </code>
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600111 * @throws Face::Error on unsupported protocol
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800112 */
113 Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800114 const shared_ptr<boost::asio::io_service>& ioService);
115
116 /**
Alexander Afanasyev505646e2014-02-24 20:13:37 -0800117 * @brief Set controller used for prefix registration
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800118 */
Alexander Afanasyev505646e2014-02-24 20:13:37 -0800119 void
120 setController(const shared_ptr<Controller>& controller);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700121
Jeff Thompson4fe45512013-08-23 14:06:38 -0700122 /**
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800123 * @brief Express Interest
124 *
125 * @param interest A reference to the Interest. This copies the Interest.
126 * @param onData A function object to call when a matching data packet is received.
127 * @param onTimeout A function object to call if the interest times out.
128 * If onTimeout is an empty OnTimeout(), this does not use it.
129 *
Jeff Thompson11095142013-10-01 16:20:28 -0700130 * @return The pending interest ID which can be used with removePendingInterest.
Jeff Thompson4fe45512013-08-23 14:06:38 -0700131 */
Alexander Afanasyevb790d952014-01-24 12:07:53 -0800132 const PendingInterestId*
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800133 expressInterest(const Interest& interest,
134 const OnData& onData, const OnTimeout& onTimeout = OnTimeout());
Jeff Thompson4fe45512013-08-23 14:06:38 -0700135
136 /**
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800137 * @brief Express Interest using name and Interest template
138 *
139 * @param name Name of the Interest
140 * @param tmpl Interest template to fill parameters
141 * @param onData A callback to call when a matching data packet is received.
142 * @param onTimeout A callback to call if the interest times out.
143 * If onTimeout is an empty OnTimeout(), this does not use it.
144 *
Jeff Thompson11095142013-10-01 16:20:28 -0700145 * @return The pending interest ID which can be used with removePendingInterest.
Jeff Thompson7aec0252013-08-22 17:29:57 -0700146 */
Alexander Afanasyevb790d952014-01-24 12:07:53 -0800147 const PendingInterestId*
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800148 expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800149 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800150 const OnData& onData, const OnTimeout& onTimeout = OnTimeout());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700151
Jeff Thompson11095142013-10-01 16:20:28 -0700152 /**
153 * Remove the pending interest entry with the pendingInterestId from the pending interest table.
154 * This does not affect another pending interest with a different pendingInterestId, even it if has the same interest name.
155 * If there is no entry with the pendingInterestId, do nothing.
156 * @param pendingInterestId The ID returned from expressInterest.
157 */
158 void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800159 removePendingInterest(const PendingInterestId* pendingInterestId);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700160
Jeff Thompson432c8be2013-08-09 16:16:08 -0700161 /**
Jeff Thompson86507bc2013-08-23 20:51:38 -0700162 * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
163 * @param prefix A reference to a Name for the prefix to register. This copies the Name.
164 * @param onInterest A function object to call when a matching interest is received. This copies the function object, so you may need to
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800165 * use ref() as appropriate.
Jeff Thompson590ec232013-09-18 15:55:56 -0700166 * @param onRegisterFailed A function object to call if failed to retrieve the connected hub’s ID or failed to register the prefix.
167 * This calls onRegisterFailed(prefix) where prefix is the prefix given to registerPrefix.
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800168 * @param flags The flags for finer control of which interests are forward to the application.
Jeff Thompson11095142013-10-01 16:20:28 -0700169 * @return The registered prefix ID which can be used with removeRegisteredPrefix.
Jeff Thompson86507bc2013-08-23 20:51:38 -0700170 */
Alexander Afanasyevb790d952014-01-24 12:07:53 -0800171 const RegisteredPrefixId*
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800172 setInterestFilter(const Name& prefix,
173 const OnInterest& onInterest,
174 const OnSetInterestFilterFailed& onSetInterestFilterFailed);
Jeff Thompson11095142013-10-01 16:20:28 -0700175
176 /**
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700177 * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.
Jeff Thompson11095142013-10-01 16:20:28 -0700178 * This does not affect another registered prefix with a different registeredPrefixId, even it if has the same prefix name.
179 * If there is no entry with the registeredPrefixId, do nothing.
180 * @param registeredPrefixId The ID returned from registerPrefix.
181 */
182 void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800183 unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId);
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800184
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800185 /**
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800186 * @brief Publish data packet
187 *
188 * This method can be called to satisfy the incoming Interest or to put Data packet into the cache
189 * of the local NDN forwarder
190 */
191 void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800192 put(const Data& data);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700193
Jeff Thompson86507bc2013-08-23 20:51:38 -0700194 /**
Jeff Thompsonbf50a1a2013-08-20 18:01:01 -0700195 * Process any data to receive or call timeout callbacks.
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800196 *
197 * This call will block forever (default timeout == 0) to process IO on the face.
198 * To exit, one expected to call face.shutdown() from one of the callback methods.
199 *
Alexander Afanasyevf75a0aa2014-01-09 14:29:22 -0800200 * If positive timeout is specified, then processEvents will exit after this timeout,
201 * if not stopped earlier with face.shutdown() or when all active events finish.
Alexander Afanasyeva557d5a2013-12-28 21:59:03 -0800202 * The call can be called repeatedly, if desired.
203 *
Alexander Afanasyevf75a0aa2014-01-09 14:29:22 -0800204 * If negative timeout is specified, then processEvents will not block and process only pending
205 * events.
206 *
Jeff Thompson432c8be2013-08-09 16:16:08 -0700207 * @throw This may throw an exception for reading data or in the callback for processing the data. If you
208 * call this from an main event loop, you may want to catch and log/disregard all exceptions.
209 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700210 void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700211 processEvents(const time::milliseconds& timeout = time::milliseconds::zero(),
212 bool keepThread = false);
Jeff Thompson432c8be2013-08-09 16:16:08 -0700213
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700214 void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700215 shutdown();
Yingdi Yu0d920812014-01-30 14:50:57 -0800216
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700217 shared_ptr<boost::asio::io_service>
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800218 ioService() { return m_ioService; }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800219
220private:
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600221
222 /**
223 * @throws Face::Error on unsupported protocol
224 */
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800225 void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800226 construct(const shared_ptr<Transport>& transport,
Alexander Afanasyev505646e2014-02-24 20:13:37 -0800227 const shared_ptr<boost::asio::io_service>& ioService);
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600228
229 bool
230 isSupportedNfdProtocol(const std::string& protocol);
231
232 bool
233 isSupportedNrdProtocol(const std::string& protocol);
234
235 bool
236 isSupportedNdndProtocol(const std::string& protocol);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700237
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800238 struct ProcessEventsTimeout {};
239 typedef std::list<shared_ptr<PendingInterest> > PendingInterestTable;
240 typedef std::list<shared_ptr<RegisteredPrefix> > RegisteredPrefixTable;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700241
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800242 void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800243 asyncExpressInterest(const shared_ptr<const Interest>& interest,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800244 const OnData& onData, const OnTimeout& onTimeout);
245
246 void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800247 asyncRemovePendingInterest(const PendingInterestId* pendingInterestId);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800248
249 void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800250 asyncUnsetInterestFilter(const RegisteredPrefixId* registeredPrefixId);
Alexander Afanasyev12dfbad2014-02-11 14:42:46 -0800251
252 void
Alexander Afanasyev52afb3f2014-03-07 09:05:35 +0000253 finalizeUnsetInterestFilter(RegisteredPrefixTable::iterator item);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700254
255 void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800256 onReceiveElement(const Block& wire);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800257
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700258 void
259 asyncShutdown();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700260
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800261 static void
262 fireProcessEventsTimeout(const boost::system::error_code& error);
263
Alexander Afanasyev42c81852014-02-25 21:37:26 -0800264 void
265 satisfyPendingInterests(Data& data);
266
267 void
268 processInterestFilters(Interest& interest);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700269
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800270 void
271 checkPitExpire();
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800272
Jeff Thompsonb982b6d2013-07-15 18:15:45 -0700273private:
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800274 shared_ptr<boost::asio::io_service> m_ioService;
275 shared_ptr<boost::asio::io_service::work> m_ioServiceWork; // needed if thread needs to be preserved
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700276 shared_ptr<monotonic_deadline_timer> m_pitTimeoutCheckTimer;
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800277 bool m_pitTimeoutCheckTimerActive;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700278 shared_ptr<monotonic_deadline_timer> m_processEventsTimeoutTimer;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700279
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800280 shared_ptr<Transport> m_transport;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800281
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800282 PendingInterestTable m_pendingInterestTable;
283 RegisteredPrefixTable m_registeredPrefixTable;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800284
285 shared_ptr<Controller> m_fwController;
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600286
287 ConfigFile m_config;
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700288};
289
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600290inline bool
291Face::isSupportedNfdProtocol(const std::string& protocol)
292{
293 return protocol == "nfd-0.1";
294}
295
296inline bool
297Face::isSupportedNrdProtocol(const std::string& protocol)
298{
299 return protocol == "nrd-0.1";
300}
301
302inline bool
303Face::isSupportedNdndProtocol(const std::string& protocol)
304{
305 return protocol == "ndnd-tlv-0.7";
306}
307
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800308} // namespace ndn
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700309
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800310#endif // NDN_FACE_HPP