blob: 2b9f2f5798dc61ae3d45fe901cd2ed2221b7c59e [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
10#include <string>
11#include <sstream>
12#include <fstream>
13#include <vector>
14
15#include "logger.hpp"
16
17#include <boost/asio.hpp>
18#include <boost/filesystem.hpp>
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070019#include <boost/lexical_cast.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080020#include <boost/date_time/posix_time/posix_time.hpp>
21
22#include <ndn-cpp-dev/face.hpp>
23#include <ndn-cpp-dev/exclude.hpp>
24#include <ndn-cpp-dev/name-component.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080025
26namespace ndn {
27
28class NdnTrafficClient
29{
30public:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070031
32 explicit
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070033 NdnTrafficClient(char* programName)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070034 : m_programName(programName)
35 , m_logger("NdnTrafficClient")
36 , m_hasError(false)
37 , m_ioService(new boost::asio::io_service)
38 , m_face(m_ioService)
39 , m_interestInterval(getDefaultInterestInterval())
40 , m_nMaximumInterests(-1)
41 , m_nInterestsSent(0)
42 , m_nInterestsReceived(0)
43 , m_minimumInterestRoundTripTime(std::numeric_limits<double>::max())
44 , m_maximumInterestRoundTripTime(0)
45 , m_totalInterestRoundTripTime(0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080046 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070047 m_instanceId = boost::lexical_cast<std::string>(std::rand());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080048 }
49
50 class InterestTrafficConfiguration
51 {
52 public:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080053 InterestTrafficConfiguration()
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070054 : m_trafficPercentage(-1)
55 , m_nameAppendBytes(-1)
56 , m_nameAppendSequenceNumber(-1)
57 , m_minSuffixComponents(-1)
58 , m_maxSuffixComponents(-1)
59 , m_excludeBeforeBytes(-1)
60 , m_excludeAfterBytes(-1)
61 , m_childSelector(-1)
62 , m_mustBeFresh(-1)
63 , m_nonceDuplicationPercentage(-1)
64 , m_scope(-1)
65 , m_interestLifetime(getDefaultInterestLifetime())
66 , m_nInterestsSent(-1)
67 , m_nInterestsReceived(-1)
68 , m_minimumInterestRoundTripTime(std::numeric_limits<double>::max())
69 , m_maximumInterestRoundTripTime(0)
70 , m_totalInterestRoundTripTime(0)
71 , m_nContentInconsistencies(0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080072 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070073 }
74
75 time::milliseconds
76 getDefaultInterestLifetime()
77 {
78 return time::milliseconds(-1);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080079 }
80
81 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070082 printTrafficConfiguration(Logger& logger)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080083 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070084 std::string detail = "";
85 if (m_trafficPercentage > 0)
86 detail += "TrafficPercentage=" +
87 boost::lexical_cast<std::string>(m_trafficPercentage) + ", ";
88 if (m_name != "")
89 detail += "Name=" + m_name + ", ";
90 if (m_nameAppendBytes > 0)
91 detail += "NameAppendBytes=" + boost::lexical_cast<std::string>(m_nameAppendBytes) + ", ";
92 if (m_nameAppendSequenceNumber > 0)
93 detail += "NameAppendSequenceNumber=" +
94 boost::lexical_cast<std::string>(m_nameAppendSequenceNumber) + ", ";
95 if (m_minSuffixComponents >= 0)
96 detail += "MinSuffixComponents=" +
97 boost::lexical_cast<std::string>(m_minSuffixComponents) + ", ";
98 if (m_maxSuffixComponents >= 0)
99 detail += "MaxSuffixComponents=" +
100 boost::lexical_cast<std::string>(m_maxSuffixComponents) + ", ";
101 if (m_excludeBefore != "")
102 detail += "ExcludeBefore=" + m_excludeBefore + ", ";
103 if (m_excludeAfter != "")
104 detail += "ExcludeAfter=" + m_excludeAfter + ", ";
105 if (m_excludeBeforeBytes > 0)
106 detail += "ExcludeBeforeBytes=" +
107 boost::lexical_cast<std::string>(m_excludeBeforeBytes) + ", ";
108 if (m_excludeAfterBytes > 0)
109 detail += "ExcludeAfterBytes=" +
110 boost::lexical_cast<std::string>(m_excludeAfterBytes) + ", ";
111 if (m_childSelector >= 0)
112 detail += "ChildSelector=" +
113 boost::lexical_cast<std::string>(m_childSelector) + ", ";
114 if (m_mustBeFresh >= 0)
115 detail += "MustBeFresh=" +
116 boost::lexical_cast<std::string>(m_mustBeFresh) + ", ";
117 if (m_nonceDuplicationPercentage > 0)
118 detail += "NonceDuplicationPercentage=" +
119 boost::lexical_cast<std::string>(m_nonceDuplicationPercentage) + ", ";
120 if (m_scope >= 0)
121 detail += "Scope="+boost::lexical_cast<std::string>(m_scope) + ", ";
122 if (m_interestLifetime >= time::milliseconds(0))
123 detail += "InterestLifetime=" +
124 boost::lexical_cast<std::string>(m_interestLifetime.count()) + ", ";
125 if (m_expectedContent != "")
126 detail += "ExpectedContent=" + m_expectedContent + ", ";
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800127 if (detail.length() >= 2)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700128 detail = detail.substr(0, detail.length() - 2); //Removing suffix ", "
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800129 logger.log(detail, false, false);
130 }
131
132 bool
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700133 extractParameterValue(const std::string& detail,
134 std::string& parameter,
135 std::string& value)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800136 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800137 std::string allowedCharacters = ":/+._-%";
138 parameter = "";
139 value = "";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700140 int i = 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800141 while (detail[i] != '=' && i < detail.length())
142 {
143 parameter += detail[i];
144 i++;
145 }
146 if (i == detail.length())
147 return false;
148 i++;
jeraldabraham79c0c232014-03-31 21:43:59 -0700149 while ((std::isalnum(detail[i]) ||
150 allowedCharacters.find(detail[i]) != std::string::npos) &&
151 i < detail.length())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800152 {
153 value += detail[i];
154 i++;
155 }
jeraldabraham79c0c232014-03-31 21:43:59 -0700156 if (parameter == "" || value == "")
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800157 return false;
158 return true;
159 }
160
161 bool
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700162 processConfigurationDetail(const std::string& detail, Logger& logger, int lineNumber)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800163 {
164 std::string parameter, value;
165 if (extractParameterValue(detail, parameter, value))
166 {
167 if (parameter == "TrafficPercentage")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700168 m_trafficPercentage = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800169 else if (parameter == "Name")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700170 m_name = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800171 else if (parameter == "NameAppendBytes")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700172 m_nameAppendBytes = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800173 else if (parameter == "NameAppendSequenceNumber")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700174 m_nameAppendSequenceNumber = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800175 else if (parameter == "MinSuffixComponents")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700176 m_minSuffixComponents = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800177 else if (parameter == "MaxSuffixComponents")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700178 m_maxSuffixComponents = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800179 else if (parameter == "ExcludeBefore")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700180 m_excludeBefore = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800181 else if (parameter == "ExcludeAfter")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700182 m_excludeAfter = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800183 else if (parameter == "ExcludeBeforeBytes")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700184 m_excludeBeforeBytes = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800185 else if (parameter == "ExcludeAfterBytes")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700186 m_excludeAfterBytes = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800187 else if (parameter == "ChildSelector")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700188 m_childSelector = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800189 else if (parameter == "MustBeFresh")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700190 m_mustBeFresh = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800191 else if (parameter == "NonceDuplicationPercentage")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700192 m_nonceDuplicationPercentage = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800193 else if (parameter == "Scope")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700194 m_scope = boost::lexical_cast<int>(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800195 else if (parameter == "InterestLifetime")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700196 m_interestLifetime = time::milliseconds(boost::lexical_cast<int>(value));
jeraldabraham473ef3d2014-03-06 12:40:35 -0700197 else if (parameter == "ExpectedContent")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700198 m_expectedContent = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800199 else
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700200 logger.log("Line " + boost::lexical_cast<std::string>(lineNumber) +
201 " \t- Invalid Parameter='" + parameter + "'", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800202 }
203 else
204 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700205 logger.log("Line " + boost::lexical_cast<std::string>(lineNumber) +
206 " \t- Improper Traffic Configuration Line- " + detail, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800207 return false;
208 }
209 return true;
210 }
211
212 bool
213 checkTrafficDetailCorrectness()
214 {
215 return true;
216 }
217
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700218 int m_trafficPercentage;
219 std::string m_name;
220 int m_nameAppendBytes;
221 int m_nameAppendSequenceNumber;
222 int m_minSuffixComponents;
223 int m_maxSuffixComponents;
224 std::string m_excludeBefore;
225 std::string m_excludeAfter;
226 int m_excludeBeforeBytes;
227 int m_excludeAfterBytes;
228 int m_childSelector;
229 int m_mustBeFresh;
230 int m_nonceDuplicationPercentage;
231 int m_scope;
232 time::milliseconds m_interestLifetime;
233 int m_nInterestsSent;
234 int m_nInterestsReceived;
235
236 //round trip time is stored as milliseconds with fractional
237 //sub-millisecond precision
238 double m_minimumInterestRoundTripTime;
239 double m_maximumInterestRoundTripTime;
240 double m_totalInterestRoundTripTime;
241
242 int m_nContentInconsistencies;
243 std::string m_expectedContent;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700244 }; // class InterestTrafficConfiguration
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800245
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700246 bool
247 hasError() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800248 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700249 return m_hasError;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800250 }
251
252 void
253 usage()
254 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700255 std::cout << "\nUsage: " << m_programName << " [options] <Traffic_Configuration_File>\n"
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800256 "Generate Interest Traffic as per provided Traffic Configuration File\n"
257 "Interests are continuously generated unless a total number is specified.\n"
258 "Set environment variable NDN_TRAFFIC_LOGFOLDER for redirecting output to a log.\n"
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700259 " [-i interval] - set interest generation interval in milliseconds (default "
260 << getDefaultInterestInterval() << ")\n"
261 " [-c count] - set total number of interests to be generated\n"
262 " [-h] - print help and exit\n\n";
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800263 exit(1);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800264 }
265
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700266 time::milliseconds
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800267 getDefaultInterestInterval()
268 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700269 return time::milliseconds(1000);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800270 }
271
272 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700273 setInterestInterval(int interestInterval)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800274 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700275 if (interestInterval <= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800276 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700277 m_interestInterval = time::milliseconds(interestInterval);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800278 }
279
280 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700281 setMaximumInterests(int maximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800282 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700283 if (maximumInterests <= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800284 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700285 m_nMaximumInterests = maximumInterests;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800286 }
287
288 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700289 setConfigurationFile(char* configurationFile)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800290 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700291 m_configurationFile = configurationFile;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800292 }
293
294 void
295 signalHandler()
296 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800297 logStatistics();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700298 m_logger.shutdownLogger();
299 m_face.shutdown();
300 m_ioService->stop();
301 if (m_hasError)
302 exit(1);
303 else
304 exit(0);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800305 }
306
307 void
308 logStatistics()
309 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800310 m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700311 m_logger.log("Total Traffic Pattern Types = " +
312 boost::lexical_cast<std::string>(static_cast<int>(m_trafficPatterns.size())), false, true);
313 m_logger.log("Total Interests Sent = " +
314 boost::lexical_cast<std::string>(m_nInterestsSent), false, true);
315 m_logger.log("Total Responses Received = " +
316 boost::lexical_cast<std::string>(m_nInterestsReceived), false, true);
317 double loss = 0;
318 if (m_nInterestsSent > 0)
319 loss = (m_nInterestsSent - m_nInterestsReceived) * 100.0 / m_nInterestsSent;
320 m_logger.log("Total Interest Loss = " +
321 boost::lexical_cast<std::string>(loss) + "%", false, true);
322 if (m_nContentInconsistencies != 0 || m_nInterestsSent != m_nInterestsReceived)
323 m_hasError = true;
324 double average = 0;
325 double inconsistency = 0;
326 if (m_nInterestsReceived > 0)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700327 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700328 average = m_totalInterestRoundTripTime / m_nInterestsReceived;
329 inconsistency = m_nContentInconsistencies * 100.0 / m_nInterestsReceived;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700330 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700331 m_logger.log("Total Data Inconsistency = " +
332 boost::lexical_cast<std::string>(inconsistency) + "%", false, true);
333 m_logger.log("Total Round Trip Time = " +
334 boost::lexical_cast<std::string>(m_totalInterestRoundTripTime) + "ms", false, true);
335 m_logger.log("Average Round Trip Time = " +
336 boost::lexical_cast<std::string>(average) + "ms\n", false, true);
337
338 for (int patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700339 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700340 m_logger.log("Traffic Pattern Type #" +
341 boost::lexical_cast<std::string>(patternId + 1), false, true);
342 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
343 m_logger.log("Total Interests Sent = " +
344 boost::lexical_cast<std::string>(
345 m_trafficPatterns[patternId].m_nInterestsSent), false, true);
346 m_logger.log("Total Responses Received = " +
347 boost::lexical_cast<std::string>(
348 m_trafficPatterns[patternId].m_nInterestsReceived), false, true);
349 loss = 0;
350 if (m_trafficPatterns[patternId].m_nInterestsSent > 0)
351 {
352 loss = (m_trafficPatterns[patternId].m_nInterestsSent -
353 m_trafficPatterns[patternId].m_nInterestsReceived);
354 loss *= 100.0;
355 loss /= m_trafficPatterns[patternId].m_nInterestsSent;
356 }
357 m_logger.log("Total Interest Loss = " +
358 boost::lexical_cast<std::string>(loss) + "%", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700359 average = 0;
360 inconsistency = 0;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700361 if (m_trafficPatterns[patternId].m_nInterestsReceived > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800362 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700363 average = (m_trafficPatterns[patternId].m_totalInterestRoundTripTime /
364 m_trafficPatterns[patternId].m_nInterestsReceived);
365 inconsistency = m_trafficPatterns[patternId].m_nContentInconsistencies;
366 inconsistency =
367 inconsistency * 100.0 / m_trafficPatterns[patternId].m_nInterestsReceived;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800368 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700369 m_logger.log("Total Data Inconsistency = " +
370 boost::lexical_cast<std::string>(inconsistency) + "%", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700371 m_logger.log("Total Round Trip Time = " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700372 boost::lexical_cast<std::string>(
373 m_trafficPatterns[patternId].m_totalInterestRoundTripTime) + "ms", false, true);
374 m_logger.log("Average Round Trip Time = " +
375 boost::lexical_cast<std::string>(average) + "ms\n", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800376 }
377 }
378
379 bool
380 checkTrafficPatternCorrectness()
381 {
382 return true;
383 }
384
385 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700386 parseConfigurationFile()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800387 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800388 std::string patternLine;
389 std::ifstream patternFile;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700390 m_logger.log("Analyzing Traffic Configuration File: " + m_configurationFile, true, true);
391 patternFile.open(m_configurationFile.c_str());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800392 if (patternFile.is_open())
393 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700394 int patternId = 0;
395 int lineNumber = 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800396 while (getline(patternFile, patternLine))
397 {
398 lineNumber++;
399 if (std::isalpha(patternLine[0]))
400 {
401 InterestTrafficConfiguration interestData;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700402 bool shouldSkipLine = false;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800403 patternId++;
404 if (interestData.processConfigurationDetail(patternLine, m_logger, lineNumber))
405 {
406 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
407 {
408 lineNumber++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700409 if (!interestData.processConfigurationDetail(patternLine,
410 m_logger, lineNumber))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800411 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700412 shouldSkipLine = true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800413 break;
414 }
415 }
416 lineNumber++;
417 }
418 else
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700419 shouldSkipLine = true;
420 if (!shouldSkipLine)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800421 {
422 if (interestData.checkTrafficDetailCorrectness())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700423 m_trafficPatterns.push_back(interestData);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800424 }
425 }
426 }
427 patternFile.close();
428 if (!checkTrafficPatternCorrectness())
429 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700430 m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper- " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700431 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800432 m_logger.shutdownLogger();
433 exit(1);
434 }
435 m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700436 for (patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800437 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700438 m_logger.log("Traffic Pattern Type #" +
439 boost::lexical_cast<std::string>(patternId + 1), false, false);
440 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800441 m_logger.log("", false, false);
442 }
443 }
444 else
445 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700446 m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700447 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800448 m_logger.shutdownLogger();
449 exit(1);
450 }
451 }
452
453 void
454 initializeTrafficConfiguration()
455 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700456 if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800457 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700458 if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800459 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700460 parseConfigurationFile();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800461 }
462 else
463 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700464 m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700465 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800466 m_logger.shutdownLogger();
467 exit(1);
468 }
469 }
470 else
471 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700472 m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700473 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800474 m_logger.shutdownLogger();
475 exit(1);
476 }
477 }
478
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700479 uint32_t
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800480 getOldNonce()
481 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700482 if (m_nonces.size() == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800483 return getNewNonce();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700484 int randomNonceIndex = std::rand() % m_nonces.size();
485 return m_nonces[randomNonceIndex];
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800486 }
487
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700488 uint32_t
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800489 getNewNonce()
490 {
jeraldabraham473ef3d2014-03-06 12:40:35 -0700491 //Performance Enhancement
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700492 if (m_nonces.size() > 1000)
493 m_nonces.clear();
jeraldabraham473ef3d2014-03-06 12:40:35 -0700494
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700495 uint32_t randomNonce = static_cast<uint32_t>(std::rand());
496 while (std::find(m_nonces.begin(), m_nonces.end(), randomNonce) != m_nonces.end())
497 randomNonce = static_cast<uint32_t>(std::rand());
498
499 m_nonces.push_back(randomNonce);
500 return randomNonce;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800501 }
502
503 static std::string
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700504 getRandomByteString(int randomSize)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800505 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700506 std::string randomString;
507 for (int i = 0; i < randomSize; i++)
508 randomString += static_cast<char>(std::rand() % 128);
509 return randomString;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800510 }
511
512 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700513 onData(const ndn::Interest& interest,
514 ndn::Data& data,
515 int globalReference,
516 int localReference,
517 int patternId,
518 time::steady_clock::TimePoint sentTime)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800519 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700520 std::string logLine =
521 "Data Received - PatternType=" + boost::lexical_cast<std::string>(patternId+1);
522 logLine += ", GlobalID=" + boost::lexical_cast<std::string>(globalReference);
523 logLine += ", LocalID=" + boost::lexical_cast<std::string>(localReference);
524 logLine += ", Name=" + interest.getName().toUri();
525
526 m_nInterestsReceived++;
527 m_trafficPatterns[patternId].m_nInterestsReceived++;
528 if (m_trafficPatterns[patternId].m_expectedContent != "")
jeraldabraham473ef3d2014-03-06 12:40:35 -0700529 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700530 std::string receivedContent = reinterpret_cast<const char*>(data.getContent().value());
531 int receivedContentLength = data.getContent().value_size();
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700532 receivedContent = receivedContent.substr(0, receivedContentLength);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700533 if (receivedContent != m_trafficPatterns[patternId].m_expectedContent)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700534 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700535 m_nContentInconsistencies++;
536 m_trafficPatterns[patternId].m_nContentInconsistencies++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700537 logLine += ", IsConsistent=No";
538 }
539 else
540 logLine += ", IsConsistent=Yes";
jeraldabraham473ef3d2014-03-06 12:40:35 -0700541 }
jeraldabraham473ef3d2014-03-06 12:40:35 -0700542 else
543 logLine += ", IsConsistent=NotChecked";
544 m_logger.log(logLine, true, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700545 double roundTripTime = (time::steady_clock::now() - sentTime).count() / 1000000.0;
546 if (m_minimumInterestRoundTripTime > roundTripTime)
547 m_minimumInterestRoundTripTime = roundTripTime;
548 if (m_maximumInterestRoundTripTime < roundTripTime)
549 m_maximumInterestRoundTripTime = roundTripTime;
550 if (m_trafficPatterns[patternId].m_minimumInterestRoundTripTime > roundTripTime)
551 m_trafficPatterns[patternId].m_minimumInterestRoundTripTime = roundTripTime;
552 if (m_trafficPatterns[patternId].m_maximumInterestRoundTripTime < roundTripTime)
553 m_trafficPatterns[patternId].m_maximumInterestRoundTripTime = roundTripTime;
554 m_totalInterestRoundTripTime += roundTripTime;
555 m_trafficPatterns[patternId].m_totalInterestRoundTripTime += roundTripTime;
556 if (m_nMaximumInterests >= 0 && m_nInterestsSent == m_nMaximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800557 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700558 logStatistics();
559 m_logger.shutdownLogger();
560 m_face.shutdown();
561 m_ioService->stop();
562 }
563 }
564
565 void
566 onTimeout(const ndn::Interest& interest,
567 int globalReference,
568 int localReference,
569 int patternId)
570 {
571 std::string logLine = "Interest Timed Out - PatternType=" +
572 boost::lexical_cast<std::string>(patternId + 1);
573 logLine += ", GlobalID=" + boost::lexical_cast<std::string>(globalReference);
574 logLine += ", LocalID=" + boost::lexical_cast<std::string>(localReference);
575 logLine += ", Name=" + interest.getName().toUri();
576 m_logger.log(logLine, true, false);
577 if (m_nMaximumInterests >= 0 && m_nInterestsSent == m_nMaximumInterests)
578 {
579 logStatistics();
580 m_logger.shutdownLogger();
581 m_face.shutdown();
582 m_ioService->stop();
583 }
584 }
585
586 void
587 generateTraffic(boost::asio::deadline_timer* deadlineTimer)
588 {
589 if (m_nMaximumInterests < 0 || m_nInterestsSent < m_nMaximumInterests)
590 {
591 int trafficKey = std::rand() % 100;
592 int cumulativePercentage = 0;
593 int patternId;
594 for (patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800595 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700596 cumulativePercentage += m_trafficPatterns[patternId].m_trafficPercentage;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800597 if (trafficKey <= cumulativePercentage)
598 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700599 Name interestName(m_trafficPatterns[patternId].m_name);
600 if (m_trafficPatterns[patternId].m_nameAppendBytes > 0)
601 interestName.append(
602 getRandomByteString(m_trafficPatterns[patternId].m_nameAppendBytes));
603 if (m_trafficPatterns[patternId].m_nameAppendSequenceNumber >= 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800604 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700605 interestName.append(
606 boost::lexical_cast<std::string>(
607 m_trafficPatterns[patternId].m_nameAppendSequenceNumber));
608 m_trafficPatterns[patternId].m_nameAppendSequenceNumber++;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800609 }
610 Interest interest(interestName);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700611 if (m_trafficPatterns[patternId].m_minSuffixComponents >= 0)
612 interest.setMinSuffixComponents(
613 m_trafficPatterns[patternId].m_minSuffixComponents);
614 if (m_trafficPatterns[patternId].m_maxSuffixComponents >= 0)
615 interest.setMaxSuffixComponents(
616 m_trafficPatterns[patternId].m_maxSuffixComponents);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800617 Exclude exclude;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700618 if (m_trafficPatterns[patternId].m_excludeBefore != "" &&
619 m_trafficPatterns[patternId].m_excludeAfter != "")
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800620 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700621 exclude.excludeRange(
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700622 name::Component(
623 m_trafficPatterns[patternId].m_excludeAfter),
624 name::Component(m_trafficPatterns[patternId].m_excludeBefore));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800625 interest.setExclude(exclude);
626 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700627 else if (m_trafficPatterns[patternId].m_excludeBefore != "")
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800628 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700629 exclude.excludeBefore(
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700630 name::Component(m_trafficPatterns[patternId].m_excludeBefore));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800631 interest.setExclude(exclude);
632 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700633 else if (m_trafficPatterns[patternId].m_excludeAfter != "")
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800634 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700635 exclude.excludeAfter(
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700636 name::Component(m_trafficPatterns[patternId].m_excludeAfter));
637 interest.setExclude(exclude);
638 }
639 if (m_trafficPatterns[patternId].m_excludeBeforeBytes > 0 &&
640 m_trafficPatterns[patternId].m_excludeAfterBytes > 0)
641 {
642 exclude.excludeRange(
643 name::Component(
644 getRandomByteString(
645 m_trafficPatterns[patternId].m_excludeAfterBytes)),
646 name::Component(
647 getRandomByteString(
648 m_trafficPatterns[patternId].m_excludeBeforeBytes)));
649 interest.setExclude(exclude);
650 }
651 else if (m_trafficPatterns[patternId].m_excludeBeforeBytes > 0)
652 {
653 exclude.excludeBefore(
654 name::Component(
655 getRandomByteString(
656 m_trafficPatterns[patternId].m_excludeBeforeBytes)));
657 interest.setExclude(exclude);
658 }
659 else if (m_trafficPatterns[patternId].m_excludeAfterBytes > 0)
660 {
661 exclude.excludeAfter(
662 name::Component(
663 getRandomByteString(
664 m_trafficPatterns[patternId].m_excludeAfterBytes)));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800665 interest.setExclude(exclude);
666 }
667
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700668 if (m_trafficPatterns[patternId].m_childSelector >= 0)
669 interest.setChildSelector(m_trafficPatterns[patternId].m_childSelector);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800670
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700671 if (m_trafficPatterns[patternId].m_mustBeFresh == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800672 interest.setMustBeFresh(false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700673 else if (m_trafficPatterns[patternId].m_mustBeFresh > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800674 interest.setMustBeFresh(true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700675 if (m_trafficPatterns[patternId].m_nonceDuplicationPercentage > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800676 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700677 int duplicationPercentage = std::rand() % 100;
678 if (m_trafficPatterns[patternId].m_nonceDuplicationPercentage <=
679 duplicationPercentage)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800680 interest.setNonce(getOldNonce());
681 else
682 interest.setNonce(getNewNonce());
683 }
684 else
685 interest.setNonce(getNewNonce());
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700686 if (m_trafficPatterns[patternId].m_scope >= 0)
687 interest.setScope(m_trafficPatterns[patternId].m_scope);
688 if (m_trafficPatterns[patternId].m_interestLifetime >= time::milliseconds(0))
689 interest.setInterestLifetime(m_trafficPatterns[patternId].m_interestLifetime);
690
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800691 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700692 m_nInterestsSent++;
693 m_trafficPatterns[patternId].m_nInterestsSent++;
694 time::steady_clock::TimePoint sentTime = time::steady_clock::now();
695 m_face.expressInterest(interest,
696 bind(&NdnTrafficClient::onData,
697 this, _1, _2, m_nInterestsSent,
698 m_trafficPatterns[patternId].m_nInterestsSent,
699 patternId, sentTime),
700 bind(&NdnTrafficClient::onTimeout,
701 this, _1, m_nInterestsSent,
702 m_trafficPatterns[patternId].m_nInterestsSent,
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700703 patternId));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700704 std::string logLine = "";
705 logLine += "Sending Interest - PatternType=" +
706 boost::lexical_cast<std::string>(patternId+1);
707 logLine += ", GlobalID=" + boost::lexical_cast<std::string>(m_nInterestsSent);
708 logLine += ", LocalID=" + boost::lexical_cast<std::string>(
709 m_trafficPatterns[patternId].m_nInterestsSent);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800710 logLine += ", Name="+interest.getName().toUri();
711 m_logger.log(logLine, true, false);
712 deadlineTimer->expires_at(deadlineTimer->expires_at() +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700713 boost::posix_time::millisec(
714 m_interestInterval.count()));
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700715 deadlineTimer->async_wait(bind(&NdnTrafficClient::generateTraffic,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700716 this, deadlineTimer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800717 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700718 catch (std::exception& e) {
719 m_logger.log("ERROR: " + static_cast<std::string>(e.what()), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800720 }
721 break;
722 }
723 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700724 if (patternId == m_trafficPatterns.size())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800725 {
726 deadlineTimer->expires_at(deadlineTimer->expires_at() +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700727 boost::posix_time::millisec(
728 m_interestInterval.count()));
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700729 deadlineTimer->async_wait(bind(&NdnTrafficClient::generateTraffic,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700730 this, deadlineTimer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800731 }
732 }
733 }
734
735 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700736 run()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800737 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700738 boost::asio::signal_set signalSet(*m_ioService, SIGINT, SIGTERM);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700739 signalSet.async_wait(bind(&NdnTrafficClient::signalHandler, this));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700740 m_logger.initializeLog(m_instanceId);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800741 initializeTrafficConfiguration();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700742
743 if (m_nMaximumInterests == 0)
744 {
745 logStatistics();
746 m_logger.shutdownLogger();
747 return;
748 }
749
750 boost::asio::deadline_timer deadlineTimer(
751 *m_ioService,
752 boost::posix_time::millisec(m_interestInterval.count()));
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700753 deadlineTimer.async_wait(bind(&NdnTrafficClient::generateTraffic,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700754 this, &deadlineTimer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800755 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700756 m_face.processEvents();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800757 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700758 catch(std::exception& e) {
759 m_logger.log("ERROR: " + static_cast<std::string>(e.what()), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800760 m_logger.shutdownLogger();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700761 m_hasError = true;
762 m_ioService->stop();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800763 }
764 }
765
766private:
767
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700768 std::string m_programName;
769 std::string m_instanceId;
770 bool m_hasError;
771 time::milliseconds m_interestInterval;
772 int m_nMaximumInterests;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800773 Logger m_logger;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700774 std::string m_configurationFile;
775 shared_ptr<boost::asio::io_service> m_ioService;
776 Face m_face;
777 std::vector<InterestTrafficConfiguration> m_trafficPatterns;
778 std::vector<uint32_t> m_nonces;
779 int m_nInterestsSent;
780 int m_nInterestsReceived;
781 int m_nContentInconsistencies;
782
783 //round trip time is stored as milliseconds with fractional
784 //sub-milliseconds precision
785 double m_minimumInterestRoundTripTime;
786 double m_maximumInterestRoundTripTime;
787 double m_totalInterestRoundTripTime;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800788
789};
790
791} // namespace ndn
792
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700793int
794main(int argc, char* argv[])
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800795{
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700796 std::srand(std::time(0));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800797 ndn::NdnTrafficClient ndnTrafficClient (argv[0]);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700798 int option;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800799 while ((option = getopt(argc, argv, "hi:c:")) != -1) {
800 switch (option) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700801 case 'h':
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800802 ndnTrafficClient.usage();
803 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700804 case 'i':
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800805 ndnTrafficClient.setInterestInterval(atoi(optarg));
806 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700807 case 'c':
808 ndnTrafficClient.setMaximumInterests(atoi(optarg));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800809 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700810 default:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800811 ndnTrafficClient.usage();
812 break;
813 }
814 }
815
816 argc -= optind;
817 argv += optind;
818
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700819 if (argv[0] == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800820 ndnTrafficClient.usage();
821
822 ndnTrafficClient.setConfigurationFile(argv[0]);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700823 ndnTrafficClient.run();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800824
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700825 if (ndnTrafficClient.hasError())
826 return 1;
827 else
828 return 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800829}