blob: 1e159fffdcc8036bbd3a2065896b8ff35bece3de [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 {
jeraldabrahambd241fe2014-02-19 11:39:09 -0700343
344 std::cout << "\nUsage: " << programName_ << " [options] <Traffic_Configuration_File>\n"
345 "Generate Interest Traffic as per provided Traffic Configuration File\n"
346 "Interests are continuously generated unless a total number is specified.\n"
347 "Set environment variable NDN_TRAFFIC_LOGFOLDER for redirecting output to a log.\n"
348 " [-i interval] - set interest generation interval in milliseconds (minimum "
349 << getDefaultInterestInterval() << " milliseconds)\n"
350 " [-c count] - set total number of interests to be generated\n"
351 " [-h] - print help and exit\n\n";
jeraldabrahamf9543a42014-02-11 06:37:34 -0700352 exit(1);
jeraldabrahambd241fe2014-02-19 11:39:09 -0700353
jeraldabrahamf9543a42014-02-11 06:37:34 -0700354 }
355
356 int
357 getDefaultInterestInterval()
358 {
jeraldabrahame891ac92014-02-16 11:04:01 -0700359 return 1000;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700360 }
361
362 int
363 getDefaultInterestCount()
364 {
365 return -1;
366 }
367
jeraldabrahamf9543a42014-02-11 06:37:34 -0700368 void
369 setInterestInterval( int interestInterval )
370 {
371 if (interestInterval < 0)
372 usage();
373 interestInterval_ = interestInterval;
374 }
375
376 void
377 setInterestCount( int interestCount )
378 {
379 if (interestCount < 0)
380 usage();
381 interestCount_ = interestCount;
382 }
383
384 void
jeraldabrahamf9543a42014-02-11 06:37:34 -0700385 setConfigurationFile( char* configurationFile )
386 {
387 configurationFile_ = configurationFile;
388 }
389
jeraldabrahame891ac92014-02-16 11:04:01 -0700390 void
391 signalHandler()
392 {
393 logger_.shutdownLogger();
394 face_.shutdown();
395 ioService_.reset();
jeraldabraham89a58422014-02-18 14:27:14 -0700396 logStatistics();
jeraldabrahame891ac92014-02-16 11:04:01 -0700397 exit(1);
398 }
399
jeraldabraham89a58422014-02-18 14:27:14 -0700400 void
401 logStatistics()
402 {
403 int patternId;
404 double loss, average;
405
406 logger_.log("\n\n== Interest Traffic Report ==\n", false, true);
407 logger_.log("Total Traffic Pattern Types = "+toString((int)trafficPattern_.size()), false, true);
408 logger_.log("Total Interests Sent = "+toString(totalInterestSent_), false, true);
409 logger_.log("Total Responses Received = "+toString(totalInterestReceived_), false, true);
410 if (totalInterestSent_ > 0)
411 loss = (totalInterestSent_-totalInterestReceived_)*100.0/totalInterestSent_;
412 else
413 loss = 0;
414 logger_.log("Total Interest Loss = "+toString(loss)+"%", false, true);
415 if (totalInterestReceived_ > 0)
416 average = totalInterestRoundTripTime_/totalInterestReceived_;
417 else
418 average = 0;
419 logger_.log("Total Round Trip Time = "+toString(totalInterestRoundTripTime_)+"ms", false, true);
420 logger_.log("Average Round Trip Time = "+toString(average)+"ms\n", false, true);
421
422 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
423 {
424 logger_.log("Traffic Pattern Type #"+toString(patternId+1), false, true);
425 trafficPattern_[patternId].printTrafficConfiguration(logger_);
426 logger_.log("Total Interests Sent = "+toString(trafficPattern_[patternId].totalInterestSent), false, true);
427 logger_.log("Total Responses Received = "+toString(trafficPattern_[patternId].totalInterestReceived), false, true);
428 if (trafficPattern_[patternId].totalInterestSent > 0)
429 {
430 loss = (trafficPattern_[patternId].totalInterestSent-trafficPattern_[patternId].totalInterestReceived);
431 loss *= 100.0;
432 loss /= trafficPattern_[patternId].totalInterestSent;
433 }
434 else
435 loss = 0;
436 logger_.log("Total Interest Loss = "+toString(loss)+"%", false, true);
437 if (trafficPattern_[patternId].totalInterestReceived > 0)
438 average = trafficPattern_[patternId].totalInterestRoundTripTime/trafficPattern_[patternId].totalInterestReceived;
439 else
440 average = 0;
441 logger_.log("Total Round Trip Time = "+toString(trafficPattern_[patternId].totalInterestRoundTripTime)+"ms", false, true);
442 logger_.log("Average Round Trip Time = "+toString(average)+"ms\n", false, true);
443 }
444 }
445
jeraldabrahame891ac92014-02-16 11:04:01 -0700446 bool
447 checkTrafficPatternCorrectness()
448 {
449 return true;
450 }
451
452 void
453 analyzeConfigurationFile()
454 {
455 int patternId;
456 int lineNumber;
457 bool skipLine;
458 std::string patternLine;
459 std::ifstream patternFile;
jeraldabraham662266d2014-02-17 10:26:12 -0700460 logger_.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700461 patternFile.open(configurationFile_.c_str());
462 if (patternFile.is_open())
463 {
464 patternId = 0;
465 lineNumber = 0;
466 while (getline(patternFile, patternLine))
467 {
468 lineNumber++;
469 if (std::isalpha(patternLine[0]))
470 {
471 InterestTrafficConfiguration interestData;
472 skipLine = false;
473 patternId++;
474 if (interestData.processConfigurationDetail(patternLine, logger_, lineNumber))
475 {
476 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
477 {
478 lineNumber++;
479 if (!interestData.processConfigurationDetail(patternLine, logger_, lineNumber))
480 {
481 skipLine = true;
482 break;
483 }
484 }
485 lineNumber++;
486 }
487 else
488 skipLine = true;
489 if( !skipLine )
490 {
491 if (interestData.checkTrafficDetailCorrectness())
492 trafficPattern_.push_back(interestData);
493 }
494 }
495 }
496 patternFile.close();
497 if (!checkTrafficPatternCorrectness())
498 {
jeraldabraham662266d2014-02-17 10:26:12 -0700499 logger_.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700500 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700501 exit(1);
502 }
jeraldabraham89a58422014-02-18 14:27:14 -0700503 logger_.log("Traffic Configuration File Processing Completed\n", true, false);
504 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
505 {
506 logger_.log("Traffic Pattern Type #"+toString(patternId+1), false, false);
jeraldabrahame891ac92014-02-16 11:04:01 -0700507 trafficPattern_[patternId].printTrafficConfiguration(logger_);
jeraldabraham89a58422014-02-18 14:27:14 -0700508 logger_.log("", false, false);
509 }
jeraldabrahame891ac92014-02-16 11:04:01 -0700510 }
511 else
512 {
jeraldabraham662266d2014-02-17 10:26:12 -0700513 logger_.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700514 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700515 exit(1);
516 }
517 }
518
519 void
520 initializeTrafficConfiguration()
521 {
522 if (boost::filesystem::exists(boost::filesystem::path(configurationFile_)))
523 {
524 if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_)))
525 {
526 analyzeConfigurationFile();
527 }
528 else
529 {
jeraldabraham662266d2014-02-17 10:26:12 -0700530 logger_.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700531 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700532 exit(1);
533 }
534 }
535 else
536 {
jeraldabraham662266d2014-02-17 10:26:12 -0700537 logger_.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700538 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700539 exit(1);
540 }
541 }
542
jeraldabraham662266d2014-02-17 10:26:12 -0700543 int
544 getOldNonce()
545 {
546 int randomNonceKey;
547 if (nonceList_.size() == 0)
548 return getNewNonce();
549 std::srand(std::time(0));
550 randomNonceKey = std::rand() % nonceList_.size();
551 return nonceList_[randomNonceKey];
552 }
553
554 int
555 getNewNonce()
556 {
557 int randomNonceKey, i;
558 bool isOld;
559 isOld = true;
560 std::srand(std::time(0));
561 do
562 {
563 randomNonceKey = std::rand();
564 isOld = false;
565 for (i=0; i<nonceList_.size(); i++)
566 if (nonceList_[i] == randomNonceKey)
567 isOld = true;
568 } while(isOld);
569 nonceList_.push_back(randomNonceKey);
570 return randomNonceKey;
571 }
572
573 static std::string
574 getRandomByteString( int randomSize )
575 {
576 int i;
577 std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789";
578 std::string randomData;
579 for (i=0; i<randomSize; i++)
580 randomData += characterSet[std::rand() % characterSet.length()];
581 return randomData;
582 }
583
584 void
585 onData( ndn::Face &face,
586 const ndn::Interest& interest,
587 ndn::Data& data,
588 int globalReference,
589 int localReference,
590 int patternId,
591 boost::posix_time::ptime sentTime )
592 {
593 double roundTripTime;
594 std::string logLine;
595 logLine = "";
jeraldabrahamb735e8d2014-02-19 09:16:35 -0700596 logLine += "Data Received - PatternType="+toString(patternId+1);
597 logLine += ", GlobalID="+toString(globalReference);
jeraldabraham662266d2014-02-17 10:26:12 -0700598 logLine += ", LocalID="+toString(localReference);
jeraldabraham662266d2014-02-17 10:26:12 -0700599 logLine += ", Name="+interest.getName().toUri();
600 logger_.log(logLine, true, false);
601 boost::posix_time::time_duration roundTripDuration;
602 totalInterestReceived_++;
603 trafficPattern_[patternId].totalInterestReceived++;
604 roundTripDuration = boost::posix_time::microsec_clock::local_time() - sentTime;
605 roundTripTime = roundTripDuration.total_microseconds()/1000.0;
606 if (minimumInterestRoundTripTime_ > roundTripTime)
607 minimumInterestRoundTripTime_ = roundTripTime;
608 if (maximumInterestRoundTripTime_ < roundTripTime)
609 maximumInterestRoundTripTime_ = roundTripTime;
610 if (trafficPattern_[patternId].minimumInterestRoundTripTime > roundTripTime)
611 trafficPattern_[patternId].minimumInterestRoundTripTime = roundTripTime;
612 if (trafficPattern_[patternId].maximumInterestRoundTripTime < roundTripTime)
613 trafficPattern_[patternId].maximumInterestRoundTripTime = roundTripTime;
614 totalInterestRoundTripTime_ += roundTripTime;
615 trafficPattern_[patternId].totalInterestRoundTripTime += roundTripTime;
jeraldabraham89a58422014-02-18 14:27:14 -0700616 if (totalInterestSent_ == interestCount_)
617 signalHandler();
jeraldabraham662266d2014-02-17 10:26:12 -0700618 }
619
620 void
621 onTimeout( ndn::Face &face,
622 const ndn::Interest& interest,
623 int globalReference,
624 int localReference,
625 int patternId)
626 {
627 std::string logLine;
628 logLine = "";
jeraldabrahamb735e8d2014-02-19 09:16:35 -0700629 logLine += "Interest Timed Out - PatternType="+toString(patternId+1);
630 logLine += ", GlobalID="+toString(globalReference);
jeraldabraham662266d2014-02-17 10:26:12 -0700631 logLine += ", LocalID="+toString(localReference);
jeraldabraham662266d2014-02-17 10:26:12 -0700632 logLine += ", Name="+interest.getName().toUri();
633 logger_.log(logLine, true, false);
jeraldabraham89a58422014-02-18 14:27:14 -0700634 if (totalInterestSent_ == interestCount_)
635 signalHandler();
jeraldabraham662266d2014-02-17 10:26:12 -0700636 }
637
638 void
639 generateTraffic( const boost::system::error_code& errorCode,
640 boost::asio::deadline_timer* deadlineTimer )
641 {
642 if ((interestCount_ < 0) || (totalInterestSent_ < interestCount_))
643 {
644 int trafficKey, patternId, cumulativePercentage;
645 std::srand(std::time(0));
646 trafficKey = std::rand() % 100;
647 cumulativePercentage = 0;
jeraldabraham662266d2014-02-17 10:26:12 -0700648 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
649 {
650 cumulativePercentage += trafficPattern_[patternId].trafficPercentage;
651 if (trafficKey <= cumulativePercentage)
652 {
653 Name interestName(trafficPattern_[patternId].name);
654 if (trafficPattern_[patternId].nameAppendBytes > 0)
655 interestName.append(getRandomByteString(trafficPattern_[patternId].nameAppendBytes));
656 if (trafficPattern_[patternId].nameAppendSequenceNumber >= 0)
657 {
658 interestName.append(toString(trafficPattern_[patternId].nameAppendSequenceNumber));
659 trafficPattern_[patternId].nameAppendSequenceNumber++;
660 }
661 Interest interest(interestName);
jeraldabraham89a58422014-02-18 14:27:14 -0700662 if (trafficPattern_[patternId].minSuffixComponents >= 0)
jeraldabraham662266d2014-02-17 10:26:12 -0700663 interest.setMinSuffixComponents(trafficPattern_[patternId].minSuffixComponents);
jeraldabraham89a58422014-02-18 14:27:14 -0700664 if (trafficPattern_[patternId].maxSuffixComponents >= 0)
jeraldabraham662266d2014-02-17 10:26:12 -0700665 interest.setMaxSuffixComponents(trafficPattern_[patternId].maxSuffixComponents);
666 Exclude exclude;
667 if (trafficPattern_[patternId].excludeBefore != "" && trafficPattern_[patternId].excludeAfter != "")
668 {
669 exclude.excludeRange(name::Component(trafficPattern_[patternId].excludeAfter),
670 name::Component(trafficPattern_[patternId].excludeBefore));
671 interest.setExclude(exclude);
672 }
673 else if (trafficPattern_[patternId].excludeBefore != "")
674 {
675 exclude.excludeBefore(name::Component(trafficPattern_[patternId].excludeBefore));
676 interest.setExclude(exclude);
677 }
678 else if (trafficPattern_[patternId].excludeAfter != "")
679 {
680 exclude.excludeAfter(name::Component(trafficPattern_[patternId].excludeAfter));
681 interest.setExclude(exclude);
682 }
683 if (trafficPattern_[patternId].excludeBeforeBytes > 0 && trafficPattern_[patternId].excludeAfterBytes > 0)
684 {
685 exclude.excludeRange(name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)),
686 name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
687 interest.setExclude(exclude);
688 }
689 else if (trafficPattern_[patternId].excludeBeforeBytes > 0)
690 {
691 exclude.excludeBefore(name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
692 interest.setExclude(exclude);
693 }
694 else if (trafficPattern_[patternId].excludeAfterBytes > 0)
695 {
696 exclude.excludeAfter(name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)));
697 interest.setExclude(exclude);
698 }
699
700 if (trafficPattern_[patternId].childSelector >= 0)
701 interest.setChildSelector(trafficPattern_[patternId].childSelector);
702
703 if (trafficPattern_[patternId].mustBeFresh == 0)
704 interest.setMustBeFresh(false);
jeraldabraham89a58422014-02-18 14:27:14 -0700705 else if (trafficPattern_[patternId].mustBeFresh > 0)
jeraldabraham662266d2014-02-17 10:26:12 -0700706 interest.setMustBeFresh(true);
707 if (trafficPattern_[patternId].nonceDuplicationPercentage > 0)
708 {
709 int duplicationKey;
710 std::srand(std::time(0));
711 duplicationKey = std::rand() % 100;
712 if (trafficPattern_[patternId].nonceDuplicationPercentage <= duplicationKey)
713 interest.setNonce(getOldNonce());
714 else
715 interest.setNonce(getNewNonce());
716 }
717 else
718 interest.setNonce(getNewNonce());
719 if (trafficPattern_[patternId].scope >= 0)
720 interest.setScope(trafficPattern_[patternId].scope);
jeraldabraham89a58422014-02-18 14:27:14 -0700721 if (trafficPattern_[patternId].interestLifetime >= 0)
jeraldabraham662266d2014-02-17 10:26:12 -0700722 interest.setInterestLifetime(trafficPattern_[patternId].interestLifetime);
jeraldabraham89a58422014-02-18 14:27:14 -0700723 else
724 interest.setInterestLifetime(getDefaultInterestLifetime());
jeraldabraham662266d2014-02-17 10:26:12 -0700725 try {
726 totalInterestSent_++;
727 trafficPattern_[patternId].totalInterestSent++;
728 boost::posix_time::ptime sentTime;
729 sentTime = boost::posix_time::microsec_clock::local_time();
730 face_.expressInterest(interest,
731 func_lib::bind( &NdnTrafficClient::onData,
732 this, boost::ref(face_),
733 _1, _2, totalInterestSent_,
734 trafficPattern_[patternId].totalInterestSent,
735 patternId,
736 sentTime),
737 func_lib::bind( &NdnTrafficClient::onTimeout,
738 this, boost::ref(face_),
739 _1, totalInterestSent_,
740 trafficPattern_[patternId].totalInterestSent,
741 patternId));
742 std::string logLine;
743 logLine = "";
jeraldabrahamb735e8d2014-02-19 09:16:35 -0700744 logLine += "Sending Interest - PatternType="+toString(patternId+1);
745 logLine += ", GlobalID="+toString(totalInterestSent_);
jeraldabraham662266d2014-02-17 10:26:12 -0700746 logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestSent);
jeraldabraham662266d2014-02-17 10:26:12 -0700747 logLine += ", Name="+interest.getName().toUri();
748 logger_.log(logLine, true, false);
749 deadlineTimer->expires_at(deadlineTimer->expires_at() +
750 boost::posix_time::millisec(interestInterval_));
751 deadlineTimer->async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
752 this,
753 boost::asio::placeholders::error,
754 deadlineTimer));
755 }
756 catch (std::exception &e) {
757 logger_.log("ERROR: "+(std::string)e.what(), true, true);
758 }
759 break;
760 }
761 }
762 if (patternId==trafficPattern_.size())
763 {
764 deadlineTimer->expires_at(deadlineTimer->expires_at() +
765 boost::posix_time::millisec(interestInterval_));
766 deadlineTimer->async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
767 this,
768 boost::asio::placeholders::error,
769 deadlineTimer));
770 }
771 }
772 }
773
jeraldabrahame891ac92014-02-16 11:04:01 -0700774 void
775 initialize()
776 {
777 boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
778 signalSet.async_wait(boost::bind(&NdnTrafficClient::signalHandler, this));
779 logger_.initializeLog(instanceId_);
780 initializeTrafficConfiguration();
jeraldabraham662266d2014-02-17 10:26:12 -0700781 boost::asio::deadline_timer deadlineTimer(*ioService_,
782 boost::posix_time::millisec(interestInterval_));
783 deadlineTimer.async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
784 this,
785 boost::asio::placeholders::error,
786 &deadlineTimer));
787 try {
788 face_.processEvents();
789 }
790 catch(std::exception &e) {
791 logger_.log("ERROR: "+(std::string)e.what(), true, true);
792 logger_.shutdownLogger();
793 }
jeraldabrahame891ac92014-02-16 11:04:01 -0700794 }
795
jeraldabrahamf9543a42014-02-11 06:37:34 -0700796private:
797
798 KeyChain keyChain_;
799 std::string programName_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700800 std::string instanceId_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700801 int interestInterval_;
802 int interestCount_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700803 Logger logger_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700804 std::string configurationFile_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700805 ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700806 Face face_;
jeraldabraham662266d2014-02-17 10:26:12 -0700807 std::vector<InterestTrafficConfiguration> trafficPattern_;
808 std::vector<int> nonceList_;
809 int totalInterestSent_;
810 int totalInterestReceived_;
811 double minimumInterestRoundTripTime_;
812 double maximumInterestRoundTripTime_;
813 double totalInterestRoundTripTime_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700814
815};
816
817int main( int argc, char* argv[] )
818{
819 int option;
820 NdnTrafficClient ndnTrafficClient (argv[0]);
jeraldabrahame891ac92014-02-16 11:04:01 -0700821 while ((option = getopt(argc, argv, "hi:c:")) != -1) {
jeraldabrahamf9543a42014-02-11 06:37:34 -0700822 switch (option) {
823 case 'h' :
824 ndnTrafficClient.usage();
825 break;
826 case 'i' :
827 ndnTrafficClient.setInterestInterval(atoi(optarg));
828 break;
829 case 'c' :
830 ndnTrafficClient.setInterestCount(atoi(optarg));
831 break;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700832 default :
833 ndnTrafficClient.usage();
834 break;
835 }
836 }
837
838 argc -= optind;
839 argv += optind;
840
jeraldabrahame891ac92014-02-16 11:04:01 -0700841 if (argv[0] == NULL)
jeraldabrahamf9543a42014-02-11 06:37:34 -0700842 ndnTrafficClient.usage();
843
844 ndnTrafficClient.setConfigurationFile(argv[0]);
jeraldabrahame891ac92014-02-16 11:04:01 -0700845 ndnTrafficClient.initialize();
jeraldabrahamf9543a42014-02-11 06:37:34 -0700846
847 return 0;
848}