blob: 48f34f7b8cfc3932c97cdf753608d531b1777623 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompson47eecfc2013-07-07 22:56:46 -07002/**
Alexander Afanasyev74633892015-02-08 18:08:46 -08003 * Copyright (c) 2013-2015 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Jeff Thompsonb7f95562013-07-03 18:36:42 -070020 */
21
22#ifndef NDN_INTEREST_HPP
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070023#define NDN_INTEREST_HPP
Jeff Thompsonb7f95562013-07-03 18:36:42 -070024
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080025#include "common.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070026
Jeff Thompson53412192013-08-06 13:35:50 -070027#include "name.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080028#include "selectors.hpp"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070029#include "util/time.hpp"
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080030#include "management/nfd-local-control-header.hpp"
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080031#include "tag-host.hpp"
Jeff Thompsonb7f95562013-07-03 18:36:42 -070032
33namespace ndn {
Alexander Afanasyevc348f832014-02-17 16:35:17 -080034
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070035class Data;
36
Junxiao Shi7007a3c2014-11-20 22:37:55 -070037/** @var const unspecified_duration_type DEFAULT_INTEREST_LIFETIME;
38 * @brief default value for InterestLifetime
39 */
40const time::milliseconds DEFAULT_INTEREST_LIFETIME = time::milliseconds(4000);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080041
Junxiao Shic2b8d242014-11-04 08:35:29 -070042/** @brief represents an Interest packet
Jeff Thompson8238d002013-07-10 11:56:49 -070043 */
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080044class Interest : public TagHost, public enable_shared_from_this<Interest>
Alexander Afanasyevc348f832014-02-17 16:35:17 -080045{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070046public:
Junxiao Shic2b8d242014-11-04 08:35:29 -070047 class Error : public tlv::Error
48 {
49 public:
50 explicit
51 Error(const std::string& what)
52 : tlv::Error(what)
53 {
54 }
55 };
56
Junxiao Shi2af905b2014-11-27 13:10:54 -070057 /** @brief Create a new Interest with an empty name (`ndn:/`)
58 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
59 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080060 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070061 Interest();
Alexander Afanasyevc348f832014-02-17 16:35:17 -080062
Junxiao Shi2af905b2014-11-27 13:10:54 -070063 /** @brief Create a new Interest with the given name
64 * @param name The name for the interest.
65 * @note This constructor allows implicit conversion from Name.
66 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
67 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080068 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070069 Interest(const Name& name);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080070
Junxiao Shi2af905b2014-11-27 13:10:54 -070071 /** @brief Create a new Interest with the given name and interest lifetime
72 * @param name The name for the interest.
73 * @param interestLifetime The interest lifetime in time::milliseconds, or -1 for none.
74 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
75 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080076 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070077 Interest(const Name& name, const time::milliseconds& interestLifetime);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070078
Junxiao Shi2af905b2014-11-27 13:10:54 -070079 /** @brief Create a new Interest for the given name, selectors, and guiders
80 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
81 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyev770827c2014-05-13 17:42:55 -070082 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -080083 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070084 const Selectors& selectors,
Alexander Afanasyevc348f832014-02-17 16:35:17 -080085 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070086 const time::milliseconds& interestLifetime,
Junxiao Shi2af905b2014-11-27 13:10:54 -070087 uint32_t nonce = 0);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070088
Junxiao Shi2af905b2014-11-27 13:10:54 -070089 /** @brief Create from wire encoding
90 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
91 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070092 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080093 explicit
Junxiao Shi2af905b2014-11-27 13:10:54 -070094 Interest(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080095
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080096 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080097 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080098 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080099 template<encoding::Tag TAG>
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700100 size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -0800101 wireEncode(EncodingImpl<TAG>& block) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800102
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800103 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800104 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800105 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700106 const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -0800107 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800108
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800109 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800110 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800111 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700112 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700113 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800114
115 /**
116 * @brief Check if already has wire
117 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700118 bool
Junxiao Shi2af905b2014-11-27 13:10:54 -0700119 hasWire() const
120 {
121 return m_wire.hasWire();
122 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700123
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700124 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700125 * @brief Encode the name according to the NDN URI Scheme
126 *
127 * If there are interest selectors, this method will append "?" and add the selectors as
128 * a query string. For example, "/test/name?ndn.ChildSelector=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800129 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700130 std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800131 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700132
Junxiao Shi2af905b2014-11-27 13:10:54 -0700133public: // matching
134 /** @brief Check if Interest, including selectors, matches the given @p name
135 * @param name The name to be matched. If this is a Data name, it shall contain the
136 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800137 */
138 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700139 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800140
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700141 /**
142 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700143 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700144 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
145 * PublisherPublicKeyLocator, and Exclude.
146 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700147 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700148 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700149 */
150 bool
151 matchesData(const Data& data) const;
152
Junxiao Shi2af905b2014-11-27 13:10:54 -0700153public: // Name and guiders
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700154 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800155 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700156 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800157 return m_name;
158 }
159
160 Interest&
161 setName(const Name& name)
162 {
163 m_name = name;
164 m_wire.reset();
165 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700166 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700167
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700168 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800169 getScope() const
170 {
171 return m_scope;
172 }
173
174 Interest&
175 setScope(int scope)
176 {
177 m_scope = scope;
178 m_wire.reset();
179 return *this;
180 }
181
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700182 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800183 getInterestLifetime() const
184 {
185 return m_interestLifetime;
186 }
187
188 Interest&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700189 setInterestLifetime(const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800190 {
191 m_interestLifetime = interestLifetime;
192 m_wire.reset();
193 return *this;
194 }
195
Junxiao Shi2af905b2014-11-27 13:10:54 -0700196 /** @brief Check if Nonce set
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300197 */
198 bool
199 hasNonce() const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800200 {
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300201 return m_nonce.hasWire();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800202 }
203
Junxiao Shi2af905b2014-11-27 13:10:54 -0700204 /** @brief Get Interest's nonce
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300205 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700206 * If nonce was not set before this call, it will be automatically assigned to a random value
207 */
208 uint32_t
209 getNonce() const;
210
211 /** @brief Set Interest's nonce
212 *
213 * If wire format already exists, this call simply replaces nonce in the
214 * existing wire format, without resetting and recreating it.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300215 */
216 Interest&
217 setNonce(uint32_t nonce);
218
Junxiao Shi2af905b2014-11-27 13:10:54 -0700219 /** @brief Refresh nonce
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700220 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700221 * It's guaranteed that new nonce value differs from the existing one.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700222 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700223 * If nonce is already set, it will be updated to a different random value.
224 * If nonce is not set, this method does nothing.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700225 */
226 void
227 refreshNonce();
228
Junxiao Shi2af905b2014-11-27 13:10:54 -0700229public: // local control header
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800230 nfd::LocalControlHeader&
231 getLocalControlHeader()
232 {
233 return m_localControlHeader;
234 }
235
236 const nfd::LocalControlHeader&
237 getLocalControlHeader() const
238 {
239 return m_localControlHeader;
240 }
241
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800242 uint64_t
243 getIncomingFaceId() const
244 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800245 return getLocalControlHeader().getIncomingFaceId();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800246 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800247
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800248 Interest&
249 setIncomingFaceId(uint64_t incomingFaceId)
250 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800251 getLocalControlHeader().setIncomingFaceId(incomingFaceId);
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800252 // ! do not reset Interest's wire !
253 return *this;
254 }
255
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800256 uint64_t
257 getNextHopFaceId() const
258 {
259 return getLocalControlHeader().getNextHopFaceId();
260 }
261
262 Interest&
263 setNextHopFaceId(uint64_t nextHopFaceId)
264 {
265 getLocalControlHeader().setNextHopFaceId(nextHopFaceId);
266 // ! do not reset Interest's wire !
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800267 return *this;
268 }
269
Junxiao Shi2af905b2014-11-27 13:10:54 -0700270public: // Selectors
271 /**
272 * @return true if Interest has any selector present
273 */
274 bool
275 hasSelectors() const
276 {
277 return !m_selectors.empty();
278 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700279
Junxiao Shi2af905b2014-11-27 13:10:54 -0700280 const Selectors&
281 getSelectors() const
282 {
283 return m_selectors;
284 }
285
286 Interest&
287 setSelectors(const Selectors& selectors)
288 {
289 m_selectors = selectors;
290 m_wire.reset();
291 return *this;
292 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700293
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800294 int
295 getMinSuffixComponents() const
296 {
297 return m_selectors.getMinSuffixComponents();
298 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700299
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800300 Interest&
301 setMinSuffixComponents(int minSuffixComponents)
302 {
303 m_selectors.setMinSuffixComponents(minSuffixComponents);
304 m_wire.reset();
305 return *this;
306 }
307
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800308 int
309 getMaxSuffixComponents() const
310 {
311 return m_selectors.getMaxSuffixComponents();
312 }
313
314 Interest&
315 setMaxSuffixComponents(int maxSuffixComponents)
316 {
317 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
318 m_wire.reset();
319 return *this;
320 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700321
Junxiao Shib332e782014-03-31 14:23:46 -0700322 const KeyLocator&
323 getPublisherPublicKeyLocator() const
324 {
325 return m_selectors.getPublisherPublicKeyLocator();
326 }
327
328 Interest&
329 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
330 {
331 m_selectors.setPublisherPublicKeyLocator(keyLocator);
332 m_wire.reset();
333 return *this;
334 }
335
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800336 const Exclude&
337 getExclude() const
338 {
339 return m_selectors.getExclude();
340 }
341
342 Interest&
343 setExclude(const Exclude& exclude)
344 {
345 m_selectors.setExclude(exclude);
346 m_wire.reset();
347 return *this;
348 }
349
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700350 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800351 getChildSelector() const
352 {
353 return m_selectors.getChildSelector();
354 }
355
356 Interest&
357 setChildSelector(int childSelector)
358 {
359 m_selectors.setChildSelector(childSelector);
360 m_wire.reset();
361 return *this;
362 }
363
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700364 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800365 getMustBeFresh() const
366 {
367 return m_selectors.getMustBeFresh();
368 }
369
370 Interest&
371 setMustBeFresh(bool mustBeFresh)
372 {
373 m_selectors.setMustBeFresh(mustBeFresh);
374 m_wire.reset();
375 return *this;
376 }
377
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700378public: // EqualityComparable concept
379 bool
380 operator==(const Interest& other) const
381 {
382 return wireEncode() == other.wireEncode();
383 }
384
385 bool
386 operator!=(const Interest& other) const
387 {
388 return !(*this == other);
389 }
390
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800391private:
392 Name m_name;
393 Selectors m_selectors;
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300394 mutable Block m_nonce;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800395 int m_scope;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700396 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800397
398 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800399
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800400 nfd::LocalControlHeader m_localControlHeader;
401 friend class nfd::LocalControlHeader;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700402};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800403
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700404std::ostream&
405operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800406
407inline std::string
408Interest::toUri() const
409{
410 std::ostringstream os;
411 os << *this;
412 return os.str();
413}
414
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800415} // namespace ndn
416
417#endif // NDN_INTEREST_HPP