blob: db3744c15f1010e651895550b78dd2544ca6e3c6 [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
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080024#include "common.hpp"
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080025
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080026#include "interest.hpp"
Alexander Afanasyeve9fdb802014-02-05 17:36:51 -080027#include "util/random.hpp"
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070028#include "data.hpp"
Alexander Afanasyev840139f2013-12-28 15:02:50 -080029
Jeff Thompsonb7f95562013-07-03 18:36:42 -070030namespace ndn {
Alexander Afanasyev84681982014-01-03 13:26:09 -080031
Alexander Afanasyeve881e932014-06-08 14:47:03 +030032uint32_t
Alexander Afanasyev840139f2013-12-28 15:02:50 -080033Interest::getNonce() const
34{
Alexander Afanasyeve881e932014-06-08 14:47:03 +030035 if (!m_nonce.hasWire())
36 const_cast<Interest*>(this)->setNonce(random::generateWord32());
Alexander Afanasyev840139f2013-12-28 15:02:50 -080037
Alexander Afanasyeve881e932014-06-08 14:47:03 +030038 if (m_nonce.value_size() == sizeof(uint32_t))
39 return *reinterpret_cast<const uint32_t*>(m_nonce.value());
40 else {
41 // for compatibility reasons. Should be removed eventually
42 return readNonNegativeInteger(m_nonce);
43 }
Alexander Afanasyev840139f2013-12-28 15:02:50 -080044}
45
Alexander Afanasyeve881e932014-06-08 14:47:03 +030046Interest&
47Interest::setNonce(uint32_t nonce)
48{
49 if (m_wire.hasWire() && m_nonce.value_size() == sizeof(uint32_t)) {
50 std::memcpy(const_cast<uint8_t*>(m_nonce.value()), &nonce, sizeof(nonce));
51 }
52 else {
53 m_nonce = dataBlock(Tlv::Nonce,
54 reinterpret_cast<const uint8_t*>(&nonce),
55 sizeof(nonce));
56 m_wire.reset();
57 }
58 return *this;
59}
Alexander Afanasyev840139f2013-12-28 15:02:50 -080060
Alexander Afanasyevc3932172014-07-10 18:53:56 -070061void
62Interest::refreshNonce()
63{
64 if (!hasNonce())
65 return;
66
67 uint32_t oldNonce = getNonce();
68 uint32_t newNonce = oldNonce;
69 while (newNonce == oldNonce)
70 newNonce = random::generateWord32();
71
72 setNonce(newNonce);
73}
74
Alexander Afanasyev84681982014-01-03 13:26:09 -080075bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070076Interest::matchesName(const Name& name) const
Jeff Thompson25b4e612013-10-10 16:03:24 -070077{
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070078 if (name.size() < m_name.size())
79 return false;
80
Alexander Afanasyevc348f832014-02-17 16:35:17 -080081 if (!m_name.isPrefixOf(name))
Alexander Afanasyev84681982014-01-03 13:26:09 -080082 return false;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070083
Alexander Afanasyevc348f832014-02-17 16:35:17 -080084 if (getMinSuffixComponents() >= 0 &&
Alexander Afanasyev3b703102014-06-13 17:01:14 -070085 // name must include implicit digest
86 !(name.size() - m_name.size() >= static_cast<size_t>(getMinSuffixComponents())))
Alexander Afanasyev84681982014-01-03 13:26:09 -080087 return false;
88
Alexander Afanasyevc348f832014-02-17 16:35:17 -080089 if (getMaxSuffixComponents() >= 0 &&
Alexander Afanasyev3b703102014-06-13 17:01:14 -070090 // name must include implicit digest
91 !(name.size() - m_name.size() <= static_cast<size_t>(getMaxSuffixComponents())))
Alexander Afanasyev84681982014-01-03 13:26:09 -080092 return false;
93
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070094 if (!getExclude().empty() &&
95 name.size() > m_name.size() &&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080096 getExclude().isExcluded(name[m_name.size()]))
Alexander Afanasyev84681982014-01-03 13:26:09 -080097 return false;
98
99 return true;
Jeff Thompson25b4e612013-10-10 16:03:24 -0700100}
101
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700102bool
103Interest::matchesData(const Data& data) const
104{
Alexander Afanasyev3b703102014-06-13 17:01:14 -0700105 if (!this->matchesName(data.getFullName())) {
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700106 return false;
107 }
108
109 const KeyLocator& publisherPublicKeyLocator = this->getPublisherPublicKeyLocator();
110 if (!publisherPublicKeyLocator.empty()) {
111 const Signature& signature = data.getSignature();
112 const Block& signatureInfo = signature.getInfo();
113 Block::element_const_iterator it = signatureInfo.find(Tlv::KeyLocator);
114 if (it == signatureInfo.elements_end()) {
115 return false;
116 }
117 if (publisherPublicKeyLocator.wireEncode() != *it) {
118 return false;
119 }
120 }
121
122 return true;
123}
124
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700125template<bool T>
126size_t
127Interest::wireEncode(EncodingImpl<T>& block) const
128{
129 size_t totalLength = 0;
130
131 // Interest ::= INTEREST-TYPE TLV-LENGTH
132 // Name
133 // Selectors?
134 // Nonce
135 // Scope?
136 // InterestLifetime?
137
138 // (reverse encoding)
139
140 // InterestLifetime
141 if (getInterestLifetime() >= time::milliseconds::zero() &&
142 getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
143 {
144 totalLength += prependNonNegativeIntegerBlock(block,
145 Tlv::InterestLifetime,
146 getInterestLifetime().count());
147 }
148
149 // Scope
150 if (getScope() >= 0)
151 {
152 totalLength += prependNonNegativeIntegerBlock(block, Tlv::Scope, getScope());
153 }
154
155 // Nonce
156 getNonce(); // to ensure that Nonce is properly set
157 totalLength += block.prependBlock(m_nonce);
158
159 // Selectors
160 if (hasSelectors())
161 {
162 totalLength += getSelectors().wireEncode(block);
163 }
164
165 // Name
166 totalLength += getName().wireEncode(block);
167
168 totalLength += block.prependVarNumber(totalLength);
169 totalLength += block.prependVarNumber(Tlv::Interest);
170 return totalLength;
171}
172
173const Block&
174Interest::wireEncode() const
175{
176 if (m_wire.hasWire())
177 return m_wire;
178
179 EncodingEstimator estimator;
180 size_t estimatedSize = wireEncode(estimator);
181
182 EncodingBuffer buffer(estimatedSize, 0);
183 wireEncode(buffer);
184
185 // to ensure that Nonce block points to the right memory location
186 const_cast<Interest*>(this)->wireDecode(buffer.block());
187
188 return m_wire;
189}
190
191void
192Interest::wireDecode(const Block& wire)
193{
194 m_wire = wire;
195 m_wire.parse();
196
197 // Interest ::= INTEREST-TYPE TLV-LENGTH
198 // Name
199 // Selectors?
200 // Nonce
201 // Scope?
202 // InterestLifetime?
203
204 if (m_wire.type() != Tlv::Interest)
205 throw Tlv::Error("Unexpected TLV number when decoding Interest");
206
207 // Name
208 m_name.wireDecode(m_wire.get(Tlv::Name));
209
210 // Selectors
211 Block::element_const_iterator val = m_wire.find(Tlv::Selectors);
212 if (val != m_wire.elements_end())
213 {
214 m_selectors.wireDecode(*val);
215 }
216 else
217 m_selectors = Selectors();
218
219 // Nonce
220 m_nonce = m_wire.get(Tlv::Nonce);
221
222 // Scope
223 val = m_wire.find(Tlv::Scope);
224 if (val != m_wire.elements_end())
225 {
226 m_scope = readNonNegativeInteger(*val);
227 }
228 else
229 m_scope = -1;
230
231 // InterestLifetime
232 val = m_wire.find(Tlv::InterestLifetime);
233 if (val != m_wire.elements_end())
234 {
235 m_interestLifetime = time::milliseconds(readNonNegativeInteger(*val));
236 }
237 else
238 {
239 m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
240 }
241}
242
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700243std::ostream&
244operator<<(std::ostream& os, const Interest& interest)
Jeff Thompsonfe556862013-07-09 13:52:55 -0700245{
Alexander Afanasyev84681982014-01-03 13:26:09 -0800246 os << interest.getName();
Jeff Thompsonfe556862013-07-09 13:52:55 -0700247
Alexander Afanasyev84681982014-01-03 13:26:09 -0800248 char delim = '?';
249
250 if (interest.getMinSuffixComponents() >= 0) {
251 os << delim << "ndn.MinSuffixComponents=" << interest.getMinSuffixComponents();
252 delim = '&';
Jeff Thompsonfe556862013-07-09 13:52:55 -0700253 }
Alexander Afanasyev84681982014-01-03 13:26:09 -0800254 if (interest.getMaxSuffixComponents() >= 0) {
255 os << delim << "ndn.MaxSuffixComponents=" << interest.getMaxSuffixComponents();
256 delim = '&';
Jeff Thompson37527d62013-08-21 11:15:54 -0700257 }
Alexander Afanasyev84681982014-01-03 13:26:09 -0800258 if (interest.getChildSelector() >= 0) {
259 os << delim << "ndn.ChildSelector=" << interest.getChildSelector();
260 delim = '&';
Jeff Thompson13e280b2013-12-03 13:12:23 -0800261 }
Alexander Afanasyev84681982014-01-03 13:26:09 -0800262 if (interest.getMustBeFresh()) {
263 os << delim << "ndn.MustBeFresh=" << interest.getMustBeFresh();
264 delim = '&';
Jeff Thompson13e280b2013-12-03 13:12:23 -0800265 }
Alexander Afanasyev84681982014-01-03 13:26:09 -0800266 if (interest.getScope() >= 0) {
267 os << delim << "ndn.Scope=" << interest.getScope();
268 delim = '&';
Jeff Thompson13e280b2013-12-03 13:12:23 -0800269 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700270 if (interest.getInterestLifetime() >= time::milliseconds::zero()
271 && interest.getInterestLifetime() != DEFAULT_INTEREST_LIFETIME) {
Alexander Afanasyeva0c5f832014-06-19 13:27:56 -0700272 os << delim << "ndn.InterestLifetime=" << interest.getInterestLifetime().count();
Alexander Afanasyev84681982014-01-03 13:26:09 -0800273 delim = '&';
274 }
275
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300276 if (interest.hasNonce()) {
Alexander Afanasyev84681982014-01-03 13:26:09 -0800277 os << delim << "ndn.Nonce=" << interest.getNonce();
278 delim = '&';
279 }
280 if (!interest.getExclude().empty()) {
281 os << delim << "ndn.Exclude=" << interest.getExclude();
282 delim = '&';
283 }
284
285 return os;
Jeff Thompson13e280b2013-12-03 13:12:23 -0800286}
287
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700288}