blob: c297446645cba4767bdb5c839f8f6443a5c1ce77 [file] [log] [blame]
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Eric Newberry976c2042016-06-19 23:37:35 -07003 * Copyright (C) 2014-2016 The University of Arizona.
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -08004 *
Davide Pesaventod0b59982015-02-27 19:15:15 +01005 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080017 *
18 * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
19 */
20
Davide Pesaventod0b59982015-02-27 19:15:15 +010021#include <cctype>
22#include <cstdlib>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080023#include <fstream>
jeraldabraham420dbf02014-04-25 22:58:31 -070024#include <string>
Davide Pesaventod0b59982015-02-27 19:15:15 +010025#include <unistd.h>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080026#include <vector>
27
jeraldabraham420dbf02014-04-25 22:58:31 -070028#include <boost/asio.hpp>
29#include <boost/date_time/posix_time/posix_time.hpp>
30#include <boost/filesystem.hpp>
jeraldabraham420dbf02014-04-25 22:58:31 -070031#include <boost/noncopyable.hpp>
32
33#include <ndn-cxx/exclude.hpp>
34#include <ndn-cxx/face.hpp>
35#include <ndn-cxx/name-component.hpp>
Junxiao Shi6f33e0f2016-09-06 03:11:53 +000036#include <ndn-cxx/lp/tags.hpp>
Spencer Lee8e990232015-11-27 03:54:39 -070037#include <ndn-cxx/util/backports.hpp>
jeraldabraham420dbf02014-04-25 22:58:31 -070038
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080039#include "logger.hpp"
40
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080041namespace ndn {
42
jeraldabraham420dbf02014-04-25 22:58:31 -070043class NdnTrafficClient : boost::noncopyable
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080044{
45public:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070046 explicit
Davide Pesaventod0b59982015-02-27 19:15:15 +010047 NdnTrafficClient(const char* programName)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070048 : m_programName(programName)
49 , m_logger("NdnTrafficClient")
Spencer Lee8e990232015-11-27 03:54:39 -070050 , m_instanceId(to_string(std::rand()))
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070051 , m_hasError(false)
jeraldabraham420dbf02014-04-25 22:58:31 -070052 , m_hasQuietLogging(false)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070053 , m_interestInterval(getDefaultInterestInterval())
54 , m_nMaximumInterests(-1)
Alexander Afanasyev740812e2014-10-30 15:37:45 -070055 , m_face(m_ioService)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070056 , m_nInterestsSent(0)
57 , m_nInterestsReceived(0)
Eric Newberry976c2042016-06-19 23:37:35 -070058 , m_nNacks(0)
jeraldabrahamdbfee2e2014-04-04 01:18:14 -070059 , m_nContentInconsistencies(0)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070060 , m_minimumInterestRoundTripTime(std::numeric_limits<double>::max())
61 , m_maximumInterestRoundTripTime(0)
62 , m_totalInterestRoundTripTime(0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080063 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080064 }
65
66 class InterestTrafficConfiguration
67 {
68 public:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080069 InterestTrafficConfiguration()
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070070 : m_trafficPercentage(-1)
71 , m_nameAppendBytes(-1)
72 , m_nameAppendSequenceNumber(-1)
73 , m_minSuffixComponents(-1)
74 , m_maxSuffixComponents(-1)
75 , m_excludeBeforeBytes(-1)
76 , m_excludeAfterBytes(-1)
77 , m_childSelector(-1)
78 , m_mustBeFresh(-1)
79 , m_nonceDuplicationPercentage(-1)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070080 , m_interestLifetime(getDefaultInterestLifetime())
Eric Newberryeab462b2016-03-18 11:56:31 -070081 , m_nextHopFaceId(0)
jeraldabrahamdbfee2e2014-04-04 01:18:14 -070082 , m_nInterestsSent(0)
83 , m_nInterestsReceived(0)
Eric Newberry976c2042016-06-19 23:37:35 -070084 , m_nNacks(0)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070085 , m_minimumInterestRoundTripTime(std::numeric_limits<double>::max())
86 , m_maximumInterestRoundTripTime(0)
87 , m_totalInterestRoundTripTime(0)
88 , m_nContentInconsistencies(0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080089 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070090 }
91
Davide Pesaventod0b59982015-02-27 19:15:15 +010092 static time::milliseconds
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070093 getDefaultInterestLifetime()
94 {
95 return time::milliseconds(-1);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080096 }
97
98 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070099 printTrafficConfiguration(Logger& logger)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800100 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100101 std::string detail;
102
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700103 if (m_trafficPercentage > 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700104 detail += "TrafficPercentage=" + to_string(m_trafficPercentage) + ", ";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100105 if (!m_name.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700106 detail += "Name=" + m_name + ", ";
107 if (m_nameAppendBytes > 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700108 detail += "NameAppendBytes=" + to_string(m_nameAppendBytes) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700109 if (m_nameAppendSequenceNumber > 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700110 detail += "NameAppendSequenceNumber=" + to_string(m_nameAppendSequenceNumber) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700111 if (m_minSuffixComponents >= 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700112 detail += "MinSuffixComponents=" + to_string(m_minSuffixComponents) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700113 if (m_maxSuffixComponents >= 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700114 detail += "MaxSuffixComponents=" + to_string(m_maxSuffixComponents) + ", ";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100115 if (!m_excludeBefore.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700116 detail += "ExcludeBefore=" + m_excludeBefore + ", ";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100117 if (!m_excludeAfter.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700118 detail += "ExcludeAfter=" + m_excludeAfter + ", ";
Eric Newberry25e9ba02016-08-02 22:02:22 -0700119 if (!m_excludeRange.empty())
120 detail += "ExcludeRange=" + m_excludeRange + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700121 if (m_excludeBeforeBytes > 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700122 detail += "ExcludeBeforeBytes=" + to_string(m_excludeBeforeBytes) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700123 if (m_excludeAfterBytes > 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700124 detail += "ExcludeAfterBytes=" + to_string(m_excludeAfterBytes) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700125 if (m_childSelector >= 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700126 detail += "ChildSelector=" + to_string(m_childSelector) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700127 if (m_mustBeFresh >= 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700128 detail += "MustBeFresh=" + to_string(m_mustBeFresh) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700129 if (m_nonceDuplicationPercentage > 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700130 detail += "NonceDuplicationPercentage=" + to_string(m_nonceDuplicationPercentage) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700131 if (m_interestLifetime >= time::milliseconds(0))
Spencer Lee8e990232015-11-27 03:54:39 -0700132 detail += "InterestLifetime=" + to_string(m_interestLifetime.count()) + ", ";
Eric Newberryeab462b2016-03-18 11:56:31 -0700133 if (m_nextHopFaceId > 0)
134 detail += "NextHopFaceId=" + to_string(m_nextHopFaceId) + ", ";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100135 if (!m_expectedContent.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700136 detail += "ExpectedContent=" + m_expectedContent + ", ";
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800137 if (detail.length() >= 2)
Davide Pesaventod0b59982015-02-27 19:15:15 +0100138 detail = detail.substr(0, detail.length() - 2); // Removing suffix ", "
139
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800140 logger.log(detail, false, false);
141 }
142
143 bool
Davide Pesaventod0b59982015-02-27 19:15:15 +0100144 extractParameterValue(const std::string& detail, std::string& parameter, std::string& value)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800145 {
Eric Newberry25e9ba02016-08-02 22:02:22 -0700146 std::string allowedCharacters = ":/+.,_-%";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100147 std::size_t i = 0;
148
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800149 parameter = "";
150 value = "";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100151 while (detail[i] != '=' && i < detail.length()) {
152 parameter += detail[i];
153 i++;
154 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800155 if (i == detail.length())
156 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100157
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800158 i++;
jeraldabraham79c0c232014-03-31 21:43:59 -0700159 while ((std::isalnum(detail[i]) ||
Davide Pesaventod0b59982015-02-27 19:15:15 +0100160 allowedCharacters.find(detail[i]) != std::string::npos) &&
161 i < detail.length()) {
162 value += detail[i];
163 i++;
164 }
165
166 if (parameter.empty() || value.empty())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800167 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100168 else
169 return true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800170 }
171
172 bool
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700173 processConfigurationDetail(const std::string& detail, Logger& logger, int lineNumber)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800174 {
175 std::string parameter, value;
176 if (extractParameterValue(detail, parameter, value))
177 {
178 if (parameter == "TrafficPercentage")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100179 m_trafficPercentage = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800180 else if (parameter == "Name")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700181 m_name = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800182 else if (parameter == "NameAppendBytes")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100183 m_nameAppendBytes = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800184 else if (parameter == "NameAppendSequenceNumber")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100185 m_nameAppendSequenceNumber = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800186 else if (parameter == "MinSuffixComponents")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100187 m_minSuffixComponents = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800188 else if (parameter == "MaxSuffixComponents")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100189 m_maxSuffixComponents = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800190 else if (parameter == "ExcludeBefore")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700191 m_excludeBefore = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800192 else if (parameter == "ExcludeAfter")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700193 m_excludeAfter = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800194 else if (parameter == "ExcludeBeforeBytes")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100195 m_excludeBeforeBytes = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800196 else if (parameter == "ExcludeAfterBytes")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100197 m_excludeAfterBytes = std::stoi(value);
Eric Newberry25e9ba02016-08-02 22:02:22 -0700198 else if (parameter == "ExcludeRange")
199 m_excludeRange = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800200 else if (parameter == "ChildSelector")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100201 m_childSelector = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800202 else if (parameter == "MustBeFresh")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100203 m_mustBeFresh = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800204 else if (parameter == "NonceDuplicationPercentage")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100205 m_nonceDuplicationPercentage = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800206 else if (parameter == "InterestLifetime")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100207 m_interestLifetime = time::milliseconds(std::stoi(value));
Eric Newberryeab462b2016-03-18 11:56:31 -0700208 else if (parameter == "NextHopFaceId")
209 m_nextHopFaceId = std::stoi(value);
jeraldabraham473ef3d2014-03-06 12:40:35 -0700210 else if (parameter == "ExpectedContent")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700211 m_expectedContent = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800212 else
Spencer Lee8e990232015-11-27 03:54:39 -0700213 logger.log("Line " + to_string(lineNumber) +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700214 " \t- Invalid Parameter='" + parameter + "'", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800215 }
216 else
217 {
Spencer Lee8e990232015-11-27 03:54:39 -0700218 logger.log("Line " + to_string(lineNumber) +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700219 " \t- Improper Traffic Configuration Line- " + detail, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800220 return false;
221 }
222 return true;
223 }
224
225 bool
226 checkTrafficDetailCorrectness()
227 {
228 return true;
229 }
230
Davide Pesaventod0b59982015-02-27 19:15:15 +0100231 private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700232 int m_trafficPercentage;
233 std::string m_name;
234 int m_nameAppendBytes;
235 int m_nameAppendSequenceNumber;
236 int m_minSuffixComponents;
237 int m_maxSuffixComponents;
238 std::string m_excludeBefore;
239 std::string m_excludeAfter;
Eric Newberry25e9ba02016-08-02 22:02:22 -0700240 std::string m_excludeRange;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700241 int m_excludeBeforeBytes;
242 int m_excludeAfterBytes;
243 int m_childSelector;
244 int m_mustBeFresh;
245 int m_nonceDuplicationPercentage;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700246 time::milliseconds m_interestLifetime;
Eric Newberryeab462b2016-03-18 11:56:31 -0700247 uint64_t m_nextHopFaceId;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700248 int m_nInterestsSent;
249 int m_nInterestsReceived;
Eric Newberry976c2042016-06-19 23:37:35 -0700250 int m_nNacks;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700251
252 //round trip time is stored as milliseconds with fractional
253 //sub-millisecond precision
254 double m_minimumInterestRoundTripTime;
255 double m_maximumInterestRoundTripTime;
256 double m_totalInterestRoundTripTime;
257
258 int m_nContentInconsistencies;
259 std::string m_expectedContent;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100260
261 friend class NdnTrafficClient;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700262 }; // class InterestTrafficConfiguration
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800263
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700264 bool
265 hasError() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800266 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700267 return m_hasError;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800268 }
269
270 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100271 usage() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800272 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100273 std::cout << "Usage:\n"
274 << " " << m_programName << " [options] <Traffic_Configuration_File>\n"
275 << "\n"
276 << "Generate Interest traffic as per provided Traffic Configuration File.\n"
277 << "Interests are continuously generated unless a total number is specified.\n"
278 << "Set environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
279 << "\n"
280 << "Options:\n"
281 << " [-i interval] - set interest generation interval in milliseconds (default "
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700282 << getDefaultInterestInterval() << ")\n"
Davide Pesaventod0b59982015-02-27 19:15:15 +0100283 << " [-c count] - set total number of interests to be generated\n"
284 << " [-q] - quiet mode: no interest reception/data generation logging\n"
285 << " [-h] - print this help text and exit\n";
286 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800287 }
288
Davide Pesaventod0b59982015-02-27 19:15:15 +0100289 static time::milliseconds
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800290 getDefaultInterestInterval()
291 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700292 return time::milliseconds(1000);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800293 }
294
295 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700296 setInterestInterval(int interestInterval)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800297 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700298 if (interestInterval <= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800299 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700300 m_interestInterval = time::milliseconds(interestInterval);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800301 }
302
303 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700304 setMaximumInterests(int maximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800305 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700306 if (maximumInterests <= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800307 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700308 m_nMaximumInterests = maximumInterests;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800309 }
310
311 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700312 setConfigurationFile(char* configurationFile)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800313 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700314 m_configurationFile = configurationFile;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800315 }
316
317 void
jeraldabraham420dbf02014-04-25 22:58:31 -0700318 setQuietLogging()
319 {
320 m_hasQuietLogging = true;
321 }
322
323 void
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800324 signalHandler()
325 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800326 logStatistics();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100327
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700328 m_logger.shutdownLogger();
329 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300330 m_ioService.stop();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100331
332 exit(m_hasError ? EXIT_FAILURE : EXIT_SUCCESS);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800333 }
334
335 void
336 logStatistics()
337 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800338 m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700339 m_logger.log("Total Traffic Pattern Types = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700340 to_string(m_trafficPatterns.size()), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700341 m_logger.log("Total Interests Sent = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700342 to_string(m_nInterestsSent), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700343 m_logger.log("Total Responses Received = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700344 to_string(m_nInterestsReceived), false, true);
Eric Newberry976c2042016-06-19 23:37:35 -0700345 m_logger.log("Total Nacks Received = " +
346 to_string(m_nNacks), false, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100347
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700348 double loss = 0;
349 if (m_nInterestsSent > 0)
350 loss = (m_nInterestsSent - m_nInterestsReceived) * 100.0 / m_nInterestsSent;
Spencer Lee8e990232015-11-27 03:54:39 -0700351 m_logger.log("Total Interest Loss = " + to_string(loss) + "%", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700352 if (m_nContentInconsistencies != 0 || m_nInterestsSent != m_nInterestsReceived)
353 m_hasError = true;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100354
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700355 double average = 0;
356 double inconsistency = 0;
357 if (m_nInterestsReceived > 0)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700358 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700359 average = m_totalInterestRoundTripTime / m_nInterestsReceived;
360 inconsistency = m_nContentInconsistencies * 100.0 / m_nInterestsReceived;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700361 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700362 m_logger.log("Total Data Inconsistency = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700363 to_string(inconsistency) + "%", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700364 m_logger.log("Total Round Trip Time = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700365 to_string(m_totalInterestRoundTripTime) + "ms", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700366 m_logger.log("Average Round Trip Time = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700367 to_string(average) + "ms\n", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700368
Davide Pesaventod0b59982015-02-27 19:15:15 +0100369 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700370 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700371 m_logger.log("Traffic Pattern Type #" +
Spencer Lee8e990232015-11-27 03:54:39 -0700372 to_string(patternId + 1), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700373 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
374 m_logger.log("Total Interests Sent = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700375 to_string(m_trafficPatterns[patternId].m_nInterestsSent), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700376 m_logger.log("Total Responses Received = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700377 to_string(m_trafficPatterns[patternId].m_nInterestsReceived), false, true);
Eric Newberry976c2042016-06-19 23:37:35 -0700378 m_logger.log("Total Nacks Received = " +
379 to_string(m_trafficPatterns[patternId].m_nNacks), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700380 loss = 0;
381 if (m_trafficPatterns[patternId].m_nInterestsSent > 0)
382 {
383 loss = (m_trafficPatterns[patternId].m_nInterestsSent -
384 m_trafficPatterns[patternId].m_nInterestsReceived);
385 loss *= 100.0;
386 loss /= m_trafficPatterns[patternId].m_nInterestsSent;
387 }
Spencer Lee8e990232015-11-27 03:54:39 -0700388 m_logger.log("Total Interest Loss = " + to_string(loss) + "%", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700389 average = 0;
390 inconsistency = 0;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700391 if (m_trafficPatterns[patternId].m_nInterestsReceived > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800392 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700393 average = (m_trafficPatterns[patternId].m_totalInterestRoundTripTime /
394 m_trafficPatterns[patternId].m_nInterestsReceived);
395 inconsistency = m_trafficPatterns[patternId].m_nContentInconsistencies;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100396 inconsistency *= 100.0 / m_trafficPatterns[patternId].m_nInterestsReceived;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800397 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700398 m_logger.log("Total Data Inconsistency = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700399 to_string(inconsistency) + "%", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700400 m_logger.log("Total Round Trip Time = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700401 to_string(m_trafficPatterns[patternId].m_totalInterestRoundTripTime) +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100402 "ms", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700403 m_logger.log("Average Round Trip Time = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700404 to_string(average) + "ms\n", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800405 }
406 }
407
408 bool
409 checkTrafficPatternCorrectness()
410 {
411 return true;
412 }
413
414 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700415 parseConfigurationFile()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800416 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800417 std::string patternLine;
418 std::ifstream patternFile;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700419 m_logger.log("Analyzing Traffic Configuration File: " + m_configurationFile, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100420
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700421 patternFile.open(m_configurationFile.c_str());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800422 if (patternFile.is_open())
423 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700424 int lineNumber = 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800425 while (getline(patternFile, patternLine))
426 {
427 lineNumber++;
428 if (std::isalpha(patternLine[0]))
429 {
430 InterestTrafficConfiguration interestData;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700431 bool shouldSkipLine = false;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800432 if (interestData.processConfigurationDetail(patternLine, m_logger, lineNumber))
433 {
434 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
435 {
436 lineNumber++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700437 if (!interestData.processConfigurationDetail(patternLine,
438 m_logger, lineNumber))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800439 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700440 shouldSkipLine = true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800441 break;
442 }
443 }
444 lineNumber++;
445 }
446 else
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700447 shouldSkipLine = true;
448 if (!shouldSkipLine)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800449 {
450 if (interestData.checkTrafficDetailCorrectness())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700451 m_trafficPatterns.push_back(interestData);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800452 }
453 }
454 }
455 patternFile.close();
456 if (!checkTrafficPatternCorrectness())
457 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700458 m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper- " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700459 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800460 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100461 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800462 }
463 m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100464 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800465 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700466 m_logger.log("Traffic Pattern Type #" +
Spencer Lee8e990232015-11-27 03:54:39 -0700467 to_string(patternId + 1), false, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700468 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800469 m_logger.log("", false, false);
470 }
471 }
472 else
473 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700474 m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700475 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800476 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100477 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800478 }
479 }
480
481 void
482 initializeTrafficConfiguration()
483 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700484 if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800485 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700486 if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800487 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700488 parseConfigurationFile();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800489 }
490 else
491 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700492 m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700493 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800494 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100495 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800496 }
497 }
498 else
499 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700500 m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700501 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800502 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100503 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800504 }
505 }
506
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700507 uint32_t
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800508 getOldNonce()
509 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700510 if (m_nonces.size() == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800511 return getNewNonce();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700512 int randomNonceIndex = std::rand() % m_nonces.size();
513 return m_nonces[randomNonceIndex];
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800514 }
515
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700516 uint32_t
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800517 getNewNonce()
518 {
jeraldabraham473ef3d2014-03-06 12:40:35 -0700519 //Performance Enhancement
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700520 if (m_nonces.size() > 1000)
521 m_nonces.clear();
jeraldabraham473ef3d2014-03-06 12:40:35 -0700522
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700523 uint32_t randomNonce = static_cast<uint32_t>(std::rand());
524 while (std::find(m_nonces.begin(), m_nonces.end(), randomNonce) != m_nonces.end())
525 randomNonce = static_cast<uint32_t>(std::rand());
526
527 m_nonces.push_back(randomNonce);
528 return randomNonce;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800529 }
530
Eric Newberry3b284192015-07-06 21:44:46 -0700531 static name::Component
532 generateRandomNameComponent(size_t length)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800533 {
Eric Newberry3b284192015-07-06 21:44:46 -0700534 Buffer buffer(length);
535 for (size_t i = 0; i < length; i++) {
536 buffer[i] = static_cast<uint8_t>(std::rand() % 256);
537 }
538 return name::Component(buffer);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800539 }
540
541 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700542 onData(const ndn::Interest& interest,
Eric Newberry976c2042016-06-19 23:37:35 -0700543 const ndn::Data& data,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700544 int globalReference,
545 int localReference,
546 int patternId,
547 time::steady_clock::TimePoint sentTime)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800548 {
Spencer Lee8e990232015-11-27 03:54:39 -0700549 std::string logLine = "Data Received - PatternType=" + to_string(patternId + 1);
550 logLine += ", GlobalID=" + to_string(globalReference);
551 logLine += ", LocalID=" + to_string(localReference);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700552 logLine += ", Name=" + interest.getName().toUri();
553
554 m_nInterestsReceived++;
555 m_trafficPatterns[patternId].m_nInterestsReceived++;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100556 if (!m_trafficPatterns[patternId].m_expectedContent.empty())
jeraldabraham473ef3d2014-03-06 12:40:35 -0700557 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700558 std::string receivedContent = reinterpret_cast<const char*>(data.getContent().value());
559 int receivedContentLength = data.getContent().value_size();
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700560 receivedContent = receivedContent.substr(0, receivedContentLength);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700561 if (receivedContent != m_trafficPatterns[patternId].m_expectedContent)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700562 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700563 m_nContentInconsistencies++;
564 m_trafficPatterns[patternId].m_nContentInconsistencies++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700565 logLine += ", IsConsistent=No";
566 }
567 else
568 logLine += ", IsConsistent=Yes";
jeraldabraham473ef3d2014-03-06 12:40:35 -0700569 }
jeraldabraham473ef3d2014-03-06 12:40:35 -0700570 else
571 logLine += ", IsConsistent=NotChecked";
jeraldabraham420dbf02014-04-25 22:58:31 -0700572 if (!m_hasQuietLogging)
573 m_logger.log(logLine, true, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700574 double roundTripTime = (time::steady_clock::now() - sentTime).count() / 1000000.0;
575 if (m_minimumInterestRoundTripTime > roundTripTime)
576 m_minimumInterestRoundTripTime = roundTripTime;
577 if (m_maximumInterestRoundTripTime < roundTripTime)
578 m_maximumInterestRoundTripTime = roundTripTime;
579 if (m_trafficPatterns[patternId].m_minimumInterestRoundTripTime > roundTripTime)
580 m_trafficPatterns[patternId].m_minimumInterestRoundTripTime = roundTripTime;
581 if (m_trafficPatterns[patternId].m_maximumInterestRoundTripTime < roundTripTime)
582 m_trafficPatterns[patternId].m_maximumInterestRoundTripTime = roundTripTime;
583 m_totalInterestRoundTripTime += roundTripTime;
584 m_trafficPatterns[patternId].m_totalInterestRoundTripTime += roundTripTime;
jeraldabrahamdbfee2e2014-04-04 01:18:14 -0700585 if (m_nMaximumInterests >= 0 && globalReference == m_nMaximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800586 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700587 logStatistics();
588 m_logger.shutdownLogger();
589 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300590 m_ioService.stop();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700591 }
592 }
593
594 void
Eric Newberry976c2042016-06-19 23:37:35 -0700595 onNack(const ndn::Interest& interest,
596 const ndn::lp::Nack& nack,
597 int globalReference,
598 int localReference,
599 int patternId)
600 {
601 std::string logLine = "Interest Nack'd - PatternType=" + to_string(patternId + 1);
602 logLine += ", GlobalID=" + to_string(globalReference);
603 logLine += ", LocalID=" + to_string(localReference);
604 logLine += ", Name=" + interest.getName().toUri();
605 logLine += ", NackReason=" + to_string((int)nack.getReason());
606 m_logger.log(logLine, true, false);
607
608 m_nNacks++;
609 m_trafficPatterns[patternId].m_nNacks++;
610
611 if (m_nMaximumInterests >= 0 && globalReference == m_nMaximumInterests) {
612 logStatistics();
613 m_logger.shutdownLogger();
614 m_face.shutdown();
615 m_ioService.stop();
616 }
617 }
618
619 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700620 onTimeout(const ndn::Interest& interest,
621 int globalReference,
622 int localReference,
623 int patternId)
624 {
Spencer Lee8e990232015-11-27 03:54:39 -0700625 std::string logLine = "Interest Timed Out - PatternType=" + to_string(patternId + 1);
626 logLine += ", GlobalID=" + to_string(globalReference);
627 logLine += ", LocalID=" + to_string(localReference);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700628 logLine += ", Name=" + interest.getName().toUri();
629 m_logger.log(logLine, true, false);
jeraldabrahamdbfee2e2014-04-04 01:18:14 -0700630 if (m_nMaximumInterests >= 0 && globalReference == m_nMaximumInterests)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700631 {
632 logStatistics();
633 m_logger.shutdownLogger();
634 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300635 m_ioService.stop();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700636 }
637 }
638
639 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100640 generateTraffic(boost::asio::deadline_timer* timer)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700641 {
642 if (m_nMaximumInterests < 0 || m_nInterestsSent < m_nMaximumInterests)
643 {
644 int trafficKey = std::rand() % 100;
645 int cumulativePercentage = 0;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100646 std::size_t patternId;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700647 for (patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800648 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700649 cumulativePercentage += m_trafficPatterns[patternId].m_trafficPercentage;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800650 if (trafficKey <= cumulativePercentage)
651 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700652 Name interestName(m_trafficPatterns[patternId].m_name);
653 if (m_trafficPatterns[patternId].m_nameAppendBytes > 0)
654 interestName.append(
Eric Newberry3b284192015-07-06 21:44:46 -0700655 generateRandomNameComponent(m_trafficPatterns[patternId].m_nameAppendBytes));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700656 if (m_trafficPatterns[patternId].m_nameAppendSequenceNumber >= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800657 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700658 interestName.append(
Spencer Lee8e990232015-11-27 03:54:39 -0700659 to_string(m_trafficPatterns[patternId].m_nameAppendSequenceNumber));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700660 m_trafficPatterns[patternId].m_nameAppendSequenceNumber++;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800661 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100662
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800663 Interest interest(interestName);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700664 if (m_trafficPatterns[patternId].m_minSuffixComponents >= 0)
665 interest.setMinSuffixComponents(
666 m_trafficPatterns[patternId].m_minSuffixComponents);
667 if (m_trafficPatterns[patternId].m_maxSuffixComponents >= 0)
668 interest.setMaxSuffixComponents(
669 m_trafficPatterns[patternId].m_maxSuffixComponents);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100670
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800671 Exclude exclude;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100672 if (!m_trafficPatterns[patternId].m_excludeBefore.empty() &&
673 !m_trafficPatterns[patternId].m_excludeAfter.empty())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800674 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700675 exclude.excludeRange(
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700676 name::Component(
677 m_trafficPatterns[patternId].m_excludeAfter),
678 name::Component(m_trafficPatterns[patternId].m_excludeBefore));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800679 interest.setExclude(exclude);
680 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100681 else if (!m_trafficPatterns[patternId].m_excludeBefore.empty())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800682 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700683 exclude.excludeBefore(
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700684 name::Component(m_trafficPatterns[patternId].m_excludeBefore));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800685 interest.setExclude(exclude);
686 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100687 else if (!m_trafficPatterns[patternId].m_excludeAfter.empty())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800688 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700689 exclude.excludeAfter(
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700690 name::Component(m_trafficPatterns[patternId].m_excludeAfter));
691 interest.setExclude(exclude);
692 }
693 if (m_trafficPatterns[patternId].m_excludeBeforeBytes > 0 &&
694 m_trafficPatterns[patternId].m_excludeAfterBytes > 0)
695 {
696 exclude.excludeRange(
Eric Newberry3b284192015-07-06 21:44:46 -0700697 generateRandomNameComponent(
698 m_trafficPatterns[patternId].m_excludeAfterBytes),
699 generateRandomNameComponent(
700 m_trafficPatterns[patternId].m_excludeBeforeBytes));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700701 interest.setExclude(exclude);
702 }
703 else if (m_trafficPatterns[patternId].m_excludeBeforeBytes > 0)
704 {
705 exclude.excludeBefore(
Eric Newberry3b284192015-07-06 21:44:46 -0700706 generateRandomNameComponent(
707 m_trafficPatterns[patternId].m_excludeBeforeBytes));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700708 interest.setExclude(exclude);
709 }
710 else if (m_trafficPatterns[patternId].m_excludeAfterBytes > 0)
711 {
712 exclude.excludeAfter(
Eric Newberry3b284192015-07-06 21:44:46 -0700713 generateRandomNameComponent(
714 m_trafficPatterns[patternId].m_excludeAfterBytes));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800715 interest.setExclude(exclude);
716 }
717
Eric Newberry25e9ba02016-08-02 22:02:22 -0700718 if (!m_trafficPatterns[patternId].m_excludeRange.empty()) {
719 auto& range = m_trafficPatterns[patternId].m_excludeRange;
720
721 if (range.find(",") != std::string::npos) {
722 std::string after = range.substr(0, range.find(","));
723 std::string before = range.substr(range.find(",") + 1, std::string::npos);
724 exclude.clear();
725 exclude.excludeRange(name::Component::fromEscapedString(after),
726 name::Component::fromEscapedString(before));
727 interest.setExclude(exclude);
728 }
729 }
730
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700731 if (m_trafficPatterns[patternId].m_childSelector >= 0)
732 interest.setChildSelector(m_trafficPatterns[patternId].m_childSelector);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800733
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700734 if (m_trafficPatterns[patternId].m_mustBeFresh == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800735 interest.setMustBeFresh(false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700736 else if (m_trafficPatterns[patternId].m_mustBeFresh > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800737 interest.setMustBeFresh(true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700738 if (m_trafficPatterns[patternId].m_nonceDuplicationPercentage > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800739 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700740 int duplicationPercentage = std::rand() % 100;
741 if (m_trafficPatterns[patternId].m_nonceDuplicationPercentage <=
742 duplicationPercentage)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800743 interest.setNonce(getOldNonce());
744 else
745 interest.setNonce(getNewNonce());
746 }
747 else
748 interest.setNonce(getNewNonce());
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700749 if (m_trafficPatterns[patternId].m_interestLifetime >= time::milliseconds(0))
750 interest.setInterestLifetime(m_trafficPatterns[patternId].m_interestLifetime);
751
Eric Newberryeab462b2016-03-18 11:56:31 -0700752 if (m_trafficPatterns[patternId].m_nextHopFaceId > 0) {
753 interest.setTag(make_shared<lp::NextHopFaceIdTag>(
754 m_trafficPatterns[patternId].m_nextHopFaceId));
755 }
756
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800757 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700758 m_nInterestsSent++;
759 m_trafficPatterns[patternId].m_nInterestsSent++;
760 time::steady_clock::TimePoint sentTime = time::steady_clock::now();
761 m_face.expressInterest(interest,
762 bind(&NdnTrafficClient::onData,
763 this, _1, _2, m_nInterestsSent,
764 m_trafficPatterns[patternId].m_nInterestsSent,
765 patternId, sentTime),
Eric Newberry976c2042016-06-19 23:37:35 -0700766 bind(&NdnTrafficClient::onNack,
767 this, _1, _2, m_nInterestsSent,
768 m_trafficPatterns[patternId].m_nInterestsSent,
769 patternId),
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700770 bind(&NdnTrafficClient::onTimeout,
771 this, _1, m_nInterestsSent,
772 m_trafficPatterns[patternId].m_nInterestsSent,
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700773 patternId));
Davide Pesaventod0b59982015-02-27 19:15:15 +0100774
775 if (!m_hasQuietLogging) {
776 std::string logLine =
Spencer Lee8e990232015-11-27 03:54:39 -0700777 "Sending Interest - PatternType=" + to_string(patternId + 1) +
778 ", GlobalID=" + to_string(m_nInterestsSent) +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100779 ", LocalID=" +
Spencer Lee8e990232015-11-27 03:54:39 -0700780 to_string(m_trafficPatterns[patternId].m_nInterestsSent) +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100781 ", Name=" + interest.getName().toUri();
jeraldabraham420dbf02014-04-25 22:58:31 -0700782 m_logger.log(logLine, true, false);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100783 }
784
785 timer->expires_at(timer->expires_at() +
786 boost::posix_time::millisec(m_interestInterval.count()));
787 timer->async_wait(bind(&NdnTrafficClient::generateTraffic, this, timer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800788 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100789 catch (const std::exception& e) {
790 m_logger.log("ERROR: " + std::string(e.what()), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800791 }
792 break;
793 }
794 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700795 if (patternId == m_trafficPatterns.size())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800796 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100797 timer->expires_at(timer->expires_at() +
798 boost::posix_time::millisec(m_interestInterval.count()));
799 timer->async_wait(bind(&NdnTrafficClient::generateTraffic, this, timer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800800 }
801 }
802 }
803
804 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700805 run()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800806 {
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300807 boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700808 signalSet.async_wait(bind(&NdnTrafficClient::signalHandler, this));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700809 m_logger.initializeLog(m_instanceId);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800810 initializeTrafficConfiguration();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700811
812 if (m_nMaximumInterests == 0)
813 {
814 logStatistics();
815 m_logger.shutdownLogger();
816 return;
817 }
818
Davide Pesaventod0b59982015-02-27 19:15:15 +0100819 boost::asio::deadline_timer deadlineTimer(m_ioService,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700820 boost::posix_time::millisec(m_interestInterval.count()));
Davide Pesaventod0b59982015-02-27 19:15:15 +0100821 deadlineTimer.async_wait(bind(&NdnTrafficClient::generateTraffic, this, &deadlineTimer));
822
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800823 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700824 m_face.processEvents();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800825 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100826 catch (const std::exception& e) {
827 m_logger.log("ERROR: " + std::string(e.what()), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800828 m_logger.shutdownLogger();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700829 m_hasError = true;
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300830 m_ioService.stop();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800831 }
832 }
833
834private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700835 std::string m_programName;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700836 Logger m_logger;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700837 std::string m_instanceId;
838 bool m_hasError;
jeraldabraham420dbf02014-04-25 22:58:31 -0700839 bool m_hasQuietLogging;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700840 time::milliseconds m_interestInterval;
841 int m_nMaximumInterests;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700842 std::string m_configurationFile;
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300843 boost::asio::io_service m_ioService;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700844 Face m_face;
845 std::vector<InterestTrafficConfiguration> m_trafficPatterns;
846 std::vector<uint32_t> m_nonces;
847 int m_nInterestsSent;
848 int m_nInterestsReceived;
Eric Newberry976c2042016-06-19 23:37:35 -0700849 int m_nNacks;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700850 int m_nContentInconsistencies;
851
852 //round trip time is stored as milliseconds with fractional
853 //sub-milliseconds precision
854 double m_minimumInterestRoundTripTime;
855 double m_maximumInterestRoundTripTime;
856 double m_totalInterestRoundTripTime;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800857};
858
859} // namespace ndn
860
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700861int
862main(int argc, char* argv[])
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800863{
Davide Pesaventod0b59982015-02-27 19:15:15 +0100864 std::srand(std::time(nullptr));
865
866 ndn::NdnTrafficClient client(argv[0]);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700867 int option;
jeraldabraham420dbf02014-04-25 22:58:31 -0700868 while ((option = getopt(argc, argv, "hqi:c:")) != -1) {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800869 switch (option) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700870 case 'h':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100871 client.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800872 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700873 case 'i':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100874 client.setInterestInterval(atoi(optarg));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800875 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700876 case 'c':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100877 client.setMaximumInterests(atoi(optarg));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800878 break;
jeraldabraham420dbf02014-04-25 22:58:31 -0700879 case 'q':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100880 client.setQuietLogging();
jeraldabraham420dbf02014-04-25 22:58:31 -0700881 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700882 default:
Davide Pesaventod0b59982015-02-27 19:15:15 +0100883 client.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800884 break;
885 }
886 }
887
888 argc -= optind;
889 argv += optind;
890
Davide Pesaventod0b59982015-02-27 19:15:15 +0100891 if (!argc)
892 client.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800893
Davide Pesaventod0b59982015-02-27 19:15:15 +0100894 client.setConfigurationFile(argv[0]);
895 client.run();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800896
Davide Pesaventod0b59982015-02-27 19:15:15 +0100897 return client.hasError() ? EXIT_FAILURE : EXIT_SUCCESS;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800898}