blob: 951645457fece7083f9c688b2d246d06fc973b85 [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"
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080033#include "tag-host.hpp"
Jeff Thompsonb7f95562013-07-03 18:36:42 -070034
35namespace ndn {
Alexander Afanasyevc348f832014-02-17 16:35:17 -080036
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070037class Data;
38
Junxiao Shi7007a3c2014-11-20 22:37:55 -070039/** @var const unspecified_duration_type DEFAULT_INTEREST_LIFETIME;
40 * @brief default value for InterestLifetime
41 */
42const time::milliseconds DEFAULT_INTEREST_LIFETIME = time::milliseconds(4000);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080043
Junxiao Shic2b8d242014-11-04 08:35:29 -070044/** @brief represents an Interest packet
Jeff Thompson8238d002013-07-10 11:56:49 -070045 */
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080046class Interest : public TagHost, public enable_shared_from_this<Interest>
Alexander Afanasyevc348f832014-02-17 16:35:17 -080047{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070048public:
Junxiao Shic2b8d242014-11-04 08:35:29 -070049 class Error : public tlv::Error
50 {
51 public:
52 explicit
53 Error(const std::string& what)
54 : tlv::Error(what)
55 {
56 }
57 };
58
Junxiao Shi2af905b2014-11-27 13:10:54 -070059 /** @brief Create a new Interest with an empty name (`ndn:/`)
60 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
61 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080062 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070063 Interest();
Alexander Afanasyevc348f832014-02-17 16:35:17 -080064
Junxiao Shi2af905b2014-11-27 13:10:54 -070065 /** @brief Create a new Interest with the given name
66 * @param name The name for the interest.
67 * @note This constructor allows implicit conversion from Name.
68 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
69 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080070 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070071 Interest(const Name& name);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080072
Junxiao Shi2af905b2014-11-27 13:10:54 -070073 /** @brief Create a new Interest with the given name and interest lifetime
74 * @param name The name for the interest.
75 * @param interestLifetime The interest lifetime in time::milliseconds, or -1 for none.
76 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
77 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080078 */
Junxiao Shi2af905b2014-11-27 13:10:54 -070079 Interest(const Name& name, const time::milliseconds& interestLifetime);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070080
Junxiao Shi2af905b2014-11-27 13:10:54 -070081 /** @brief Create a new Interest for the given name, selectors, and guiders
82 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
83 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyev770827c2014-05-13 17:42:55 -070084 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -080085 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070086 const Selectors& selectors,
Alexander Afanasyevc348f832014-02-17 16:35:17 -080087 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070088 const time::milliseconds& interestLifetime,
Junxiao Shi2af905b2014-11-27 13:10:54 -070089 uint32_t nonce = 0);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070090
Junxiao Shi2af905b2014-11-27 13:10:54 -070091 /** @brief Create from wire encoding
92 * @warning In certain contexts that use Interest::shared_from_this(), Interest must be created
93 * using `make_shared`. Otherwise, .shared_from_this() will throw an exception.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070094 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080095 explicit
Junxiao Shi2af905b2014-11-27 13:10:54 -070096 Interest(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080097
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080098 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080099 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800100 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800101 template<bool T>
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700102 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700103 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800104
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800105 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800106 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800107 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700108 const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -0800109 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800110
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800111 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800112 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800113 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700114 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700115 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800116
117 /**
118 * @brief Check if already has wire
119 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700120 bool
Junxiao Shi2af905b2014-11-27 13:10:54 -0700121 hasWire() const
122 {
123 return m_wire.hasWire();
124 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700125
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700126 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700127 * @brief Encode the name according to the NDN URI Scheme
128 *
129 * If there are interest selectors, this method will append "?" and add the selectors as
130 * a query string. For example, "/test/name?ndn.ChildSelector=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800131 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700132 std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800133 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700134
Junxiao Shi2af905b2014-11-27 13:10:54 -0700135public: // matching
136 /** @brief Check if Interest, including selectors, matches the given @p name
137 * @param name The name to be matched. If this is a Data name, it shall contain the
138 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800139 */
140 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700141 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800142
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700143 /**
144 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700145 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700146 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
147 * PublisherPublicKeyLocator, and Exclude.
148 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700149 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700150 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700151 */
152 bool
153 matchesData(const Data& data) const;
154
Junxiao Shi2af905b2014-11-27 13:10:54 -0700155public: // Name and guiders
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700156 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800157 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700158 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800159 return m_name;
160 }
161
162 Interest&
163 setName(const Name& name)
164 {
165 m_name = name;
166 m_wire.reset();
167 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700168 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700169
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700170 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800171 getScope() const
172 {
173 return m_scope;
174 }
175
176 Interest&
177 setScope(int scope)
178 {
179 m_scope = scope;
180 m_wire.reset();
181 return *this;
182 }
183
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700184 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800185 getInterestLifetime() const
186 {
187 return m_interestLifetime;
188 }
189
190 Interest&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700191 setInterestLifetime(const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800192 {
193 m_interestLifetime = interestLifetime;
194 m_wire.reset();
195 return *this;
196 }
197
Junxiao Shi2af905b2014-11-27 13:10:54 -0700198 /** @brief Check if Nonce set
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300199 */
200 bool
201 hasNonce() const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800202 {
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300203 return m_nonce.hasWire();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800204 }
205
Junxiao Shi2af905b2014-11-27 13:10:54 -0700206 /** @brief Get Interest's nonce
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300207 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700208 * If nonce was not set before this call, it will be automatically assigned to a random value
209 */
210 uint32_t
211 getNonce() const;
212
213 /** @brief Set Interest's nonce
214 *
215 * If wire format already exists, this call simply replaces nonce in the
216 * existing wire format, without resetting and recreating it.
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300217 */
218 Interest&
219 setNonce(uint32_t nonce);
220
Junxiao Shi2af905b2014-11-27 13:10:54 -0700221 /** @brief Refresh nonce
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700222 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700223 * It's guaranteed that new nonce value differs from the existing one.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700224 *
Junxiao Shi2af905b2014-11-27 13:10:54 -0700225 * If nonce is already set, it will be updated to a different random value.
226 * If nonce is not set, this method does nothing.
Alexander Afanasyevc3932172014-07-10 18:53:56 -0700227 */
228 void
229 refreshNonce();
230
Junxiao Shi2af905b2014-11-27 13:10:54 -0700231public: // local control header
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800232 nfd::LocalControlHeader&
233 getLocalControlHeader()
234 {
235 return m_localControlHeader;
236 }
237
238 const nfd::LocalControlHeader&
239 getLocalControlHeader() const
240 {
241 return m_localControlHeader;
242 }
243
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800244 uint64_t
245 getIncomingFaceId() const
246 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800247 return getLocalControlHeader().getIncomingFaceId();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800248 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800249
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800250 Interest&
251 setIncomingFaceId(uint64_t incomingFaceId)
252 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800253 getLocalControlHeader().setIncomingFaceId(incomingFaceId);
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800254 // ! do not reset Interest's wire !
255 return *this;
256 }
257
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800258 uint64_t
259 getNextHopFaceId() const
260 {
261 return getLocalControlHeader().getNextHopFaceId();
262 }
263
264 Interest&
265 setNextHopFaceId(uint64_t nextHopFaceId)
266 {
267 getLocalControlHeader().setNextHopFaceId(nextHopFaceId);
268 // ! do not reset Interest's wire !
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800269 return *this;
270 }
271
Junxiao Shi2af905b2014-11-27 13:10:54 -0700272public: // Selectors
273 /**
274 * @return true if Interest has any selector present
275 */
276 bool
277 hasSelectors() const
278 {
279 return !m_selectors.empty();
280 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700281
Junxiao Shi2af905b2014-11-27 13:10:54 -0700282 const Selectors&
283 getSelectors() const
284 {
285 return m_selectors;
286 }
287
288 Interest&
289 setSelectors(const Selectors& selectors)
290 {
291 m_selectors = selectors;
292 m_wire.reset();
293 return *this;
294 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700295
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800296 int
297 getMinSuffixComponents() const
298 {
299 return m_selectors.getMinSuffixComponents();
300 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700301
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800302 Interest&
303 setMinSuffixComponents(int minSuffixComponents)
304 {
305 m_selectors.setMinSuffixComponents(minSuffixComponents);
306 m_wire.reset();
307 return *this;
308 }
309
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800310 int
311 getMaxSuffixComponents() const
312 {
313 return m_selectors.getMaxSuffixComponents();
314 }
315
316 Interest&
317 setMaxSuffixComponents(int maxSuffixComponents)
318 {
319 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
320 m_wire.reset();
321 return *this;
322 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700323
Junxiao Shib332e782014-03-31 14:23:46 -0700324 const KeyLocator&
325 getPublisherPublicKeyLocator() const
326 {
327 return m_selectors.getPublisherPublicKeyLocator();
328 }
329
330 Interest&
331 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
332 {
333 m_selectors.setPublisherPublicKeyLocator(keyLocator);
334 m_wire.reset();
335 return *this;
336 }
337
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800338 const Exclude&
339 getExclude() const
340 {
341 return m_selectors.getExclude();
342 }
343
344 Interest&
345 setExclude(const Exclude& exclude)
346 {
347 m_selectors.setExclude(exclude);
348 m_wire.reset();
349 return *this;
350 }
351
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700352 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800353 getChildSelector() const
354 {
355 return m_selectors.getChildSelector();
356 }
357
358 Interest&
359 setChildSelector(int childSelector)
360 {
361 m_selectors.setChildSelector(childSelector);
362 m_wire.reset();
363 return *this;
364 }
365
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700366 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800367 getMustBeFresh() const
368 {
369 return m_selectors.getMustBeFresh();
370 }
371
372 Interest&
373 setMustBeFresh(bool mustBeFresh)
374 {
375 m_selectors.setMustBeFresh(mustBeFresh);
376 m_wire.reset();
377 return *this;
378 }
379
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700380public: // EqualityComparable concept
381 bool
382 operator==(const Interest& other) const
383 {
384 return wireEncode() == other.wireEncode();
385 }
386
387 bool
388 operator!=(const Interest& other) const
389 {
390 return !(*this == other);
391 }
392
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800393private:
394 Name m_name;
395 Selectors m_selectors;
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300396 mutable Block m_nonce;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800397 int m_scope;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700398 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800399
400 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800401
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800402 nfd::LocalControlHeader m_localControlHeader;
403 friend class nfd::LocalControlHeader;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700404};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800405
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700406std::ostream&
407operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800408
409inline std::string
410Interest::toUri() const
411{
412 std::ostringstream os;
413 os << *this;
414 return os.str();
415}
416
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800417} // namespace ndn
418
419#endif // NDN_INTEREST_HPP