blob: 135d4ceb488d715a6cedf0277861c6b13bc2dd8e [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>
19#include <boost/date_time/posix_time/posix_time.hpp>
20
21#include <ndn-cpp-dev/face.hpp>
22#include <ndn-cpp-dev/exclude.hpp>
23#include <ndn-cpp-dev/name-component.hpp>
24#include <ndn-cpp-dev/security/key-chain.hpp>
25
26namespace ndn {
27
28class NdnTrafficClient
29{
30public:
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070031 NdnTrafficClient(char* programName)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080032 : m_logger("NDNTrafficClient")
33 , ioService_(new boost::asio::io_service)
34 , face_(ioService_)
35 , keyChain_()
36 {
37 std::srand(std::time(0));
38 instanceId_ = toString(std::rand());
39 programName_ = programName;
40 interestInterval_ = getDefaultInterestInterval();
41 interestCount_ = getDefaultInterestCount();
42 configurationFile_ = "";
43 totalInterestSent_ = 0;
44 totalInterestReceived_ = 0;
45 minimumInterestRoundTripTime_ = std::numeric_limits<double>::max();
46 maximumInterestRoundTripTime_ = 0;
47 totalInterestRoundTripTime_ = 0;
48 }
49
50 class InterestTrafficConfiguration
51 {
52 public:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080053 InterestTrafficConfiguration()
54 {
55 trafficPercentage = -1;
56 name = "";
57 nameAppendBytes = -1;
58 nameAppendSequenceNumber = -1;
59 minSuffixComponents = -1;
60 maxSuffixComponents = -1;
61 excludeBefore = "";
62 excludeAfter = "";
63 excludeBeforeBytes = -1;
64 excludeAfterBytes = -1;
65 childSelector = -1;
66 mustBeFresh = -1;
67 nonceDuplicationPercentage = -1;
68 scope = -1;
69 interestLifetime = -1;
70 totalInterestSent = 0;
71 totalInterestReceived = 0;
72 minimumInterestRoundTripTime = std::numeric_limits<double>::max();
73 maximumInterestRoundTripTime = 0;
74 totalInterestRoundTripTime = 0;
jeraldabraham473ef3d2014-03-06 12:40:35 -070075 contentInconsistencies = 0;
76 expectedContent = "";
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080077 }
78
79 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070080 printTrafficConfiguration(Logger& logger)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080081 {
82 std::string detail;
83 detail = "";
84 if (trafficPercentage > 0)
85 detail += "TrafficPercentage="+toString(trafficPercentage)+", ";
86 if (name != "")
87 detail += "Name="+name+", ";
88 if (nameAppendBytes > 0)
89 detail += "NameAppendBytes="+toString(nameAppendBytes)+", ";
90 if (nameAppendSequenceNumber > 0)
91 detail += "NameAppendSequenceNumber="+toString(nameAppendSequenceNumber)+", ";
92 if (minSuffixComponents >= 0)
93 detail += "MinSuffixComponents="+toString(minSuffixComponents)+", ";
94 if (maxSuffixComponents >= 0)
95 detail += "MaxSuffixComponents="+toString(maxSuffixComponents)+", ";
96 if (excludeBefore != "")
97 detail += "ExcludeBefore="+excludeBefore+", ";
98 if (excludeAfter != "")
99 detail += "ExcludeAfter="+excludeAfter+", ";
100 if (excludeBeforeBytes > 0)
101 detail += "ExcludeBeforeBytes="+toString(excludeBeforeBytes)+", ";
102 if (excludeAfterBytes > 0)
103 detail += "ExcludeAfterBytes="+toString(excludeAfterBytes)+", ";
104 if (childSelector >= 0)
105 detail += "ChildSelector="+toString(childSelector)+", ";
106 if (mustBeFresh >= 0)
107 detail += "MustBeFresh="+toString(mustBeFresh)+", ";
108 if (nonceDuplicationPercentage > 0)
109 detail += "NonceDuplicationPercentage="+toString(nonceDuplicationPercentage)+", ";
110 if (scope >= 0)
111 detail += "Scope="+toString(scope)+", ";
112 if (interestLifetime >= 0)
113 detail += "InterestLifetime="+toString(interestLifetime)+", ";
jeraldabraham473ef3d2014-03-06 12:40:35 -0700114 if (expectedContent != "")
115 detail += "ExpectedContent="+expectedContent+", ";
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800116 if (detail.length() >= 2)
117 detail = detail.substr(0, detail.length()-2);
118 logger.log(detail, false, false);
119 }
120
121 bool
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700122 extractParameterValue(const std::string& detail, std::string& parameter, std::string& value)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800123 {
124 int i;
125 std::string allowedCharacters = ":/+._-%";
126 parameter = "";
127 value = "";
128 i = 0;
129 while (detail[i] != '=' && i < detail.length())
130 {
131 parameter += detail[i];
132 i++;
133 }
134 if (i == detail.length())
135 return false;
136 i++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700137 while ((std::isalnum(detail[i]) || allowedCharacters.find(detail[i]) != std::string::npos) &&
138 i < detail.length())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800139 {
140 value += detail[i];
141 i++;
142 }
143 if(parameter == "" || value == "")
144 return false;
145 return true;
146 }
147
148 bool
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700149 processConfigurationDetail(const std::string& detail, Logger& logger, int lineNumber)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800150 {
151 std::string parameter, value;
152 if (extractParameterValue(detail, parameter, value))
153 {
154 if (parameter == "TrafficPercentage")
155 trafficPercentage = toInteger(value);
156 else if (parameter == "Name")
157 name = value;
158 else if (parameter == "NameAppendBytes")
159 nameAppendBytes = toInteger(value);
160 else if (parameter == "NameAppendSequenceNumber")
161 nameAppendSequenceNumber = toInteger(value);
162 else if (parameter == "MinSuffixComponents")
163 minSuffixComponents = toInteger(value);
164 else if (parameter == "MaxSuffixComponents")
165 maxSuffixComponents = toInteger(value);
166 else if (parameter == "ExcludeBefore")
167 excludeBefore = value;
168 else if (parameter == "ExcludeAfter")
169 excludeAfter = value;
170 else if (parameter == "ExcludeBeforeBytes")
171 excludeBeforeBytes = toInteger(value);
172 else if (parameter == "ExcludeAfterBytes")
173 excludeAfterBytes = toInteger(value);
174 else if (parameter == "ChildSelector")
175 childSelector = toInteger(value);
176 else if (parameter == "MustBeFresh")
177 mustBeFresh = toInteger(value);
178 else if (parameter == "NonceDuplicationPercentage")
179 nonceDuplicationPercentage = toInteger(value);
180 else if (parameter == "Scope")
181 scope = toInteger(value);
182 else if (parameter == "InterestLifetime")
183 interestLifetime = toInteger(value);
jeraldabraham473ef3d2014-03-06 12:40:35 -0700184 else if (parameter == "ExpectedContent")
185 expectedContent = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800186 else
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700187 logger.log("Line "+toString(lineNumber) +
188 " \t- Invalid Parameter='"+parameter+"'", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800189 }
190 else
191 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700192 logger.log("Line "+toString(lineNumber) +
193 " \t- Improper Traffic Configuration Line- "+detail, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800194 return false;
195 }
196 return true;
197 }
198
199 bool
200 checkTrafficDetailCorrectness()
201 {
202 return true;
203 }
204
205 int trafficPercentage;
206 std::string name;
207 int nameAppendBytes;
208 int nameAppendSequenceNumber;
209 int minSuffixComponents;
210 int maxSuffixComponents;
211 std::string excludeBefore;
212 std::string excludeAfter;
213 int excludeBeforeBytes;
214 int excludeAfterBytes;
215 int childSelector;
216 int mustBeFresh;
217 int nonceDuplicationPercentage;
218 int scope;
219 int interestLifetime;
220 int totalInterestSent;
221 int totalInterestReceived;
222 double minimumInterestRoundTripTime;
223 double maximumInterestRoundTripTime;
224 double totalInterestRoundTripTime;
jeraldabraham473ef3d2014-03-06 12:40:35 -0700225 int contentInconsistencies;
226 std::string expectedContent;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700227 }; // class InterestTrafficConfiguration
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800228
229 int
230 getDefaultInterestLifetime()
231 {
232 return 4000;
233 }
234
235 static std::string
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700236 toString(int integerValue)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800237 {
238 std::stringstream stream;
239 stream << integerValue;
240 return stream.str();
241 }
242
243 static std::string
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700244 toString(double doubleValue)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800245 {
246 std::stringstream stream;
247 stream << doubleValue;
248 return stream.str();
249 }
250
251 static int
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700252 toInteger(const std::string& stringValue)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800253 {
254 int integerValue;
255 std::stringstream stream(stringValue);
256 stream >> integerValue;
257 return integerValue;
258 }
259
260 void
261 usage()
262 {
263
264 std::cout << "\nUsage: " << programName_ << " [options] <Traffic_Configuration_File>\n"
265 "Generate Interest Traffic as per provided Traffic Configuration File\n"
266 "Interests are continuously generated unless a total number is specified.\n"
267 "Set environment variable NDN_TRAFFIC_LOGFOLDER for redirecting output to a log.\n"
268 " [-i interval] - set interest generation interval in milliseconds (minimum "
269 << getDefaultInterestInterval() << " milliseconds)\n"
270 " [-c count] - set total number of interests to be generated\n"
271 " [-h] - print help and exit\n\n";
272 exit(1);
273
274 }
275
276 int
277 getDefaultInterestInterval()
278 {
279 return 1000;
280 }
281
282 int
283 getDefaultInterestCount()
284 {
285 return -1;
286 }
287
288 void
289 setInterestInterval( int interestInterval )
290 {
291 if (interestInterval < 0)
292 usage();
293 interestInterval_ = interestInterval;
294 }
295
296 void
297 setInterestCount( int interestCount )
298 {
299 if (interestCount < 0)
300 usage();
301 interestCount_ = interestCount;
302 }
303
304 void
305 setConfigurationFile( char* configurationFile )
306 {
307 configurationFile_ = configurationFile;
308 }
309
310 void
311 signalHandler()
312 {
313 m_logger.shutdownLogger();
314 face_.shutdown();
315 ioService_.reset();
316 logStatistics();
317 exit(1);
318 }
319
320 void
321 logStatistics()
322 {
323 int patternId;
jeraldabraham473ef3d2014-03-06 12:40:35 -0700324 double loss, average, inconsistency;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800325
326 m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700327 m_logger.log("Total Traffic Pattern Types = " + toString((int)trafficPattern_.size()), false, true);
328 m_logger.log("Total Interests Sent = " + toString(totalInterestSent_), false, true);
329 m_logger.log("Total Responses Received = " + toString(totalInterestReceived_), false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800330 if (totalInterestSent_ > 0)
331 loss = (totalInterestSent_-totalInterestReceived_)*100.0/totalInterestSent_;
332 else
333 loss = 0;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700334 m_logger.log("Total Interest Loss = " + toString(loss)+"%", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800335 if (totalInterestReceived_ > 0)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700336 {
337 average = totalInterestRoundTripTime_/totalInterestReceived_;
338 inconsistency = contentInconsistencies_*100.0/totalInterestReceived_;
339 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800340 else
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700341 {
342 average = 0;
343 inconsistency = 0;
344 }
345 m_logger.log("Total Data Inconsistency = " + toString(inconsistency)+"%", false, true);
346 m_logger.log("Total Round Trip Time = " +
347 toString(totalInterestRoundTripTime_)+"ms", false, true);
348 m_logger.log("Average Round Trip Time = " + toString(average)+"ms\n", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800349
350 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
351 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700352 m_logger.log("Traffic Pattern Type #" + toString(patternId+1), false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800353 trafficPattern_[patternId].printTrafficConfiguration(m_logger);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700354 m_logger.log("Total Interests Sent = " +
355 toString(trafficPattern_[patternId].totalInterestSent), false, true);
356 m_logger.log("Total Responses Received = " +
357 toString(trafficPattern_[patternId].totalInterestReceived), false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800358 if (trafficPattern_[patternId].totalInterestSent > 0)
359 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700360 loss = (trafficPattern_[patternId].totalInterestSent -
361 trafficPattern_[patternId].totalInterestReceived);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800362 loss *= 100.0;
363 loss /= trafficPattern_[patternId].totalInterestSent;
364 }
365 else
366 loss = 0;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700367 m_logger.log("Total Interest Loss = " + toString(loss)+"%", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800368 if (trafficPattern_[patternId].totalInterestReceived > 0)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700369 {
370 average = (trafficPattern_[patternId].totalInterestRoundTripTime /
371 trafficPattern_[patternId].totalInterestReceived);
372 inconsistency = trafficPattern_[patternId].contentInconsistencies;
373 inconsistency = inconsistency * 100.0 / trafficPattern_[patternId].totalInterestReceived;
374 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800375 else
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700376 {
377 average = 0;
378 inconsistency = 0;
379 }
380 m_logger.log("Total Data Inconsistency = " + toString(inconsistency)+"%", false, true);
381 m_logger.log("Total Round Trip Time = " +
382 toString(trafficPattern_[patternId].totalInterestRoundTripTime)+"ms",
383 false, true);
384 m_logger.log("Average Round Trip Time = " + toString(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
395 analyzeConfigurationFile()
396 {
397 int patternId;
398 int lineNumber;
399 bool skipLine;
400 std::string patternLine;
401 std::ifstream patternFile;
402 m_logger.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true);
403 patternFile.open(configurationFile_.c_str());
404 if (patternFile.is_open())
405 {
406 patternId = 0;
407 lineNumber = 0;
408 while (getline(patternFile, patternLine))
409 {
410 lineNumber++;
411 if (std::isalpha(patternLine[0]))
412 {
413 InterestTrafficConfiguration interestData;
414 skipLine = false;
415 patternId++;
416 if (interestData.processConfigurationDetail(patternLine, m_logger, lineNumber))
417 {
418 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
419 {
420 lineNumber++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700421 if (!interestData.processConfigurationDetail(patternLine,
422 m_logger, lineNumber))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800423 {
424 skipLine = true;
425 break;
426 }
427 }
428 lineNumber++;
429 }
430 else
431 skipLine = true;
432 if( !skipLine )
433 {
434 if (interestData.checkTrafficDetailCorrectness())
435 trafficPattern_.push_back(interestData);
436 }
437 }
438 }
439 patternFile.close();
440 if (!checkTrafficPatternCorrectness())
441 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700442 m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper- " +
443 configurationFile_, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800444 m_logger.shutdownLogger();
445 exit(1);
446 }
447 m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
448 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
449 {
450 m_logger.log("Traffic Pattern Type #"+toString(patternId+1), false, false);
451 trafficPattern_[patternId].printTrafficConfiguration(m_logger);
452 m_logger.log("", false, false);
453 }
454 }
455 else
456 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700457 m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
458 configurationFile_, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800459 m_logger.shutdownLogger();
460 exit(1);
461 }
462 }
463
464 void
465 initializeTrafficConfiguration()
466 {
467 if (boost::filesystem::exists(boost::filesystem::path(configurationFile_)))
468 {
469 if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_)))
470 {
471 analyzeConfigurationFile();
472 }
473 else
474 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700475 m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
476 configurationFile_, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800477 m_logger.shutdownLogger();
478 exit(1);
479 }
480 }
481 else
482 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700483 m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
484 configurationFile_, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800485 m_logger.shutdownLogger();
486 exit(1);
487 }
488 }
489
490 int
491 getOldNonce()
492 {
493 int randomNonceKey;
494 if (nonceList_.size() == 0)
495 return getNewNonce();
496 std::srand(std::time(0));
497 randomNonceKey = std::rand() % nonceList_.size();
498 return nonceList_[randomNonceKey];
499 }
500
501 int
502 getNewNonce()
503 {
504 int randomNonceKey, i;
505 bool isOld;
506 isOld = true;
507 std::srand(std::time(0));
jeraldabraham473ef3d2014-03-06 12:40:35 -0700508
509 //Performance Enhancement
510 if (nonceList_.size() > 1000)
511 nonceList_.clear();
512
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800513 do
514 {
515 randomNonceKey = std::rand();
516 isOld = false;
517 for (i=0; i<nonceList_.size(); i++)
518 if (nonceList_[i] == randomNonceKey)
519 isOld = true;
520 } while(isOld);
521 nonceList_.push_back(randomNonceKey);
522 return randomNonceKey;
523 }
524
525 static std::string
526 getRandomByteString( int randomSize )
527 {
528 int i;
529 std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789";
530 std::string randomData;
531 for (i=0; i<randomSize; i++)
532 randomData += characterSet[std::rand() % characterSet.length()];
533 return randomData;
534 }
535
536 void
537 onData( ndn::Face &face,
538 const ndn::Interest& interest,
539 ndn::Data& data,
540 int globalReference,
541 int localReference,
542 int patternId,
543 boost::posix_time::ptime sentTime )
544 {
545 double roundTripTime;
jeraldabraham473ef3d2014-03-06 12:40:35 -0700546 int receivedContentLength;
547 std::string receivedContent;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800548 std::string logLine;
549 logLine = "";
550 logLine += "Data Received - PatternType="+toString(patternId+1);
551 logLine += ", GlobalID="+toString(globalReference);
552 logLine += ", LocalID="+toString(localReference);
553 logLine += ", Name="+interest.getName().toUri();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800554 boost::posix_time::time_duration roundTripDuration;
555 totalInterestReceived_++;
556 trafficPattern_[patternId].totalInterestReceived++;
jeraldabraham473ef3d2014-03-06 12:40:35 -0700557 if (trafficPattern_[patternId].expectedContent != "")
jeraldabraham473ef3d2014-03-06 12:40:35 -0700558 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700559 receivedContent = (char*)(data.getContent().value());
560 receivedContentLength = data.getContent().value_size();
561 receivedContent = receivedContent.substr(0, receivedContentLength);
562 if (receivedContent != trafficPattern_[patternId].expectedContent)
563 {
564 contentInconsistencies_++;
565 trafficPattern_[patternId].contentInconsistencies++;
566 logLine += ", IsConsistent=No";
567 }
568 else
569 logLine += ", IsConsistent=Yes";
jeraldabraham473ef3d2014-03-06 12:40:35 -0700570 }
jeraldabraham473ef3d2014-03-06 12:40:35 -0700571 else
572 logLine += ", IsConsistent=NotChecked";
573 m_logger.log(logLine, true, false);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800574 roundTripDuration = boost::posix_time::microsec_clock::local_time() - sentTime;
575 roundTripTime = roundTripDuration.total_microseconds()/1000.0;
576 if (minimumInterestRoundTripTime_ > roundTripTime)
577 minimumInterestRoundTripTime_ = roundTripTime;
578 if (maximumInterestRoundTripTime_ < roundTripTime)
579 maximumInterestRoundTripTime_ = roundTripTime;
580 if (trafficPattern_[patternId].minimumInterestRoundTripTime > roundTripTime)
581 trafficPattern_[patternId].minimumInterestRoundTripTime = roundTripTime;
582 if (trafficPattern_[patternId].maximumInterestRoundTripTime < roundTripTime)
583 trafficPattern_[patternId].maximumInterestRoundTripTime = roundTripTime;
584 totalInterestRoundTripTime_ += roundTripTime;
585 trafficPattern_[patternId].totalInterestRoundTripTime += roundTripTime;
586 if (totalInterestSent_ == interestCount_)
587 signalHandler();
588 }
589
590 void
591 onTimeout( ndn::Face &face,
592 const ndn::Interest& interest,
593 int globalReference,
594 int localReference,
595 int patternId)
596 {
597 std::string logLine;
598 logLine = "";
599 logLine += "Interest Timed Out - PatternType="+toString(patternId+1);
600 logLine += ", GlobalID="+toString(globalReference);
601 logLine += ", LocalID="+toString(localReference);
602 logLine += ", Name="+interest.getName().toUri();
603 m_logger.log(logLine, true, false);
604 if (totalInterestSent_ == interestCount_)
605 signalHandler();
606 }
607
608 void
609 generateTraffic( const boost::system::error_code& errorCode,
610 boost::asio::deadline_timer* deadlineTimer )
611 {
612 if ((interestCount_ < 0) || (totalInterestSent_ < interestCount_))
613 {
614 int trafficKey, patternId, cumulativePercentage;
615 std::srand(std::time(0));
616 trafficKey = std::rand() % 100;
617 cumulativePercentage = 0;
618 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
619 {
620 cumulativePercentage += trafficPattern_[patternId].trafficPercentage;
621 if (trafficKey <= cumulativePercentage)
622 {
623 Name interestName(trafficPattern_[patternId].name);
624 if (trafficPattern_[patternId].nameAppendBytes > 0)
625 interestName.append(getRandomByteString(trafficPattern_[patternId].nameAppendBytes));
626 if (trafficPattern_[patternId].nameAppendSequenceNumber >= 0)
627 {
628 interestName.append(toString(trafficPattern_[patternId].nameAppendSequenceNumber));
629 trafficPattern_[patternId].nameAppendSequenceNumber++;
630 }
631 Interest interest(interestName);
632 if (trafficPattern_[patternId].minSuffixComponents >= 0)
633 interest.setMinSuffixComponents(trafficPattern_[patternId].minSuffixComponents);
634 if (trafficPattern_[patternId].maxSuffixComponents >= 0)
635 interest.setMaxSuffixComponents(trafficPattern_[patternId].maxSuffixComponents);
636 Exclude exclude;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700637 if (trafficPattern_[patternId].excludeBefore != "" &&
638 trafficPattern_[patternId].excludeAfter != "")
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800639 {
640 exclude.excludeRange(name::Component(trafficPattern_[patternId].excludeAfter),
641 name::Component(trafficPattern_[patternId].excludeBefore));
642 interest.setExclude(exclude);
643 }
644 else if (trafficPattern_[patternId].excludeBefore != "")
645 {
646 exclude.excludeBefore(name::Component(trafficPattern_[patternId].excludeBefore));
647 interest.setExclude(exclude);
648 }
649 else if (trafficPattern_[patternId].excludeAfter != "")
650 {
651 exclude.excludeAfter(name::Component(trafficPattern_[patternId].excludeAfter));
652 interest.setExclude(exclude);
653 }
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700654 if (trafficPattern_[patternId].excludeBeforeBytes > 0 &&
655 trafficPattern_[patternId].excludeAfterBytes > 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800656 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700657 exclude.excludeRange(
658 name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)),
659 name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800660 interest.setExclude(exclude);
661 }
662 else if (trafficPattern_[patternId].excludeBeforeBytes > 0)
663 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700664 exclude.excludeBefore(
665 name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800666 interest.setExclude(exclude);
667 }
668 else if (trafficPattern_[patternId].excludeAfterBytes > 0)
669 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700670 exclude.excludeAfter(
671 name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800672 interest.setExclude(exclude);
673 }
674
675 if (trafficPattern_[patternId].childSelector >= 0)
676 interest.setChildSelector(trafficPattern_[patternId].childSelector);
677
678 if (trafficPattern_[patternId].mustBeFresh == 0)
679 interest.setMustBeFresh(false);
680 else if (trafficPattern_[patternId].mustBeFresh > 0)
681 interest.setMustBeFresh(true);
682 if (trafficPattern_[patternId].nonceDuplicationPercentage > 0)
683 {
684 int duplicationKey;
685 std::srand(std::time(0));
686 duplicationKey = std::rand() % 100;
687 if (trafficPattern_[patternId].nonceDuplicationPercentage <= duplicationKey)
688 interest.setNonce(getOldNonce());
689 else
690 interest.setNonce(getNewNonce());
691 }
692 else
693 interest.setNonce(getNewNonce());
694 if (trafficPattern_[patternId].scope >= 0)
695 interest.setScope(trafficPattern_[patternId].scope);
696 if (trafficPattern_[patternId].interestLifetime >= 0)
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700697 interest.setInterestLifetime(
698 time::milliseconds(trafficPattern_[patternId].interestLifetime));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800699 else
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700700 interest.setInterestLifetime(
701 time::milliseconds(getDefaultInterestLifetime()));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800702 try {
703 totalInterestSent_++;
704 trafficPattern_[patternId].totalInterestSent++;
705 boost::posix_time::ptime sentTime;
706 sentTime = boost::posix_time::microsec_clock::local_time();
707 face_.expressInterest(interest,
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700708 bind( &NdnTrafficClient::onData,
709 this, boost::ref(face_),
710 _1, _2, totalInterestSent_,
711 trafficPattern_[patternId].totalInterestSent,
712 patternId,
713 sentTime),
714 bind( &NdnTrafficClient::onTimeout,
715 this, boost::ref(face_),
716 _1, totalInterestSent_,
717 trafficPattern_[patternId].totalInterestSent,
718 patternId));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800719 std::string logLine;
720 logLine = "";
721 logLine += "Sending Interest - PatternType="+toString(patternId+1);
722 logLine += ", GlobalID="+toString(totalInterestSent_);
723 logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestSent);
724 logLine += ", Name="+interest.getName().toUri();
725 m_logger.log(logLine, true, false);
726 deadlineTimer->expires_at(deadlineTimer->expires_at() +
727 boost::posix_time::millisec(interestInterval_));
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700728 deadlineTimer->async_wait(bind(&NdnTrafficClient::generateTraffic,
729 this,
730 boost::asio::placeholders::error,
731 deadlineTimer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800732 }
733 catch (std::exception &e) {
734 m_logger.log("ERROR: "+(std::string)e.what(), true, true);
735 }
736 break;
737 }
738 }
739 if (patternId==trafficPattern_.size())
740 {
741 deadlineTimer->expires_at(deadlineTimer->expires_at() +
742 boost::posix_time::millisec(interestInterval_));
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700743 deadlineTimer->async_wait(bind(&NdnTrafficClient::generateTraffic,
744 this,
745 boost::asio::placeholders::error,
746 deadlineTimer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800747 }
748 }
749 }
750
751 void
752 initialize()
753 {
754 boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700755 signalSet.async_wait(bind(&NdnTrafficClient::signalHandler, this));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800756 m_logger.initializeLog(instanceId_);
757 initializeTrafficConfiguration();
758 boost::asio::deadline_timer deadlineTimer(*ioService_,
759 boost::posix_time::millisec(interestInterval_));
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700760 deadlineTimer.async_wait(bind(&NdnTrafficClient::generateTraffic,
761 this,
762 boost::asio::placeholders::error,
763 &deadlineTimer));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800764 try {
765 face_.processEvents();
766 }
767 catch(std::exception &e) {
768 m_logger.log("ERROR: "+(std::string)e.what(), true, true);
769 m_logger.shutdownLogger();
770 }
771 }
772
773private:
774
775 KeyChain keyChain_;
776 std::string programName_;
777 std::string instanceId_;
778 int interestInterval_;
779 int interestCount_;
780 Logger m_logger;
781 std::string configurationFile_;
782 ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
783 Face face_;
784 std::vector<InterestTrafficConfiguration> trafficPattern_;
785 std::vector<int> nonceList_;
786 int totalInterestSent_;
787 int totalInterestReceived_;
jeraldabraham473ef3d2014-03-06 12:40:35 -0700788 int contentInconsistencies_;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800789 double minimumInterestRoundTripTime_;
790 double maximumInterestRoundTripTime_;
791 double totalInterestRoundTripTime_;
792
793};
794
795} // namespace ndn
796
797int main( int argc, char* argv[] )
798{
799 int option;
800 ndn::NdnTrafficClient ndnTrafficClient (argv[0]);
801 while ((option = getopt(argc, argv, "hi:c:")) != -1) {
802 switch (option) {
803 case 'h' :
804 ndnTrafficClient.usage();
805 break;
806 case 'i' :
807 ndnTrafficClient.setInterestInterval(atoi(optarg));
808 break;
809 case 'c' :
810 ndnTrafficClient.setInterestCount(atoi(optarg));
811 break;
812 default :
813 ndnTrafficClient.usage();
814 break;
815 }
816 }
817
818 argc -= optind;
819 argv += optind;
820
821 if (argv[0] == NULL)
822 ndnTrafficClient.usage();
823
824 ndnTrafficClient.setConfigurationFile(argv[0]);
825 ndnTrafficClient.initialize();
826
827 return 0;
828}