blob: dde6866f7a2849802d9d88bbdd133d7955981723 [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 Pesavento3dade002019-03-19 11:29:56 -060027#include "daemon/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
35const RttStats::Rtt RttStats::RTT_TIMEOUT(-1.0);
36const RttStats::Rtt RttStats::RTT_NO_MEASUREMENT(0.0);
37const double RttStats::ALPHA = 0.125;
38
39RttStats::RttStats()
40 : m_srtt(RTT_NO_MEASUREMENT)
41 , m_rtt(RTT_NO_MEASUREMENT)
42{
43}
44
45void
46RttStats::addRttMeasurement(RttEstimator::Duration& durationRtt)
47{
48 m_rtt = static_cast<RttStats::Rtt>(durationRtt.count());
49
50 m_rttEstimator.addMeasurement(durationRtt);
51
52 m_srtt = computeSrtt(m_srtt, m_rtt);
53}
54
55RttStats::Rtt
56RttStats::computeSrtt(Rtt previousSrtt, Rtt currentRtt)
57{
58 if (previousSrtt == RTT_NO_MEASUREMENT) {
59 return currentRtt;
60 }
61
62 return Rtt(ALPHA * currentRtt + (1 - ALPHA) * previousSrtt);
63}
64
65////////////////////////////////////////////////////////////////////////////////
66////////////////////////////////////////////////////////////////////////////////
67
68FaceInfo::FaceInfo()
69 : m_isTimeoutScheduled(false)
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -050070 , m_nSilentTimeouts(0)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000071{
72}
73
74FaceInfo::~FaceInfo()
75{
76 cancelTimeoutEvent();
Davide Pesavento3dade002019-03-19 11:29:56 -060077 m_measurementExpirationId.cancel();
Vince Lehman8a4c29e2016-07-11 08:49:35 +000078}
79
80void
Junxiao Shifc021862016-08-25 21:51:18 +000081FaceInfo::setTimeoutEvent(const scheduler::EventId& id, const Name& interestName)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000082{
83 if (!m_isTimeoutScheduled) {
84 m_timeoutEventId = id;
85 m_isTimeoutScheduled = true;
86 m_lastInterestName = interestName;
87 }
88 else {
Davide Pesavento19779d82019-02-14 13:40:04 -050089 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 +000090 }
91}
92
93void
94FaceInfo::cancelTimeoutEvent()
95{
Davide Pesavento3dade002019-03-19 11:29:56 -060096 m_timeoutEventId.cancel();
Vince Lehman8a4c29e2016-07-11 08:49:35 +000097 m_isTimeoutScheduled = false;
98}
99
100void
Junxiao Shifc021862016-08-25 21:51:18 +0000101FaceInfo::cancelTimeoutEvent(const Name& prefix)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000102{
103 if (isTimeoutScheduled() && doesNameMatchLastInterest(prefix)) {
104 cancelTimeoutEvent();
105 }
106}
107
108bool
Junxiao Shifc021862016-08-25 21:51:18 +0000109FaceInfo::doesNameMatchLastInterest(const Name& name)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000110{
111 return m_lastInterestName.isPrefixOf(name);
112}
113
114void
Junxiao Shi15e98b02016-08-12 11:21:44 +0000115FaceInfo::recordRtt(const shared_ptr<pit::Entry>& pitEntry, const Face& inFace)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000116{
117 // Calculate RTT
Davide Pesavento3dade002019-03-19 11:29:56 -0600118 auto outRecord = pitEntry->getOutRecord(inFace, 0);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600119
120 if (outRecord == pitEntry->out_end()) { // no out-record
121 NFD_LOG_TRACE(pitEntry->getInterest() << " dataFrom inFace=" << inFace.getId() << " no-out-record");
122 return;
123 }
124
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000125 time::steady_clock::Duration steadyRtt = time::steady_clock::now() - outRecord->getLastRenewed();
Davide Pesavento3dade002019-03-19 11:29:56 -0600126 auto durationRtt = time::duration_cast<RttEstimator::Duration>(steadyRtt);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000127
128 m_rttStats.addRttMeasurement(durationRtt);
129
130 NFD_LOG_TRACE("Recording RTT for FaceId: " << inFace.getId()
131 << " RTT: " << m_rttStats.getRtt()
132 << " SRTT: " << m_rttStats.getSrtt());
133}
134
135void
Junxiao Shifc021862016-08-25 21:51:18 +0000136FaceInfo::recordTimeout(const Name& interestName)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000137{
138 m_rttStats.recordTimeout();
139 cancelTimeoutEvent(interestName);
140}
141
142////////////////////////////////////////////////////////////////////////////////
143////////////////////////////////////////////////////////////////////////////////
144
145NamespaceInfo::NamespaceInfo()
146 : m_isProbingDue(false)
147 , m_hasFirstProbeBeenScheduled(false)
148{
149}
150
151FaceInfo*
Davide Pesavento3dade002019-03-19 11:29:56 -0600152NamespaceInfo::getFaceInfo(const fib::Entry&, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000153{
Davide Pesavento3dade002019-03-19 11:29:56 -0600154 auto it = m_fit.find(faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000155 if (it != m_fit.end()) {
156 return &it->second;
157 }
158 else {
159 return nullptr;
160 }
161}
162
163FaceInfo&
Davide Pesavento3dade002019-03-19 11:29:56 -0600164NamespaceInfo::getOrCreateFaceInfo(const fib::Entry&, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000165{
Davide Pesavento3dade002019-03-19 11:29:56 -0600166 auto it = m_fit.find(faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000167 FaceInfo* info = nullptr;
168
169 if (it == m_fit.end()) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400170 const auto& pair = m_fit.emplace(faceId, FaceInfo());
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000171 info = &pair.first->second;
172
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500173 extendFaceInfoLifetime(*info, faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000174 }
175 else {
176 info = &it->second;
177 }
178
179 return *info;
180}
181
182void
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500183NamespaceInfo::expireFaceInfo(FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000184{
185 m_fit.erase(faceId);
186}
187
188void
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500189NamespaceInfo::extendFaceInfoLifetime(FaceInfo& info, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000190{
191 // Cancel previous expiration
Davide Pesavento3dade002019-03-19 11:29:56 -0600192 info.getMeasurementExpirationEventId().cancel();
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000193
194 // Refresh measurement
Davide Pesavento3dade002019-03-19 11:29:56 -0600195 auto id = getScheduler().schedule(AsfMeasurements::MEASUREMENTS_LIFETIME,
196 [=] { expireFaceInfo(faceId); });
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000197 info.setMeasurementExpirationEventId(id);
198}
199
200////////////////////////////////////////////////////////////////////////////////
201////////////////////////////////////////////////////////////////////////////////
202
203constexpr time::microseconds AsfMeasurements::MEASUREMENTS_LIFETIME;
204
205AsfMeasurements::AsfMeasurements(MeasurementsAccessor& measurements)
206 : m_measurements(measurements)
207{
208}
209
210FaceInfo*
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500211AsfMeasurements::getFaceInfo(const fib::Entry& fibEntry, const Interest& interest, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000212{
213 NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500214 return info.getFaceInfo(fibEntry, faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000215}
216
217FaceInfo&
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500218AsfMeasurements::getOrCreateFaceInfo(const fib::Entry& fibEntry, const Interest& interest,
219 FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000220{
221 NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500222 return info.getOrCreateFaceInfo(fibEntry, faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000223}
224
Junxiao Shifc021862016-08-25 21:51:18 +0000225NamespaceInfo*
226AsfMeasurements::getNamespaceInfo(const Name& prefix)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000227{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000228 measurements::Entry* me = m_measurements.findLongestPrefixMatch(prefix);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000229 if (me == nullptr) {
230 return nullptr;
231 }
232
233 // Set or update entry lifetime
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000234 extendLifetime(*me);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000235
Junxiao Shifc021862016-08-25 21:51:18 +0000236 NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000237 BOOST_ASSERT(info != nullptr);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000238 return info;
239}
240
241NamespaceInfo&
Junxiao Shifc021862016-08-25 21:51:18 +0000242AsfMeasurements::getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const Interest& interest)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000243{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000244 measurements::Entry* me = m_measurements.get(fibEntry);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000245
246 // If the FIB entry is not under the strategy's namespace, find a part of the prefix
247 // that falls under the strategy's namespace
248 for (size_t prefixLen = fibEntry.getPrefix().size() + 1;
249 me == nullptr && prefixLen <= interest.getName().size(); ++prefixLen) {
250 me = m_measurements.get(interest.getName().getPrefix(prefixLen));
251 }
252
253 // Either the FIB entry or the Interest's name must be under this strategy's namespace
254 BOOST_ASSERT(me != nullptr);
255
256 // Set or update entry lifetime
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000257 extendLifetime(*me);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000258
Junxiao Shifc021862016-08-25 21:51:18 +0000259 NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000260 BOOST_ASSERT(info != nullptr);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000261 return *info;
262}
263
264void
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000265AsfMeasurements::extendLifetime(measurements::Entry& me)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000266{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000267 m_measurements.extendLifetime(me, MEASUREMENTS_LIFETIME);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000268}
269
270} // namespace asf
271} // namespace fw
272} // namespace nfd