blob: cf3a317ad5e601b872bc4ccb8f1949e236822545 [file] [log] [blame]
Vince Lehman8a4c29e2016-07-11 08:49:35 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -05002/*
Davide Pesavento19779d82019-02-14 13:40:04 -05003 * Copyright (c) 2014-2019, Regents of the University of California,
Vince Lehman8a4c29e2016-07-11 08:49:35 +00004 * 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.
10 *
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/>.
24 */
25
26#include "asf-measurements.hpp"
Davide Pesavento2cae8ca2019-04-18 20:48:05 -040027#include "common/global.hpp"
Vince Lehman8a4c29e2016-07-11 08:49:35 +000028
29namespace nfd {
30namespace fw {
31namespace asf {
32
Davide Pesaventoa3148082018-04-12 18:21:54 -040033NFD_LOG_INIT(AsfMeasurements);
Vince Lehman8a4c29e2016-07-11 08:49:35 +000034
Ernest McCracken1402fa12019-06-09 00:36:28 -070035const time::nanoseconds RttStats::RTT_TIMEOUT(-1);
36const time::nanoseconds RttStats::RTT_NO_MEASUREMENT(0);
Vince Lehman8a4c29e2016-07-11 08:49:35 +000037const double RttStats::ALPHA = 0.125;
38
39RttStats::RttStats()
40 : m_srtt(RTT_NO_MEASUREMENT)
41 , m_rtt(RTT_NO_MEASUREMENT)
42{
43}
44
45void
Ernest McCracken1402fa12019-06-09 00:36:28 -070046RttStats::addRttMeasurement(time::nanoseconds durationRtt)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000047{
Ernest McCracken1402fa12019-06-09 00:36:28 -070048 m_rtt = durationRtt;
49 m_rttEstimator.addMeasurement(durationRtt, 1);
50 m_srtt = m_rttEstimator.getSmoothedRtt();
Vince Lehman8a4c29e2016-07-11 08:49:35 +000051}
52
53////////////////////////////////////////////////////////////////////////////////
54////////////////////////////////////////////////////////////////////////////////
55
56FaceInfo::FaceInfo()
57 : m_isTimeoutScheduled(false)
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -050058 , m_nSilentTimeouts(0)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000059{
60}
61
62FaceInfo::~FaceInfo()
63{
64 cancelTimeoutEvent();
Davide Pesavento3dade002019-03-19 11:29:56 -060065 m_measurementExpirationId.cancel();
Vince Lehman8a4c29e2016-07-11 08:49:35 +000066}
67
68void
Junxiao Shifc021862016-08-25 21:51:18 +000069FaceInfo::setTimeoutEvent(const scheduler::EventId& id, const Name& interestName)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000070{
71 if (!m_isTimeoutScheduled) {
72 m_timeoutEventId = id;
73 m_isTimeoutScheduled = true;
74 m_lastInterestName = interestName;
75 }
76 else {
Davide Pesavento19779d82019-02-14 13:40:04 -050077 NDN_THROW(FaceInfo::Error("Tried to schedule a timeout for a face that already has a timeout scheduled"));
Vince Lehman8a4c29e2016-07-11 08:49:35 +000078 }
79}
80
81void
82FaceInfo::cancelTimeoutEvent()
83{
Davide Pesavento3dade002019-03-19 11:29:56 -060084 m_timeoutEventId.cancel();
Vince Lehman8a4c29e2016-07-11 08:49:35 +000085 m_isTimeoutScheduled = false;
86}
87
88void
Junxiao Shifc021862016-08-25 21:51:18 +000089FaceInfo::cancelTimeoutEvent(const Name& prefix)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000090{
91 if (isTimeoutScheduled() && doesNameMatchLastInterest(prefix)) {
92 cancelTimeoutEvent();
93 }
94}
95
96bool
Junxiao Shifc021862016-08-25 21:51:18 +000097FaceInfo::doesNameMatchLastInterest(const Name& name)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000098{
99 return m_lastInterestName.isPrefixOf(name);
100}
101
102void
Junxiao Shi15e98b02016-08-12 11:21:44 +0000103FaceInfo::recordRtt(const shared_ptr<pit::Entry>& pitEntry, const Face& inFace)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000104{
105 // Calculate RTT
Davide Pesavento3dade002019-03-19 11:29:56 -0600106 auto outRecord = pitEntry->getOutRecord(inFace, 0);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600107
108 if (outRecord == pitEntry->out_end()) { // no out-record
109 NFD_LOG_TRACE(pitEntry->getInterest() << " dataFrom inFace=" << inFace.getId() << " no-out-record");
110 return;
111 }
112
Ernest McCracken1402fa12019-06-09 00:36:28 -0700113 m_rttStats.addRttMeasurement(time::steady_clock::now() - outRecord->getLastRenewed());
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000114 NFD_LOG_TRACE("Recording RTT for FaceId: " << inFace.getId()
Ernest McCracken1402fa12019-06-09 00:36:28 -0700115 << " RTT: " << m_rttStats.getRtt() << " SRTT: " << m_rttStats.getSrtt());
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000116}
117
118void
Junxiao Shifc021862016-08-25 21:51:18 +0000119FaceInfo::recordTimeout(const Name& interestName)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000120{
121 m_rttStats.recordTimeout();
122 cancelTimeoutEvent(interestName);
123}
124
125////////////////////////////////////////////////////////////////////////////////
126////////////////////////////////////////////////////////////////////////////////
127
128NamespaceInfo::NamespaceInfo()
129 : m_isProbingDue(false)
130 , m_hasFirstProbeBeenScheduled(false)
131{
132}
133
134FaceInfo*
Davide Pesavento3dade002019-03-19 11:29:56 -0600135NamespaceInfo::getFaceInfo(const fib::Entry&, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000136{
Davide Pesavento3dade002019-03-19 11:29:56 -0600137 auto it = m_fit.find(faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000138 if (it != m_fit.end()) {
139 return &it->second;
140 }
141 else {
142 return nullptr;
143 }
144}
145
146FaceInfo&
Davide Pesavento3dade002019-03-19 11:29:56 -0600147NamespaceInfo::getOrCreateFaceInfo(const fib::Entry&, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000148{
Davide Pesavento3dade002019-03-19 11:29:56 -0600149 auto it = m_fit.find(faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000150 FaceInfo* info = nullptr;
151
152 if (it == m_fit.end()) {
Ernest McCracken1402fa12019-06-09 00:36:28 -0700153 const auto& pair = m_fit.emplace(std::piecewise_construct,
154 std::forward_as_tuple(faceId),
155 std::forward_as_tuple());
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000156 info = &pair.first->second;
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500157 extendFaceInfoLifetime(*info, faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000158 }
159 else {
160 info = &it->second;
161 }
162
163 return *info;
164}
165
166void
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500167NamespaceInfo::expireFaceInfo(FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000168{
169 m_fit.erase(faceId);
170}
171
172void
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500173NamespaceInfo::extendFaceInfoLifetime(FaceInfo& info, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000174{
175 // Cancel previous expiration
Davide Pesavento3dade002019-03-19 11:29:56 -0600176 info.getMeasurementExpirationEventId().cancel();
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000177
178 // Refresh measurement
Davide Pesavento3dade002019-03-19 11:29:56 -0600179 auto id = getScheduler().schedule(AsfMeasurements::MEASUREMENTS_LIFETIME,
180 [=] { expireFaceInfo(faceId); });
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000181 info.setMeasurementExpirationEventId(id);
182}
183
184////////////////////////////////////////////////////////////////////////////////
185////////////////////////////////////////////////////////////////////////////////
186
187constexpr time::microseconds AsfMeasurements::MEASUREMENTS_LIFETIME;
188
189AsfMeasurements::AsfMeasurements(MeasurementsAccessor& measurements)
190 : m_measurements(measurements)
191{
192}
193
194FaceInfo*
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500195AsfMeasurements::getFaceInfo(const fib::Entry& fibEntry, const Interest& interest, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000196{
197 NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500198 return info.getFaceInfo(fibEntry, faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000199}
200
201FaceInfo&
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500202AsfMeasurements::getOrCreateFaceInfo(const fib::Entry& fibEntry, const Interest& interest,
203 FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000204{
205 NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500206 return info.getOrCreateFaceInfo(fibEntry, faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000207}
208
Junxiao Shifc021862016-08-25 21:51:18 +0000209NamespaceInfo*
210AsfMeasurements::getNamespaceInfo(const Name& prefix)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000211{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000212 measurements::Entry* me = m_measurements.findLongestPrefixMatch(prefix);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000213 if (me == nullptr) {
214 return nullptr;
215 }
216
217 // Set or update entry lifetime
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000218 extendLifetime(*me);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000219
Junxiao Shifc021862016-08-25 21:51:18 +0000220 NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000221 BOOST_ASSERT(info != nullptr);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000222 return info;
223}
224
225NamespaceInfo&
Junxiao Shifc021862016-08-25 21:51:18 +0000226AsfMeasurements::getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const Interest& interest)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000227{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000228 measurements::Entry* me = m_measurements.get(fibEntry);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000229
230 // If the FIB entry is not under the strategy's namespace, find a part of the prefix
231 // that falls under the strategy's namespace
232 for (size_t prefixLen = fibEntry.getPrefix().size() + 1;
233 me == nullptr && prefixLen <= interest.getName().size(); ++prefixLen) {
234 me = m_measurements.get(interest.getName().getPrefix(prefixLen));
235 }
236
237 // Either the FIB entry or the Interest's name must be under this strategy's namespace
238 BOOST_ASSERT(me != nullptr);
239
240 // Set or update entry lifetime
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000241 extendLifetime(*me);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000242
Junxiao Shifc021862016-08-25 21:51:18 +0000243 NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000244 BOOST_ASSERT(info != nullptr);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000245 return *info;
246}
247
248void
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000249AsfMeasurements::extendLifetime(measurements::Entry& me)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000250{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000251 m_measurements.extendLifetime(me, MEASUREMENTS_LIFETIME);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000252}
253
254} // namespace asf
255} // namespace fw
256} // namespace nfd