blob: 062b54dd7f2d0253bff5b47f0adcbb65bc446c9f [file] [log] [blame]
Davide Pesavento912d2e82019-01-10 17:04:31 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014-2019, Arizona Board of Regents.
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 Pesavento912d2e82019-01-10 17:04:31 -050021#include "logger.hpp"
22
Davide Pesaventod0b59982015-02-27 19:15:15 +010023#include <cctype>
Davide Pesaventod0b59982015-02-27 19:15:15 +010024#include <unistd.h>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080025#include <vector>
26
Davide Pesavento912d2e82019-01-10 17:04:31 -050027#include <boost/asio/deadline_timer.hpp>
28#include <boost/asio/io_service.hpp>
29#include <boost/asio/signal_set.hpp>
jeraldabraham420dbf02014-04-25 22:58:31 -070030#include <boost/date_time/posix_time/posix_time.hpp>
Davide Pesavento912d2e82019-01-10 17:04:31 -050031#include <boost/lexical_cast.hpp>
jeraldabraham420dbf02014-04-25 22:58:31 -070032#include <boost/noncopyable.hpp>
33
jeraldabraham420dbf02014-04-25 22:58:31 -070034#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 -080039namespace ndn {
40
jeraldabraham420dbf02014-04-25 22:58:31 -070041class NdnTrafficClient : boost::noncopyable
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080042{
43public:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070044 explicit
Davide Pesaventod0b59982015-02-27 19:15:15 +010045 NdnTrafficClient(const char* programName)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070046 : m_programName(programName)
47 , m_logger("NdnTrafficClient")
Spencer Lee8e990232015-11-27 03:54:39 -070048 , m_instanceId(to_string(std::rand()))
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070049 , m_hasError(false)
jeraldabraham420dbf02014-04-25 22:58:31 -070050 , m_hasQuietLogging(false)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070051 , m_interestInterval(getDefaultInterestInterval())
52 , m_nMaximumInterests(-1)
Alexander Afanasyev740812e2014-10-30 15:37:45 -070053 , m_face(m_ioService)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070054 , m_nInterestsSent(0)
55 , m_nInterestsReceived(0)
Eric Newberry976c2042016-06-19 23:37:35 -070056 , m_nNacks(0)
jeraldabrahamdbfee2e2014-04-04 01:18:14 -070057 , m_nContentInconsistencies(0)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070058 , m_minimumInterestRoundTripTime(std::numeric_limits<double>::max())
59 , m_maximumInterestRoundTripTime(0)
60 , m_totalInterestRoundTripTime(0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080061 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080062 }
63
64 class InterestTrafficConfiguration
65 {
66 public:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080067 InterestTrafficConfiguration()
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070068 : m_trafficPercentage(-1)
69 , m_nameAppendBytes(-1)
70 , m_nameAppendSequenceNumber(-1)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070071 , m_mustBeFresh(-1)
72 , m_nonceDuplicationPercentage(-1)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070073 , m_interestLifetime(getDefaultInterestLifetime())
Eric Newberryeab462b2016-03-18 11:56:31 -070074 , m_nextHopFaceId(0)
jeraldabrahamdbfee2e2014-04-04 01:18:14 -070075 , m_nInterestsSent(0)
76 , m_nInterestsReceived(0)
Eric Newberry976c2042016-06-19 23:37:35 -070077 , m_nNacks(0)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070078 , m_minimumInterestRoundTripTime(std::numeric_limits<double>::max())
79 , m_maximumInterestRoundTripTime(0)
80 , m_totalInterestRoundTripTime(0)
81 , m_nContentInconsistencies(0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080082 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070083 }
84
Davide Pesaventod0b59982015-02-27 19:15:15 +010085 static time::milliseconds
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070086 getDefaultInterestLifetime()
87 {
Davide Pesavento912d2e82019-01-10 17:04:31 -050088 return -1_ms;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080089 }
90
91 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070092 printTrafficConfiguration(Logger& logger)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080093 {
Davide Pesaventod0b59982015-02-27 19:15:15 +010094 std::string detail;
95
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070096 if (m_trafficPercentage > 0)
Spencer Lee8e990232015-11-27 03:54:39 -070097 detail += "TrafficPercentage=" + to_string(m_trafficPercentage) + ", ";
Davide Pesaventod0b59982015-02-27 19:15:15 +010098 if (!m_name.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070099 detail += "Name=" + m_name + ", ";
100 if (m_nameAppendBytes > 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700101 detail += "NameAppendBytes=" + to_string(m_nameAppendBytes) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700102 if (m_nameAppendSequenceNumber > 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700103 detail += "NameAppendSequenceNumber=" + to_string(m_nameAppendSequenceNumber) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700104 if (m_mustBeFresh >= 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700105 detail += "MustBeFresh=" + to_string(m_mustBeFresh) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700106 if (m_nonceDuplicationPercentage > 0)
Spencer Lee8e990232015-11-27 03:54:39 -0700107 detail += "NonceDuplicationPercentage=" + to_string(m_nonceDuplicationPercentage) + ", ";
Davide Pesavento912d2e82019-01-10 17:04:31 -0500108 if (m_interestLifetime >= 0_ms)
Spencer Lee8e990232015-11-27 03:54:39 -0700109 detail += "InterestLifetime=" + to_string(m_interestLifetime.count()) + ", ";
Eric Newberryeab462b2016-03-18 11:56:31 -0700110 if (m_nextHopFaceId > 0)
111 detail += "NextHopFaceId=" + to_string(m_nextHopFaceId) + ", ";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100112 if (!m_expectedContent.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700113 detail += "ExpectedContent=" + m_expectedContent + ", ";
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800114 if (detail.length() >= 2)
Davide Pesaventod0b59982015-02-27 19:15:15 +0100115 detail = detail.substr(0, detail.length() - 2); // Removing suffix ", "
116
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800117 logger.log(detail, false, false);
118 }
119
120 bool
Davide Pesaventod0b59982015-02-27 19:15:15 +0100121 extractParameterValue(const std::string& detail, std::string& parameter, std::string& value)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800122 {
Eric Newberry25e9ba02016-08-02 22:02:22 -0700123 std::string allowedCharacters = ":/+.,_-%";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100124 std::size_t i = 0;
125
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800126 parameter = "";
127 value = "";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100128 while (detail[i] != '=' && i < detail.length()) {
129 parameter += detail[i];
130 i++;
131 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800132 if (i == detail.length())
133 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100134
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800135 i++;
jeraldabraham79c0c232014-03-31 21:43:59 -0700136 while ((std::isalnum(detail[i]) ||
Davide Pesaventod0b59982015-02-27 19:15:15 +0100137 allowedCharacters.find(detail[i]) != std::string::npos) &&
138 i < detail.length()) {
139 value += detail[i];
140 i++;
141 }
142
143 if (parameter.empty() || value.empty())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800144 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100145 else
146 return true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800147 }
148
149 bool
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700150 processConfigurationDetail(const std::string& detail, Logger& logger, int lineNumber)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800151 {
152 std::string parameter, value;
153 if (extractParameterValue(detail, parameter, value))
154 {
155 if (parameter == "TrafficPercentage")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100156 m_trafficPercentage = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800157 else if (parameter == "Name")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700158 m_name = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800159 else if (parameter == "NameAppendBytes")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100160 m_nameAppendBytes = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800161 else if (parameter == "NameAppendSequenceNumber")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100162 m_nameAppendSequenceNumber = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800163 else if (parameter == "MustBeFresh")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100164 m_mustBeFresh = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800165 else if (parameter == "NonceDuplicationPercentage")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100166 m_nonceDuplicationPercentage = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800167 else if (parameter == "InterestLifetime")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100168 m_interestLifetime = time::milliseconds(std::stoi(value));
Eric Newberryeab462b2016-03-18 11:56:31 -0700169 else if (parameter == "NextHopFaceId")
170 m_nextHopFaceId = std::stoi(value);
jeraldabraham473ef3d2014-03-06 12:40:35 -0700171 else if (parameter == "ExpectedContent")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700172 m_expectedContent = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800173 else
Spencer Lee8e990232015-11-27 03:54:39 -0700174 logger.log("Line " + to_string(lineNumber) +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700175 " \t- Invalid Parameter='" + parameter + "'", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800176 }
177 else
178 {
Spencer Lee8e990232015-11-27 03:54:39 -0700179 logger.log("Line " + to_string(lineNumber) +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700180 " \t- Improper Traffic Configuration Line- " + detail, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800181 return false;
182 }
183 return true;
184 }
185
186 bool
187 checkTrafficDetailCorrectness()
188 {
189 return true;
190 }
191
Davide Pesaventod0b59982015-02-27 19:15:15 +0100192 private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700193 int m_trafficPercentage;
194 std::string m_name;
195 int m_nameAppendBytes;
196 int m_nameAppendSequenceNumber;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700197 int m_mustBeFresh;
198 int m_nonceDuplicationPercentage;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700199 time::milliseconds m_interestLifetime;
Eric Newberryeab462b2016-03-18 11:56:31 -0700200 uint64_t m_nextHopFaceId;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700201 int m_nInterestsSent;
202 int m_nInterestsReceived;
Eric Newberry976c2042016-06-19 23:37:35 -0700203 int m_nNacks;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700204
205 //round trip time is stored as milliseconds with fractional
206 //sub-millisecond precision
207 double m_minimumInterestRoundTripTime;
208 double m_maximumInterestRoundTripTime;
209 double m_totalInterestRoundTripTime;
210
211 int m_nContentInconsistencies;
212 std::string m_expectedContent;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100213
214 friend class NdnTrafficClient;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700215 }; // class InterestTrafficConfiguration
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800216
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700217 bool
218 hasError() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800219 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700220 return m_hasError;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800221 }
222
223 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100224 usage() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800225 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100226 std::cout << "Usage:\n"
227 << " " << m_programName << " [options] <Traffic_Configuration_File>\n"
228 << "\n"
229 << "Generate Interest traffic as per provided Traffic Configuration File.\n"
230 << "Interests are continuously generated unless a total number is specified.\n"
231 << "Set environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
232 << "\n"
233 << "Options:\n"
234 << " [-i interval] - set interest generation interval in milliseconds (default "
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700235 << getDefaultInterestInterval() << ")\n"
Davide Pesaventod0b59982015-02-27 19:15:15 +0100236 << " [-c count] - set total number of interests to be generated\n"
237 << " [-q] - quiet mode: no interest reception/data generation logging\n"
238 << " [-h] - print this help text and exit\n";
239 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800240 }
241
Davide Pesaventod0b59982015-02-27 19:15:15 +0100242 static time::milliseconds
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800243 getDefaultInterestInterval()
244 {
Davide Pesavento912d2e82019-01-10 17:04:31 -0500245 return 1_s;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800246 }
247
248 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700249 setInterestInterval(int interestInterval)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800250 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700251 if (interestInterval <= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800252 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700253 m_interestInterval = time::milliseconds(interestInterval);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800254 }
255
256 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700257 setMaximumInterests(int maximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800258 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700259 if (maximumInterests <= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800260 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700261 m_nMaximumInterests = maximumInterests;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800262 }
263
264 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700265 setConfigurationFile(char* configurationFile)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800266 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700267 m_configurationFile = configurationFile;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800268 }
269
270 void
jeraldabraham420dbf02014-04-25 22:58:31 -0700271 setQuietLogging()
272 {
273 m_hasQuietLogging = true;
274 }
275
276 void
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800277 signalHandler()
278 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800279 logStatistics();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100280
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700281 m_logger.shutdownLogger();
282 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300283 m_ioService.stop();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100284
285 exit(m_hasError ? EXIT_FAILURE : EXIT_SUCCESS);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800286 }
287
288 void
289 logStatistics()
290 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800291 m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700292 m_logger.log("Total Traffic Pattern Types = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700293 to_string(m_trafficPatterns.size()), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700294 m_logger.log("Total Interests Sent = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700295 to_string(m_nInterestsSent), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700296 m_logger.log("Total Responses Received = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700297 to_string(m_nInterestsReceived), false, true);
Eric Newberry976c2042016-06-19 23:37:35 -0700298 m_logger.log("Total Nacks Received = " +
299 to_string(m_nNacks), false, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100300
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700301 double loss = 0;
302 if (m_nInterestsSent > 0)
303 loss = (m_nInterestsSent - m_nInterestsReceived) * 100.0 / m_nInterestsSent;
Spencer Lee8e990232015-11-27 03:54:39 -0700304 m_logger.log("Total Interest Loss = " + to_string(loss) + "%", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700305 if (m_nContentInconsistencies != 0 || m_nInterestsSent != m_nInterestsReceived)
306 m_hasError = true;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100307
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700308 double average = 0;
309 double inconsistency = 0;
310 if (m_nInterestsReceived > 0)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700311 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700312 average = m_totalInterestRoundTripTime / m_nInterestsReceived;
313 inconsistency = m_nContentInconsistencies * 100.0 / m_nInterestsReceived;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700314 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700315 m_logger.log("Total Data Inconsistency = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700316 to_string(inconsistency) + "%", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700317 m_logger.log("Total Round Trip Time = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700318 to_string(m_totalInterestRoundTripTime) + "ms", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700319 m_logger.log("Average Round Trip Time = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700320 to_string(average) + "ms\n", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700321
Davide Pesaventod0b59982015-02-27 19:15:15 +0100322 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700323 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700324 m_logger.log("Traffic Pattern Type #" +
Spencer Lee8e990232015-11-27 03:54:39 -0700325 to_string(patternId + 1), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700326 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
327 m_logger.log("Total Interests Sent = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700328 to_string(m_trafficPatterns[patternId].m_nInterestsSent), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700329 m_logger.log("Total Responses Received = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700330 to_string(m_trafficPatterns[patternId].m_nInterestsReceived), false, true);
Eric Newberry976c2042016-06-19 23:37:35 -0700331 m_logger.log("Total Nacks Received = " +
332 to_string(m_trafficPatterns[patternId].m_nNacks), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700333 loss = 0;
334 if (m_trafficPatterns[patternId].m_nInterestsSent > 0)
335 {
336 loss = (m_trafficPatterns[patternId].m_nInterestsSent -
337 m_trafficPatterns[patternId].m_nInterestsReceived);
338 loss *= 100.0;
339 loss /= m_trafficPatterns[patternId].m_nInterestsSent;
340 }
Spencer Lee8e990232015-11-27 03:54:39 -0700341 m_logger.log("Total Interest Loss = " + to_string(loss) + "%", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700342 average = 0;
343 inconsistency = 0;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700344 if (m_trafficPatterns[patternId].m_nInterestsReceived > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800345 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700346 average = (m_trafficPatterns[patternId].m_totalInterestRoundTripTime /
347 m_trafficPatterns[patternId].m_nInterestsReceived);
348 inconsistency = m_trafficPatterns[patternId].m_nContentInconsistencies;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100349 inconsistency *= 100.0 / m_trafficPatterns[patternId].m_nInterestsReceived;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800350 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700351 m_logger.log("Total Data Inconsistency = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700352 to_string(inconsistency) + "%", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700353 m_logger.log("Total Round Trip Time = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700354 to_string(m_trafficPatterns[patternId].m_totalInterestRoundTripTime) +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100355 "ms", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700356 m_logger.log("Average Round Trip Time = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700357 to_string(average) + "ms\n", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800358 }
359 }
360
361 bool
362 checkTrafficPatternCorrectness()
363 {
364 return true;
365 }
366
367 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700368 parseConfigurationFile()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800369 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800370 std::string patternLine;
371 std::ifstream patternFile;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700372 m_logger.log("Analyzing Traffic Configuration File: " + m_configurationFile, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100373
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700374 patternFile.open(m_configurationFile.c_str());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800375 if (patternFile.is_open())
376 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700377 int lineNumber = 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800378 while (getline(patternFile, patternLine))
379 {
380 lineNumber++;
381 if (std::isalpha(patternLine[0]))
382 {
383 InterestTrafficConfiguration interestData;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700384 bool shouldSkipLine = false;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800385 if (interestData.processConfigurationDetail(patternLine, m_logger, lineNumber))
386 {
387 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
388 {
389 lineNumber++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700390 if (!interestData.processConfigurationDetail(patternLine,
391 m_logger, lineNumber))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800392 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700393 shouldSkipLine = true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800394 break;
395 }
396 }
397 lineNumber++;
398 }
399 else
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700400 shouldSkipLine = true;
401 if (!shouldSkipLine)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800402 {
403 if (interestData.checkTrafficDetailCorrectness())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700404 m_trafficPatterns.push_back(interestData);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800405 }
406 }
407 }
408 patternFile.close();
409 if (!checkTrafficPatternCorrectness())
410 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700411 m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper- " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700412 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800413 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100414 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800415 }
416 m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100417 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800418 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700419 m_logger.log("Traffic Pattern Type #" +
Spencer Lee8e990232015-11-27 03:54:39 -0700420 to_string(patternId + 1), false, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700421 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800422 m_logger.log("", false, false);
423 }
424 }
425 else
426 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700427 m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700428 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800429 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100430 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800431 }
432 }
433
434 void
435 initializeTrafficConfiguration()
436 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700437 if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800438 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700439 if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800440 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700441 parseConfigurationFile();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800442 }
443 else
444 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700445 m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700446 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800447 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100448 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800449 }
450 }
451 else
452 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700453 m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700454 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800455 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100456 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800457 }
458 }
459
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700460 uint32_t
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800461 getOldNonce()
462 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700463 if (m_nonces.size() == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800464 return getNewNonce();
Davide Pesavento912d2e82019-01-10 17:04:31 -0500465 std::size_t randomNonceIndex = std::rand() % m_nonces.size();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700466 return m_nonces[randomNonceIndex];
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800467 }
468
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700469 uint32_t
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800470 getNewNonce()
471 {
jeraldabraham473ef3d2014-03-06 12:40:35 -0700472 //Performance Enhancement
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700473 if (m_nonces.size() > 1000)
474 m_nonces.clear();
jeraldabraham473ef3d2014-03-06 12:40:35 -0700475
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700476 uint32_t randomNonce = static_cast<uint32_t>(std::rand());
477 while (std::find(m_nonces.begin(), m_nonces.end(), randomNonce) != m_nonces.end())
478 randomNonce = static_cast<uint32_t>(std::rand());
479
480 m_nonces.push_back(randomNonce);
481 return randomNonce;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800482 }
483
Eric Newberry3b284192015-07-06 21:44:46 -0700484 static name::Component
Davide Pesavento912d2e82019-01-10 17:04:31 -0500485 generateRandomNameComponent(std::size_t length)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800486 {
Eric Newberry3b284192015-07-06 21:44:46 -0700487 Buffer buffer(length);
Davide Pesavento912d2e82019-01-10 17:04:31 -0500488 for (std::size_t i = 0; i < length; i++) {
Eric Newberry3b284192015-07-06 21:44:46 -0700489 buffer[i] = static_cast<uint8_t>(std::rand() % 256);
490 }
491 return name::Component(buffer);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800492 }
493
494 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700495 onData(const ndn::Interest& interest,
Eric Newberry976c2042016-06-19 23:37:35 -0700496 const ndn::Data& data,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700497 int globalReference,
498 int localReference,
Davide Pesavento912d2e82019-01-10 17:04:31 -0500499 std::size_t patternId,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700500 time::steady_clock::TimePoint sentTime)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800501 {
Spencer Lee8e990232015-11-27 03:54:39 -0700502 std::string logLine = "Data Received - PatternType=" + to_string(patternId + 1);
503 logLine += ", GlobalID=" + to_string(globalReference);
504 logLine += ", LocalID=" + to_string(localReference);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700505 logLine += ", Name=" + interest.getName().toUri();
506
507 m_nInterestsReceived++;
508 m_trafficPatterns[patternId].m_nInterestsReceived++;
Davide Pesavento912d2e82019-01-10 17:04:31 -0500509 if (!m_trafficPatterns[patternId].m_expectedContent.empty()) {
510 std::string receivedContent = reinterpret_cast<const char*>(data.getContent().value());
511 std::size_t receivedContentLength = data.getContent().value_size();
512 receivedContent = receivedContent.substr(0, receivedContentLength);
513 if (receivedContent != m_trafficPatterns[patternId].m_expectedContent) {
514 m_nContentInconsistencies++;
515 m_trafficPatterns[patternId].m_nContentInconsistencies++;
516 logLine += ", IsConsistent=No";
jeraldabraham473ef3d2014-03-06 12:40:35 -0700517 }
Davide Pesavento912d2e82019-01-10 17:04:31 -0500518 else
519 logLine += ", IsConsistent=Yes";
520 }
jeraldabraham473ef3d2014-03-06 12:40:35 -0700521 else
522 logLine += ", IsConsistent=NotChecked";
jeraldabraham420dbf02014-04-25 22:58:31 -0700523 if (!m_hasQuietLogging)
524 m_logger.log(logLine, true, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700525 double roundTripTime = (time::steady_clock::now() - sentTime).count() / 1000000.0;
526 if (m_minimumInterestRoundTripTime > roundTripTime)
527 m_minimumInterestRoundTripTime = roundTripTime;
528 if (m_maximumInterestRoundTripTime < roundTripTime)
529 m_maximumInterestRoundTripTime = roundTripTime;
530 if (m_trafficPatterns[patternId].m_minimumInterestRoundTripTime > roundTripTime)
531 m_trafficPatterns[patternId].m_minimumInterestRoundTripTime = roundTripTime;
532 if (m_trafficPatterns[patternId].m_maximumInterestRoundTripTime < roundTripTime)
533 m_trafficPatterns[patternId].m_maximumInterestRoundTripTime = roundTripTime;
534 m_totalInterestRoundTripTime += roundTripTime;
535 m_trafficPatterns[patternId].m_totalInterestRoundTripTime += roundTripTime;
Davide Pesavento912d2e82019-01-10 17:04:31 -0500536 if (m_nMaximumInterests >= 0 && globalReference == m_nMaximumInterests) {
537 logStatistics();
538 m_logger.shutdownLogger();
539 m_face.shutdown();
540 m_ioService.stop();
541 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700542 }
543
544 void
Eric Newberry976c2042016-06-19 23:37:35 -0700545 onNack(const ndn::Interest& interest,
546 const ndn::lp::Nack& nack,
547 int globalReference,
548 int localReference,
Davide Pesavento912d2e82019-01-10 17:04:31 -0500549 std::size_t patternId)
Eric Newberry976c2042016-06-19 23:37:35 -0700550 {
551 std::string logLine = "Interest Nack'd - PatternType=" + to_string(patternId + 1);
552 logLine += ", GlobalID=" + to_string(globalReference);
553 logLine += ", LocalID=" + to_string(localReference);
554 logLine += ", Name=" + interest.getName().toUri();
Davide Pesavento912d2e82019-01-10 17:04:31 -0500555 logLine += ", NackReason=" + boost::lexical_cast<std::string>(nack.getReason());
Eric Newberry976c2042016-06-19 23:37:35 -0700556 m_logger.log(logLine, true, false);
557
558 m_nNacks++;
559 m_trafficPatterns[patternId].m_nNacks++;
560
561 if (m_nMaximumInterests >= 0 && globalReference == m_nMaximumInterests) {
562 logStatistics();
563 m_logger.shutdownLogger();
564 m_face.shutdown();
565 m_ioService.stop();
566 }
567 }
568
569 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700570 onTimeout(const ndn::Interest& interest,
571 int globalReference,
572 int localReference,
573 int patternId)
574 {
Spencer Lee8e990232015-11-27 03:54:39 -0700575 std::string logLine = "Interest Timed Out - PatternType=" + to_string(patternId + 1);
576 logLine += ", GlobalID=" + to_string(globalReference);
577 logLine += ", LocalID=" + to_string(localReference);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700578 logLine += ", Name=" + interest.getName().toUri();
579 m_logger.log(logLine, true, false);
jeraldabrahamdbfee2e2014-04-04 01:18:14 -0700580 if (m_nMaximumInterests >= 0 && globalReference == m_nMaximumInterests)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700581 {
582 logStatistics();
583 m_logger.shutdownLogger();
584 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300585 m_ioService.stop();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700586 }
587 }
588
589 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100590 generateTraffic(boost::asio::deadline_timer* timer)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700591 {
592 if (m_nMaximumInterests < 0 || m_nInterestsSent < m_nMaximumInterests)
593 {
594 int trafficKey = std::rand() % 100;
595 int cumulativePercentage = 0;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100596 std::size_t patternId;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700597 for (patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800598 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700599 cumulativePercentage += m_trafficPatterns[patternId].m_trafficPercentage;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800600 if (trafficKey <= cumulativePercentage)
601 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700602 Name interestName(m_trafficPatterns[patternId].m_name);
603 if (m_trafficPatterns[patternId].m_nameAppendBytes > 0)
604 interestName.append(
Eric Newberry3b284192015-07-06 21:44:46 -0700605 generateRandomNameComponent(m_trafficPatterns[patternId].m_nameAppendBytes));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700606 if (m_trafficPatterns[patternId].m_nameAppendSequenceNumber >= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800607 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700608 interestName.append(
Spencer Lee8e990232015-11-27 03:54:39 -0700609 to_string(m_trafficPatterns[patternId].m_nameAppendSequenceNumber));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700610 m_trafficPatterns[patternId].m_nameAppendSequenceNumber++;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800611 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100612
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800613 Interest interest(interestName);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800614
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700615 if (m_trafficPatterns[patternId].m_mustBeFresh == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800616 interest.setMustBeFresh(false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700617 else if (m_trafficPatterns[patternId].m_mustBeFresh > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800618 interest.setMustBeFresh(true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700619 if (m_trafficPatterns[patternId].m_nonceDuplicationPercentage > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800620 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700621 int duplicationPercentage = std::rand() % 100;
622 if (m_trafficPatterns[patternId].m_nonceDuplicationPercentage <=
623 duplicationPercentage)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800624 interest.setNonce(getOldNonce());
625 else
626 interest.setNonce(getNewNonce());
627 }
628 else
629 interest.setNonce(getNewNonce());
Davide Pesavento912d2e82019-01-10 17:04:31 -0500630 if (m_trafficPatterns[patternId].m_interestLifetime >= 0_ms)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700631 interest.setInterestLifetime(m_trafficPatterns[patternId].m_interestLifetime);
632
Eric Newberryeab462b2016-03-18 11:56:31 -0700633 if (m_trafficPatterns[patternId].m_nextHopFaceId > 0) {
634 interest.setTag(make_shared<lp::NextHopFaceIdTag>(
635 m_trafficPatterns[patternId].m_nextHopFaceId));
636 }
637
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800638 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700639 m_nInterestsSent++;
640 m_trafficPatterns[patternId].m_nInterestsSent++;
Davide Pesavento912d2e82019-01-10 17:04:31 -0500641 auto sentTime = time::steady_clock::now();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700642 m_face.expressInterest(interest,
643 bind(&NdnTrafficClient::onData,
644 this, _1, _2, m_nInterestsSent,
645 m_trafficPatterns[patternId].m_nInterestsSent,
646 patternId, sentTime),
Eric Newberry976c2042016-06-19 23:37:35 -0700647 bind(&NdnTrafficClient::onNack,
648 this, _1, _2, m_nInterestsSent,
649 m_trafficPatterns[patternId].m_nInterestsSent,
650 patternId),
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700651 bind(&NdnTrafficClient::onTimeout,
652 this, _1, m_nInterestsSent,
653 m_trafficPatterns[patternId].m_nInterestsSent,
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700654 patternId));
Davide Pesaventod0b59982015-02-27 19:15:15 +0100655
656 if (!m_hasQuietLogging) {
657 std::string logLine =
Spencer Lee8e990232015-11-27 03:54:39 -0700658 "Sending Interest - PatternType=" + to_string(patternId + 1) +
659 ", GlobalID=" + to_string(m_nInterestsSent) +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100660 ", LocalID=" +
Spencer Lee8e990232015-11-27 03:54:39 -0700661 to_string(m_trafficPatterns[patternId].m_nInterestsSent) +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100662 ", Name=" + interest.getName().toUri();
jeraldabraham420dbf02014-04-25 22:58:31 -0700663 m_logger.log(logLine, true, false);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100664 }
665
666 timer->expires_at(timer->expires_at() +
667 boost::posix_time::millisec(m_interestInterval.count()));
668 timer->async_wait(bind(&NdnTrafficClient::generateTraffic, this, timer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800669 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100670 catch (const std::exception& e) {
Davide Pesavento912d2e82019-01-10 17:04:31 -0500671 m_logger.log("ERROR: "s + e.what(), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800672 }
673 break;
674 }
675 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700676 if (patternId == m_trafficPatterns.size())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800677 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100678 timer->expires_at(timer->expires_at() +
679 boost::posix_time::millisec(m_interestInterval.count()));
680 timer->async_wait(bind(&NdnTrafficClient::generateTraffic, this, timer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800681 }
682 }
683 }
684
685 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700686 run()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800687 {
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300688 boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700689 signalSet.async_wait(bind(&NdnTrafficClient::signalHandler, this));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700690 m_logger.initializeLog(m_instanceId);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800691 initializeTrafficConfiguration();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700692
Davide Pesavento912d2e82019-01-10 17:04:31 -0500693 if (m_nMaximumInterests == 0) {
694 logStatistics();
695 m_logger.shutdownLogger();
696 return;
697 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700698
Davide Pesaventod0b59982015-02-27 19:15:15 +0100699 boost::asio::deadline_timer deadlineTimer(m_ioService,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700700 boost::posix_time::millisec(m_interestInterval.count()));
Davide Pesaventod0b59982015-02-27 19:15:15 +0100701 deadlineTimer.async_wait(bind(&NdnTrafficClient::generateTraffic, this, &deadlineTimer));
702
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800703 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700704 m_face.processEvents();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800705 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100706 catch (const std::exception& e) {
Davide Pesavento912d2e82019-01-10 17:04:31 -0500707 m_logger.log("ERROR: "s + e.what(), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800708 m_logger.shutdownLogger();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700709 m_hasError = true;
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300710 m_ioService.stop();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800711 }
712 }
713
714private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700715 std::string m_programName;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700716 Logger m_logger;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700717 std::string m_instanceId;
718 bool m_hasError;
jeraldabraham420dbf02014-04-25 22:58:31 -0700719 bool m_hasQuietLogging;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700720 time::milliseconds m_interestInterval;
721 int m_nMaximumInterests;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700722 std::string m_configurationFile;
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300723 boost::asio::io_service m_ioService;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700724 Face m_face;
725 std::vector<InterestTrafficConfiguration> m_trafficPatterns;
726 std::vector<uint32_t> m_nonces;
727 int m_nInterestsSent;
728 int m_nInterestsReceived;
Eric Newberry976c2042016-06-19 23:37:35 -0700729 int m_nNacks;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700730 int m_nContentInconsistencies;
731
Davide Pesavento912d2e82019-01-10 17:04:31 -0500732 // RTT is stored as milliseconds with fractional sub-milliseconds precision
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700733 double m_minimumInterestRoundTripTime;
734 double m_maximumInterestRoundTripTime;
735 double m_totalInterestRoundTripTime;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800736};
737
738} // namespace ndn
739
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700740int
741main(int argc, char* argv[])
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800742{
Davide Pesaventod0b59982015-02-27 19:15:15 +0100743 std::srand(std::time(nullptr));
744
745 ndn::NdnTrafficClient client(argv[0]);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700746 int option;
jeraldabraham420dbf02014-04-25 22:58:31 -0700747 while ((option = getopt(argc, argv, "hqi:c:")) != -1) {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800748 switch (option) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700749 case 'h':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100750 client.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800751 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700752 case 'i':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100753 client.setInterestInterval(atoi(optarg));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800754 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700755 case 'c':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100756 client.setMaximumInterests(atoi(optarg));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800757 break;
jeraldabraham420dbf02014-04-25 22:58:31 -0700758 case 'q':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100759 client.setQuietLogging();
jeraldabraham420dbf02014-04-25 22:58:31 -0700760 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700761 default:
Davide Pesaventod0b59982015-02-27 19:15:15 +0100762 client.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800763 break;
764 }
765 }
766
767 argc -= optind;
768 argv += optind;
769
Davide Pesaventod0b59982015-02-27 19:15:15 +0100770 if (!argc)
771 client.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800772
Davide Pesaventod0b59982015-02-27 19:15:15 +0100773 client.setConfigurationFile(argv[0]);
774 client.run();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800775
Davide Pesaventod0b59982015-02-27 19:15:15 +0100776 return client.hasError() ? EXIT_FAILURE : EXIT_SUCCESS;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800777}