blob: 7d0705ef34e7d7b2e130f9cf7585982af61d6470 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi899277a2017-07-07 22:12:12 +00002/*
Davide Pesavento0f830802018-01-16 23:58:58 -05003 * Copyright (c) 2013-2018 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
Junxiao Shi9c154cb2017-07-07 22:14:54 +000025#include "delegation-list.hpp"
Jeff Thompson53412192013-08-06 13:35:50 -070026#include "name.hpp"
Eric Newberryc3a46792017-09-24 14:54:24 -070027#include "packet-base.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080028#include "selectors.hpp"
Junxiao Shi899277a2017-07-07 22:12:12 +000029#include "util/time.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 */
Davide Pesavento0f830802018-01-16 23:58:58 -050038const time::milliseconds DEFAULT_INTEREST_LIFETIME = 4_s;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080039
Junxiao Shi8d3f8342018-04-04 12:46:37 +000040/** @brief Represents an Interest packet.
Jeff Thompson8238d002013-07-10 11:56:49 -070041 */
Davide Pesavento1fd00242018-05-20 00:11:01 -040042class Interest : public PacketBase, public std::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 Shi8d3f8342018-04-04 12:46:37 +000055 /** @brief Construct an Interest with given @p name and @p lifetime.
56 * @throw std::invalid_argument @p lifetime is negative
57 * @warning In certain contexts that use `Interest::shared_from_this()`, Interest must be created
58 * using `make_shared`. Otherwise, `shared_from_this()` will trigger undefined behavior.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080059 */
Junxiao Shi909ffef2017-07-07 22:12:27 +000060 explicit
Junxiao Shi8d3f8342018-04-04 12:46:37 +000061 Interest(const Name& name = Name(), time::milliseconds lifetime = DEFAULT_INTEREST_LIFETIME);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070062
Junxiao Shi8d3f8342018-04-04 12:46:37 +000063 /** @brief Construct an Interest by decoding from @p wire.
64 * @warning In certain contexts that use `Interest::shared_from_this()`, Interest must be created
65 * using `make_shared`. Otherwise, `shared_from_this()` will trigger undefined behavior.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070066 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080067 explicit
Junxiao Shi2af905b2014-11-27 13:10:54 -070068 Interest(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080069
Junxiao Shi8d3f8342018-04-04 12:46:37 +000070 /** @brief Prepend wire encoding to @p encoder in NDN Packet Format v0.2.
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080071 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080072 template<encoding::Tag TAG>
Alexander Afanasyev197e5652014-06-13 16:56:31 -070073 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070074 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080075
Junxiao Shi6efa3b72018-04-14 15:54:08 +000076 /** @brief Encode to a @c Block.
77 *
78 * Normally, this function encodes to NDN Packet Format v0.2. However, if this instance has
79 * cached wire encoding (@c hasWire() is true), the cached encoding is returned and it might
80 * be in v0.3 format.
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080081 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070082 const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -080083 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080084
Junxiao Shi6efa3b72018-04-14 15:54:08 +000085 /** @brief Decode from @p wire in NDN Packet Format v0.2 or v0.3.
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080086 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070087 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070088 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080089
Junxiao Shi8d3f8342018-04-04 12:46:37 +000090 /** @brief Check if this instance has cached wire encoding.
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080091 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070092 bool
Junxiao Shi2af905b2014-11-27 13:10:54 -070093 hasWire() const
94 {
95 return m_wire.hasWire();
96 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070097
Junxiao Shi8d3f8342018-04-04 12:46:37 +000098 /** @brief Return a URI-like string that represents the Interest.
Alexander Afanasyev770827c2014-05-13 17:42:55 -070099 *
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000100 * The string starts with `getName().toUri()`.
101 * If the Interest contains selectors, they are included as a query string.
102 * Example: "/test/name?ndn.MustBeFresh=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800103 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700104 std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800105 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700106
Junxiao Shi2af905b2014-11-27 13:10:54 -0700107public: // matching
108 /** @brief Check if Interest, including selectors, matches the given @p name
109 * @param name The name to be matched. If this is a Data name, it shall contain the
110 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800111 */
112 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700113 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800114
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000115 /** @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700116 *
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000117 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
118 * PublisherPublicKeyLocator, and Exclude.
119 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700120 */
121 bool
122 matchesData(const Data& data) const;
123
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000124 /** @brief Check if Interest matches @p other interest
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800125 *
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000126 * Interest matches @p other if both have the same name, selectors, and link. Other fields
127 * (e.g., Nonce) may be different.
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800128 *
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000129 * @todo Implement distinguishing Interests by forwarding hint. The current implementation
130 * checks only name+selectors (Issue #3162).
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800131 */
132 bool
133 matchesInterest(const Interest& other) const;
134
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000135public: // element access
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700136 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800137 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700138 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800139 return m_name;
140 }
141
142 Interest&
143 setName(const Name& name)
144 {
145 m_name = name;
146 m_wire.reset();
147 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700148 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700149
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000150 /** @brief Check whether the CanBePrefix element is present.
151 *
152 * This is a getter for the CanBePrefix element as defined in NDN Packet Format v0.3.
153 * In this implementation, it is mapped to the closest v0.2 semantics:
154 * MaxSuffixComponents=1 means CanBePrefix is absent.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300155 */
156 bool
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000157 getCanBePrefix() const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800158 {
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000159 return m_selectors.getMaxSuffixComponents() != 1;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800160 }
161
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000162 /** @brief Add or remove CanBePrefix element.
163 * @param canBePrefix whether CanBePrefix element should be present.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300164 *
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000165 * This is a setter for the CanBePrefix element as defined in NDN Packet Format v0.3.
166 * In this implementation, it is mapped to the closest v0.2 semantics:
167 * MaxSuffixComponents=1 means CanBePrefix is absent.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300168 */
169 Interest&
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000170 setCanBePrefix(bool canBePrefix)
Junxiao Shi899277a2017-07-07 22:12:12 +0000171 {
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000172 m_selectors.setMaxSuffixComponents(canBePrefix ? -1 : 1);
173 m_wire.reset();
174 return *this;
Junxiao Shi899277a2017-07-07 22:12:12 +0000175 }
176
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000177 /** @brief Check whether the MustBeFresh element is present.
178 *
179 * This is a getter for the MustBeFresh element as defined in NDN Packet Format v0.3.
180 * In this implementation, it is mapped to the closest v0.2 semantics and appears as
181 * MustBeFresh element under Selectors.
182 */
183 bool
184 getMustBeFresh() const
185 {
186 return m_selectors.getMustBeFresh();
187 }
188
189 /** @brief Add or remove MustBeFresh element.
190 * @param mustBeFresh whether MustBeFresh element should be present.
191 *
192 * This is a setter for the MustBeFresh element as defined in NDN Packet Format v0.3.
193 * In this implementation, it is mapped to the closest v0.2 semantics and appears as
194 * MustBeFresh element under Selectors.
Junxiao Shi899277a2017-07-07 22:12:12 +0000195 */
196 Interest&
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000197 setMustBeFresh(bool mustBeFresh)
198 {
199 m_selectors.setMustBeFresh(mustBeFresh);
200 m_wire.reset();
201 return *this;
202 }
Junxiao Shi899277a2017-07-07 22:12:12 +0000203
Junxiao Shi9c154cb2017-07-07 22:14:54 +0000204 const DelegationList&
205 getForwardingHint() const
206 {
207 return m_forwardingHint;
208 }
209
210 Interest&
211 setForwardingHint(const DelegationList& value);
212
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000213 /** @brief Modify ForwardingHint in-place.
Junxiao Shib2a70332017-07-07 22:15:03 +0000214 * @tparam Modifier a unary function that accepts DelegationList&
215 *
216 * This is equivalent to, but more efficient (avoids copying) than:
217 * @code
218 * auto fh = interest.getForwardingHint();
219 * modifier(fh);
220 * interest.setForwardingHint(fh);
221 * @endcode
222 */
223 template<typename Modifier>
224 Interest&
225 modifyForwardingHint(const Modifier& modifier)
226 {
227 modifier(m_forwardingHint);
228 m_wire.reset();
229 return *this;
230 }
231
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000232 /** @brief Check if the Nonce element is present.
Junxiao Shi2af905b2014-11-27 13:10:54 -0700233 */
234 bool
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000235 hasNonce() const
236 {
237 return static_cast<bool>(m_nonce);
238 }
239
240 /** @brief Get nonce value.
241 *
242 * If nonce was not present, it is added and assigned a random value.
243 */
244 uint32_t
245 getNonce() const;
246
247 /** @brief Set nonce value.
248 */
249 Interest&
250 setNonce(uint32_t nonce);
251
252 /** @brief Change nonce value.
253 *
254 * If the Nonce element is present, the new nonce value will differ from the old value.
255 * If the Nonce element is not present, this method does nothing.
256 */
257 void
258 refreshNonce();
259
260 time::milliseconds
261 getInterestLifetime() const
262 {
263 return m_interestLifetime;
264 }
265
266 /** @brief Set Interest's lifetime
267 * @throw std::invalid_argument @p lifetime is negative
268 */
269 Interest&
270 setInterestLifetime(time::milliseconds lifetime);
271
272public: // Selectors (deprecated)
273 /** @brief Check if Interest has any selector present.
274 */
Davide Pesavento1fd00242018-05-20 00:11:01 -0400275 [[deprecated]]
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000276 bool
Junxiao Shi2af905b2014-11-27 13:10:54 -0700277 hasSelectors() const
278 {
279 return !m_selectors.empty();
280 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700281
Davide Pesavento1fd00242018-05-20 00:11:01 -0400282 [[deprecated]]
Junxiao Shi2af905b2014-11-27 13:10:54 -0700283 const Selectors&
284 getSelectors() const
285 {
286 return m_selectors;
287 }
288
Davide Pesavento1fd00242018-05-20 00:11:01 -0400289 [[deprecated]]
Junxiao Shi2af905b2014-11-27 13:10:54 -0700290 Interest&
291 setSelectors(const Selectors& selectors)
292 {
293 m_selectors = selectors;
294 m_wire.reset();
295 return *this;
296 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700297
Davide Pesavento1fd00242018-05-20 00:11:01 -0400298 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800299 int
300 getMinSuffixComponents() const
301 {
302 return m_selectors.getMinSuffixComponents();
303 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700304
Davide Pesavento1fd00242018-05-20 00:11:01 -0400305 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800306 Interest&
307 setMinSuffixComponents(int minSuffixComponents)
308 {
309 m_selectors.setMinSuffixComponents(minSuffixComponents);
310 m_wire.reset();
311 return *this;
312 }
313
Davide Pesavento1fd00242018-05-20 00:11:01 -0400314 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800315 int
316 getMaxSuffixComponents() const
317 {
318 return m_selectors.getMaxSuffixComponents();
319 }
320
Davide Pesavento1fd00242018-05-20 00:11:01 -0400321 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800322 Interest&
323 setMaxSuffixComponents(int maxSuffixComponents)
324 {
325 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
326 m_wire.reset();
327 return *this;
328 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700329
Davide Pesavento1fd00242018-05-20 00:11:01 -0400330 [[deprecated]]
Junxiao Shib332e782014-03-31 14:23:46 -0700331 const KeyLocator&
332 getPublisherPublicKeyLocator() const
333 {
334 return m_selectors.getPublisherPublicKeyLocator();
335 }
336
Davide Pesavento1fd00242018-05-20 00:11:01 -0400337 [[deprecated]]
Junxiao Shib332e782014-03-31 14:23:46 -0700338 Interest&
339 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
340 {
341 m_selectors.setPublisherPublicKeyLocator(keyLocator);
342 m_wire.reset();
343 return *this;
344 }
345
Davide Pesavento1fd00242018-05-20 00:11:01 -0400346 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800347 const Exclude&
348 getExclude() const
349 {
350 return m_selectors.getExclude();
351 }
352
Davide Pesavento1fd00242018-05-20 00:11:01 -0400353 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800354 Interest&
355 setExclude(const Exclude& exclude)
356 {
357 m_selectors.setExclude(exclude);
358 m_wire.reset();
359 return *this;
360 }
361
Davide Pesavento1fd00242018-05-20 00:11:01 -0400362 [[deprecated]]
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700363 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800364 getChildSelector() const
365 {
366 return m_selectors.getChildSelector();
367 }
368
Davide Pesavento1fd00242018-05-20 00:11:01 -0400369 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800370 Interest&
371 setChildSelector(int childSelector)
372 {
373 m_selectors.setChildSelector(childSelector);
374 m_wire.reset();
375 return *this;
376 }
377
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800378private:
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000379 /** @brief Decode @c m_wire as NDN Packet Format v0.2.
380 * @retval true decoding successful.
381 * @retval false decoding failed due to structural error.
382 * @throw tlv::Error decoding error within a sub-element.
383 */
384 bool
385 decode02();
386
387 /** @brief Decode @c m_wire as NDN Packet Format v0.3.
388 * @throw tlv::Error decoding error.
389 */
390 void
391 decode03();
392
393private:
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800394 Name m_name;
395 Selectors m_selectors;
Junxiao Shi2dd711d2017-07-21 13:40:52 +0000396 mutable optional<uint32_t> m_nonce;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700397 time::milliseconds m_interestLifetime;
Junxiao Shi9c154cb2017-07-07 22:14:54 +0000398 DelegationList m_forwardingHint;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800399
400 mutable Block m_wire;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700401};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800402
Davide Pesavento88a0d812017-08-19 21:31:42 -0400403NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Interest);
404
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700405std::ostream&
406operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800407
Junxiao Shi899277a2017-07-07 22:12:12 +0000408inline bool
409operator==(const Interest& lhs, const Interest& rhs)
410{
411 return lhs.wireEncode() == rhs.wireEncode();
412}
413
414inline bool
415operator!=(const Interest& lhs, const Interest& rhs)
416{
417 return !(lhs == rhs);
418}
419
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800420} // namespace ndn
421
422#endif // NDN_INTEREST_HPP