blob: f743e06be46c8f3fc5e41377c088d278d179f1bc [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
Davide Pesaventoa3148082018-04-12 18:21:54 -040032NFD_LOG_INIT(AsfMeasurements);
Vince Lehman8a4c29e2016-07-11 08:49:35 +000033
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()) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400171 const auto& pair = m_fit.emplace(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
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400196 auto id = scheduler::schedule(AsfMeasurements::MEASUREMENTS_LIFETIME, [=] { 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