blob: 1ec414b75e339208e03fa3e06329e507431be717 [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/*
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
Junxiao Shi899277a2017-07-07 22:12:12 +000025#include "link.hpp"
Jeff Thompson53412192013-08-06 13:35:50 -070026#include "name.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080027#include "selectors.hpp"
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080028#include "tag-host.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 */
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 the given name and interest lifetime
Junxiao Shi899277a2017-07-07 22:12:12 +000056 * @throw std::invalid_argument InterestLifetime is negative
Junxiao Shi2af905b2014-11-27 13:10:54 -070057 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
Junxiao Shi899277a2017-07-07 22:12:12 +000058 * 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 Shi899277a2017-07-07 22:12:12 +000061 Interest(const Name& name = Name(), time::milliseconds interestLifetime = DEFAULT_INTEREST_LIFETIME);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070062
Junxiao Shi2af905b2014-11-27 13:10:54 -070063 /** @brief Create from wire encoding
64 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
Junxiao Shi899277a2017-07-07 22:12:12 +000065 * 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
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080070 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080071 * @brief Fast encoding or block size estimation
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
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080077 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080078 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080079 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070080 const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -080081 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080082
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080083 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080084 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080085 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070086 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070087 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080088
89 /**
90 * @brief Check if already has wire
91 */
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
Jeff Thompsond9e278c2013-07-08 15:20:13 -070098 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070099 * @brief Encode the name according to the NDN URI Scheme
100 *
101 * If there are interest selectors, this method will append "?" and add the selectors as
102 * a query string. For example, "/test/name?ndn.ChildSelector=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
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700115 /**
116 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700117 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700118 * 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
Alexander Afanasyev1013fd02017-01-03 13:19:03 -0800125 /**
126 * @brief Check if Interest matches @p other interest
127 *
128 * Interest matches @p other if both have the same name, selectors, and link. Other fields
129 * (e.g., Nonce) may be different.
130 *
131 * @todo Implement distinguishing interests by link. The current implementation checks only
132 * name+selectors (Issue #3162).
133 */
134 bool
135 matchesInterest(const Interest& other) const;
136
Junxiao Shi899277a2017-07-07 22:12:12 +0000137public: // Name, Nonce, and Guiders
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700138 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800139 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700140 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800141 return m_name;
142 }
143
144 Interest&
145 setName(const Name& name)
146 {
147 m_name = name;
148 m_wire.reset();
149 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700150 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700151
Junxiao Shi2af905b2014-11-27 13:10:54 -0700152 /** @brief Check if Nonce set
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300153 */
154 bool
155 hasNonce() const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800156 {
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300157 return m_nonce.hasWire();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800158 }
159
Junxiao Shi2af905b2014-11-27 13:10:54 -0700160 /** @brief Get Interest's nonce
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300161 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700162 * If nonce was not set before this call, it will be automatically assigned to a random value
163 */
164 uint32_t
165 getNonce() const;
166
167 /** @brief Set Interest's nonce
168 *
169 * If wire format already exists, this call simply replaces nonce in the
170 * existing wire format, without resetting and recreating it.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300171 */
172 Interest&
173 setNonce(uint32_t nonce);
174
Junxiao Shi2af905b2014-11-27 13:10:54 -0700175 /** @brief Refresh nonce
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700176 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700177 * It's guaranteed that new nonce value differs from the existing one.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700178 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700179 * If nonce is already set, it will be updated to a different random value.
180 * If nonce is not set, this method does nothing.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700181 */
182 void
183 refreshNonce();
184
Junxiao Shi899277a2017-07-07 22:12:12 +0000185 time::milliseconds
186 getInterestLifetime() const
187 {
188 return m_interestLifetime;
189 }
190
191 /**
192 * @brief Set Interest's lifetime
193 * @throw std::invalid_argument specified lifetime is < 0
194 */
195 Interest&
196 setInterestLifetime(time::milliseconds interestLifetime);
197
Junxiao Shi2af905b2014-11-27 13:10:54 -0700198public: // Selectors
199 /**
200 * @return true if Interest has any selector present
201 */
202 bool
203 hasSelectors() const
204 {
205 return !m_selectors.empty();
206 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700207
Junxiao Shi2af905b2014-11-27 13:10:54 -0700208 const Selectors&
209 getSelectors() const
210 {
211 return m_selectors;
212 }
213
214 Interest&
215 setSelectors(const Selectors& selectors)
216 {
217 m_selectors = selectors;
218 m_wire.reset();
219 return *this;
220 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700221
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800222 int
223 getMinSuffixComponents() const
224 {
225 return m_selectors.getMinSuffixComponents();
226 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700227
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800228 Interest&
229 setMinSuffixComponents(int minSuffixComponents)
230 {
231 m_selectors.setMinSuffixComponents(minSuffixComponents);
232 m_wire.reset();
233 return *this;
234 }
235
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800236 int
237 getMaxSuffixComponents() const
238 {
239 return m_selectors.getMaxSuffixComponents();
240 }
241
242 Interest&
243 setMaxSuffixComponents(int maxSuffixComponents)
244 {
245 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
246 m_wire.reset();
247 return *this;
248 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700249
Junxiao Shib332e782014-03-31 14:23:46 -0700250 const KeyLocator&
251 getPublisherPublicKeyLocator() const
252 {
253 return m_selectors.getPublisherPublicKeyLocator();
254 }
255
256 Interest&
257 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
258 {
259 m_selectors.setPublisherPublicKeyLocator(keyLocator);
260 m_wire.reset();
261 return *this;
262 }
263
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800264 const Exclude&
265 getExclude() const
266 {
267 return m_selectors.getExclude();
268 }
269
270 Interest&
271 setExclude(const Exclude& exclude)
272 {
273 m_selectors.setExclude(exclude);
274 m_wire.reset();
275 return *this;
276 }
277
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700278 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800279 getChildSelector() const
280 {
281 return m_selectors.getChildSelector();
282 }
283
284 Interest&
285 setChildSelector(int childSelector)
286 {
287 m_selectors.setChildSelector(childSelector);
288 m_wire.reset();
289 return *this;
290 }
291
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700292 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800293 getMustBeFresh() const
294 {
295 return m_selectors.getMustBeFresh();
296 }
297
298 Interest&
299 setMustBeFresh(bool mustBeFresh)
300 {
301 m_selectors.setMustBeFresh(mustBeFresh);
302 m_wire.reset();
303 return *this;
304 }
305
Junxiao Shi899277a2017-07-07 22:12:12 +0000306public: // Link and SelectedDelegation
307 /**
308 * @brief Check whether the Interest contains a Link object
309 * @return True if there is a link object, otherwise false
310 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700311 bool
Junxiao Shi899277a2017-07-07 22:12:12 +0000312 hasLink() const;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700313
Junxiao Shi899277a2017-07-07 22:12:12 +0000314 /**
315 * @brief Get the link object for this interest
316 * @return The link object if there is one contained in this interest
317 * @throws Interest::Error if there is no link object contained in the interest
318 * @throws tlv::Error if the incorporated link object is malformed
319 */
320 const Link&
321 getLink() const;
322
323 /**
324 * @brief Set the link object for this interest
325 * @param link The link object that will be included in this interest (in wire format)
326 * @post !hasSelectedDelegation()
327 */
328 void
329 setLink(const Block& link);
330
331 /**
332 * @brief Delete the link object for this interest
333 * @post !hasLink()
334 */
335 void
336 unsetLink();
337
338 /**
339 * @brief Check whether the Interest includes a selected delegation
340 * @return True if there is a selected delegation, otherwise false
341 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700342 bool
Junxiao Shi899277a2017-07-07 22:12:12 +0000343 hasSelectedDelegation() const;
344
345 /**
346 * @brief Get the name of the selected delegation
347 * @return The name of the selected delegation
348 * @throw Error SelectedDelegation is not set.
349 */
350 Name
351 getSelectedDelegation() const;
352
353 /**
354 * @brief Set the selected delegation
355 * @param delegationName The name of the selected delegation
356 * @throw Error Link is not set.
357 * @throw std::invalid_argument @p delegationName does not exist in Link.
358 */
359 void
360 setSelectedDelegation(const Name& delegationName);
361
362 /**
363 * @brief Set the selected delegation
364 * @param delegationIndex The index of the selected delegation
365 * @throw Error Link is not set.
366 * @throw std::out_of_range @p delegationIndex is out of bound in Link.
367 */
368 void
369 setSelectedDelegation(size_t delegationIndex);
370
371 /**
372 * @brief Unset the selected delegation
373 */
374 void
375 unsetSelectedDelegation();
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700376
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800377private:
378 Name m_name;
379 Selectors m_selectors;
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300380 mutable Block m_nonce;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700381 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800382
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700383 mutable Block m_link;
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700384 mutable shared_ptr<Link> m_linkCached;
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700385 size_t m_selectedDelegationIndex;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800386 mutable Block m_wire;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700387};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800388
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700389std::ostream&
390operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800391
392inline std::string
393Interest::toUri() const
394{
395 std::ostringstream os;
396 os << *this;
397 return os.str();
398}
399
Junxiao Shi899277a2017-07-07 22:12:12 +0000400inline bool
401operator==(const Interest& lhs, const Interest& rhs)
402{
403 return lhs.wireEncode() == rhs.wireEncode();
404}
405
406inline bool
407operator!=(const Interest& lhs, const Interest& rhs)
408{
409 return !(lhs == rhs);
410}
411
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800412} // namespace ndn
413
414#endif // NDN_INTEREST_HPP