blob: a314ae6a52011a7a2a7b9ebb9086b16dbab57ae0 [file] [log] [blame]
Junxiao Shicbba04c2014-01-26 14:21:22 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Teng Liang6f09ab62018-03-01 20:04:08 -07002/*
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -05003 * Copyright (c) 2014-2024, Regents of the University of California,
Junxiao Shi1e46be32015-01-08 20:18:05 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyev28d586a2014-07-10 20:10:54 -070024 */
Junxiao Shicbba04c2014-01-26 14:21:22 -070025
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070026#ifndef NFD_DAEMON_TABLE_PIT_ENTRY_HPP
27#define NFD_DAEMON_TABLE_PIT_ENTRY_HPP
Junxiao Shicbba04c2014-01-26 14:21:22 -070028
Davide Pesaventob124b8e2024-02-16 16:54:26 -050029#include "strategy-info-host.hpp"
Junxiao Shicbba04c2014-01-26 14:21:22 -070030
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -050031#include <ndn-cxx/util/scheduler.hpp>
32
Davide Pesaventoc0822fa2018-05-10 21:54:10 -040033#include <list>
34
Davide Pesaventob124b8e2024-02-16 16:54:26 -050035namespace nfd {
HangZhangcb4fc832014-03-11 16:57:11 +080036
Davide Pesaventob124b8e2024-02-16 16:54:26 -050037namespace face {
38class Face;
39} // namespace face
40using face::Face;
41
42namespace name_tree {
43class Entry;
44} // namespace name_tree
45
46namespace pit {
47
48/**
49 * \brief Contains information about an Interest on an incoming or outgoing face.
50 * \note This class is an implementation detail to extract common functionality
51 * of InRecord and OutRecord.
52 */
53class FaceRecord : public StrategyInfoHost
54{
55public:
56 explicit
57 FaceRecord(Face& face)
58 : m_face(face)
59 {
60 }
61
62 Face&
63 getFace() const noexcept
64 {
65 return m_face;
66 }
67
68 Interest::Nonce
69 getLastNonce() const noexcept
70 {
71 return m_lastNonce;
72 }
73
74 time::steady_clock::time_point
75 getLastRenewed() const noexcept
76 {
77 return m_lastRenewed;
78 }
79
80 /**
81 * \brief Returns the time point at which this record expires.
82 * \return getLastRenewed() + InterestLifetime
83 */
84 time::steady_clock::time_point
85 getExpiry() const noexcept
86 {
87 return m_expiry;
88 }
89
90 /**
91 * \brief Updates lastNonce, lastRenewed, expiry fields.
92 */
93 void
94 update(const Interest& interest);
95
96private:
97 Face& m_face;
98 Interest::Nonce m_lastNonce{0, 0, 0, 0};
99 time::steady_clock::time_point m_lastRenewed = time::steady_clock::time_point::min();
100 time::steady_clock::time_point m_expiry = time::steady_clock::time_point::min();
101};
102
103/**
104 * \brief Contains information about an Interest from an incoming face.
105 */
106class InRecord : public FaceRecord
107{
108public:
109 using FaceRecord::FaceRecord;
110
111 const Interest&
112 getInterest() const noexcept
113 {
114 BOOST_ASSERT(m_interest != nullptr);
115 return *m_interest;
116 }
117
118 void
119 update(const Interest& interest);
120
121private:
122 shared_ptr<const Interest> m_interest;
123};
124
125/**
126 * \brief Contains information about an Interest toward an outgoing face.
127 */
128class OutRecord : public FaceRecord
129{
130public:
131 using FaceRecord::FaceRecord;
132
133 /**
134 * \brief Returns the last Nack returned by getFace().
135 *
136 * A nullptr return value means the Interest is still pending or has timed out.
137 * A non-null return value means the last outgoing Interest has been Nacked.
138 */
139 const lp::NackHeader*
140 getIncomingNack() const noexcept
141 {
142 return m_incomingNack.get();
143 }
144
145 /**
146 * \brief Sets a Nack received from getFace().
147 * \return whether incoming Nack is accepted
148 *
149 * This is invoked in incoming Nack pipeline.
150 *
151 * An incoming Nack is accepted if its Nonce matches getLastNonce().
152 * If accepted, `nack.getHeader()` will be copied, and any pointers
153 * previously returned by getIncomingNack() are invalidated.
154 */
155 bool
156 setIncomingNack(const lp::Nack& nack);
157
158 /**
159 * \brief Clears last Nack.
160 *
161 * This is invoked in outgoing Interest pipeline.
162 *
163 * Any pointers previously returned by getIncomingNack() are invalidated.
164 */
165 void
166 clearIncomingNack() noexcept
167 {
168 m_incomingNack.reset();
169 }
170
171private:
172 unique_ptr<lp::NackHeader> m_incomingNack;
173};
Junxiao Shicbba04c2014-01-26 14:21:22 -0700174
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400175/**
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400176 * \brief An unordered collection of in-records.
Junxiao Shicbba04c2014-01-26 14:21:22 -0700177 */
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400178using InRecordCollection = std::list<InRecord>;
Junxiao Shicbba04c2014-01-26 14:21:22 -0700179
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400180/**
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400181 * \brief An unordered collection of out-records.
Junxiao Shicbba04c2014-01-26 14:21:22 -0700182 */
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400183using OutRecordCollection = std::list<OutRecord>;
Junxiao Shicbba04c2014-01-26 14:21:22 -0700184
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400185/**
186 * \brief Represents an entry in the %Interest table (PIT).
Junxiao Shi4846f372016-04-05 13:39:30 -0700187 *
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400188 * An Interest table entry represents either a pending Interest or a recently satisfied Interest.
189 * Each entry contains a collection of in-records, a collection of out-records,
190 * and two timers used in forwarding pipelines.
191 * In addition, the entry, in-records, and out-records are subclasses of StrategyInfoHost,
192 * which allows forwarding strategy to store arbitrary information on them.
193 *
194 * \sa Pit
Junxiao Shicbba04c2014-01-26 14:21:22 -0700195 */
Junxiao Shi408a7002014-02-12 17:53:47 -0700196class Entry : public StrategyInfoHost, noncopyable
Junxiao Shicbba04c2014-01-26 14:21:22 -0700197{
198public:
199 explicit
200 Entry(const Interest& interest);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700201
Junxiao Shi4846f372016-04-05 13:39:30 -0700202 /** \return the representative Interest of the PIT entry
203 * \note Every Interest in in-records and out-records should have same Name and Selectors
204 * as the representative Interest.
205 * \todo #3162 require Link field to match the representative Interest
206 */
Junxiao Shicbba04c2014-01-26 14:21:22 -0700207 const Interest&
Junxiao Shi340d5532016-08-13 04:00:35 +0000208 getInterest() const
209 {
210 return *m_interest;
211 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700212
213 /** \return Interest Name
Junxiao Shicbba04c2014-01-26 14:21:22 -0700214 */
215 const Name&
Junxiao Shi340d5532016-08-13 04:00:35 +0000216 getName() const
217 {
218 return m_interest->getName();
219 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700220
Junxiao Shia2742922016-11-17 22:53:23 +0000221 /** \return whether interest matches this entry
222 * \param interest the Interest
223 * \param nEqualNameComps number of initial name components guaranteed to be equal
224 */
225 bool
226 canMatch(const Interest& interest, size_t nEqualNameComps = 0) const;
227
Junxiao Shi4846f372016-04-05 13:39:30 -0700228public: // in-record
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500229 /**
230 * \brief Returns the collection of in-records.
Junxiao Shi4846f372016-04-05 13:39:30 -0700231 */
Junxiao Shi66f91f82014-05-10 17:28:58 -0700232 const InRecordCollection&
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500233 getInRecords() const noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000234 {
235 return m_inRecords;
236 }
Junxiao Shi66f91f82014-05-10 17:28:58 -0700237
Junxiao Shi4846f372016-04-05 13:39:30 -0700238 /** \retval true There is at least one in-record.
239 * This implies some downstream is waiting for Data or Nack.
240 * \retval false There is no in-record.
241 * This implies the entry is new or has been satisfied or Nacked.
242 */
243 bool
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500244 hasInRecords() const noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000245 {
246 return !m_inRecords.empty();
247 }
Junxiao Shi4846f372016-04-05 13:39:30 -0700248
249 InRecordCollection::iterator
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500250 in_begin() noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000251 {
252 return m_inRecords.begin();
253 }
Junxiao Shi4846f372016-04-05 13:39:30 -0700254
255 InRecordCollection::const_iterator
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500256 in_begin() const noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000257 {
258 return m_inRecords.begin();
259 }
Junxiao Shi4846f372016-04-05 13:39:30 -0700260
261 InRecordCollection::iterator
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500262 in_end() noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000263 {
264 return m_inRecords.end();
265 }
Junxiao Shi4846f372016-04-05 13:39:30 -0700266
267 InRecordCollection::const_iterator
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500268 in_end() const noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000269 {
270 return m_inRecords.end();
271 }
Junxiao Shi4846f372016-04-05 13:39:30 -0700272
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500273 /**
274 * \brief Get the in-record for \p face.
275 * \return an iterator to the in-record, or in_end() if it does not exist
Junxiao Shi4846f372016-04-05 13:39:30 -0700276 */
277 InRecordCollection::iterator
Davide Pesaventob124b8e2024-02-16 16:54:26 -0500278 findInRecord(const Face& face);
Junxiao Shi4846f372016-04-05 13:39:30 -0700279
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500280 /**
281 * \brief Insert or update an in-record.
282 * \return an iterator to the new or updated in-record
Junxiao Shicbba04c2014-01-26 14:21:22 -0700283 */
284 InRecordCollection::iterator
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000285 insertOrUpdateInRecord(Face& face, const Interest& interest);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700286
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500287 /**
288 * \brief Removes the in-record at position \p pos.
289 * \param pos iterator to the in-record to remove; must be valid and dereferenceable.
Junxiao Shi66f91f82014-05-10 17:28:58 -0700290 */
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700291 void
Davide Pesaventob124b8e2024-02-16 16:54:26 -0500292 deleteInRecord(InRecordCollection::const_iterator pos)
293 {
294 m_inRecords.erase(pos);
295 }
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700296
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500297 /**
298 * \brief Removes all in-records.
Junxiao Shi4846f372016-04-05 13:39:30 -0700299 */
Junxiao Shicbba04c2014-01-26 14:21:22 -0700300 void
Davide Pesaventob124b8e2024-02-16 16:54:26 -0500301 clearInRecords() noexcept
302 {
303 m_inRecords.clear();
304 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700305
Junxiao Shi4846f372016-04-05 13:39:30 -0700306public: // out-record
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500307 /**
308 * \brief Returns the collection of out-records.
Junxiao Shi4846f372016-04-05 13:39:30 -0700309 */
Junxiao Shi66f91f82014-05-10 17:28:58 -0700310 const OutRecordCollection&
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500311 getOutRecords() const noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000312 {
313 return m_outRecords;
314 }
Junxiao Shi66f91f82014-05-10 17:28:58 -0700315
Junxiao Shi4846f372016-04-05 13:39:30 -0700316 /** \retval true There is at least one out-record.
317 * This implies the Interest has been forwarded to some upstream,
318 * and they haven't returned Data, but may have returned Nacks.
319 * \retval false There is no out-record.
320 * This implies the Interest has not been forwarded.
Junxiao Shicbba04c2014-01-26 14:21:22 -0700321 */
Junxiao Shi4846f372016-04-05 13:39:30 -0700322 bool
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500323 hasOutRecords() const noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000324 {
325 return !m_outRecords.empty();
326 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700327
Junxiao Shi4846f372016-04-05 13:39:30 -0700328 OutRecordCollection::iterator
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500329 out_begin() noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000330 {
331 return m_outRecords.begin();
332 }
Junxiao Shi4846f372016-04-05 13:39:30 -0700333
334 OutRecordCollection::const_iterator
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500335 out_begin() const noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000336 {
337 return m_outRecords.begin();
338 }
Junxiao Shi4846f372016-04-05 13:39:30 -0700339
340 OutRecordCollection::iterator
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500341 out_end() noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000342 {
343 return m_outRecords.end();
344 }
Junxiao Shi4846f372016-04-05 13:39:30 -0700345
346 OutRecordCollection::const_iterator
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500347 out_end() const noexcept
Junxiao Shi340d5532016-08-13 04:00:35 +0000348 {
349 return m_outRecords.end();
350 }
Junxiao Shi4846f372016-04-05 13:39:30 -0700351
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500352 /**
353 * \brief Get the out-record for \p face.
354 * \return an iterator to the out-record, or out_end() if it does not exist
Junxiao Shi66f91f82014-05-10 17:28:58 -0700355 */
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700356 OutRecordCollection::iterator
Davide Pesaventob124b8e2024-02-16 16:54:26 -0500357 findOutRecord(const Face& face);
Junxiao Shi66f91f82014-05-10 17:28:58 -0700358
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500359 /**
360 * \brief Insert or update an out-record.
361 * \return an iterator to the new or updated out-record
Junxiao Shi4846f372016-04-05 13:39:30 -0700362 */
363 OutRecordCollection::iterator
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000364 insertOrUpdateOutRecord(Face& face, const Interest& interest);
Junxiao Shi4846f372016-04-05 13:39:30 -0700365
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500366 /**
367 * \brief Delete the out-record for \p face if it exists.
Junxiao Shi4846f372016-04-05 13:39:30 -0700368 */
Junxiao Shicbba04c2014-01-26 14:21:22 -0700369 void
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000370 deleteOutRecord(const Face& face);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700371
Junxiao Shid3c792f2014-01-30 00:46:13 -0700372public:
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400373 /** \brief Expiry timer.
Junxiao Shi4846f372016-04-05 13:39:30 -0700374 *
375 * This timer is used in forwarding pipelines to delete the entry
Junxiao Shi4846f372016-04-05 13:39:30 -0700376 */
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -0500377 ndn::scheduler::EventId expiryTimer;
Junxiao Shicbba04c2014-01-26 14:21:22 -0700378
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400379 /** \brief Indicates whether this PIT entry is satisfied.
Teng Liang6f09ab62018-03-01 20:04:08 -0700380 */
Davide Pesavento50a6af32019-02-21 00:04:40 -0500381 bool isSatisfied = false;
Teng Liang6f09ab62018-03-01 20:04:08 -0700382
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400383 /** \brief Data freshness period.
Davide Pesavento4d2e7882024-02-15 23:00:21 -0500384 * \note This field is meaningful only if #isSatisfied is true
Teng Liang6f09ab62018-03-01 20:04:08 -0700385 */
Davide Pesavento50a6af32019-02-21 00:04:40 -0500386 time::milliseconds dataFreshnessPeriod = 0_ms;
Teng Liang6f09ab62018-03-01 20:04:08 -0700387
Junxiao Shicbba04c2014-01-26 14:21:22 -0700388private:
Alexander Afanasyev28d586a2014-07-10 20:10:54 -0700389 shared_ptr<const Interest> m_interest;
Junxiao Shicbba04c2014-01-26 14:21:22 -0700390 InRecordCollection m_inRecords;
391 OutRecordCollection m_outRecords;
Junxiao Shi57f0f312014-03-16 11:52:20 -0700392
Davide Pesavento50a6af32019-02-21 00:04:40 -0500393 name_tree::Entry* m_nameTreeEntry = nullptr;
HangZhangcb4fc832014-03-11 16:57:11 +0800394
Davide Pesavento9a28c3f2022-06-11 21:50:01 -0400395 friend ::nfd::name_tree::Entry;
Junxiao Shicbba04c2014-01-26 14:21:22 -0700396};
397
Davide Pesaventob124b8e2024-02-16 16:54:26 -0500398} // namespace pit
399} // namespace nfd
Junxiao Shicbba04c2014-01-26 14:21:22 -0700400
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700401#endif // NFD_DAEMON_TABLE_PIT_ENTRY_HPP