blob: e98747e7dfe84a5272d42d24f02a18c10a6c17d3 [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 Afanasyev1013fd02017-01-03 13:19:03 -08003 * Copyright (c) 2013-2017 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
Jeff Thompson53412192013-08-06 13:35:50 -070025#include "name.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080026#include "selectors.hpp"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070027#include "util/time.hpp"
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080028#include "tag-host.hpp"
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -070029#include "link.hpp"
Jeff Thompsonb7f95562013-07-03 18:36:42 -070030
31namespace ndn {
Alexander Afanasyevc348f832014-02-17 16:35:17 -080032
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070033class Data;
34
Junxiao Shi7007a3c2014-11-20 22:37:55 -070035/** @var const unspecified_duration_type DEFAULT_INTEREST_LIFETIME;
36 * @brief default value for InterestLifetime
37 */
38const time::milliseconds DEFAULT_INTEREST_LIFETIME = time::milliseconds(4000);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080039
Junxiao Shic2b8d242014-11-04 08:35:29 -070040/** @brief represents an Interest packet
Jeff Thompson8238d002013-07-10 11:56:49 -070041 */
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080042class Interest : public TagHost, public enable_shared_from_this<Interest>
Alexander Afanasyevc348f832014-02-17 16:35:17 -080043{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070044public:
Junxiao Shic2b8d242014-11-04 08:35:29 -070045 class Error : public tlv::Error
46 {
47 public:
48 explicit
49 Error(const std::string& what)
50 : tlv::Error(what)
51 {
52 }
53 };
54
Junxiao Shi2af905b2014-11-27 13:10:54 -070055 /** @brief Create a new Interest with an empty name (`ndn:/`)
56 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
57 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080058 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070059 Interest();
Alexander Afanasyevc348f832014-02-17 16:35:17 -080060
Junxiao Shi2af905b2014-11-27 13:10:54 -070061 /** @brief Create a new Interest with the given name
62 * @param name The name for the interest.
63 * @note This constructor allows implicit conversion from Name.
64 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
65 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080066 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070067 Interest(const Name& name);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080068
Junxiao Shi2af905b2014-11-27 13:10:54 -070069 /** @brief Create a new Interest with the given name and interest lifetime
70 * @param name The name for the interest.
71 * @param interestLifetime The interest lifetime in time::milliseconds, or -1 for none.
72 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
73 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080074 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070075 Interest(const Name& name, const time::milliseconds& interestLifetime);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070076
Junxiao Shi2af905b2014-11-27 13:10:54 -070077 /** @brief Create from wire encoding
78 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
79 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070080 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080081 explicit
Junxiao Shi2af905b2014-11-27 13:10:54 -070082 Interest(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080083
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080084 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080085 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080086 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080087 template<encoding::Tag TAG>
Alexander Afanasyev197e5652014-06-13 16:56:31 -070088 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070089 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080090
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080091 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080092 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080093 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070094 const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -080095 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080096
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080097 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080098 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080099 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700100 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700101 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800102
103 /**
104 * @brief Check if already has wire
105 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700106 bool
Junxiao Shi2af905b2014-11-27 13:10:54 -0700107 hasWire() const
108 {
109 return m_wire.hasWire();
110 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700111
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700112 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700113 * @brief Encode the name according to the NDN URI Scheme
114 *
115 * If there are interest selectors, this method will append "?" and add the selectors as
116 * a query string. For example, "/test/name?ndn.ChildSelector=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800117 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700118 std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800119 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700120
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700121public: // Link and forwarding hint
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800122 /**
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700123 * @brief Check whether the Interest contains a Link object
124 * @return True if there is a link object, otherwise false
125 */
126 bool
127 hasLink() const;
128
129 /**
130 * @brief Get the link object for this interest
131 * @return The link object if there is one contained in this interest
132 * @throws Interest::Error if there is no link object contained in the interest
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700133 * @throws tlv::Error if the incorporated link object is malformed
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700134 */
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700135 const Link&
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700136 getLink() const;
137
138 /**
139 * @brief Set the link object for this interest
140 * @param link The link object that will be included in this interest (in wire format)
141 * @post !hasSelectedDelegation()
142 */
143 void
144 setLink(const Block& link);
145
146 /**
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700147 * @brief Delete the link object for this interest
148 * @post !hasLink()
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700149 */
150 void
151 unsetLink();
152
153 /**
154 * @brief Check whether the Interest includes a selected delegation
155 * @return True if there is a selected delegation, otherwise false
156 */
157 bool
158 hasSelectedDelegation() const;
159
160 /**
161 * @brief Get the name of the selected delegation
162 * @return The name of the selected delegation
163 * @throw Error SelectedDelegation is not set.
164 */
165 Name
166 getSelectedDelegation() const;
167
168 /**
169 * @brief Set the selected delegation
170 * @param delegationName The name of the selected delegation
171 * @throw Error Link is not set.
172 * @throw std::invalid_argument @p delegationName does not exist in Link.
173 */
174 void
175 setSelectedDelegation(const Name& delegationName);
176
177 /**
178 * @brief Set the selected delegation
Davide Pesavento18cf81b2015-09-12 23:36:43 +0200179 * @param delegationIndex The index of the selected delegation
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700180 * @throw Error Link is not set.
181 * @throw std::out_of_range @p delegationIndex is out of bound in Link.
182 */
183 void
184 setSelectedDelegation(size_t delegationIndex);
185
186 /**
187 * @brief Unset the selected delegation
188 */
189 void
190 unsetSelectedDelegation();
191
Junxiao Shi2af905b2014-11-27 13:10:54 -0700192public: // matching
193 /** @brief Check if Interest, including selectors, matches the given @p name
194 * @param name The name to be matched. If this is a Data name, it shall contain the
195 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800196 */
197 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700198 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800199
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700200 /**
201 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700202 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700203 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
204 * PublisherPublicKeyLocator, and Exclude.
205 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700206 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700207 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700208 */
209 bool
210 matchesData(const Data& data) const;
211
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800212 /**
213 * @brief Check if Interest matches @p other interest
214 *
215 * Interest matches @p other if both have the same name, selectors, and link. Other fields
216 * (e.g., Nonce) may be different.
217 *
218 * @todo Implement distinguishing interests by link. The current implementation checks only
219 * name+selectors (Issue #3162).
220 */
221 bool
222 matchesInterest(const Interest& other) const;
223
Junxiao Shi2af905b2014-11-27 13:10:54 -0700224public: // Name and guiders
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700225 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800226 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700227 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800228 return m_name;
229 }
230
231 Interest&
232 setName(const Name& name)
233 {
234 m_name = name;
235 m_wire.reset();
236 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700237 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700238
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700239 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800240 getInterestLifetime() const
241 {
242 return m_interestLifetime;
243 }
244
Eric Newberryb555b002017-05-17 00:30:44 -0700245 /**
246 * @brief Set Interest's lifetime
247 * @throw std::invalid_argument specified lifetime is < 0
248 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800249 Interest&
Eric Newberryb555b002017-05-17 00:30:44 -0700250 setInterestLifetime(time::milliseconds interestLifetime);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800251
Junxiao Shi2af905b2014-11-27 13:10:54 -0700252 /** @brief Check if Nonce set
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300253 */
254 bool
255 hasNonce() const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800256 {
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300257 return m_nonce.hasWire();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800258 }
259
Junxiao Shi2af905b2014-11-27 13:10:54 -0700260 /** @brief Get Interest's nonce
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300261 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700262 * If nonce was not set before this call, it will be automatically assigned to a random value
263 */
264 uint32_t
265 getNonce() const;
266
267 /** @brief Set Interest's nonce
268 *
269 * If wire format already exists, this call simply replaces nonce in the
270 * existing wire format, without resetting and recreating it.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300271 */
272 Interest&
273 setNonce(uint32_t nonce);
274
Junxiao Shi2af905b2014-11-27 13:10:54 -0700275 /** @brief Refresh nonce
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700276 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700277 * It's guaranteed that new nonce value differs from the existing one.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700278 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700279 * If nonce is already set, it will be updated to a different random value.
280 * If nonce is not set, this method does nothing.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700281 */
282 void
283 refreshNonce();
284
Junxiao Shi2af905b2014-11-27 13:10:54 -0700285public: // Selectors
286 /**
287 * @return true if Interest has any selector present
288 */
289 bool
290 hasSelectors() const
291 {
292 return !m_selectors.empty();
293 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700294
Junxiao Shi2af905b2014-11-27 13:10:54 -0700295 const Selectors&
296 getSelectors() const
297 {
298 return m_selectors;
299 }
300
301 Interest&
302 setSelectors(const Selectors& selectors)
303 {
304 m_selectors = selectors;
305 m_wire.reset();
306 return *this;
307 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700308
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800309 int
310 getMinSuffixComponents() const
311 {
312 return m_selectors.getMinSuffixComponents();
313 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700314
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800315 Interest&
316 setMinSuffixComponents(int minSuffixComponents)
317 {
318 m_selectors.setMinSuffixComponents(minSuffixComponents);
319 m_wire.reset();
320 return *this;
321 }
322
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800323 int
324 getMaxSuffixComponents() const
325 {
326 return m_selectors.getMaxSuffixComponents();
327 }
328
329 Interest&
330 setMaxSuffixComponents(int maxSuffixComponents)
331 {
332 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
333 m_wire.reset();
334 return *this;
335 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700336
Junxiao Shib332e782014-03-31 14:23:46 -0700337 const KeyLocator&
338 getPublisherPublicKeyLocator() const
339 {
340 return m_selectors.getPublisherPublicKeyLocator();
341 }
342
343 Interest&
344 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
345 {
346 m_selectors.setPublisherPublicKeyLocator(keyLocator);
347 m_wire.reset();
348 return *this;
349 }
350
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800351 const Exclude&
352 getExclude() const
353 {
354 return m_selectors.getExclude();
355 }
356
357 Interest&
358 setExclude(const Exclude& exclude)
359 {
360 m_selectors.setExclude(exclude);
361 m_wire.reset();
362 return *this;
363 }
364
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700365 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800366 getChildSelector() const
367 {
368 return m_selectors.getChildSelector();
369 }
370
371 Interest&
372 setChildSelector(int childSelector)
373 {
374 m_selectors.setChildSelector(childSelector);
375 m_wire.reset();
376 return *this;
377 }
378
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700379 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800380 getMustBeFresh() const
381 {
382 return m_selectors.getMustBeFresh();
383 }
384
385 Interest&
386 setMustBeFresh(bool mustBeFresh)
387 {
388 m_selectors.setMustBeFresh(mustBeFresh);
389 m_wire.reset();
390 return *this;
391 }
392
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700393public: // EqualityComparable concept
394 bool
395 operator==(const Interest& other) const
396 {
397 return wireEncode() == other.wireEncode();
398 }
399
400 bool
401 operator!=(const Interest& other) const
402 {
403 return !(*this == other);
404 }
405
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800406private:
407 Name m_name;
408 Selectors m_selectors;
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300409 mutable Block m_nonce;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700410 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800411
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700412 mutable Block m_link;
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700413 mutable shared_ptr<Link> m_linkCached;
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700414 size_t m_selectedDelegationIndex;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800415 mutable Block m_wire;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700416};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800417
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700418std::ostream&
419operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800420
421inline std::string
422Interest::toUri() const
423{
424 std::ostringstream os;
425 os << *this;
426 return os.str();
427}
428
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800429} // namespace ndn
430
431#endif // NDN_INTEREST_HPP