blob: 14ba33e4aec7595e1a15bd1313bd0ed99ee41fed [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/**
Junxiao Shia1478db2016-09-09 04:13:15 +00003 * Copyright (c) 2013-2016 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
122
123 /**
124 * @brief Check whether the Interest contains a Link object
125 * @return True if there is a link object, otherwise false
126 */
127 bool
128 hasLink() const;
129
130 /**
131 * @brief Get the link object for this interest
132 * @return The link object if there is one contained in this interest
133 * @throws Interest::Error if there is no link object contained in the interest
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700134 * @throws tlv::Error if the incorporated link object is malformed
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700135 */
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700136 const Link&
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700137 getLink() const;
138
139 /**
140 * @brief Set the link object for this interest
141 * @param link The link object that will be included in this interest (in wire format)
142 * @post !hasSelectedDelegation()
143 */
144 void
145 setLink(const Block& link);
146
147 /**
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700148 * @brief Delete the link object for this interest
149 * @post !hasLink()
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700150 */
151 void
152 unsetLink();
153
154 /**
155 * @brief Check whether the Interest includes a selected delegation
156 * @return True if there is a selected delegation, otherwise false
157 */
158 bool
159 hasSelectedDelegation() const;
160
161 /**
162 * @brief Get the name of the selected delegation
163 * @return The name of the selected delegation
164 * @throw Error SelectedDelegation is not set.
165 */
166 Name
167 getSelectedDelegation() const;
168
169 /**
170 * @brief Set the selected delegation
171 * @param delegationName The name of the selected delegation
172 * @throw Error Link is not set.
173 * @throw std::invalid_argument @p delegationName does not exist in Link.
174 */
175 void
176 setSelectedDelegation(const Name& delegationName);
177
178 /**
179 * @brief Set the selected delegation
Davide Pesavento18cf81b2015-09-12 23:36:43 +0200180 * @param delegationIndex The index of the selected delegation
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700181 * @throw Error Link is not set.
182 * @throw std::out_of_range @p delegationIndex is out of bound in Link.
183 */
184 void
185 setSelectedDelegation(size_t delegationIndex);
186
187 /**
188 * @brief Unset the selected delegation
189 */
190 void
191 unsetSelectedDelegation();
192
Junxiao Shi2af905b2014-11-27 13:10:54 -0700193public: // matching
194 /** @brief Check if Interest, including selectors, matches the given @p name
195 * @param name The name to be matched. If this is a Data name, it shall contain the
196 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800197 */
198 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700199 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800200
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700201 /**
202 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700203 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700204 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
205 * PublisherPublicKeyLocator, and Exclude.
206 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700207 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700208 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700209 */
210 bool
211 matchesData(const Data& data) const;
212
Junxiao Shi2af905b2014-11-27 13:10:54 -0700213public: // Name and guiders
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700214 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800215 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700216 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800217 return m_name;
218 }
219
220 Interest&
221 setName(const Name& name)
222 {
223 m_name = name;
224 m_wire.reset();
225 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700226 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700227
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700228 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800229 getInterestLifetime() const
230 {
231 return m_interestLifetime;
232 }
233
234 Interest&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700235 setInterestLifetime(const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800236 {
237 m_interestLifetime = interestLifetime;
238 m_wire.reset();
239 return *this;
240 }
241
Junxiao Shi2af905b2014-11-27 13:10:54 -0700242 /** @brief Check if Nonce set
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300243 */
244 bool
245 hasNonce() const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800246 {
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300247 return m_nonce.hasWire();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800248 }
249
Junxiao Shi2af905b2014-11-27 13:10:54 -0700250 /** @brief Get Interest's nonce
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300251 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700252 * If nonce was not set before this call, it will be automatically assigned to a random value
253 */
254 uint32_t
255 getNonce() const;
256
257 /** @brief Set Interest's nonce
258 *
259 * If wire format already exists, this call simply replaces nonce in the
260 * existing wire format, without resetting and recreating it.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300261 */
262 Interest&
263 setNonce(uint32_t nonce);
264
Junxiao Shi2af905b2014-11-27 13:10:54 -0700265 /** @brief Refresh nonce
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700266 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700267 * It's guaranteed that new nonce value differs from the existing one.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700268 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700269 * If nonce is already set, it will be updated to a different random value.
270 * If nonce is not set, this method does nothing.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700271 */
272 void
273 refreshNonce();
274
Junxiao Shi2af905b2014-11-27 13:10:54 -0700275public: // Selectors
276 /**
277 * @return true if Interest has any selector present
278 */
279 bool
280 hasSelectors() const
281 {
282 return !m_selectors.empty();
283 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700284
Junxiao Shi2af905b2014-11-27 13:10:54 -0700285 const Selectors&
286 getSelectors() const
287 {
288 return m_selectors;
289 }
290
291 Interest&
292 setSelectors(const Selectors& selectors)
293 {
294 m_selectors = selectors;
295 m_wire.reset();
296 return *this;
297 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700298
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
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800305 Interest&
306 setMinSuffixComponents(int minSuffixComponents)
307 {
308 m_selectors.setMinSuffixComponents(minSuffixComponents);
309 m_wire.reset();
310 return *this;
311 }
312
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800313 int
314 getMaxSuffixComponents() const
315 {
316 return m_selectors.getMaxSuffixComponents();
317 }
318
319 Interest&
320 setMaxSuffixComponents(int maxSuffixComponents)
321 {
322 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
323 m_wire.reset();
324 return *this;
325 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700326
Junxiao Shib332e782014-03-31 14:23:46 -0700327 const KeyLocator&
328 getPublisherPublicKeyLocator() const
329 {
330 return m_selectors.getPublisherPublicKeyLocator();
331 }
332
333 Interest&
334 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
335 {
336 m_selectors.setPublisherPublicKeyLocator(keyLocator);
337 m_wire.reset();
338 return *this;
339 }
340
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800341 const Exclude&
342 getExclude() const
343 {
344 return m_selectors.getExclude();
345 }
346
347 Interest&
348 setExclude(const Exclude& exclude)
349 {
350 m_selectors.setExclude(exclude);
351 m_wire.reset();
352 return *this;
353 }
354
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700355 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800356 getChildSelector() const
357 {
358 return m_selectors.getChildSelector();
359 }
360
361 Interest&
362 setChildSelector(int childSelector)
363 {
364 m_selectors.setChildSelector(childSelector);
365 m_wire.reset();
366 return *this;
367 }
368
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700369 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800370 getMustBeFresh() const
371 {
372 return m_selectors.getMustBeFresh();
373 }
374
375 Interest&
376 setMustBeFresh(bool mustBeFresh)
377 {
378 m_selectors.setMustBeFresh(mustBeFresh);
379 m_wire.reset();
380 return *this;
381 }
382
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700383public: // EqualityComparable concept
384 bool
385 operator==(const Interest& other) const
386 {
387 return wireEncode() == other.wireEncode();
388 }
389
390 bool
391 operator!=(const Interest& other) const
392 {
393 return !(*this == other);
394 }
395
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800396private:
397 Name m_name;
398 Selectors m_selectors;
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300399 mutable Block m_nonce;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700400 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800401
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700402 mutable Block m_link;
Alexander Afanasyevcac08382015-09-02 14:52:40 -0700403 mutable shared_ptr<Link> m_linkCached;
Spyridon Mastorakisc8188b32015-04-18 18:33:38 -0700404 size_t m_selectedDelegationIndex;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800405 mutable Block m_wire;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700406};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800407
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700408std::ostream&
409operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800410
411inline std::string
412Interest::toUri() const
413{
414 std::ostringstream os;
415 os << *this;
416 return os.str();
417}
418
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800419} // namespace ndn
420
421#endif // NDN_INTEREST_HPP