blob: 8fc04a3e42bbf121f5843d39096907e38bd16ab8 [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/*
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +00003 * 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
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080022#include "interest.hpp"
Alexander Afanasyeve9fdb802014-02-05 17:36:51 -080023#include "util/random.hpp"
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070024#include "data.hpp"
Alexander Afanasyev840139f2013-12-28 15:02:50 -080025
Junxiao Shib55e5d32018-07-18 13:32:00 -060026#include <boost/scope_exit.hpp>
27
Davide Pesaventoe1789892017-02-26 15:50:52 -050028#include <cstring>
Junxiao Shib55e5d32018-07-18 13:32:00 -060029#include <iostream>
Davide Pesaventoa84f4642017-08-23 16:14:51 -040030#include <sstream>
Davide Pesaventoe1789892017-02-26 15:50:52 -050031
Jeff Thompsonb7f95562013-07-03 18:36:42 -070032namespace ndn {
Alexander Afanasyev84681982014-01-03 13:26:09 -080033
Junxiao Shic2b8d242014-11-04 08:35:29 -070034BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Interest>));
35BOOST_CONCEPT_ASSERT((WireEncodable<Interest>));
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070036BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Interest>));
Junxiao Shic2b8d242014-11-04 08:35:29 -070037BOOST_CONCEPT_ASSERT((WireDecodable<Interest>));
38static_assert(std::is_base_of<tlv::Error, Interest::Error>::value,
39 "Interest::Error must inherit from tlv::Error");
40
Junxiao Shib55e5d32018-07-18 13:32:00 -060041#ifdef NDN_CXX_HAVE_TESTS
42bool Interest::s_errorIfCanBePrefixUnset = true;
43#endif // NDN_CXX_HAVE_TESTS
44boost::logic::tribool Interest::s_defaultCanBePrefix = boost::logic::indeterminate;
45
Junxiao Shi8d3f8342018-04-04 12:46:37 +000046Interest::Interest(const Name& name, time::milliseconds lifetime)
Junxiao Shi2af905b2014-11-27 13:10:54 -070047 : m_name(name)
Junxiao Shib55e5d32018-07-18 13:32:00 -060048 , m_isCanBePrefixSet(false)
Junxiao Shi8d3f8342018-04-04 12:46:37 +000049 , m_interestLifetime(lifetime)
Junxiao Shi2af905b2014-11-27 13:10:54 -070050{
Junxiao Shi8d3f8342018-04-04 12:46:37 +000051 if (lifetime < time::milliseconds::zero()) {
Junxiao Shi899277a2017-07-07 22:12:12 +000052 BOOST_THROW_EXCEPTION(std::invalid_argument("InterestLifetime must be >= 0"));
53 }
Junxiao Shib55e5d32018-07-18 13:32:00 -060054
55 if (!boost::logic::indeterminate(s_defaultCanBePrefix)) {
56 setCanBePrefix(static_cast<bool>(s_defaultCanBePrefix));
57 }
Junxiao Shi2af905b2014-11-27 13:10:54 -070058}
59
Junxiao Shi2af905b2014-11-27 13:10:54 -070060Interest::Interest(const Block& wire)
Junxiao Shib55e5d32018-07-18 13:32:00 -060061 : m_isCanBePrefixSet(true)
Junxiao Shi2af905b2014-11-27 13:10:54 -070062{
63 wireDecode(wire);
64}
65
Junxiao Shi899277a2017-07-07 22:12:12 +000066// ---- encode and decode ----
Alexander Afanasyev840139f2013-12-28 15:02:50 -080067
Junxiao Shi899277a2017-07-07 22:12:12 +000068template<encoding::Tag TAG>
69size_t
70Interest::wireEncode(EncodingImpl<TAG>& encoder) const
71{
Junxiao Shib55e5d32018-07-18 13:32:00 -060072 static bool hasDefaultCanBePrefixWarning = false;
73 if (!m_isCanBePrefixSet) {
74 if (!hasDefaultCanBePrefixWarning) {
75 std::cerr << "WARNING: Interest.CanBePrefix will be set to 0 in the near future. "
76 << "Please declare a preferred setting via Interest::setDefaultCanBePrefix.";
77 hasDefaultCanBePrefixWarning = true;
78 }
79#ifdef NDN_CXX_HAVE_TESTS
80 if (s_errorIfCanBePrefixUnset) {
81 BOOST_THROW_EXCEPTION(std::logic_error("Interest.CanBePrefix is unset"));
82 }
83#endif // NDN_CXX_HAVE_TESTS
84 }
85
Junxiao Shi899277a2017-07-07 22:12:12 +000086 size_t totalLength = 0;
87
88 // Interest ::= INTEREST-TYPE TLV-LENGTH
89 // Name
90 // Selectors?
91 // Nonce
92 // InterestLifetime?
Junxiao Shi9c154cb2017-07-07 22:14:54 +000093 // ForwardingHint?
Junxiao Shi899277a2017-07-07 22:12:12 +000094
95 // (reverse encoding)
96
Junxiao Shi9c154cb2017-07-07 22:14:54 +000097 // ForwardingHint
98 if (m_forwardingHint.size() > 0) {
99 totalLength += m_forwardingHint.wireEncode(encoder);
100 }
101
Junxiao Shi899277a2017-07-07 22:12:12 +0000102 // InterestLifetime
103 if (getInterestLifetime() != DEFAULT_INTEREST_LIFETIME) {
104 totalLength += prependNonNegativeIntegerBlock(encoder,
105 tlv::InterestLifetime,
106 getInterestLifetime().count());
107 }
108
109 // Nonce
Junxiao Shi2dd711d2017-07-21 13:40:52 +0000110 uint32_t nonce = this->getNonce(); // assigns random Nonce if needed
111 totalLength += encoder.prependByteArray(reinterpret_cast<uint8_t*>(&nonce), sizeof(nonce));
112 totalLength += encoder.prependVarNumber(sizeof(nonce));
113 totalLength += encoder.prependVarNumber(tlv::Nonce);
Junxiao Shi899277a2017-07-07 22:12:12 +0000114
115 // Selectors
116 if (hasSelectors()) {
117 totalLength += getSelectors().wireEncode(encoder);
118 }
119
120 // Name
121 totalLength += getName().wireEncode(encoder);
122
123 totalLength += encoder.prependVarNumber(totalLength);
124 totalLength += encoder.prependVarNumber(tlv::Interest);
125 return totalLength;
Alexander Afanasyev840139f2013-12-28 15:02:50 -0800126}
127
Davide Pesavento88a0d812017-08-19 21:31:42 -0400128NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Interest);
Junxiao Shi899277a2017-07-07 22:12:12 +0000129
130const Block&
131Interest::wireEncode() const
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300132{
Junxiao Shi899277a2017-07-07 22:12:12 +0000133 if (m_wire.hasWire())
134 return m_wire;
135
136 EncodingEstimator estimator;
137 size_t estimatedSize = wireEncode(estimator);
138
139 EncodingBuffer buffer(estimatedSize, 0);
140 wireEncode(buffer);
141
Junxiao Shi899277a2017-07-07 22:12:12 +0000142 const_cast<Interest*>(this)->wireDecode(buffer.block());
Junxiao Shi899277a2017-07-07 22:12:12 +0000143 return m_wire;
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300144}
Alexander Afanasyev840139f2013-12-28 15:02:50 -0800145
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700146void
Junxiao Shi899277a2017-07-07 22:12:12 +0000147Interest::wireDecode(const Block& wire)
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700148{
Junxiao Shi899277a2017-07-07 22:12:12 +0000149 m_wire = wire;
150 m_wire.parse();
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700151
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000152 if (m_wire.type() != tlv::Interest) {
153 BOOST_THROW_EXCEPTION(Error("expecting Interest element, got " + to_string(m_wire.type())));
154 }
155
156 if (!decode02()) {
157 decode03();
158 if (!hasNonce()) {
159 setNonce(getNonce());
160 }
161 }
Junxiao Shib55e5d32018-07-18 13:32:00 -0600162
163 m_isCanBePrefixSet = true; // don't trigger warning from decoded packet
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000164}
165
166bool
167Interest::decode02()
168{
169 auto ele = m_wire.elements_begin();
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700170
Junxiao Shi899277a2017-07-07 22:12:12 +0000171 // Name
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000172 if (ele != m_wire.elements_end() && ele->type() == tlv::Name) {
173 m_name.wireDecode(*ele);
174 ++ele;
Junxiao Shi899277a2017-07-07 22:12:12 +0000175 }
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000176 else {
177 return false;
178 }
179
180 // Selectors?
181 if (ele != m_wire.elements_end() && ele->type() == tlv::Selectors) {
182 m_selectors.wireDecode(*ele);
183 ++ele;
184 }
185 else {
Junxiao Shi899277a2017-07-07 22:12:12 +0000186 m_selectors = Selectors();
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000187 }
Junxiao Shi899277a2017-07-07 22:12:12 +0000188
189 // Nonce
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000190 if (ele != m_wire.elements_end() && ele->type() == tlv::Nonce) {
191 uint32_t nonce = 0;
192 if (ele->value_size() != sizeof(nonce)) {
193 BOOST_THROW_EXCEPTION(Error("Nonce element is malformed"));
194 }
195 std::memcpy(&nonce, ele->value(), sizeof(nonce));
196 m_nonce = nonce;
197 ++ele;
Junxiao Shi2dd711d2017-07-21 13:40:52 +0000198 }
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000199 else {
200 return false;
Junxiao Shi2dd711d2017-07-21 13:40:52 +0000201 }
Junxiao Shi899277a2017-07-07 22:12:12 +0000202
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000203 // InterestLifetime?
204 if (ele != m_wire.elements_end() && ele->type() == tlv::InterestLifetime) {
205 m_interestLifetime = time::milliseconds(readNonNegativeInteger(*ele));
206 ++ele;
Junxiao Shi899277a2017-07-07 22:12:12 +0000207 }
208 else {
209 m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
210 }
211
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000212 // ForwardingHint?
213 if (ele != m_wire.elements_end() && ele->type() == tlv::ForwardingHint) {
214 m_forwardingHint.wireDecode(*ele, false);
215 ++ele;
Junxiao Shi9c154cb2017-07-07 22:14:54 +0000216 }
217 else {
218 m_forwardingHint = DelegationList();
219 }
Junxiao Shi6efa3b72018-04-14 15:54:08 +0000220
221 return ele == m_wire.elements_end();
222}
223
224void
225Interest::decode03()
226{
227 // Interest ::= INTEREST-TYPE TLV-LENGTH
228 // Name
229 // CanBePrefix?
230 // MustBeFresh?
231 // ForwardingHint?
232 // Nonce?
233 // InterestLifetime?
234 // HopLimit?
235 // Parameters?
236
237 bool hasName = false;
238 m_selectors = Selectors().setMaxSuffixComponents(1); // CanBePrefix=0
239 m_nonce.reset();
240 m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
241 m_forwardingHint = DelegationList();
242
243 int lastEle = 0; // last recognized element index, in spec order
244 for (const Block& ele : m_wire.elements()) {
245 switch (ele.type()) {
246 case tlv::Name: {
247 if (lastEle >= 1) {
248 BOOST_THROW_EXCEPTION(Error("Name element is out of order"));
249 }
250 hasName = true;
251 m_name.wireDecode(ele);
252 if (m_name.empty()) {
253 BOOST_THROW_EXCEPTION(Error("Name has zero name components"));
254 }
255 lastEle = 1;
256 break;
257 }
258 case tlv::CanBePrefix: {
259 if (lastEle >= 2) {
260 BOOST_THROW_EXCEPTION(Error("CanBePrefix element is out of order"));
261 }
262 if (ele.value_size() != 0) {
263 BOOST_THROW_EXCEPTION(Error("CanBePrefix element has non-zero TLV-LENGTH"));
264 }
265 m_selectors.setMaxSuffixComponents(-1);
266 lastEle = 2;
267 break;
268 }
269 case tlv::MustBeFresh: {
270 if (lastEle >= 3) {
271 BOOST_THROW_EXCEPTION(Error("MustBeFresh element is out of order"));
272 }
273 if (ele.value_size() != 0) {
274 BOOST_THROW_EXCEPTION(Error("MustBeFresh element has non-zero TLV-LENGTH"));
275 }
276 m_selectors.setMustBeFresh(true);
277 lastEle = 3;
278 break;
279 }
280 case tlv::ForwardingHint: {
281 if (lastEle >= 4) {
282 BOOST_THROW_EXCEPTION(Error("ForwardingHint element is out of order"));
283 }
284 m_forwardingHint.wireDecode(ele);
285 lastEle = 4;
286 break;
287 }
288 case tlv::Nonce: {
289 if (lastEle >= 5) {
290 BOOST_THROW_EXCEPTION(Error("Nonce element is out of order"));
291 }
292 uint32_t nonce = 0;
293 if (ele.value_size() != sizeof(nonce)) {
294 BOOST_THROW_EXCEPTION(Error("Nonce element is malformed"));
295 }
296 std::memcpy(&nonce, ele.value(), sizeof(nonce));
297 m_nonce = nonce;
298 lastEle = 5;
299 break;
300 }
301 case tlv::InterestLifetime: {
302 if (lastEle >= 6) {
303 BOOST_THROW_EXCEPTION(Error("InterestLifetime element is out of order"));
304 }
305 m_interestLifetime = time::milliseconds(readNonNegativeInteger(ele));
306 lastEle = 6;
307 break;
308 }
309 case tlv::HopLimit: {
310 if (lastEle >= 7) {
311 break; // HopLimit is non-critical, ignore out-of-order appearance
312 }
313 if (ele.value_size() != 1) {
314 BOOST_THROW_EXCEPTION(Error("HopLimit element is malformed"));
315 }
316 // TLV-VALUE is ignored
317 lastEle = 7;
318 break;
319 }
320 case tlv::Parameters: {
321 if (lastEle >= 8) {
322 BOOST_THROW_EXCEPTION(Error("Parameters element is out of order"));
323 }
324 // TLV-VALUE is ignored
325 lastEle = 8;
326 break;
327 }
328 default: {
329 if (tlv::isCriticalType(ele.type())) {
330 BOOST_THROW_EXCEPTION(Error("unrecognized element of critical type " +
331 to_string(ele.type())));
332 }
333 break;
334 }
335 }
336 }
337
338 if (!hasName) {
339 BOOST_THROW_EXCEPTION(Error("Name element is missing"));
340 }
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700341}
342
Davide Pesaventoa84f4642017-08-23 16:14:51 -0400343std::string
344Interest::toUri() const
345{
346 std::ostringstream os;
347 os << *this;
348 return os.str();
349}
350
Junxiao Shi899277a2017-07-07 22:12:12 +0000351// ---- matching ----
352
Alexander Afanasyev84681982014-01-03 13:26:09 -0800353bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700354Interest::matchesName(const Name& name) const
Jeff Thompson25b4e612013-10-10 16:03:24 -0700355{
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700356 if (name.size() < m_name.size())
357 return false;
358
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800359 if (!m_name.isPrefixOf(name))
Alexander Afanasyev84681982014-01-03 13:26:09 -0800360 return false;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700361
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800362 if (getMinSuffixComponents() >= 0 &&
Alexander Afanasyev3b703102014-06-13 17:01:14 -0700363 // name must include implicit digest
364 !(name.size() - m_name.size() >= static_cast<size_t>(getMinSuffixComponents())))
Alexander Afanasyev84681982014-01-03 13:26:09 -0800365 return false;
366
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800367 if (getMaxSuffixComponents() >= 0 &&
Alexander Afanasyev3b703102014-06-13 17:01:14 -0700368 // name must include implicit digest
369 !(name.size() - m_name.size() <= static_cast<size_t>(getMaxSuffixComponents())))
Alexander Afanasyev84681982014-01-03 13:26:09 -0800370 return false;
371
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700372 if (!getExclude().empty() &&
373 name.size() > m_name.size() &&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800374 getExclude().isExcluded(name[m_name.size()]))
Alexander Afanasyev84681982014-01-03 13:26:09 -0800375 return false;
376
377 return true;
Jeff Thompson25b4e612013-10-10 16:03:24 -0700378}
379
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700380bool
381Interest::matchesData(const Data& data) const
382{
Junxiao Shi42c23622014-07-03 00:55:11 -0700383 size_t interestNameLength = m_name.size();
384 const Name& dataName = data.getName();
385 size_t fullNameLength = dataName.size() + 1;
386
387 // check MinSuffixComponents
388 bool hasMinSuffixComponents = getMinSuffixComponents() >= 0;
389 size_t minSuffixComponents = hasMinSuffixComponents ?
390 static_cast<size_t>(getMinSuffixComponents()) : 0;
391 if (!(interestNameLength + minSuffixComponents <= fullNameLength))
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700392 return false;
Junxiao Shi42c23622014-07-03 00:55:11 -0700393
394 // check MaxSuffixComponents
395 bool hasMaxSuffixComponents = getMaxSuffixComponents() >= 0;
396 if (hasMaxSuffixComponents &&
397 !(interestNameLength + getMaxSuffixComponents() >= fullNameLength))
398 return false;
399
400 // check prefix
401 if (interestNameLength == fullNameLength) {
Alexander Afanasyev56860f52014-11-07 11:51:17 -0800402 if (m_name.get(-1).isImplicitSha256Digest()) {
403 if (m_name != data.getFullName())
Junxiao Shi42c23622014-07-03 00:55:11 -0700404 return false;
405 }
406 else {
407 // Interest Name is same length as Data full Name, but last component isn't digest
408 // so there's no possibility of matching
409 return false;
410 }
411 }
412 else {
413 // Interest Name is a strict prefix of Data full Name
414 if (!m_name.isPrefixOf(dataName))
415 return false;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700416 }
417
Junxiao Shi42c23622014-07-03 00:55:11 -0700418 // check Exclude
419 // Exclude won't be violated if Interest Name is same as Data full Name
420 if (!getExclude().empty() && fullNameLength > interestNameLength) {
421 if (interestNameLength == fullNameLength - 1) {
422 // component to exclude is the digest
423 if (getExclude().isExcluded(data.getFullName().get(interestNameLength)))
424 return false;
425 // There's opportunity to inspect the Exclude filter and determine whether
426 // the digest would make a difference.
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000427 // eg. "<GenericNameComponent>AA</GenericNameComponent><Any/>" doesn't exclude
428 // any digest - fullName not needed;
429 // "<Any/><GenericNameComponent>AA</GenericNameComponent>" and
Junxiao Shi08d07082014-12-03 11:31:44 -0700430 // "<Any/><ImplicitSha256DigestComponent>ffffffffffffffffffffffffffffffff
431 // </ImplicitSha256DigestComponent>"
432 // excludes all digests - fullName not needed;
433 // "<Any/><ImplicitSha256DigestComponent>80000000000000000000000000000000
434 // </ImplicitSha256DigestComponent>"
435 // excludes some digests - fullName required
Junxiao Shi42c23622014-07-03 00:55:11 -0700436 // But Interests that contain the exact Data Name before digest and also
437 // contain Exclude filter is too rare to optimize for, so we request
Junxiao Shi68247832017-07-03 22:06:49 +0000438 // fullName no matter what's in the Exclude filter.
Junxiao Shi42c23622014-07-03 00:55:11 -0700439 }
440 else {
441 // component to exclude is not the digest
442 if (getExclude().isExcluded(dataName.get(interestNameLength)))
443 return false;
444 }
445 }
446
447 // check PublisherPublicKeyLocator
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700448 const KeyLocator& publisherPublicKeyLocator = this->getPublisherPublicKeyLocator();
449 if (!publisherPublicKeyLocator.empty()) {
450 const Signature& signature = data.getSignature();
451 const Block& signatureInfo = signature.getInfo();
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600452 Block::element_const_iterator it = signatureInfo.find(tlv::KeyLocator);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700453 if (it == signatureInfo.elements_end()) {
454 return false;
455 }
456 if (publisherPublicKeyLocator.wireEncode() != *it) {
457 return false;
458 }
459 }
460
461 return true;
462}
463
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800464bool
465Interest::matchesInterest(const Interest& other) const
466{
Junxiao Shi2dd711d2017-07-21 13:40:52 +0000467 /// @todo #3162 match ForwardingHint field
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800468 return (this->getName() == other.getName() &&
469 this->getSelectors() == other.getSelectors());
470}
471
Junxiao Shi899277a2017-07-07 22:12:12 +0000472// ---- field accessors ----
473
474uint32_t
475Interest::getNonce() const
476{
Junxiao Shi2dd711d2017-07-21 13:40:52 +0000477 if (!m_nonce) {
478 m_nonce = random::generateWord32();
Junxiao Shic2ac5d22017-07-17 22:18:31 +0000479 }
Junxiao Shi2dd711d2017-07-21 13:40:52 +0000480 return *m_nonce;
Junxiao Shi899277a2017-07-07 22:12:12 +0000481}
482
483Interest&
484Interest::setNonce(uint32_t nonce)
485{
Junxiao Shi2dd711d2017-07-21 13:40:52 +0000486 m_nonce = nonce;
487 m_wire.reset();
Junxiao Shi899277a2017-07-07 22:12:12 +0000488 return *this;
489}
490
491void
492Interest::refreshNonce()
493{
494 if (!hasNonce())
495 return;
496
497 uint32_t oldNonce = getNonce();
498 uint32_t newNonce = oldNonce;
499 while (newNonce == oldNonce)
500 newNonce = random::generateWord32();
501
502 setNonce(newNonce);
503}
504
Eric Newberryb555b002017-05-17 00:30:44 -0700505Interest&
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000506Interest::setInterestLifetime(time::milliseconds lifetime)
Eric Newberryb555b002017-05-17 00:30:44 -0700507{
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000508 if (lifetime < time::milliseconds::zero()) {
Eric Newberryb555b002017-05-17 00:30:44 -0700509 BOOST_THROW_EXCEPTION(std::invalid_argument("InterestLifetime must be >= 0"));
510 }
Junxiao Shi8d3f8342018-04-04 12:46:37 +0000511 m_interestLifetime = lifetime;
Eric Newberryb555b002017-05-17 00:30:44 -0700512 m_wire.reset();
513 return *this;
514}
515
Junxiao Shi9c154cb2017-07-07 22:14:54 +0000516Interest&
517Interest::setForwardingHint(const DelegationList& value)
518{
519 m_forwardingHint = value;
520 m_wire.reset();
521 return *this;
522}
523
Junxiao Shi899277a2017-07-07 22:12:12 +0000524// ---- operators ----
525
Junxiao Shib55e5d32018-07-18 13:32:00 -0600526bool
527operator==(const Interest& lhs, const Interest& rhs)
528{
529 bool wasCanBePrefixSetOnLhs = lhs.m_isCanBePrefixSet;
530 bool wasCanBePrefixSetOnRhs = rhs.m_isCanBePrefixSet;
531 lhs.m_isCanBePrefixSet = true;
532 rhs.m_isCanBePrefixSet = true;
533 BOOST_SCOPE_EXIT_ALL(&) {
534 lhs.m_isCanBePrefixSet = wasCanBePrefixSetOnLhs;
535 rhs.m_isCanBePrefixSet = wasCanBePrefixSetOnRhs;
536 };
537
538 return lhs.wireEncode() == rhs.wireEncode();
539}
540
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700541std::ostream&
542operator<<(std::ostream& os, const Interest& interest)
Jeff Thompsonfe556862013-07-09 13:52:55 -0700543{
Alexander Afanasyev84681982014-01-03 13:26:09 -0800544 os << interest.getName();
Jeff Thompsonfe556862013-07-09 13:52:55 -0700545
Alexander Afanasyev84681982014-01-03 13:26:09 -0800546 char delim = '?';
547
548 if (interest.getMinSuffixComponents() >= 0) {
549 os << delim << "ndn.MinSuffixComponents=" << interest.getMinSuffixComponents();
550 delim = '&';
Jeff Thompsonfe556862013-07-09 13:52:55 -0700551 }
Alexander Afanasyev84681982014-01-03 13:26:09 -0800552 if (interest.getMaxSuffixComponents() >= 0) {
553 os << delim << "ndn.MaxSuffixComponents=" << interest.getMaxSuffixComponents();
554 delim = '&';
Jeff Thompson37527d62013-08-21 11:15:54 -0700555 }
Eric Newberryb555b002017-05-17 00:30:44 -0700556 if (interest.getChildSelector() != DEFAULT_CHILD_SELECTOR) {
Alexander Afanasyev84681982014-01-03 13:26:09 -0800557 os << delim << "ndn.ChildSelector=" << interest.getChildSelector();
558 delim = '&';
Jeff Thompson13e280b2013-12-03 13:12:23 -0800559 }
Alexander Afanasyev84681982014-01-03 13:26:09 -0800560 if (interest.getMustBeFresh()) {
561 os << delim << "ndn.MustBeFresh=" << interest.getMustBeFresh();
562 delim = '&';
Jeff Thompson13e280b2013-12-03 13:12:23 -0800563 }
Eric Newberryb555b002017-05-17 00:30:44 -0700564 if (interest.getInterestLifetime() != DEFAULT_INTEREST_LIFETIME) {
Alexander Afanasyeva0c5f832014-06-19 13:27:56 -0700565 os << delim << "ndn.InterestLifetime=" << interest.getInterestLifetime().count();
Alexander Afanasyev84681982014-01-03 13:26:09 -0800566 delim = '&';
567 }
568
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300569 if (interest.hasNonce()) {
Alexander Afanasyev84681982014-01-03 13:26:09 -0800570 os << delim << "ndn.Nonce=" << interest.getNonce();
571 delim = '&';
572 }
573 if (!interest.getExclude().empty()) {
574 os << delim << "ndn.Exclude=" << interest.getExclude();
575 delim = '&';
576 }
577
578 return os;
Jeff Thompson13e280b2013-12-03 13:12:23 -0800579}
580
Junxiao Shi08d07082014-12-03 11:31:44 -0700581} // namespace ndn