blob: 1357352d99e97d7beb53d9c901ebc7f2caada78c [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"
Junxiao Shib55e5d32018-07-18 13:32:00 -060030#include <boost/logic/tribool.hpp>
Jeff Thompsonb7f95562013-07-03 18:36:42 -070031
32namespace ndn {
Alexander Afanasyevc348f832014-02-17 16:35:17 -080033
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070034class Data;
35
Junxiao Shi7007a3c2014-11-20 22:37:55 -070036/** @var const unspecified_duration_type DEFAULT_INTEREST_LIFETIME;
37 * @brief default value for InterestLifetime
38 */
Davide Pesavento0f830802018-01-16 23:58:58 -050039const time::milliseconds DEFAULT_INTEREST_LIFETIME = 4_s;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080040
Junxiao Shi8d3f8342018-04-04 12:46:37 +000041/** @brief Represents an Interest packet.
Jeff Thompson8238d002013-07-10 11:56:49 -070042 */
Davide Pesavento1fd00242018-05-20 00:11:01 -040043class Interest : public PacketBase, public std::enable_shared_from_this<Interest>
Alexander Afanasyevc348f832014-02-17 16:35:17 -080044{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070045public:
Junxiao Shic2b8d242014-11-04 08:35:29 -070046 class Error : public tlv::Error
47 {
48 public:
49 explicit
50 Error(const std::string& what)
51 : tlv::Error(what)
52 {
53 }
54 };
55
Junxiao Shi8d3f8342018-04-04 12:46:37 +000056 /** @brief Construct an Interest with given @p name and @p lifetime.
57 * @throw std::invalid_argument @p lifetime is negative
58 * @warning In certain contexts that use `Interest::shared_from_this()`, Interest must be created
59 * using `make_shared`. Otherwise, `shared_from_this()` will trigger undefined behavior.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080060 */
Junxiao Shi909ffef2017-07-07 22:12:27 +000061 explicit
Junxiao Shi8d3f8342018-04-04 12:46:37 +000062 Interest(const Name& name = Name(), time::milliseconds lifetime = DEFAULT_INTEREST_LIFETIME);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070063
Junxiao Shi8d3f8342018-04-04 12:46:37 +000064 /** @brief Construct an Interest by decoding from @p wire.
65 * @warning In certain contexts that use `Interest::shared_from_this()`, Interest must be created
66 * using `make_shared`. Otherwise, `shared_from_this()` will trigger undefined behavior.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070067 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080068 explicit
Junxiao Shi2af905b2014-11-27 13:10:54 -070069 Interest(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080070
Junxiao Shi8d3f8342018-04-04 12:46:37 +000071 /** @brief Prepend wire encoding to @p encoder in NDN Packet Format v0.2.
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080072 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080073 template<encoding::Tag TAG>
Alexander Afanasyev197e5652014-06-13 16:56:31 -070074 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070075 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080076
Junxiao Shi6efa3b72018-04-14 15:54:08 +000077 /** @brief Encode to a @c Block.
78 *
79 * Normally, this function encodes to NDN Packet Format v0.2. However, if this instance has
80 * cached wire encoding (@c hasWire() is true), the cached encoding is returned and it might
81 * be in v0.3 format.
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080082 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070083 const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -080084 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080085
Junxiao Shi6efa3b72018-04-14 15:54:08 +000086 /** @brief Decode from @p wire in NDN Packet Format v0.2 or v0.3.
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080087 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070088 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070089 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080090
Junxiao Shi8d3f8342018-04-04 12:46:37 +000091 /** @brief Check if this instance has cached wire encoding.
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080092 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070093 bool
Junxiao Shi2af905b2014-11-27 13:10:54 -070094 hasWire() const
95 {
96 return m_wire.hasWire();
97 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070098
Junxiao Shi8d3f8342018-04-04 12:46:37 +000099 /** @brief Return a URI-like string that represents the Interest.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700100 *
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000101 * The string starts with `getName().toUri()`.
102 * If the Interest contains selectors, they are included as a query string.
103 * Example: "/test/name?ndn.MustBeFresh=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800104 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700105 std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800106 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700107
Junxiao Shi2af905b2014-11-27 13:10:54 -0700108public: // matching
109 /** @brief Check if Interest, including selectors, matches the given @p name
110 * @param name The name to be matched. If this is a Data name, it shall contain the
111 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800112 */
113 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700114 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800115
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000116 /** @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700117 *
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000118 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
119 * PublisherPublicKeyLocator, and Exclude.
120 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700121 */
122 bool
123 matchesData(const Data& data) const;
124
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000125 /** @brief Check if Interest matches @p other interest
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800126 *
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000127 * Interest matches @p other if both have the same name, selectors, and link. Other fields
128 * (e.g., Nonce) may be different.
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800129 *
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000130 * @todo Implement distinguishing Interests by forwarding hint. The current implementation
131 * checks only name+selectors (Issue #3162).
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800132 */
133 bool
134 matchesInterest(const Interest& other) const;
135
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000136public: // element access
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700137 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800138 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700139 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800140 return m_name;
141 }
142
143 Interest&
144 setName(const Name& name)
145 {
146 m_name = name;
147 m_wire.reset();
148 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700149 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700150
Junxiao Shib55e5d32018-07-18 13:32:00 -0600151 /** @brief Declare the default CanBePrefix setting of the application.
152 *
153 * As part of transitioning to NDN Packet Format v0.3, the default setting for CanBePrefix
154 * will be changed from "true" to "false". Application developers are advised to review all
155 * Interests expressed by their application and decide what CanBePrefix setting is appropriate
156 * for each Interest, to avoid breaking changes when the transition occurs. Application may
157 * either set CanBePrefix on a per-Interest basis, or declare a default CanBePrefix setting for
158 * all Interests expressed by the application using this function. If an application neither
159 * declares a default nor sets CanBePrefix on every Interest, Interest::wireEncode will print a
160 * one-time warning message.
161 *
162 * @note This function should not be used in libraries or in ndn-cxx unit tests.
163 * @sa https://redmine.named-data.net/projects/nfd/wiki/Packet03Transition
164 */
165 static void
166 setDefaultCanBePrefix(bool canBePrefix)
167 {
168 s_defaultCanBePrefix = canBePrefix;
169 }
170
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000171 /** @brief Check whether the CanBePrefix element is present.
172 *
173 * This is a getter for the CanBePrefix element as defined in NDN Packet Format v0.3.
174 * In this implementation, it is mapped to the closest v0.2 semantics:
175 * MaxSuffixComponents=1 means CanBePrefix is absent.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300176 */
177 bool
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000178 getCanBePrefix() const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800179 {
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000180 return m_selectors.getMaxSuffixComponents() != 1;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800181 }
182
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000183 /** @brief Add or remove CanBePrefix element.
184 * @param canBePrefix whether CanBePrefix element should be present.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300185 *
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000186 * This is a setter for the CanBePrefix element as defined in NDN Packet Format v0.3.
187 * In this implementation, it is mapped to the closest v0.2 semantics:
188 * MaxSuffixComponents=1 means CanBePrefix is absent.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300189 */
190 Interest&
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000191 setCanBePrefix(bool canBePrefix)
Junxiao Shi899277a2017-07-07 22:12:12 +0000192 {
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000193 m_selectors.setMaxSuffixComponents(canBePrefix ? -1 : 1);
194 m_wire.reset();
Junxiao Shib55e5d32018-07-18 13:32:00 -0600195 m_isCanBePrefixSet = true;
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000196 return *this;
Junxiao Shi899277a2017-07-07 22:12:12 +0000197 }
198
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000199 /** @brief Check whether the MustBeFresh element is present.
200 *
201 * This is a getter for the MustBeFresh element as defined in NDN Packet Format v0.3.
202 * In this implementation, it is mapped to the closest v0.2 semantics and appears as
203 * MustBeFresh element under Selectors.
204 */
205 bool
206 getMustBeFresh() const
207 {
208 return m_selectors.getMustBeFresh();
209 }
210
211 /** @brief Add or remove MustBeFresh element.
212 * @param mustBeFresh whether MustBeFresh element should be present.
213 *
214 * This is a setter for the MustBeFresh element as defined in NDN Packet Format v0.3.
215 * In this implementation, it is mapped to the closest v0.2 semantics and appears as
216 * MustBeFresh element under Selectors.
Junxiao Shi899277a2017-07-07 22:12:12 +0000217 */
218 Interest&
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000219 setMustBeFresh(bool mustBeFresh)
220 {
221 m_selectors.setMustBeFresh(mustBeFresh);
222 m_wire.reset();
223 return *this;
224 }
Junxiao Shi899277a2017-07-07 22:12:12 +0000225
Junxiao Shi9c154cb2017-07-07 22:14:54 +0000226 const DelegationList&
227 getForwardingHint() const
228 {
229 return m_forwardingHint;
230 }
231
232 Interest&
233 setForwardingHint(const DelegationList& value);
234
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000235 /** @brief Modify ForwardingHint in-place.
Junxiao Shib2a70332017-07-07 22:15:03 +0000236 * @tparam Modifier a unary function that accepts DelegationList&
237 *
238 * This is equivalent to, but more efficient (avoids copying) than:
239 * @code
240 * auto fh = interest.getForwardingHint();
241 * modifier(fh);
242 * interest.setForwardingHint(fh);
243 * @endcode
244 */
245 template<typename Modifier>
246 Interest&
247 modifyForwardingHint(const Modifier& modifier)
248 {
249 modifier(m_forwardingHint);
250 m_wire.reset();
251 return *this;
252 }
253
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000254 /** @brief Check if the Nonce element is present.
Junxiao Shi2af905b2014-11-27 13:10:54 -0700255 */
256 bool
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000257 hasNonce() const
258 {
259 return static_cast<bool>(m_nonce);
260 }
261
262 /** @brief Get nonce value.
263 *
264 * If nonce was not present, it is added and assigned a random value.
265 */
266 uint32_t
267 getNonce() const;
268
269 /** @brief Set nonce value.
270 */
271 Interest&
272 setNonce(uint32_t nonce);
273
274 /** @brief Change nonce value.
275 *
276 * If the Nonce element is present, the new nonce value will differ from the old value.
277 * If the Nonce element is not present, this method does nothing.
278 */
279 void
280 refreshNonce();
281
282 time::milliseconds
283 getInterestLifetime() const
284 {
285 return m_interestLifetime;
286 }
287
288 /** @brief Set Interest's lifetime
289 * @throw std::invalid_argument @p lifetime is negative
290 */
291 Interest&
292 setInterestLifetime(time::milliseconds lifetime);
293
294public: // Selectors (deprecated)
295 /** @brief Check if Interest has any selector present.
296 */
Davide Pesavento1fd00242018-05-20 00:11:01 -0400297 [[deprecated]]
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000298 bool
Junxiao Shi2af905b2014-11-27 13:10:54 -0700299 hasSelectors() const
300 {
301 return !m_selectors.empty();
302 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700303
Davide Pesavento1fd00242018-05-20 00:11:01 -0400304 [[deprecated]]
Junxiao Shi2af905b2014-11-27 13:10:54 -0700305 const Selectors&
306 getSelectors() const
307 {
308 return m_selectors;
309 }
310
Davide Pesavento1fd00242018-05-20 00:11:01 -0400311 [[deprecated]]
Junxiao Shi2af905b2014-11-27 13:10:54 -0700312 Interest&
313 setSelectors(const Selectors& selectors)
314 {
315 m_selectors = selectors;
316 m_wire.reset();
317 return *this;
318 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700319
Davide Pesavento1fd00242018-05-20 00:11:01 -0400320 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800321 int
322 getMinSuffixComponents() const
323 {
324 return m_selectors.getMinSuffixComponents();
325 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700326
Davide Pesavento1fd00242018-05-20 00:11:01 -0400327 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800328 Interest&
329 setMinSuffixComponents(int minSuffixComponents)
330 {
331 m_selectors.setMinSuffixComponents(minSuffixComponents);
332 m_wire.reset();
333 return *this;
334 }
335
Davide Pesavento1fd00242018-05-20 00:11:01 -0400336 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800337 int
338 getMaxSuffixComponents() const
339 {
340 return m_selectors.getMaxSuffixComponents();
341 }
342
Davide Pesavento1fd00242018-05-20 00:11:01 -0400343 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800344 Interest&
345 setMaxSuffixComponents(int maxSuffixComponents)
346 {
347 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
348 m_wire.reset();
349 return *this;
350 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700351
Davide Pesavento1fd00242018-05-20 00:11:01 -0400352 [[deprecated]]
Junxiao Shib332e782014-03-31 14:23:46 -0700353 const KeyLocator&
354 getPublisherPublicKeyLocator() const
355 {
356 return m_selectors.getPublisherPublicKeyLocator();
357 }
358
Davide Pesavento1fd00242018-05-20 00:11:01 -0400359 [[deprecated]]
Junxiao Shib332e782014-03-31 14:23:46 -0700360 Interest&
361 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
362 {
363 m_selectors.setPublisherPublicKeyLocator(keyLocator);
364 m_wire.reset();
365 return *this;
366 }
367
Davide Pesavento1fd00242018-05-20 00:11:01 -0400368 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800369 const Exclude&
370 getExclude() const
371 {
372 return m_selectors.getExclude();
373 }
374
Davide Pesavento1fd00242018-05-20 00:11:01 -0400375 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800376 Interest&
377 setExclude(const Exclude& exclude)
378 {
379 m_selectors.setExclude(exclude);
380 m_wire.reset();
381 return *this;
382 }
383
Davide Pesavento1fd00242018-05-20 00:11:01 -0400384 [[deprecated]]
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700385 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800386 getChildSelector() const
387 {
388 return m_selectors.getChildSelector();
389 }
390
Davide Pesavento1fd00242018-05-20 00:11:01 -0400391 [[deprecated]]
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800392 Interest&
393 setChildSelector(int childSelector)
394 {
395 m_selectors.setChildSelector(childSelector);
396 m_wire.reset();
397 return *this;
398 }
399
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800400private:
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000401 /** @brief Decode @c m_wire as NDN Packet Format v0.2.
402 * @retval true decoding successful.
403 * @retval false decoding failed due to structural error.
404 * @throw tlv::Error decoding error within a sub-element.
405 */
406 bool
407 decode02();
408
409 /** @brief Decode @c m_wire as NDN Packet Format v0.3.
410 * @throw tlv::Error decoding error.
411 */
412 void
413 decode03();
414
Junxiao Shib55e5d32018-07-18 13:32:00 -0600415#ifdef NDN_CXX_HAVE_TESTS
416public:
417 /** @brief If true, not setting CanBePrefix results in an error in wireEncode().
418 */
419 static bool s_errorIfCanBePrefixUnset;
420#endif // NDN_CXX_HAVE_TESTS
421
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000422private:
Junxiao Shib55e5d32018-07-18 13:32:00 -0600423 static boost::logic::tribool s_defaultCanBePrefix;
424
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800425 Name m_name;
426 Selectors m_selectors;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600427 mutable bool m_isCanBePrefixSet;
Junxiao Shi2dd711d2017-07-21 13:40:52 +0000428 mutable optional<uint32_t> m_nonce;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700429 time::milliseconds m_interestLifetime;
Junxiao Shi9c154cb2017-07-07 22:14:54 +0000430 DelegationList m_forwardingHint;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800431
432 mutable Block m_wire;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600433
434 friend bool operator==(const Interest& lhs, const Interest& rhs);
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700435};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800436
Davide Pesavento88a0d812017-08-19 21:31:42 -0400437NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Interest);
438
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700439std::ostream&
440operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800441
Junxiao Shib55e5d32018-07-18 13:32:00 -0600442bool
443operator==(const Interest& lhs, const Interest& rhs);
Junxiao Shi899277a2017-07-07 22:12:12 +0000444
445inline bool
446operator!=(const Interest& lhs, const Interest& rhs)
447{
448 return !(lhs == rhs);
449}
450
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800451} // namespace ndn
452
453#endif // NDN_INTEREST_HPP