blob: 80a79daa10cd379ae07637d1ac4c22306d8a1e3f [file] [log] [blame]
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2014 University of Arizona.
4 *
5 * GNU 3.0 License, see the LICENSE file for more information
6 *
7 * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
8 */
9
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080010#include <fstream>
jeraldabraham420dbf02014-04-25 22:58:31 -070011#include <sstream>
12#include <string>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080013#include <vector>
14
jeraldabraham420dbf02014-04-25 22:58:31 -070015#include <boost/asio.hpp>
16#include <boost/date_time/posix_time/posix_time.hpp>
17#include <boost/filesystem.hpp>
18#include <boost/lexical_cast.hpp>
19#include <boost/noncopyable.hpp>
20
21#include <ndn-cxx/exclude.hpp>
22#include <ndn-cxx/face.hpp>
23#include <ndn-cxx/name-component.hpp>
24
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080025#include "logger.hpp"
26
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080027namespace ndn {
28
jeraldabraham420dbf02014-04-25 22:58:31 -070029class NdnTrafficClient : boost::noncopyable
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080030{
31public:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070032
33 explicit
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070034 NdnTrafficClient(char* programName)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070035 : m_programName(programName)
36 , m_logger("NdnTrafficClient")
37 , m_hasError(false)
jeraldabraham420dbf02014-04-25 22:58:31 -070038 , m_hasQuietLogging(false)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070039 , m_face(m_ioService)
40 , m_interestInterval(getDefaultInterestInterval())
41 , m_nMaximumInterests(-1)
42 , m_nInterestsSent(0)
43 , m_nInterestsReceived(0)
jeraldabrahamdbfee2e2014-04-04 01:18:14 -070044 , m_nContentInconsistencies(0)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070045 , m_minimumInterestRoundTripTime(std::numeric_limits<double>::max())
46 , m_maximumInterestRoundTripTime(0)
47 , m_totalInterestRoundTripTime(0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080048 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070049 m_instanceId = boost::lexical_cast<std::string>(std::rand());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080050 }
51
52 class InterestTrafficConfiguration
53 {
54 public:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080055 InterestTrafficConfiguration()
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070056 : m_trafficPercentage(-1)
57 , m_nameAppendBytes(-1)
58 , m_nameAppendSequenceNumber(-1)
59 , m_minSuffixComponents(-1)
60 , m_maxSuffixComponents(-1)
61 , m_excludeBeforeBytes(-1)
62 , m_excludeAfterBytes(-1)
63 , m_childSelector(-1)
64 , m_mustBeFresh(-1)
65 , m_nonceDuplicationPercentage(-1)
66 , m_scope(-1)
67 , m_interestLifetime(getDefaultInterestLifetime())
jeraldabrahamdbfee2e2014-04-04 01:18:14 -070068 , m_nInterestsSent(0)
69 , m_nInterestsReceived(0)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070070 , m_minimumInterestRoundTripTime(std::numeric_limits<double>::max())
71 , m_maximumInterestRoundTripTime(0)
72 , m_totalInterestRoundTripTime(0)
73 , m_nContentInconsistencies(0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080074 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070075 }
76
77 time::milliseconds
78 getDefaultInterestLifetime()
79 {
80 return time::milliseconds(-1);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080081 }
82
83 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070084 printTrafficConfiguration(Logger& logger)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080085 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070086 std::string detail = "";
87 if (m_trafficPercentage > 0)
88 detail += "TrafficPercentage=" +
89 boost::lexical_cast<std::string>(m_trafficPercentage) + ", ";
90 if (m_name != "")
91 detail += "Name=" + m_name + ", ";
92 if (m_nameAppendBytes > 0)
93 detail += "NameAppendBytes=" + boost::lexical_cast<std::string>(m_nameAppendBytes) + ", ";
94 if (m_nameAppendSequenceNumber > 0)
95 detail += "NameAppendSequenceNumber=" +
96 boost::lexical_cast<std::string>(m_nameAppendSequenceNumber) + ", ";
97 if (m_minSuffixComponents >= 0)
98 detail += "MinSuffixComponents=" +
99 boost::lexical_cast<std::string>(m_minSuffixComponents) + ", ";
100 if (m_maxSuffixComponents >= 0)
101 detail += "MaxSuffixComponents=" +
102 boost::lexical_cast<std::string>(m_maxSuffixComponents) + ", ";
103 if (m_excludeBefore != "")
104 detail += "ExcludeBefore=" + m_excludeBefore + ", ";
105 if (m_excludeAfter != "")
106 detail += "ExcludeAfter=" + m_excludeAfter + ", ";
107 if (m_excludeBeforeBytes > 0)
108 detail += "ExcludeBeforeBytes=" +
109 boost::lexical_cast<std::string>(m_excludeBeforeBytes) + ", ";
110 if (m_excludeAfterBytes > 0)
111 detail += "ExcludeAfterBytes=" +
112 boost::lexical_cast<std::string>(m_excludeAfterBytes) + ", ";
113 if (m_childSelector >= 0)
114 detail += "ChildSelector=" +
115 boost::lexical_cast<std::string>(m_childSelector) + ", ";
116 if (m_mustBeFresh >= 0)
117 detail += "MustBeFresh=" +
118 boost::lexical_cast<std::string>(m_mustBeFresh) + ", ";
119 if (m_nonceDuplicationPercentage > 0)
120 detail += "NonceDuplicationPercentage=" +
121 boost::lexical_cast<std::string>(m_nonceDuplicationPercentage) + ", ";
122 if (m_scope >= 0)
123 detail += "Scope="+boost::lexical_cast<std::string>(m_scope) + ", ";
124 if (m_interestLifetime >= time::milliseconds(0))
125 detail += "InterestLifetime=" +
126 boost::lexical_cast<std::string>(m_interestLifetime.count()) + ", ";
127 if (m_expectedContent != "")
128 detail += "ExpectedContent=" + m_expectedContent + ", ";
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800129 if (detail.length() >= 2)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700130 detail = detail.substr(0, detail.length() - 2); //Removing suffix ", "
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800131 logger.log(detail, false, false);
132 }
133
134 bool
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700135 extractParameterValue(const std::string& detail,
136 std::string& parameter,
137 std::string& value)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800138 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800139 std::string allowedCharacters = ":/+._-%";
140 parameter = "";
141 value = "";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700142 int i = 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800143 while (detail[i] != '=' && i < detail.length())
144 {
145 parameter += detail[i];
146 i++;
147 }
148 if (i == detail.length())
149 return false;
150 i++;
jeraldabraham79c0c232014-03-31 21:43:59 -0700151 while ((std::isalnum(detail[i]) ||
152 allowedCharacters.find(detail[i]) != std::string::npos) &&
153 i < detail.length())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800154 {
155 value += detail[i];
156 i++;
157 }
jeraldabraham79c0c232014-03-31 21:43:59 -0700158 if (parameter == "" || value == "")
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800159 return false;
160 return true;
161 }
162
163 bool
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700164 processConfigurationDetail(const std::string& detail, Logger& logger, int lineNumber)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800165 {
166 std::string parameter, value;
167 if (extractParameterValue(detail, parameter, value))
168 {
169 if (parameter == "TrafficPercentage")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700170 m_trafficPercentage = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800171 else if (parameter == "Name")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700172 m_name = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800173 else if (parameter == "NameAppendBytes")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700174 m_nameAppendBytes = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800175 else if (parameter == "NameAppendSequenceNumber")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700176 m_nameAppendSequenceNumber = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800177 else if (parameter == "MinSuffixComponents")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700178 m_minSuffixComponents = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800179 else if (parameter == "MaxSuffixComponents")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700180 m_maxSuffixComponents = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800181 else if (parameter == "ExcludeBefore")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700182 m_excludeBefore = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800183 else if (parameter == "ExcludeAfter")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700184 m_excludeAfter = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800185 else if (parameter == "ExcludeBeforeBytes")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700186 m_excludeBeforeBytes = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800187 else if (parameter == "ExcludeAfterBytes")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700188 m_excludeAfterBytes = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800189 else if (parameter == "ChildSelector")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700190 m_childSelector = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800191 else if (parameter == "MustBeFresh")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700192 m_mustBeFresh = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800193 else if (parameter == "NonceDuplicationPercentage")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700194 m_nonceDuplicationPercentage = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800195 else if (parameter == "Scope")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700196 m_scope = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800197 else if (parameter == "InterestLifetime")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700198 m_interestLifetime = time::milliseconds(boost::lexical_cast<int>(value));
jeraldabraham473ef3d2014-03-06 12:40:35 -0700199 else if (parameter == "ExpectedContent")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700200 m_expectedContent = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800201 else
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700202 logger.log("Line " + boost::lexical_cast<std::string>(lineNumber) +
203 " \t- Invalid Parameter='" + parameter + "'", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800204 }
205 else
206 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700207 logger.log("Line " + boost::lexical_cast<std::string>(lineNumber) +
208 " \t- Improper Traffic Configuration Line- " + detail, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800209 return false;
210 }
211 return true;
212 }
213
214 bool
215 checkTrafficDetailCorrectness()
216 {
217 return true;
218 }
219
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700220 int m_trafficPercentage;
221 std::string m_name;
222 int m_nameAppendBytes;
223 int m_nameAppendSequenceNumber;
224 int m_minSuffixComponents;
225 int m_maxSuffixComponents;
226 std::string m_excludeBefore;
227 std::string m_excludeAfter;
228 int m_excludeBeforeBytes;
229 int m_excludeAfterBytes;
230 int m_childSelector;
231 int m_mustBeFresh;
232 int m_nonceDuplicationPercentage;
233 int m_scope;
234 time::milliseconds m_interestLifetime;
235 int m_nInterestsSent;
236 int m_nInterestsReceived;
237
238 //round trip time is stored as milliseconds with fractional
239 //sub-millisecond precision
240 double m_minimumInterestRoundTripTime;
241 double m_maximumInterestRoundTripTime;
242 double m_totalInterestRoundTripTime;
243
244 int m_nContentInconsistencies;
245 std::string m_expectedContent;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700246 }; // class InterestTrafficConfiguration
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800247
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700248 bool
249 hasError() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800250 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700251 return m_hasError;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800252 }
253
254 void
255 usage()
256 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700257 std::cout << "\nUsage: " << m_programName << " [options] <Traffic_Configuration_File>\n"
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800258 "Generate Interest Traffic as per provided Traffic Configuration File\n"
259 "Interests are continuously generated unless a total number is specified.\n"
260 "Set environment variable NDN_TRAFFIC_LOGFOLDER for redirecting output to a log.\n"
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700261 " [-i interval] - set interest generation interval in milliseconds (default "
262 << getDefaultInterestInterval() << ")\n"
263 " [-c count] - set total number of interests to be generated\n"
jeraldabraham420dbf02014-04-25 22:58:31 -0700264 " [-q] - quiet logging - no interest generation/data reception messages\n"
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700265 " [-h] - print help and exit\n\n";
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800266 exit(1);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800267 }
268
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700269 time::milliseconds
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800270 getDefaultInterestInterval()
271 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700272 return time::milliseconds(1000);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800273 }
274
275 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700276 setInterestInterval(int interestInterval)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800277 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700278 if (interestInterval <= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800279 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700280 m_interestInterval = time::milliseconds(interestInterval);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800281 }
282
283 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700284 setMaximumInterests(int maximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800285 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700286 if (maximumInterests <= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800287 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700288 m_nMaximumInterests = maximumInterests;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800289 }
290
291 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700292 setConfigurationFile(char* configurationFile)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800293 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700294 m_configurationFile = configurationFile;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800295 }
296
297 void
jeraldabraham420dbf02014-04-25 22:58:31 -0700298 setQuietLogging()
299 {
300 m_hasQuietLogging = true;
301 }
302
303 void
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800304 signalHandler()
305 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800306 logStatistics();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700307 m_logger.shutdownLogger();
308 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300309 m_ioService.stop();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700310 if (m_hasError)
311 exit(1);
312 else
313 exit(0);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800314 }
315
316 void
317 logStatistics()
318 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800319 m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700320 m_logger.log("Total Traffic Pattern Types = " +
321 boost::lexical_cast<std::string>(static_cast<int>(m_trafficPatterns.size())), false, true);
322 m_logger.log("Total Interests Sent = " +
323 boost::lexical_cast<std::string>(m_nInterestsSent), false, true);
324 m_logger.log("Total Responses Received = " +
325 boost::lexical_cast<std::string>(m_nInterestsReceived), false, true);
326 double loss = 0;
327 if (m_nInterestsSent > 0)
328 loss = (m_nInterestsSent - m_nInterestsReceived) * 100.0 / m_nInterestsSent;
329 m_logger.log("Total Interest Loss = " +
330 boost::lexical_cast<std::string>(loss) + "%", false, true);
331 if (m_nContentInconsistencies != 0 || m_nInterestsSent != m_nInterestsReceived)
332 m_hasError = true;
333 double average = 0;
334 double inconsistency = 0;
335 if (m_nInterestsReceived > 0)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700336 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700337 average = m_totalInterestRoundTripTime / m_nInterestsReceived;
338 inconsistency = m_nContentInconsistencies * 100.0 / m_nInterestsReceived;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700339 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700340 m_logger.log("Total Data Inconsistency = " +
341 boost::lexical_cast<std::string>(inconsistency) + "%", false, true);
342 m_logger.log("Total Round Trip Time = " +
343 boost::lexical_cast<std::string>(m_totalInterestRoundTripTime) + "ms", false, true);
344 m_logger.log("Average Round Trip Time = " +
345 boost::lexical_cast<std::string>(average) + "ms\n", false, true);
346
347 for (int patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700348 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700349 m_logger.log("Traffic Pattern Type #" +
350 boost::lexical_cast<std::string>(patternId + 1), false, true);
351 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
352 m_logger.log("Total Interests Sent = " +
353 boost::lexical_cast<std::string>(
354 m_trafficPatterns[patternId].m_nInterestsSent), false, true);
355 m_logger.log("Total Responses Received = " +
356 boost::lexical_cast<std::string>(
357 m_trafficPatterns[patternId].m_nInterestsReceived), false, true);
358 loss = 0;
359 if (m_trafficPatterns[patternId].m_nInterestsSent > 0)
360 {
361 loss = (m_trafficPatterns[patternId].m_nInterestsSent -
362 m_trafficPatterns[patternId].m_nInterestsReceived);
363 loss *= 100.0;
364 loss /= m_trafficPatterns[patternId].m_nInterestsSent;
365 }
366 m_logger.log("Total Interest Loss = " +
367 boost::lexical_cast<std::string>(loss) + "%", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700368 average = 0;
369 inconsistency = 0;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700370 if (m_trafficPatterns[patternId].m_nInterestsReceived > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800371 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700372 average = (m_trafficPatterns[patternId].m_totalInterestRoundTripTime /
373 m_trafficPatterns[patternId].m_nInterestsReceived);
374 inconsistency = m_trafficPatterns[patternId].m_nContentInconsistencies;
375 inconsistency =
376 inconsistency * 100.0 / m_trafficPatterns[patternId].m_nInterestsReceived;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800377 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700378 m_logger.log("Total Data Inconsistency = " +
379 boost::lexical_cast<std::string>(inconsistency) + "%", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700380 m_logger.log("Total Round Trip Time = " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700381 boost::lexical_cast<std::string>(
382 m_trafficPatterns[patternId].m_totalInterestRoundTripTime) + "ms", false, true);
383 m_logger.log("Average Round Trip Time = " +
384 boost::lexical_cast<std::string>(average) + "ms\n", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800385 }
386 }
387
388 bool
389 checkTrafficPatternCorrectness()
390 {
391 return true;
392 }
393
394 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700395 parseConfigurationFile()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800396 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800397 std::string patternLine;
398 std::ifstream patternFile;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700399 m_logger.log("Analyzing Traffic Configuration File: " + m_configurationFile, true, true);
400 patternFile.open(m_configurationFile.c_str());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800401 if (patternFile.is_open())
402 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700403 int patternId = 0;
404 int lineNumber = 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800405 while (getline(patternFile, patternLine))
406 {
407 lineNumber++;
408 if (std::isalpha(patternLine[0]))
409 {
410 InterestTrafficConfiguration interestData;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700411 bool shouldSkipLine = false;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800412 patternId++;
413 if (interestData.processConfigurationDetail(patternLine, m_logger, lineNumber))
414 {
415 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
416 {
417 lineNumber++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700418 if (!interestData.processConfigurationDetail(patternLine,
419 m_logger, lineNumber))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800420 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700421 shouldSkipLine = true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800422 break;
423 }
424 }
425 lineNumber++;
426 }
427 else
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700428 shouldSkipLine = true;
429 if (!shouldSkipLine)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800430 {
431 if (interestData.checkTrafficDetailCorrectness())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700432 m_trafficPatterns.push_back(interestData);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800433 }
434 }
435 }
436 patternFile.close();
437 if (!checkTrafficPatternCorrectness())
438 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700439 m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper- " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700440 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800441 m_logger.shutdownLogger();
442 exit(1);
443 }
444 m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700445 for (patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800446 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700447 m_logger.log("Traffic Pattern Type #" +
448 boost::lexical_cast<std::string>(patternId + 1), false, false);
449 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800450 m_logger.log("", false, false);
451 }
452 }
453 else
454 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700455 m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700456 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800457 m_logger.shutdownLogger();
458 exit(1);
459 }
460 }
461
462 void
463 initializeTrafficConfiguration()
464 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700465 if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800466 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700467 if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800468 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700469 parseConfigurationFile();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800470 }
471 else
472 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700473 m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700474 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800475 m_logger.shutdownLogger();
476 exit(1);
477 }
478 }
479 else
480 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700481 m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700482 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800483 m_logger.shutdownLogger();
484 exit(1);
485 }
486 }
487
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700488 uint32_t
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800489 getOldNonce()
490 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700491 if (m_nonces.size() == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800492 return getNewNonce();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700493 int randomNonceIndex = std::rand() % m_nonces.size();
494 return m_nonces[randomNonceIndex];
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800495 }
496
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700497 uint32_t
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800498 getNewNonce()
499 {
jeraldabraham473ef3d2014-03-06 12:40:35 -0700500 //Performance Enhancement
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700501 if (m_nonces.size() > 1000)
502 m_nonces.clear();
jeraldabraham473ef3d2014-03-06 12:40:35 -0700503
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700504 uint32_t randomNonce = static_cast<uint32_t>(std::rand());
505 while (std::find(m_nonces.begin(), m_nonces.end(), randomNonce) != m_nonces.end())
506 randomNonce = static_cast<uint32_t>(std::rand());
507
508 m_nonces.push_back(randomNonce);
509 return randomNonce;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800510 }
511
512 static std::string
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700513 getRandomByteString(int randomSize)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800514 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700515 std::string randomString;
516 for (int i = 0; i < randomSize; i++)
517 randomString += static_cast<char>(std::rand() % 128);
518 return randomString;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800519 }
520
521 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700522 onData(const ndn::Interest& interest,
523 ndn::Data& data,
524 int globalReference,
525 int localReference,
526 int patternId,
527 time::steady_clock::TimePoint sentTime)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800528 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700529 std::string logLine =
530 "Data Received - PatternType=" + boost::lexical_cast<std::string>(patternId+1);
531 logLine += ", GlobalID=" + boost::lexical_cast<std::string>(globalReference);
532 logLine += ", LocalID=" + boost::lexical_cast<std::string>(localReference);
533 logLine += ", Name=" + interest.getName().toUri();
534
535 m_nInterestsReceived++;
536 m_trafficPatterns[patternId].m_nInterestsReceived++;
537 if (m_trafficPatterns[patternId].m_expectedContent != "")
jeraldabraham473ef3d2014-03-06 12:40:35 -0700538 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700539 std::string receivedContent = reinterpret_cast<const char*>(data.getContent().value());
540 int receivedContentLength = data.getContent().value_size();
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700541 receivedContent = receivedContent.substr(0, receivedContentLength);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700542 if (receivedContent != m_trafficPatterns[patternId].m_expectedContent)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700543 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700544 m_nContentInconsistencies++;
545 m_trafficPatterns[patternId].m_nContentInconsistencies++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700546 logLine += ", IsConsistent=No";
547 }
548 else
549 logLine += ", IsConsistent=Yes";
jeraldabraham473ef3d2014-03-06 12:40:35 -0700550 }
jeraldabraham473ef3d2014-03-06 12:40:35 -0700551 else
552 logLine += ", IsConsistent=NotChecked";
jeraldabraham420dbf02014-04-25 22:58:31 -0700553 if (!m_hasQuietLogging)
554 m_logger.log(logLine, true, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700555 double roundTripTime = (time::steady_clock::now() - sentTime).count() / 1000000.0;
556 if (m_minimumInterestRoundTripTime > roundTripTime)
557 m_minimumInterestRoundTripTime = roundTripTime;
558 if (m_maximumInterestRoundTripTime < roundTripTime)
559 m_maximumInterestRoundTripTime = roundTripTime;
560 if (m_trafficPatterns[patternId].m_minimumInterestRoundTripTime > roundTripTime)
561 m_trafficPatterns[patternId].m_minimumInterestRoundTripTime = roundTripTime;
562 if (m_trafficPatterns[patternId].m_maximumInterestRoundTripTime < roundTripTime)
563 m_trafficPatterns[patternId].m_maximumInterestRoundTripTime = roundTripTime;
564 m_totalInterestRoundTripTime += roundTripTime;
565 m_trafficPatterns[patternId].m_totalInterestRoundTripTime += roundTripTime;
jeraldabrahamdbfee2e2014-04-04 01:18:14 -0700566 if (m_nMaximumInterests >= 0 && globalReference == m_nMaximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800567 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700568 logStatistics();
569 m_logger.shutdownLogger();
570 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300571 m_ioService.stop();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700572 }
573 }
574
575 void
576 onTimeout(const ndn::Interest& interest,
577 int globalReference,
578 int localReference,
579 int patternId)
580 {
581 std::string logLine = "Interest Timed Out - PatternType=" +
582 boost::lexical_cast<std::string>(patternId + 1);
583 logLine += ", GlobalID=" + boost::lexical_cast<std::string>(globalReference);
584 logLine += ", LocalID=" + boost::lexical_cast<std::string>(localReference);
585 logLine += ", Name=" + interest.getName().toUri();
586 m_logger.log(logLine, true, false);
jeraldabrahamdbfee2e2014-04-04 01:18:14 -0700587 if (m_nMaximumInterests >= 0 && globalReference == m_nMaximumInterests)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700588 {
589 logStatistics();
590 m_logger.shutdownLogger();
591 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300592 m_ioService.stop();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700593 }
594 }
595
596 void
597 generateTraffic(boost::asio::deadline_timer* deadlineTimer)
598 {
599 if (m_nMaximumInterests < 0 || m_nInterestsSent < m_nMaximumInterests)
600 {
601 int trafficKey = std::rand() % 100;
602 int cumulativePercentage = 0;
603 int patternId;
604 for (patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800605 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700606 cumulativePercentage += m_trafficPatterns[patternId].m_trafficPercentage;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800607 if (trafficKey <= cumulativePercentage)
608 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700609 Name interestName(m_trafficPatterns[patternId].m_name);
610 if (m_trafficPatterns[patternId].m_nameAppendBytes > 0)
611 interestName.append(
612 getRandomByteString(m_trafficPatterns[patternId].m_nameAppendBytes));
613 if (m_trafficPatterns[patternId].m_nameAppendSequenceNumber >= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800614 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700615 interestName.append(
616 boost::lexical_cast<std::string>(
617 m_trafficPatterns[patternId].m_nameAppendSequenceNumber));
618 m_trafficPatterns[patternId].m_nameAppendSequenceNumber++;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800619 }
620 Interest interest(interestName);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700621 if (m_trafficPatterns[patternId].m_minSuffixComponents >= 0)
622 interest.setMinSuffixComponents(
623 m_trafficPatterns[patternId].m_minSuffixComponents);
624 if (m_trafficPatterns[patternId].m_maxSuffixComponents >= 0)
625 interest.setMaxSuffixComponents(
626 m_trafficPatterns[patternId].m_maxSuffixComponents);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800627 Exclude exclude;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700628 if (m_trafficPatterns[patternId].m_excludeBefore != "" &&
629 m_trafficPatterns[patternId].m_excludeAfter != "")
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800630 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700631 exclude.excludeRange(
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700632 name::Component(
633 m_trafficPatterns[patternId].m_excludeAfter),
634 name::Component(m_trafficPatterns[patternId].m_excludeBefore));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800635 interest.setExclude(exclude);
636 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700637 else if (m_trafficPatterns[patternId].m_excludeBefore != "")
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800638 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700639 exclude.excludeBefore(
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700640 name::Component(m_trafficPatterns[patternId].m_excludeBefore));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800641 interest.setExclude(exclude);
642 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700643 else if (m_trafficPatterns[patternId].m_excludeAfter != "")
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800644 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700645 exclude.excludeAfter(
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700646 name::Component(m_trafficPatterns[patternId].m_excludeAfter));
647 interest.setExclude(exclude);
648 }
649 if (m_trafficPatterns[patternId].m_excludeBeforeBytes > 0 &&
650 m_trafficPatterns[patternId].m_excludeAfterBytes > 0)
651 {
652 exclude.excludeRange(
653 name::Component(
654 getRandomByteString(
655 m_trafficPatterns[patternId].m_excludeAfterBytes)),
656 name::Component(
657 getRandomByteString(
658 m_trafficPatterns[patternId].m_excludeBeforeBytes)));
659 interest.setExclude(exclude);
660 }
661 else if (m_trafficPatterns[patternId].m_excludeBeforeBytes > 0)
662 {
663 exclude.excludeBefore(
664 name::Component(
665 getRandomByteString(
666 m_trafficPatterns[patternId].m_excludeBeforeBytes)));
667 interest.setExclude(exclude);
668 }
669 else if (m_trafficPatterns[patternId].m_excludeAfterBytes > 0)
670 {
671 exclude.excludeAfter(
672 name::Component(
673 getRandomByteString(
674 m_trafficPatterns[patternId].m_excludeAfterBytes)));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800675 interest.setExclude(exclude);
676 }
677
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700678 if (m_trafficPatterns[patternId].m_childSelector >= 0)
679 interest.setChildSelector(m_trafficPatterns[patternId].m_childSelector);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800680
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700681 if (m_trafficPatterns[patternId].m_mustBeFresh == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800682 interest.setMustBeFresh(false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700683 else if (m_trafficPatterns[patternId].m_mustBeFresh > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800684 interest.setMustBeFresh(true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700685 if (m_trafficPatterns[patternId].m_nonceDuplicationPercentage > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800686 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700687 int duplicationPercentage = std::rand() % 100;
688 if (m_trafficPatterns[patternId].m_nonceDuplicationPercentage <=
689 duplicationPercentage)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800690 interest.setNonce(getOldNonce());
691 else
692 interest.setNonce(getNewNonce());
693 }
694 else
695 interest.setNonce(getNewNonce());
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700696 if (m_trafficPatterns[patternId].m_scope >= 0)
697 interest.setScope(m_trafficPatterns[patternId].m_scope);
698 if (m_trafficPatterns[patternId].m_interestLifetime >= time::milliseconds(0))
699 interest.setInterestLifetime(m_trafficPatterns[patternId].m_interestLifetime);
700
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800701 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700702 m_nInterestsSent++;
703 m_trafficPatterns[patternId].m_nInterestsSent++;
704 time::steady_clock::TimePoint sentTime = time::steady_clock::now();
705 m_face.expressInterest(interest,
706 bind(&NdnTrafficClient::onData,
707 this, _1, _2, m_nInterestsSent,
708 m_trafficPatterns[patternId].m_nInterestsSent,
709 patternId, sentTime),
710 bind(&NdnTrafficClient::onTimeout,
711 this, _1, m_nInterestsSent,
712 m_trafficPatterns[patternId].m_nInterestsSent,
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700713 patternId));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700714 std::string logLine = "";
715 logLine += "Sending Interest - PatternType=" +
716 boost::lexical_cast<std::string>(patternId+1);
717 logLine += ", GlobalID=" + boost::lexical_cast<std::string>(m_nInterestsSent);
718 logLine += ", LocalID=" + boost::lexical_cast<std::string>(
719 m_trafficPatterns[patternId].m_nInterestsSent);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800720 logLine += ", Name="+interest.getName().toUri();
jeraldabraham420dbf02014-04-25 22:58:31 -0700721 if (!m_hasQuietLogging)
722 m_logger.log(logLine, true, false);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800723 deadlineTimer->expires_at(deadlineTimer->expires_at() +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700724 boost::posix_time::millisec(
725 m_interestInterval.count()));
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700726 deadlineTimer->async_wait(bind(&NdnTrafficClient::generateTraffic,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700727 this, deadlineTimer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800728 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700729 catch (std::exception& e) {
730 m_logger.log("ERROR: " + static_cast<std::string>(e.what()), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800731 }
732 break;
733 }
734 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700735 if (patternId == m_trafficPatterns.size())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800736 {
737 deadlineTimer->expires_at(deadlineTimer->expires_at() +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700738 boost::posix_time::millisec(
739 m_interestInterval.count()));
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700740 deadlineTimer->async_wait(bind(&NdnTrafficClient::generateTraffic,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700741 this, deadlineTimer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800742 }
743 }
744 }
745
746 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700747 run()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800748 {
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300749 boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700750 signalSet.async_wait(bind(&NdnTrafficClient::signalHandler, this));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700751 m_logger.initializeLog(m_instanceId);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800752 initializeTrafficConfiguration();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700753
754 if (m_nMaximumInterests == 0)
755 {
756 logStatistics();
757 m_logger.shutdownLogger();
758 return;
759 }
760
761 boost::asio::deadline_timer deadlineTimer(
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300762 m_ioService,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700763 boost::posix_time::millisec(m_interestInterval.count()));
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700764 deadlineTimer.async_wait(bind(&NdnTrafficClient::generateTraffic,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700765 this, &deadlineTimer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800766 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700767 m_face.processEvents();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800768 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700769 catch(std::exception& e) {
770 m_logger.log("ERROR: " + static_cast<std::string>(e.what()), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800771 m_logger.shutdownLogger();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700772 m_hasError = true;
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300773 m_ioService.stop();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800774 }
775 }
776
777private:
778
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700779 std::string m_programName;
780 std::string m_instanceId;
781 bool m_hasError;
jeraldabraham420dbf02014-04-25 22:58:31 -0700782 bool m_hasQuietLogging;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700783 time::milliseconds m_interestInterval;
784 int m_nMaximumInterests;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800785 Logger m_logger;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700786 std::string m_configurationFile;
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300787 boost::asio::io_service m_ioService;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700788 Face m_face;
789 std::vector<InterestTrafficConfiguration> m_trafficPatterns;
790 std::vector<uint32_t> m_nonces;
791 int m_nInterestsSent;
792 int m_nInterestsReceived;
793 int m_nContentInconsistencies;
794
795 //round trip time is stored as milliseconds with fractional
796 //sub-milliseconds precision
797 double m_minimumInterestRoundTripTime;
798 double m_maximumInterestRoundTripTime;
799 double m_totalInterestRoundTripTime;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800800
801};
802
803} // namespace ndn
804
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700805int
806main(int argc, char* argv[])
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800807{
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700808 std::srand(std::time(0));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800809 ndn::NdnTrafficClient ndnTrafficClient (argv[0]);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700810 int option;
jeraldabraham420dbf02014-04-25 22:58:31 -0700811 while ((option = getopt(argc, argv, "hqi:c:")) != -1) {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800812 switch (option) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700813 case 'h':
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800814 ndnTrafficClient.usage();
815 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700816 case 'i':
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800817 ndnTrafficClient.setInterestInterval(atoi(optarg));
818 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700819 case 'c':
820 ndnTrafficClient.setMaximumInterests(atoi(optarg));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800821 break;
jeraldabraham420dbf02014-04-25 22:58:31 -0700822 case 'q':
823 ndnTrafficClient.setQuietLogging();
824 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700825 default:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800826 ndnTrafficClient.usage();
827 break;
828 }
829 }
830
831 argc -= optind;
832 argv += optind;
833
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700834 if (argv[0] == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800835 ndnTrafficClient.usage();
836
837 ndnTrafficClient.setConfigurationFile(argv[0]);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700838 ndnTrafficClient.run();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800839
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700840 if (ndnTrafficClient.hasError())
841 return 1;
842 else
843 return 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800844}