blob: c61d328a32d0d63b52a327c35ddd25ce3a856478 [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"
Junxiao Shi4b469982015-12-03 18:20:19 +000030#include "lp/tags.hpp"
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080031#include "tag-host.hpp"
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -070032#include "link.hpp"
Jeff Thompsonb7f95562013-07-03 18:36:42 -070033
34namespace ndn {
Alexander Afanasyevc348f832014-02-17 16:35:17 -080035
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070036class Data;
37
Junxiao Shi7007a3c2014-11-20 22:37:55 -070038/** @var const unspecified_duration_type DEFAULT_INTEREST_LIFETIME;
39 * @brief default value for InterestLifetime
40 */
41const time::milliseconds DEFAULT_INTEREST_LIFETIME = time::milliseconds(4000);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080042
Junxiao Shic2b8d242014-11-04 08:35:29 -070043/** @brief represents an Interest packet
Jeff Thompson8238d002013-07-10 11:56:49 -070044 */
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080045class Interest : public TagHost, public enable_shared_from_this<Interest>
Alexander Afanasyevc348f832014-02-17 16:35:17 -080046{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070047public:
Junxiao Shic2b8d242014-11-04 08:35:29 -070048 class Error : public tlv::Error
49 {
50 public:
51 explicit
52 Error(const std::string& what)
53 : tlv::Error(what)
54 {
55 }
56 };
57
Junxiao Shi2af905b2014-11-27 13:10:54 -070058 /** @brief Create a new Interest with an empty name (`ndn:/`)
59 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
60 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080061 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070062 Interest();
Alexander Afanasyevc348f832014-02-17 16:35:17 -080063
Junxiao Shi2af905b2014-11-27 13:10:54 -070064 /** @brief Create a new Interest with the given name
65 * @param name The name for the interest.
66 * @note This constructor allows implicit conversion from Name.
67 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
68 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080069 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070070 Interest(const Name& name);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080071
Junxiao Shi2af905b2014-11-27 13:10:54 -070072 /** @brief Create a new Interest with the given name and interest lifetime
73 * @param name The name for the interest.
74 * @param interestLifetime The interest lifetime in time::milliseconds, or -1 for none.
75 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
76 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080077 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070078 Interest(const Name& name, const time::milliseconds& interestLifetime);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070079
Junxiao Shi2af905b2014-11-27 13:10:54 -070080 /** @brief Create from wire encoding
81 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
82 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070083 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080084 explicit
Junxiao Shi2af905b2014-11-27 13:10:54 -070085 Interest(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080086
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080087 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080088 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080089 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080090 template<encoding::Tag TAG>
Alexander Afanasyev197e5652014-06-13 16:56:31 -070091 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070092 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080093
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080094 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080095 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080096 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070097 const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -080098 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080099
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800100 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800101 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800102 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700103 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700104 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800105
106 /**
107 * @brief Check if already has wire
108 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700109 bool
Junxiao Shi2af905b2014-11-27 13:10:54 -0700110 hasWire() const
111 {
112 return m_wire.hasWire();
113 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700114
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700115 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700116 * @brief Encode the name according to the NDN URI Scheme
117 *
118 * If there are interest selectors, this method will append "?" and add the selectors as
119 * a query string. For example, "/test/name?ndn.ChildSelector=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800120 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700121 std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800122 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700123
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700124public: // Link and forwarding hint
125
126 /**
127 * @brief Check whether the Interest contains a Link object
128 * @return True if there is a link object, otherwise false
129 */
130 bool
131 hasLink() const;
132
133 /**
134 * @brief Get the link object for this interest
135 * @return The link object if there is one contained in this interest
136 * @throws Interest::Error if there is no link object contained in the interest
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700137 * @throws tlv::Error if the incorporated link object is malformed
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700138 */
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700139 const Link&
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700140 getLink() const;
141
142 /**
143 * @brief Set the link object for this interest
144 * @param link The link object that will be included in this interest (in wire format)
145 * @post !hasSelectedDelegation()
146 */
147 void
148 setLink(const Block& link);
149
150 /**
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700151 * @brief Delete the link object for this interest
152 * @post !hasLink()
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700153 */
154 void
155 unsetLink();
156
157 /**
158 * @brief Check whether the Interest includes a selected delegation
159 * @return True if there is a selected delegation, otherwise false
160 */
161 bool
162 hasSelectedDelegation() const;
163
164 /**
165 * @brief Get the name of the selected delegation
166 * @return The name of the selected delegation
167 * @throw Error SelectedDelegation is not set.
168 */
169 Name
170 getSelectedDelegation() const;
171
172 /**
173 * @brief Set the selected delegation
174 * @param delegationName The name of the selected delegation
175 * @throw Error Link is not set.
176 * @throw std::invalid_argument @p delegationName does not exist in Link.
177 */
178 void
179 setSelectedDelegation(const Name& delegationName);
180
181 /**
182 * @brief Set the selected delegation
Davide Pesavento18cf81b2015-09-12 23:36:43 +0200183 * @param delegationIndex The index of the selected delegation
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700184 * @throw Error Link is not set.
185 * @throw std::out_of_range @p delegationIndex is out of bound in Link.
186 */
187 void
188 setSelectedDelegation(size_t delegationIndex);
189
190 /**
191 * @brief Unset the selected delegation
192 */
193 void
194 unsetSelectedDelegation();
195
Junxiao Shi2af905b2014-11-27 13:10:54 -0700196public: // matching
197 /** @brief Check if Interest, including selectors, matches the given @p name
198 * @param name The name to be matched. If this is a Data name, it shall contain the
199 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800200 */
201 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700202 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800203
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700204 /**
205 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700206 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700207 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
208 * PublisherPublicKeyLocator, and Exclude.
209 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700210 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700211 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700212 */
213 bool
214 matchesData(const Data& data) const;
215
Junxiao Shi2af905b2014-11-27 13:10:54 -0700216public: // Name and guiders
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700217 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800218 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700219 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800220 return m_name;
221 }
222
223 Interest&
224 setName(const Name& name)
225 {
226 m_name = name;
227 m_wire.reset();
228 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700229 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700230
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700231 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800232 getInterestLifetime() const
233 {
234 return m_interestLifetime;
235 }
236
237 Interest&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700238 setInterestLifetime(const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800239 {
240 m_interestLifetime = interestLifetime;
241 m_wire.reset();
242 return *this;
243 }
244
Junxiao Shi2af905b2014-11-27 13:10:54 -0700245 /** @brief Check if Nonce set
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300246 */
247 bool
248 hasNonce() const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800249 {
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300250 return m_nonce.hasWire();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800251 }
252
Junxiao Shi2af905b2014-11-27 13:10:54 -0700253 /** @brief Get Interest's nonce
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300254 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700255 * If nonce was not set before this call, it will be automatically assigned to a random value
256 */
257 uint32_t
258 getNonce() const;
259
260 /** @brief Set Interest's nonce
261 *
262 * If wire format already exists, this call simply replaces nonce in the
263 * existing wire format, without resetting and recreating it.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300264 */
265 Interest&
266 setNonce(uint32_t nonce);
267
Junxiao Shi2af905b2014-11-27 13:10:54 -0700268 /** @brief Refresh nonce
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700269 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700270 * It's guaranteed that new nonce value differs from the existing one.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700271 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700272 * If nonce is already set, it will be updated to a different random value.
273 * If nonce is not set, this method does nothing.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700274 */
275 void
276 refreshNonce();
277
Junxiao Shi4b469982015-12-03 18:20:19 +0000278#ifdef NDN_LP_KEEP_LOCAL_CONTROL_HEADER
Junxiao Shi2af905b2014-11-27 13:10:54 -0700279public: // local control header
Junxiao Shi4b469982015-12-03 18:20:19 +0000280 /** @deprecated use getTag and setTag with lp::IncomingFaceIdTag, lp::NextHopFaceIdTag
281 */
282 DEPRECATED(
283 lp::LocalControlHeaderFacade
284 getLocalControlHeader());
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800285
Junxiao Shi4b469982015-12-03 18:20:19 +0000286 /** @deprecated use getTag with lp::IncomingFaceIdTag, lp::NextHopFaceIdTag
287 */
288 DEPRECATED(
289 const lp::LocalControlHeaderFacade
290 getLocalControlHeader() const);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800291
Junxiao Shi4b469982015-12-03 18:20:19 +0000292 /** @deprecated use getTag<lp::IncomingFaceIdTag>
293 */
294 DEPRECATED(
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800295 uint64_t
Junxiao Shi4b469982015-12-03 18:20:19 +0000296 getIncomingFaceId() const);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800297
Junxiao Shi4b469982015-12-03 18:20:19 +0000298 /** @deprecated use setTag<lp::IncomingFaceIdTag>
299 */
300 DEPRECATED(
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800301 Interest&
Junxiao Shi4b469982015-12-03 18:20:19 +0000302 setIncomingFaceId(uint64_t incomingFaceId));
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800303
Junxiao Shi4b469982015-12-03 18:20:19 +0000304 /** @deprecated use getTag<lp::NextHopFaceIdTag>
305 */
306 DEPRECATED(
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800307 uint64_t
Junxiao Shi4b469982015-12-03 18:20:19 +0000308 getNextHopFaceId() const);
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800309
Junxiao Shi4b469982015-12-03 18:20:19 +0000310 /** @deprecated use setTag<lp::NextHopFaceIdTag>
311 */
312 DEPRECATED(
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800313 Interest&
Junxiao Shi4b469982015-12-03 18:20:19 +0000314 setNextHopFaceId(uint64_t nextHopFaceId));
315#endif // NDN_LP_KEEP_LOCAL_CONTROL_HEADER
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800316
Junxiao Shi2af905b2014-11-27 13:10:54 -0700317public: // Selectors
318 /**
319 * @return true if Interest has any selector present
320 */
321 bool
322 hasSelectors() const
323 {
324 return !m_selectors.empty();
325 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700326
Junxiao Shi2af905b2014-11-27 13:10:54 -0700327 const Selectors&
328 getSelectors() const
329 {
330 return m_selectors;
331 }
332
333 Interest&
334 setSelectors(const Selectors& selectors)
335 {
336 m_selectors = selectors;
337 m_wire.reset();
338 return *this;
339 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700340
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800341 int
342 getMinSuffixComponents() const
343 {
344 return m_selectors.getMinSuffixComponents();
345 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700346
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800347 Interest&
348 setMinSuffixComponents(int minSuffixComponents)
349 {
350 m_selectors.setMinSuffixComponents(minSuffixComponents);
351 m_wire.reset();
352 return *this;
353 }
354
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800355 int
356 getMaxSuffixComponents() const
357 {
358 return m_selectors.getMaxSuffixComponents();
359 }
360
361 Interest&
362 setMaxSuffixComponents(int maxSuffixComponents)
363 {
364 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
365 m_wire.reset();
366 return *this;
367 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700368
Junxiao Shib332e782014-03-31 14:23:46 -0700369 const KeyLocator&
370 getPublisherPublicKeyLocator() const
371 {
372 return m_selectors.getPublisherPublicKeyLocator();
373 }
374
375 Interest&
376 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
377 {
378 m_selectors.setPublisherPublicKeyLocator(keyLocator);
379 m_wire.reset();
380 return *this;
381 }
382
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800383 const Exclude&
384 getExclude() const
385 {
386 return m_selectors.getExclude();
387 }
388
389 Interest&
390 setExclude(const Exclude& exclude)
391 {
392 m_selectors.setExclude(exclude);
393 m_wire.reset();
394 return *this;
395 }
396
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700397 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800398 getChildSelector() const
399 {
400 return m_selectors.getChildSelector();
401 }
402
403 Interest&
404 setChildSelector(int childSelector)
405 {
406 m_selectors.setChildSelector(childSelector);
407 m_wire.reset();
408 return *this;
409 }
410
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700411 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800412 getMustBeFresh() const
413 {
414 return m_selectors.getMustBeFresh();
415 }
416
417 Interest&
418 setMustBeFresh(bool mustBeFresh)
419 {
420 m_selectors.setMustBeFresh(mustBeFresh);
421 m_wire.reset();
422 return *this;
423 }
424
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700425public: // EqualityComparable concept
426 bool
427 operator==(const Interest& other) const
428 {
429 return wireEncode() == other.wireEncode();
430 }
431
432 bool
433 operator!=(const Interest& other) const
434 {
435 return !(*this == other);
436 }
437
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800438private:
439 Name m_name;
440 Selectors m_selectors;
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300441 mutable Block m_nonce;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700442 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800443
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700444 mutable Block m_link;
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700445 mutable shared_ptr<Link> m_linkCached;
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700446 size_t m_selectedDelegationIndex;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800447 mutable Block m_wire;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700448};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800449
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700450std::ostream&
451operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800452
453inline std::string
454Interest::toUri() const
455{
456 std::ostringstream os;
457 os << *this;
458 return os.str();
459}
460
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800461} // namespace ndn
462
463#endif // NDN_INTEREST_HPP