blob: e85ec3f673155c50eea75b44b22c9606df68908c [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/*
3 * Copyright (c) 2014-2018, 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"
27
28namespace nfd {
29namespace fw {
30namespace asf {
31
32NFD_LOG_INIT("AsfMeasurements");
33
34const RttStats::Rtt RttStats::RTT_TIMEOUT(-1.0);
35const RttStats::Rtt RttStats::RTT_NO_MEASUREMENT(0.0);
36const double RttStats::ALPHA = 0.125;
37
38RttStats::RttStats()
39 : m_srtt(RTT_NO_MEASUREMENT)
40 , m_rtt(RTT_NO_MEASUREMENT)
41{
42}
43
44void
45RttStats::addRttMeasurement(RttEstimator::Duration& durationRtt)
46{
47 m_rtt = static_cast<RttStats::Rtt>(durationRtt.count());
48
49 m_rttEstimator.addMeasurement(durationRtt);
50
51 m_srtt = computeSrtt(m_srtt, m_rtt);
52}
53
54RttStats::Rtt
55RttStats::computeSrtt(Rtt previousSrtt, Rtt currentRtt)
56{
57 if (previousSrtt == RTT_NO_MEASUREMENT) {
58 return currentRtt;
59 }
60
61 return Rtt(ALPHA * currentRtt + (1 - ALPHA) * previousSrtt);
62}
63
64////////////////////////////////////////////////////////////////////////////////
65////////////////////////////////////////////////////////////////////////////////
66
67FaceInfo::FaceInfo()
68 : m_isTimeoutScheduled(false)
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -050069 , m_nSilentTimeouts(0)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000070{
71}
72
73FaceInfo::~FaceInfo()
74{
75 cancelTimeoutEvent();
76 scheduler::cancel(m_measurementExpirationId);
77}
78
79void
Junxiao Shifc021862016-08-25 21:51:18 +000080FaceInfo::setTimeoutEvent(const scheduler::EventId& id, const Name& interestName)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000081{
82 if (!m_isTimeoutScheduled) {
83 m_timeoutEventId = id;
84 m_isTimeoutScheduled = true;
85 m_lastInterestName = interestName;
86 }
87 else {
88 BOOST_THROW_EXCEPTION(FaceInfo::Error("Tried to schedule a timeout for a face that already has a timeout scheduled."));
89 }
90}
91
92void
93FaceInfo::cancelTimeoutEvent()
94{
95 scheduler::cancel(m_timeoutEventId);
96 m_isTimeoutScheduled = false;
97}
98
99void
Junxiao Shifc021862016-08-25 21:51:18 +0000100FaceInfo::cancelTimeoutEvent(const Name& prefix)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000101{
102 if (isTimeoutScheduled() && doesNameMatchLastInterest(prefix)) {
103 cancelTimeoutEvent();
104 }
105}
106
107bool
Junxiao Shifc021862016-08-25 21:51:18 +0000108FaceInfo::doesNameMatchLastInterest(const Name& name)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000109{
110 return m_lastInterestName.isPrefixOf(name);
111}
112
113void
Junxiao Shi15e98b02016-08-12 11:21:44 +0000114FaceInfo::recordRtt(const shared_ptr<pit::Entry>& pitEntry, const Face& inFace)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000115{
116 // Calculate RTT
117 pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(inFace);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600118
119 if (outRecord == pitEntry->out_end()) { // no out-record
120 NFD_LOG_TRACE(pitEntry->getInterest() << " dataFrom inFace=" << inFace.getId() << " no-out-record");
121 return;
122 }
123
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000124 time::steady_clock::Duration steadyRtt = time::steady_clock::now() - outRecord->getLastRenewed();
125 RttEstimator::Duration durationRtt = time::duration_cast<RttEstimator::Duration>(steadyRtt);
126
127 m_rttStats.addRttMeasurement(durationRtt);
128
129 NFD_LOG_TRACE("Recording RTT for FaceId: " << inFace.getId()
130 << " RTT: " << m_rttStats.getRtt()
131 << " SRTT: " << m_rttStats.getSrtt());
132}
133
134void
Junxiao Shifc021862016-08-25 21:51:18 +0000135FaceInfo::recordTimeout(const Name& interestName)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000136{
137 m_rttStats.recordTimeout();
138 cancelTimeoutEvent(interestName);
139}
140
141////////////////////////////////////////////////////////////////////////////////
142////////////////////////////////////////////////////////////////////////////////
143
144NamespaceInfo::NamespaceInfo()
145 : m_isProbingDue(false)
146 , m_hasFirstProbeBeenScheduled(false)
147{
148}
149
150FaceInfo*
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500151NamespaceInfo::getFaceInfo(const fib::Entry& fibEntry, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000152{
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500153 FaceInfoTable::iterator it = m_fit.find(faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000154
155 if (it != m_fit.end()) {
156 return &it->second;
157 }
158 else {
159 return nullptr;
160 }
161}
162
163FaceInfo&
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500164NamespaceInfo::getOrCreateFaceInfo(const fib::Entry& fibEntry, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000165{
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500166 FaceInfoTable::iterator it = m_fit.find(faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000167
168 FaceInfo* info = nullptr;
169
170 if (it == m_fit.end()) {
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500171 const auto& pair = m_fit.insert(std::make_pair(faceId, FaceInfo()));
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000172 info = &pair.first->second;
173
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500174 extendFaceInfoLifetime(*info, faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000175 }
176 else {
177 info = &it->second;
178 }
179
180 return *info;
181}
182
183void
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500184NamespaceInfo::expireFaceInfo(FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000185{
186 m_fit.erase(faceId);
187}
188
189void
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500190NamespaceInfo::extendFaceInfoLifetime(FaceInfo& info, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000191{
192 // Cancel previous expiration
193 scheduler::cancel(info.getMeasurementExpirationEventId());
194
195 // Refresh measurement
196 scheduler::EventId id = scheduler::schedule(AsfMeasurements::MEASUREMENTS_LIFETIME,
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500197 bind(&NamespaceInfo::expireFaceInfo, this, faceId));
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000198
199 info.setMeasurementExpirationEventId(id);
200}
201
202////////////////////////////////////////////////////////////////////////////////
203////////////////////////////////////////////////////////////////////////////////
204
205constexpr time::microseconds AsfMeasurements::MEASUREMENTS_LIFETIME;
206
207AsfMeasurements::AsfMeasurements(MeasurementsAccessor& measurements)
208 : m_measurements(measurements)
209{
210}
211
212FaceInfo*
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500213AsfMeasurements::getFaceInfo(const fib::Entry& fibEntry, const Interest& interest, FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000214{
215 NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500216 return info.getFaceInfo(fibEntry, faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000217}
218
219FaceInfo&
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500220AsfMeasurements::getOrCreateFaceInfo(const fib::Entry& fibEntry, const Interest& interest,
221 FaceId faceId)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000222{
223 NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500224 return info.getOrCreateFaceInfo(fibEntry, faceId);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000225}
226
Junxiao Shifc021862016-08-25 21:51:18 +0000227NamespaceInfo*
228AsfMeasurements::getNamespaceInfo(const Name& prefix)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000229{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000230 measurements::Entry* me = m_measurements.findLongestPrefixMatch(prefix);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000231 if (me == nullptr) {
232 return nullptr;
233 }
234
235 // Set or update entry lifetime
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000236 extendLifetime(*me);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000237
Junxiao Shifc021862016-08-25 21:51:18 +0000238 NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000239 BOOST_ASSERT(info != nullptr);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000240 return info;
241}
242
243NamespaceInfo&
Junxiao Shifc021862016-08-25 21:51:18 +0000244AsfMeasurements::getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const Interest& interest)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000245{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000246 measurements::Entry* me = m_measurements.get(fibEntry);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000247
248 // If the FIB entry is not under the strategy's namespace, find a part of the prefix
249 // that falls under the strategy's namespace
250 for (size_t prefixLen = fibEntry.getPrefix().size() + 1;
251 me == nullptr && prefixLen <= interest.getName().size(); ++prefixLen) {
252 me = m_measurements.get(interest.getName().getPrefix(prefixLen));
253 }
254
255 // Either the FIB entry or the Interest's name must be under this strategy's namespace
256 BOOST_ASSERT(me != nullptr);
257
258 // Set or update entry lifetime
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000259 extendLifetime(*me);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000260
Junxiao Shifc021862016-08-25 21:51:18 +0000261 NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000262 BOOST_ASSERT(info != nullptr);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000263 return *info;
264}
265
266void
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000267AsfMeasurements::extendLifetime(measurements::Entry& me)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000268{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000269 m_measurements.extendLifetime(me, MEASUREMENTS_LIFETIME);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000270}
271
272} // namespace asf
273} // namespace fw
274} // namespace nfd