blob: 143362864d945af5676b55e77f0c1730f9d8def0 [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/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 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.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * Based on code originally written by Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompsonb7f95562013-07-03 18:36:42 -070022 */
23
24#ifndef NDN_INTEREST_HPP
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070025#define NDN_INTEREST_HPP
Jeff Thompsonb7f95562013-07-03 18:36:42 -070026
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080027#include "common.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070028
Jeff Thompson53412192013-08-06 13:35:50 -070029#include "name.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080030#include "selectors.hpp"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070031#include "util/time.hpp"
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080032#include "management/nfd-local-control-header.hpp"
Jeff Thompsonb7f95562013-07-03 18:36:42 -070033
34namespace ndn {
Alexander Afanasyevc348f832014-02-17 16:35:17 -080035
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070036class Data;
37
Junxiao Shi7007a3c2014-11-20 22:37:55 -070038/** @var const unspecified_duration_type DEFAULT_INTEREST_LIFETIME;
39 * @brief default value for InterestLifetime
40 */
41const time::milliseconds DEFAULT_INTEREST_LIFETIME = time::milliseconds(4000);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080042
Junxiao Shic2b8d242014-11-04 08:35:29 -070043/** @brief represents an Interest packet
Jeff Thompson8238d002013-07-10 11:56:49 -070044 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -080045class Interest : public enable_shared_from_this<Interest>
46{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070047public:
Junxiao Shic2b8d242014-11-04 08:35:29 -070048 class Error : public tlv::Error
49 {
50 public:
51 explicit
52 Error(const std::string& what)
53 : tlv::Error(what)
54 {
55 }
56 };
57
Junxiao Shi2af905b2014-11-27 13:10:54 -070058 /** @brief Create a new Interest with an empty name (`ndn:/`)
59 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
60 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080061 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070062 Interest();
Alexander Afanasyevc348f832014-02-17 16:35:17 -080063
Junxiao Shi2af905b2014-11-27 13:10:54 -070064 /** @brief Create a new Interest with the given name
65 * @param name The name for the interest.
66 * @note This constructor allows implicit conversion from Name.
67 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
68 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080069 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070070 Interest(const Name& name);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080071
Junxiao Shi2af905b2014-11-27 13:10:54 -070072 /** @brief Create a new Interest with the given name and interest lifetime
73 * @param name The name for the interest.
74 * @param interestLifetime The interest lifetime in time::milliseconds, or -1 for none.
75 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
76 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080077 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070078 Interest(const Name& name, const time::milliseconds& interestLifetime);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070079
Junxiao Shi2af905b2014-11-27 13:10:54 -070080 /** @brief Create a new Interest for the given name, selectors, and guiders
81 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
82 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyev770827c2014-05-13 17:42:55 -070083 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -080084 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070085 const Selectors& selectors,
Alexander Afanasyevc348f832014-02-17 16:35:17 -080086 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070087 const time::milliseconds& interestLifetime,
Junxiao Shi2af905b2014-11-27 13:10:54 -070088 uint32_t nonce = 0);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070089
Junxiao Shi2af905b2014-11-27 13:10:54 -070090 /** @brief Create from wire encoding
91 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
92 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070093 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080094 explicit
Junxiao Shi2af905b2014-11-27 13:10:54 -070095 Interest(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080096
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080097 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080098 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080099 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800100 template<bool T>
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700101 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700102 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800103
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800104 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800105 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800106 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700107 const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -0800108 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800109
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800110 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800111 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800112 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700113 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700114 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800115
116 /**
117 * @brief Check if already has wire
118 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700119 bool
Junxiao Shi2af905b2014-11-27 13:10:54 -0700120 hasWire() const
121 {
122 return m_wire.hasWire();
123 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700124
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700125 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700126 * @brief Encode the name according to the NDN URI Scheme
127 *
128 * If there are interest selectors, this method will append "?" and add the selectors as
129 * a query string. For example, "/test/name?ndn.ChildSelector=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800130 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700131 std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800132 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700133
Junxiao Shi2af905b2014-11-27 13:10:54 -0700134public: // matching
135 /** @brief Check if Interest, including selectors, matches the given @p name
136 * @param name The name to be matched. If this is a Data name, it shall contain the
137 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800138 */
139 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700140 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800141
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700142 /**
143 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700144 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700145 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
146 * PublisherPublicKeyLocator, and Exclude.
147 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700148 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700149 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700150 */
151 bool
152 matchesData(const Data& data) const;
153
Junxiao Shi2af905b2014-11-27 13:10:54 -0700154public: // Name and guiders
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700155 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800156 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700157 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800158 return m_name;
159 }
160
161 Interest&
162 setName(const Name& name)
163 {
164 m_name = name;
165 m_wire.reset();
166 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700167 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700168
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700169 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800170 getScope() const
171 {
172 return m_scope;
173 }
174
175 Interest&
176 setScope(int scope)
177 {
178 m_scope = scope;
179 m_wire.reset();
180 return *this;
181 }
182
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700183 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800184 getInterestLifetime() const
185 {
186 return m_interestLifetime;
187 }
188
189 Interest&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700190 setInterestLifetime(const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800191 {
192 m_interestLifetime = interestLifetime;
193 m_wire.reset();
194 return *this;
195 }
196
Junxiao Shi2af905b2014-11-27 13:10:54 -0700197 /** @brief Check if Nonce set
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300198 */
199 bool
200 hasNonce() const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800201 {
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300202 return m_nonce.hasWire();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800203 }
204
Junxiao Shi2af905b2014-11-27 13:10:54 -0700205 /** @brief Get Interest's nonce
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300206 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700207 * If nonce was not set before this call, it will be automatically assigned to a random value
208 */
209 uint32_t
210 getNonce() const;
211
212 /** @brief Set Interest's nonce
213 *
214 * If wire format already exists, this call simply replaces nonce in the
215 * existing wire format, without resetting and recreating it.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300216 */
217 Interest&
218 setNonce(uint32_t nonce);
219
Junxiao Shi2af905b2014-11-27 13:10:54 -0700220 /** @brief Refresh nonce
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700221 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700222 * It's guaranteed that new nonce value differs from the existing one.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700223 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700224 * If nonce is already set, it will be updated to a different random value.
225 * If nonce is not set, this method does nothing.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700226 */
227 void
228 refreshNonce();
229
Junxiao Shi2af905b2014-11-27 13:10:54 -0700230public: // local control header
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800231 nfd::LocalControlHeader&
232 getLocalControlHeader()
233 {
234 return m_localControlHeader;
235 }
236
237 const nfd::LocalControlHeader&
238 getLocalControlHeader() const
239 {
240 return m_localControlHeader;
241 }
242
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800243 uint64_t
244 getIncomingFaceId() const
245 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800246 return getLocalControlHeader().getIncomingFaceId();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800247 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800248
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800249 Interest&
250 setIncomingFaceId(uint64_t incomingFaceId)
251 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800252 getLocalControlHeader().setIncomingFaceId(incomingFaceId);
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800253 // ! do not reset Interest's wire !
254 return *this;
255 }
256
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800257 uint64_t
258 getNextHopFaceId() const
259 {
260 return getLocalControlHeader().getNextHopFaceId();
261 }
262
263 Interest&
264 setNextHopFaceId(uint64_t nextHopFaceId)
265 {
266 getLocalControlHeader().setNextHopFaceId(nextHopFaceId);
267 // ! do not reset Interest's wire !
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800268 return *this;
269 }
270
Junxiao Shi2af905b2014-11-27 13:10:54 -0700271public: // Selectors
272 /**
273 * @return true if Interest has any selector present
274 */
275 bool
276 hasSelectors() const
277 {
278 return !m_selectors.empty();
279 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700280
Junxiao Shi2af905b2014-11-27 13:10:54 -0700281 const Selectors&
282 getSelectors() const
283 {
284 return m_selectors;
285 }
286
287 Interest&
288 setSelectors(const Selectors& selectors)
289 {
290 m_selectors = selectors;
291 m_wire.reset();
292 return *this;
293 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700294
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800295 int
296 getMinSuffixComponents() const
297 {
298 return m_selectors.getMinSuffixComponents();
299 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700300
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800301 Interest&
302 setMinSuffixComponents(int minSuffixComponents)
303 {
304 m_selectors.setMinSuffixComponents(minSuffixComponents);
305 m_wire.reset();
306 return *this;
307 }
308
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800309 int
310 getMaxSuffixComponents() const
311 {
312 return m_selectors.getMaxSuffixComponents();
313 }
314
315 Interest&
316 setMaxSuffixComponents(int maxSuffixComponents)
317 {
318 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
319 m_wire.reset();
320 return *this;
321 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700322
Junxiao Shib332e782014-03-31 14:23:46 -0700323 const KeyLocator&
324 getPublisherPublicKeyLocator() const
325 {
326 return m_selectors.getPublisherPublicKeyLocator();
327 }
328
329 Interest&
330 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
331 {
332 m_selectors.setPublisherPublicKeyLocator(keyLocator);
333 m_wire.reset();
334 return *this;
335 }
336
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800337 const Exclude&
338 getExclude() const
339 {
340 return m_selectors.getExclude();
341 }
342
343 Interest&
344 setExclude(const Exclude& exclude)
345 {
346 m_selectors.setExclude(exclude);
347 m_wire.reset();
348 return *this;
349 }
350
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700351 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800352 getChildSelector() const
353 {
354 return m_selectors.getChildSelector();
355 }
356
357 Interest&
358 setChildSelector(int childSelector)
359 {
360 m_selectors.setChildSelector(childSelector);
361 m_wire.reset();
362 return *this;
363 }
364
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700365 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800366 getMustBeFresh() const
367 {
368 return m_selectors.getMustBeFresh();
369 }
370
371 Interest&
372 setMustBeFresh(bool mustBeFresh)
373 {
374 m_selectors.setMustBeFresh(mustBeFresh);
375 m_wire.reset();
376 return *this;
377 }
378
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700379public: // EqualityComparable concept
380 bool
381 operator==(const Interest& other) const
382 {
383 return wireEncode() == other.wireEncode();
384 }
385
386 bool
387 operator!=(const Interest& other) const
388 {
389 return !(*this == other);
390 }
391
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800392private:
393 Name m_name;
394 Selectors m_selectors;
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300395 mutable Block m_nonce;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800396 int m_scope;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700397 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800398
399 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800400
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800401 nfd::LocalControlHeader m_localControlHeader;
402 friend class nfd::LocalControlHeader;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700403};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800404
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700405std::ostream&
406operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800407
408inline std::string
409Interest::toUri() const
410{
411 std::ostringstream os;
412 os << *this;
413 return os.str();
414}
415
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800416} // namespace ndn
417
418#endif // NDN_INTEREST_HPP