blob: b617b1cc207adbcf0e1bea7d8bfa3376102842b9 [file] [log] [blame]
jeraldabrahamf9543a42014-02-11 06:37:34 -07001/**
2 *
jeraldabrahame891ac92014-02-16 11:04:01 -07003 * Copyright (C) 2014 University of Arizona.
jeraldabrahamf9543a42014-02-11 06:37:34 -07004 * @author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
5 *
6 */
7
jeraldabrahame891ac92014-02-16 11:04:01 -07008#include <string>
9#include <sstream>
10#include <fstream>
11#include <vector>
12#include <boost/asio.hpp>
jeraldabraham662266d2014-02-17 10:26:12 -070013#include <boost/bind.hpp>
jeraldabraham89a58422014-02-18 14:27:14 -070014#include <boost/filesystem.hpp>
jeraldabraham662266d2014-02-17 10:26:12 -070015#include <boost/date_time/posix_time/posix_time.hpp>
jeraldabrahame891ac92014-02-16 11:04:01 -070016
17#include <ndn-cpp-dev/face.hpp>
jeraldabraham662266d2014-02-17 10:26:12 -070018#include <ndn-cpp-dev/exclude.hpp>
19#include <ndn-cpp-dev/name-component.hpp>
jeraldabrahamf9543a42014-02-11 06:37:34 -070020#include <ndn-cpp-dev/security/key-chain.hpp>
21
22using namespace ndn;
23
jeraldabrahame891ac92014-02-16 11:04:01 -070024class Logger
25{
26public:
27
28 Logger()
29 {
30 logLocation_ = "";
31 }
32
33 void
34 shutdownLogger()
35 {
36 if (logFile_.is_open())
jeraldabraham89a58422014-02-18 14:27:14 -070037 {
38 log("Terminating Logging Operations" , true, true);
jeraldabrahame891ac92014-02-16 11:04:01 -070039 logFile_.close();
jeraldabraham89a58422014-02-18 14:27:14 -070040 }
jeraldabrahame891ac92014-02-16 11:04:01 -070041 }
42
jeraldabraham662266d2014-02-17 10:26:12 -070043 static std::string
44 getTimestamp()
45 {
46 boost::posix_time::ptime now;
47 now = boost::posix_time::second_clock::local_time();
48 return to_simple_string(now);
49 }
50
jeraldabrahame891ac92014-02-16 11:04:01 -070051 void
jeraldabraham662266d2014-02-17 10:26:12 -070052 log( std::string logLine, bool printTime, bool printToConsole )
jeraldabrahame891ac92014-02-16 11:04:01 -070053 {
54 if( logLocation_.length() > 0 )
55 {
jeraldabraham662266d2014-02-17 10:26:12 -070056 if (printTime)
57 logFile_ << getTimestamp() << " - ";
jeraldabrahame891ac92014-02-16 11:04:01 -070058 logFile_ << logLine << std::endl;
59 logFile_.flush();
jeraldabraham662266d2014-02-17 10:26:12 -070060 if (printToConsole)
61 {
62 if (printTime)
63 std::cout << getTimestamp() << " - ";
64 std::cout << logLine << std::endl;
65 }
jeraldabrahame891ac92014-02-16 11:04:01 -070066 }
67 else
jeraldabraham662266d2014-02-17 10:26:12 -070068 {
69 if (printTime)
70 std::cout << getTimestamp() << " - ";
jeraldabrahame891ac92014-02-16 11:04:01 -070071 std::cout << logLine << std::endl;
jeraldabraham662266d2014-02-17 10:26:12 -070072 }
jeraldabrahame891ac92014-02-16 11:04:01 -070073 }
74
75 void
76 initializeLog( std::string instanceId )
77 {
78 char* variableValue = std::getenv("NDN_TRAFFIC_LOGFOLDER");
79 std::string logFilename;
80 logLocation_ = "";
81 if (variableValue != NULL)
82 logLocation_ = variableValue;
83 if (boost::filesystem::exists(boost::filesystem::path(logLocation_)))
84 {
85 if (boost::filesystem::is_directory(boost::filesystem::path(logLocation_)))
86 {
87 logFilename = logLocation_+"/NDNTrafficClient_"+instanceId+".log";
88 logFile_.open(logFilename.c_str(), std::ofstream::out | std::ofstream::trunc);
89 if (logFile_.is_open())
90 std::cout << "Log File Initialized: " << logFilename << std::endl;
91 else
92 {
93 std::cout << "ERROR - Unable To Initialize A Log File At: " << logLocation_ << std::endl
94 << "Using Default Output For Logging." << std::endl;
95 logLocation_ = "";
96 }
97 }
98 else
99 {
100 std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Should Be A Folder." << std::endl
101 << "Using Default Output For Logging." << std::endl;
102 logLocation_ = "";
103 }
104 }
105 else
106 {
107 std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Not Set." << std::endl
108 << "Using Default Output For Logging." << std::endl;
109 logLocation_ = "";
110 }
111 }
112
113private:
114
115 std::string logLocation_;
116 std::ofstream logFile_;
117
118};
119
jeraldabrahamf9543a42014-02-11 06:37:34 -0700120class NdnTrafficClient
121{
122public:
123
jeraldabraham89a58422014-02-18 14:27:14 -0700124 NdnTrafficClient( char* programName ) : ioService_(new boost::asio::io_service), face_(ioService_), keyChain_()
jeraldabrahamf9543a42014-02-11 06:37:34 -0700125 {
jeraldabrahame891ac92014-02-16 11:04:01 -0700126 std::srand(std::time(0));
127 instanceId_ = toString(std::rand());
jeraldabrahamf9543a42014-02-11 06:37:34 -0700128 programName_ = programName;
129 interestInterval_ = getDefaultInterestInterval();
130 interestCount_ = getDefaultInterestCount();
jeraldabrahamf9543a42014-02-11 06:37:34 -0700131 configurationFile_ = "";
jeraldabraham662266d2014-02-17 10:26:12 -0700132 totalInterestSent_ = 0;
133 totalInterestReceived_ = 0;
134 minimumInterestRoundTripTime_ = std::numeric_limits<double>::max();
135 maximumInterestRoundTripTime_ = 0;
136 totalInterestRoundTripTime_ = 0;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700137 }
138
jeraldabrahame891ac92014-02-16 11:04:01 -0700139 class InterestTrafficConfiguration
140 {
141 public:
142
143 InterestTrafficConfiguration()
144 {
145 trafficPercentage = -1;
146 name = "";
147 nameAppendBytes = -1;
148 nameAppendSequenceNumber = -1;
149 minSuffixComponents = -1;
150 maxSuffixComponents = -1;
151 excludeBefore = "";
152 excludeAfter = "";
153 excludeBeforeBytes = -1;
154 excludeAfterBytes = -1;
155 childSelector = -1;
156 mustBeFresh = -1;
157 nonceDuplicationPercentage = -1;
158 scope = -1;
jeraldabraham89a58422014-02-18 14:27:14 -0700159 interestLifetime = -1;
jeraldabraham662266d2014-02-17 10:26:12 -0700160 totalInterestSent = 0;
161 totalInterestReceived = 0;
162 minimumInterestRoundTripTime = std::numeric_limits<double>::max();
163 maximumInterestRoundTripTime = 0;
164 totalInterestRoundTripTime = 0;
165 }
166
jeraldabrahame891ac92014-02-16 11:04:01 -0700167 void
168 printTrafficConfiguration( Logger& logger )
169 {
170 std::string detail;
171 detail = "";
172 if (trafficPercentage > 0)
173 detail += "TrafficPercentage="+toString(trafficPercentage)+", ";
174 if (name != "")
175 detail += "Name="+name+", ";
jeraldabraham89a58422014-02-18 14:27:14 -0700176 if (nameAppendBytes > 0)
jeraldabrahame891ac92014-02-16 11:04:01 -0700177 detail += "NameAppendBytes="+toString(nameAppendBytes)+", ";
jeraldabraham89a58422014-02-18 14:27:14 -0700178 if (nameAppendSequenceNumber > 0)
jeraldabrahame891ac92014-02-16 11:04:01 -0700179 detail += "NameAppendSequenceNumber="+toString(nameAppendSequenceNumber)+", ";
jeraldabraham89a58422014-02-18 14:27:14 -0700180 if (minSuffixComponents >= 0)
jeraldabrahame891ac92014-02-16 11:04:01 -0700181 detail += "MinSuffixComponents="+toString(minSuffixComponents)+", ";
jeraldabraham89a58422014-02-18 14:27:14 -0700182 if (maxSuffixComponents >= 0)
jeraldabrahame891ac92014-02-16 11:04:01 -0700183 detail += "MaxSuffixComponents="+toString(maxSuffixComponents)+", ";
184 if (excludeBefore != "")
185 detail += "ExcludeBefore="+excludeBefore+", ";
186 if (excludeAfter != "")
187 detail += "ExcludeAfter="+excludeAfter+", ";
188 if (excludeBeforeBytes > 0)
189 detail += "ExcludeBeforeBytes="+toString(excludeBeforeBytes)+", ";
190 if (excludeAfterBytes > 0)
191 detail += "ExcludeAfterBytes="+toString(excludeAfterBytes)+", ";
jeraldabraham89a58422014-02-18 14:27:14 -0700192 if (childSelector >= 0)
jeraldabrahame891ac92014-02-16 11:04:01 -0700193 detail += "ChildSelector="+toString(childSelector)+", ";
jeraldabraham89a58422014-02-18 14:27:14 -0700194 if (mustBeFresh >= 0)
jeraldabrahame891ac92014-02-16 11:04:01 -0700195 detail += "MustBeFresh="+toString(mustBeFresh)+", ";
196 if (nonceDuplicationPercentage > 0)
197 detail += "NonceDuplicationPercentage="+toString(nonceDuplicationPercentage)+", ";
jeraldabraham89a58422014-02-18 14:27:14 -0700198 if (scope >= 0)
jeraldabrahame891ac92014-02-16 11:04:01 -0700199 detail += "Scope="+toString(scope)+", ";
jeraldabraham89a58422014-02-18 14:27:14 -0700200 if (interestLifetime >= 0)
jeraldabrahame891ac92014-02-16 11:04:01 -0700201 detail += "InterestLifetime="+toString(interestLifetime)+", ";
202 if (detail.length() >= 0)
203 detail = detail.substr(0, detail.length()-2);
jeraldabraham662266d2014-02-17 10:26:12 -0700204 logger.log(detail, false, false);
jeraldabrahame891ac92014-02-16 11:04:01 -0700205 }
206
207 bool
208 extractParameterValue( std::string detail, std::string& parameter, std::string& value )
209 {
210 int i;
211 std::string allowedCharacters = ":/+._-%";
212 parameter = "";
213 value = "";
214 i = 0;
215 while (detail[i] != '=' && i < detail.length())
216 {
217 parameter += detail[i];
218 i++;
219 }
220 if (i == detail.length())
221 return false;
222 i++;
223 while ((std::isalnum(detail[i]) || allowedCharacters.find(detail[i]) != std::string::npos) && i < detail.length())
224 {
225 value += detail[i];
226 i++;
227 }
228 if(parameter == "" || value == "")
229 return false;
230 return true;
231 }
232
233 bool
234 processConfigurationDetail( std::string detail, Logger& logger, int lineNumber )
235 {
236 std::string parameter, value;
237 if (extractParameterValue(detail, parameter, value))
238 {
239 if (parameter == "TrafficPercentage")
240 trafficPercentage = toInteger(value);
241 else if (parameter == "Name")
242 name = value;
243 else if (parameter == "NameAppendBytes")
244 nameAppendBytes = toInteger(value);
245 else if (parameter == "NameAppendSequenceNumber")
246 nameAppendSequenceNumber = toInteger(value);
247 else if (parameter == "MinSuffixComponents")
248 minSuffixComponents = toInteger(value);
249 else if (parameter == "MaxSuffixComponents")
250 maxSuffixComponents = toInteger(value);
251 else if (parameter == "ExcludeBefore")
252 excludeBefore = value;
253 else if (parameter == "ExcludeAfter")
254 excludeAfter = value;
255 else if (parameter == "ExcludeBeforeBytes")
256 excludeBeforeBytes = toInteger(value);
257 else if (parameter == "ExcludeAfterBytes")
258 excludeAfterBytes = toInteger(value);
259 else if (parameter == "ChildSelector")
260 childSelector = toInteger(value);
261 else if (parameter == "MustBeFresh")
262 mustBeFresh = toInteger(value);
263 else if (parameter == "NonceDuplicationPercentage")
264 nonceDuplicationPercentage = toInteger(value);
265 else if (parameter == "Scope")
266 scope = toInteger(value);
267 else if (parameter == "InterestLifetime")
268 interestLifetime = toInteger(value);
269 else
jeraldabraham662266d2014-02-17 10:26:12 -0700270 logger.log("Line "+toString(lineNumber)+" \t- Invalid Parameter='"+parameter+"'", false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700271 }
272 else
273 {
jeraldabraham662266d2014-02-17 10:26:12 -0700274 logger.log("Line "+toString(lineNumber)+" \t- Improper Traffic Configuration Line- "+detail, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700275 return false;
276 }
277 return true;
278 }
279
280 bool
281 checkTrafficDetailCorrectness()
282 {
283 return true;
284 }
285
286 int trafficPercentage;
287 std::string name;
288 int nameAppendBytes;
289 int nameAppendSequenceNumber;
290 int minSuffixComponents;
291 int maxSuffixComponents;
292 std::string excludeBefore;
293 std::string excludeAfter;
294 int excludeBeforeBytes;
295 int excludeAfterBytes;
296 int childSelector;
297 int mustBeFresh;
298 int nonceDuplicationPercentage;
299 int scope;
300 int interestLifetime;
jeraldabraham662266d2014-02-17 10:26:12 -0700301 int totalInterestSent;
302 int totalInterestReceived;
303 double minimumInterestRoundTripTime;
304 double maximumInterestRoundTripTime;
305 double totalInterestRoundTripTime;
jeraldabrahame891ac92014-02-16 11:04:01 -0700306
307 };
308
jeraldabraham89a58422014-02-18 14:27:14 -0700309 int
310 getDefaultInterestLifetime()
311 {
312 return 4000;
313 }
314
jeraldabrahame891ac92014-02-16 11:04:01 -0700315 static std::string
316 toString( int integerValue )
317 {
318 std::stringstream stream;
319 stream << integerValue;
320 return stream.str();
321 }
322
jeraldabraham89a58422014-02-18 14:27:14 -0700323 static std::string
324 toString( double doubleValue )
325 {
326 std::stringstream stream;
327 stream << doubleValue;
328 return stream.str();
329 }
330
jeraldabrahame891ac92014-02-16 11:04:01 -0700331 static int
332 toInteger( std::string stringValue )
333 {
334 int integerValue;
335 std::stringstream stream(stringValue);
336 stream >> integerValue;
337 return integerValue;
338 }
339
jeraldabrahamf9543a42014-02-11 06:37:34 -0700340 void
341 usage()
342 {
343 std::cout << "\nUsage: " << programName_ << " Printing Usage"
jeraldabrahame891ac92014-02-16 11:04:01 -0700344 << std::endl << std::endl;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700345 exit(1);
346 }
347
348 int
349 getDefaultInterestInterval()
350 {
jeraldabrahame891ac92014-02-16 11:04:01 -0700351 return 1000;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700352 }
353
354 int
355 getDefaultInterestCount()
356 {
357 return -1;
358 }
359
jeraldabrahamf9543a42014-02-11 06:37:34 -0700360 void
361 setInterestInterval( int interestInterval )
362 {
363 if (interestInterval < 0)
364 usage();
365 interestInterval_ = interestInterval;
366 }
367
368 void
369 setInterestCount( int interestCount )
370 {
371 if (interestCount < 0)
372 usage();
373 interestCount_ = interestCount;
374 }
375
376 void
jeraldabrahamf9543a42014-02-11 06:37:34 -0700377 setConfigurationFile( char* configurationFile )
378 {
379 configurationFile_ = configurationFile;
380 }
381
jeraldabrahame891ac92014-02-16 11:04:01 -0700382 void
383 signalHandler()
384 {
385 logger_.shutdownLogger();
386 face_.shutdown();
387 ioService_.reset();
jeraldabraham89a58422014-02-18 14:27:14 -0700388 logStatistics();
jeraldabrahame891ac92014-02-16 11:04:01 -0700389 exit(1);
390 }
391
jeraldabraham89a58422014-02-18 14:27:14 -0700392 void
393 logStatistics()
394 {
395 int patternId;
396 double loss, average;
397
398 logger_.log("\n\n== Interest Traffic Report ==\n", false, true);
399 logger_.log("Total Traffic Pattern Types = "+toString((int)trafficPattern_.size()), false, true);
400 logger_.log("Total Interests Sent = "+toString(totalInterestSent_), false, true);
401 logger_.log("Total Responses Received = "+toString(totalInterestReceived_), false, true);
402 if (totalInterestSent_ > 0)
403 loss = (totalInterestSent_-totalInterestReceived_)*100.0/totalInterestSent_;
404 else
405 loss = 0;
406 logger_.log("Total Interest Loss = "+toString(loss)+"%", false, true);
407 if (totalInterestReceived_ > 0)
408 average = totalInterestRoundTripTime_/totalInterestReceived_;
409 else
410 average = 0;
411 logger_.log("Total Round Trip Time = "+toString(totalInterestRoundTripTime_)+"ms", false, true);
412 logger_.log("Average Round Trip Time = "+toString(average)+"ms\n", false, true);
413
414 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
415 {
416 logger_.log("Traffic Pattern Type #"+toString(patternId+1), false, true);
417 trafficPattern_[patternId].printTrafficConfiguration(logger_);
418 logger_.log("Total Interests Sent = "+toString(trafficPattern_[patternId].totalInterestSent), false, true);
419 logger_.log("Total Responses Received = "+toString(trafficPattern_[patternId].totalInterestReceived), false, true);
420 if (trafficPattern_[patternId].totalInterestSent > 0)
421 {
422 loss = (trafficPattern_[patternId].totalInterestSent-trafficPattern_[patternId].totalInterestReceived);
423 loss *= 100.0;
424 loss /= trafficPattern_[patternId].totalInterestSent;
425 }
426 else
427 loss = 0;
428 logger_.log("Total Interest Loss = "+toString(loss)+"%", false, true);
429 if (trafficPattern_[patternId].totalInterestReceived > 0)
430 average = trafficPattern_[patternId].totalInterestRoundTripTime/trafficPattern_[patternId].totalInterestReceived;
431 else
432 average = 0;
433 logger_.log("Total Round Trip Time = "+toString(trafficPattern_[patternId].totalInterestRoundTripTime)+"ms", false, true);
434 logger_.log("Average Round Trip Time = "+toString(average)+"ms\n", false, true);
435 }
436 }
437
jeraldabrahame891ac92014-02-16 11:04:01 -0700438 bool
439 checkTrafficPatternCorrectness()
440 {
441 return true;
442 }
443
444 void
445 analyzeConfigurationFile()
446 {
447 int patternId;
448 int lineNumber;
449 bool skipLine;
450 std::string patternLine;
451 std::ifstream patternFile;
jeraldabraham662266d2014-02-17 10:26:12 -0700452 logger_.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700453 patternFile.open(configurationFile_.c_str());
454 if (patternFile.is_open())
455 {
456 patternId = 0;
457 lineNumber = 0;
458 while (getline(patternFile, patternLine))
459 {
460 lineNumber++;
461 if (std::isalpha(patternLine[0]))
462 {
463 InterestTrafficConfiguration interestData;
464 skipLine = false;
465 patternId++;
466 if (interestData.processConfigurationDetail(patternLine, logger_, lineNumber))
467 {
468 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
469 {
470 lineNumber++;
471 if (!interestData.processConfigurationDetail(patternLine, logger_, lineNumber))
472 {
473 skipLine = true;
474 break;
475 }
476 }
477 lineNumber++;
478 }
479 else
480 skipLine = true;
481 if( !skipLine )
482 {
483 if (interestData.checkTrafficDetailCorrectness())
484 trafficPattern_.push_back(interestData);
485 }
486 }
487 }
488 patternFile.close();
489 if (!checkTrafficPatternCorrectness())
490 {
jeraldabraham662266d2014-02-17 10:26:12 -0700491 logger_.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700492 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700493 exit(1);
494 }
jeraldabraham89a58422014-02-18 14:27:14 -0700495 logger_.log("Traffic Configuration File Processing Completed\n", true, false);
496 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
497 {
498 logger_.log("Traffic Pattern Type #"+toString(patternId+1), false, false);
jeraldabrahame891ac92014-02-16 11:04:01 -0700499 trafficPattern_[patternId].printTrafficConfiguration(logger_);
jeraldabraham89a58422014-02-18 14:27:14 -0700500 logger_.log("", false, false);
501 }
jeraldabrahame891ac92014-02-16 11:04:01 -0700502 }
503 else
504 {
jeraldabraham662266d2014-02-17 10:26:12 -0700505 logger_.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700506 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700507 exit(1);
508 }
509 }
510
511 void
512 initializeTrafficConfiguration()
513 {
514 if (boost::filesystem::exists(boost::filesystem::path(configurationFile_)))
515 {
516 if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_)))
517 {
518 analyzeConfigurationFile();
519 }
520 else
521 {
jeraldabraham662266d2014-02-17 10:26:12 -0700522 logger_.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700523 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700524 exit(1);
525 }
526 }
527 else
528 {
jeraldabraham662266d2014-02-17 10:26:12 -0700529 logger_.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700530 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700531 exit(1);
532 }
533 }
534
jeraldabraham662266d2014-02-17 10:26:12 -0700535 int
536 getOldNonce()
537 {
538 int randomNonceKey;
539 if (nonceList_.size() == 0)
540 return getNewNonce();
541 std::srand(std::time(0));
542 randomNonceKey = std::rand() % nonceList_.size();
543 return nonceList_[randomNonceKey];
544 }
545
546 int
547 getNewNonce()
548 {
549 int randomNonceKey, i;
550 bool isOld;
551 isOld = true;
552 std::srand(std::time(0));
553 do
554 {
555 randomNonceKey = std::rand();
556 isOld = false;
557 for (i=0; i<nonceList_.size(); i++)
558 if (nonceList_[i] == randomNonceKey)
559 isOld = true;
560 } while(isOld);
561 nonceList_.push_back(randomNonceKey);
562 return randomNonceKey;
563 }
564
565 static std::string
566 getRandomByteString( int randomSize )
567 {
568 int i;
569 std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789";
570 std::string randomData;
571 for (i=0; i<randomSize; i++)
572 randomData += characterSet[std::rand() % characterSet.length()];
573 return randomData;
574 }
575
576 void
577 onData( ndn::Face &face,
578 const ndn::Interest& interest,
579 ndn::Data& data,
580 int globalReference,
581 int localReference,
582 int patternId,
583 boost::posix_time::ptime sentTime )
584 {
585 double roundTripTime;
586 std::string logLine;
587 logLine = "";
588 logLine += "Data Received - GlobalID="+toString(globalReference);
589 logLine += ", LocalID="+toString(localReference);
590 logLine += ", PatternID="+toString(patternId);
591 logLine += ", Name="+interest.getName().toUri();
592 logger_.log(logLine, true, false);
593 boost::posix_time::time_duration roundTripDuration;
594 totalInterestReceived_++;
595 trafficPattern_[patternId].totalInterestReceived++;
596 roundTripDuration = boost::posix_time::microsec_clock::local_time() - sentTime;
597 roundTripTime = roundTripDuration.total_microseconds()/1000.0;
598 if (minimumInterestRoundTripTime_ > roundTripTime)
599 minimumInterestRoundTripTime_ = roundTripTime;
600 if (maximumInterestRoundTripTime_ < roundTripTime)
601 maximumInterestRoundTripTime_ = roundTripTime;
602 if (trafficPattern_[patternId].minimumInterestRoundTripTime > roundTripTime)
603 trafficPattern_[patternId].minimumInterestRoundTripTime = roundTripTime;
604 if (trafficPattern_[patternId].maximumInterestRoundTripTime < roundTripTime)
605 trafficPattern_[patternId].maximumInterestRoundTripTime = roundTripTime;
606 totalInterestRoundTripTime_ += roundTripTime;
607 trafficPattern_[patternId].totalInterestRoundTripTime += roundTripTime;
jeraldabraham89a58422014-02-18 14:27:14 -0700608 if (totalInterestSent_ == interestCount_)
609 signalHandler();
jeraldabraham662266d2014-02-17 10:26:12 -0700610 }
611
612 void
613 onTimeout( ndn::Face &face,
614 const ndn::Interest& interest,
615 int globalReference,
616 int localReference,
617 int patternId)
618 {
619 std::string logLine;
620 logLine = "";
621 logLine += "Interest Timed Out - GlobalID="+toString(globalReference);
622 logLine += ", LocalID="+toString(localReference);
623 logLine += ", PatternID="+toString(patternId);
624 logLine += ", Name="+interest.getName().toUri();
625 logger_.log(logLine, true, false);
jeraldabraham89a58422014-02-18 14:27:14 -0700626 if (totalInterestSent_ == interestCount_)
627 signalHandler();
jeraldabraham662266d2014-02-17 10:26:12 -0700628 }
629
630 void
631 generateTraffic( const boost::system::error_code& errorCode,
632 boost::asio::deadline_timer* deadlineTimer )
633 {
634 if ((interestCount_ < 0) || (totalInterestSent_ < interestCount_))
635 {
636 int trafficKey, patternId, cumulativePercentage;
637 std::srand(std::time(0));
638 trafficKey = std::rand() % 100;
639 cumulativePercentage = 0;
jeraldabraham662266d2014-02-17 10:26:12 -0700640 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
641 {
642 cumulativePercentage += trafficPattern_[patternId].trafficPercentage;
643 if (trafficKey <= cumulativePercentage)
644 {
645 Name interestName(trafficPattern_[patternId].name);
646 if (trafficPattern_[patternId].nameAppendBytes > 0)
647 interestName.append(getRandomByteString(trafficPattern_[patternId].nameAppendBytes));
648 if (trafficPattern_[patternId].nameAppendSequenceNumber >= 0)
649 {
650 interestName.append(toString(trafficPattern_[patternId].nameAppendSequenceNumber));
651 trafficPattern_[patternId].nameAppendSequenceNumber++;
652 }
653 Interest interest(interestName);
jeraldabraham89a58422014-02-18 14:27:14 -0700654 if (trafficPattern_[patternId].minSuffixComponents >= 0)
jeraldabraham662266d2014-02-17 10:26:12 -0700655 interest.setMinSuffixComponents(trafficPattern_[patternId].minSuffixComponents);
jeraldabraham89a58422014-02-18 14:27:14 -0700656 if (trafficPattern_[patternId].maxSuffixComponents >= 0)
jeraldabraham662266d2014-02-17 10:26:12 -0700657 interest.setMaxSuffixComponents(trafficPattern_[patternId].maxSuffixComponents);
658 Exclude exclude;
659 if (trafficPattern_[patternId].excludeBefore != "" && trafficPattern_[patternId].excludeAfter != "")
660 {
661 exclude.excludeRange(name::Component(trafficPattern_[patternId].excludeAfter),
662 name::Component(trafficPattern_[patternId].excludeBefore));
663 interest.setExclude(exclude);
664 }
665 else if (trafficPattern_[patternId].excludeBefore != "")
666 {
667 exclude.excludeBefore(name::Component(trafficPattern_[patternId].excludeBefore));
668 interest.setExclude(exclude);
669 }
670 else if (trafficPattern_[patternId].excludeAfter != "")
671 {
672 exclude.excludeAfter(name::Component(trafficPattern_[patternId].excludeAfter));
673 interest.setExclude(exclude);
674 }
675 if (trafficPattern_[patternId].excludeBeforeBytes > 0 && trafficPattern_[patternId].excludeAfterBytes > 0)
676 {
677 exclude.excludeRange(name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)),
678 name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
679 interest.setExclude(exclude);
680 }
681 else if (trafficPattern_[patternId].excludeBeforeBytes > 0)
682 {
683 exclude.excludeBefore(name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
684 interest.setExclude(exclude);
685 }
686 else if (trafficPattern_[patternId].excludeAfterBytes > 0)
687 {
688 exclude.excludeAfter(name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)));
689 interest.setExclude(exclude);
690 }
691
692 if (trafficPattern_[patternId].childSelector >= 0)
693 interest.setChildSelector(trafficPattern_[patternId].childSelector);
694
695 if (trafficPattern_[patternId].mustBeFresh == 0)
696 interest.setMustBeFresh(false);
jeraldabraham89a58422014-02-18 14:27:14 -0700697 else if (trafficPattern_[patternId].mustBeFresh > 0)
jeraldabraham662266d2014-02-17 10:26:12 -0700698 interest.setMustBeFresh(true);
699 if (trafficPattern_[patternId].nonceDuplicationPercentage > 0)
700 {
701 int duplicationKey;
702 std::srand(std::time(0));
703 duplicationKey = std::rand() % 100;
704 if (trafficPattern_[patternId].nonceDuplicationPercentage <= duplicationKey)
705 interest.setNonce(getOldNonce());
706 else
707 interest.setNonce(getNewNonce());
708 }
709 else
710 interest.setNonce(getNewNonce());
711 if (trafficPattern_[patternId].scope >= 0)
712 interest.setScope(trafficPattern_[patternId].scope);
jeraldabraham89a58422014-02-18 14:27:14 -0700713 if (trafficPattern_[patternId].interestLifetime >= 0)
jeraldabraham662266d2014-02-17 10:26:12 -0700714 interest.setInterestLifetime(trafficPattern_[patternId].interestLifetime);
jeraldabraham89a58422014-02-18 14:27:14 -0700715 else
716 interest.setInterestLifetime(getDefaultInterestLifetime());
jeraldabraham662266d2014-02-17 10:26:12 -0700717 try {
718 totalInterestSent_++;
719 trafficPattern_[patternId].totalInterestSent++;
720 boost::posix_time::ptime sentTime;
721 sentTime = boost::posix_time::microsec_clock::local_time();
722 face_.expressInterest(interest,
723 func_lib::bind( &NdnTrafficClient::onData,
724 this, boost::ref(face_),
725 _1, _2, totalInterestSent_,
726 trafficPattern_[patternId].totalInterestSent,
727 patternId,
728 sentTime),
729 func_lib::bind( &NdnTrafficClient::onTimeout,
730 this, boost::ref(face_),
731 _1, totalInterestSent_,
732 trafficPattern_[patternId].totalInterestSent,
733 patternId));
734 std::string logLine;
735 logLine = "";
736 logLine += "Sending Interest - GlobalID="+toString(totalInterestSent_);
737 logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestSent);
738 logLine += ", PatternID="+toString(patternId);
739 logLine += ", Name="+interest.getName().toUri();
740 logger_.log(logLine, true, false);
741 deadlineTimer->expires_at(deadlineTimer->expires_at() +
742 boost::posix_time::millisec(interestInterval_));
743 deadlineTimer->async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
744 this,
745 boost::asio::placeholders::error,
746 deadlineTimer));
747 }
748 catch (std::exception &e) {
749 logger_.log("ERROR: "+(std::string)e.what(), true, true);
750 }
751 break;
752 }
753 }
754 if (patternId==trafficPattern_.size())
755 {
756 deadlineTimer->expires_at(deadlineTimer->expires_at() +
757 boost::posix_time::millisec(interestInterval_));
758 deadlineTimer->async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
759 this,
760 boost::asio::placeholders::error,
761 deadlineTimer));
762 }
763 }
764 }
765
jeraldabrahame891ac92014-02-16 11:04:01 -0700766 void
767 initialize()
768 {
769 boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
770 signalSet.async_wait(boost::bind(&NdnTrafficClient::signalHandler, this));
771 logger_.initializeLog(instanceId_);
772 initializeTrafficConfiguration();
jeraldabraham662266d2014-02-17 10:26:12 -0700773 boost::asio::deadline_timer deadlineTimer(*ioService_,
774 boost::posix_time::millisec(interestInterval_));
775 deadlineTimer.async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
776 this,
777 boost::asio::placeholders::error,
778 &deadlineTimer));
779 try {
780 face_.processEvents();
781 }
782 catch(std::exception &e) {
783 logger_.log("ERROR: "+(std::string)e.what(), true, true);
784 logger_.shutdownLogger();
785 }
jeraldabrahame891ac92014-02-16 11:04:01 -0700786 }
787
jeraldabrahamf9543a42014-02-11 06:37:34 -0700788private:
789
790 KeyChain keyChain_;
791 std::string programName_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700792 std::string instanceId_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700793 int interestInterval_;
794 int interestCount_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700795 Logger logger_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700796 std::string configurationFile_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700797 ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700798 Face face_;
jeraldabraham662266d2014-02-17 10:26:12 -0700799 std::vector<InterestTrafficConfiguration> trafficPattern_;
800 std::vector<int> nonceList_;
801 int totalInterestSent_;
802 int totalInterestReceived_;
803 double minimumInterestRoundTripTime_;
804 double maximumInterestRoundTripTime_;
805 double totalInterestRoundTripTime_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700806
807};
808
809int main( int argc, char* argv[] )
810{
811 int option;
812 NdnTrafficClient ndnTrafficClient (argv[0]);
jeraldabrahame891ac92014-02-16 11:04:01 -0700813 while ((option = getopt(argc, argv, "hi:c:")) != -1) {
jeraldabrahamf9543a42014-02-11 06:37:34 -0700814 switch (option) {
815 case 'h' :
816 ndnTrafficClient.usage();
817 break;
818 case 'i' :
819 ndnTrafficClient.setInterestInterval(atoi(optarg));
820 break;
821 case 'c' :
822 ndnTrafficClient.setInterestCount(atoi(optarg));
823 break;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700824 default :
825 ndnTrafficClient.usage();
826 break;
827 }
828 }
829
830 argc -= optind;
831 argv += optind;
832
jeraldabrahame891ac92014-02-16 11:04:01 -0700833 if (argv[0] == NULL)
jeraldabrahamf9543a42014-02-11 06:37:34 -0700834 ndnTrafficClient.usage();
835
836 ndnTrafficClient.setConfigurationFile(argv[0]);
jeraldabrahame891ac92014-02-16 11:04:01 -0700837 ndnTrafficClient.initialize();
jeraldabrahamf9543a42014-02-11 06:37:34 -0700838
839 return 0;
840}