blob: 6df1ed1b8a00513bce45c97ee1a85654db4002ff [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>
13#include <boost/filesystem.hpp>
jeraldabraham662266d2014-02-17 10:26:12 -070014#include <boost/bind.hpp>
15#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())
37 logFile_.close();
38 }
39
jeraldabraham662266d2014-02-17 10:26:12 -070040 static std::string
41 getTimestamp()
42 {
43 boost::posix_time::ptime now;
44 now = boost::posix_time::second_clock::local_time();
45 return to_simple_string(now);
46 }
47
jeraldabrahame891ac92014-02-16 11:04:01 -070048 void
jeraldabraham662266d2014-02-17 10:26:12 -070049 log( std::string logLine, bool printTime, bool printToConsole )
jeraldabrahame891ac92014-02-16 11:04:01 -070050 {
51 if( logLocation_.length() > 0 )
52 {
jeraldabraham662266d2014-02-17 10:26:12 -070053 if (printTime)
54 logFile_ << getTimestamp() << " - ";
jeraldabrahame891ac92014-02-16 11:04:01 -070055 logFile_ << logLine << std::endl;
56 logFile_.flush();
jeraldabraham662266d2014-02-17 10:26:12 -070057 if (printToConsole)
58 {
59 if (printTime)
60 std::cout << getTimestamp() << " - ";
61 std::cout << logLine << std::endl;
62 }
jeraldabrahame891ac92014-02-16 11:04:01 -070063 }
64 else
jeraldabraham662266d2014-02-17 10:26:12 -070065 {
66 if (printTime)
67 std::cout << getTimestamp() << " - ";
jeraldabrahame891ac92014-02-16 11:04:01 -070068 std::cout << logLine << std::endl;
jeraldabraham662266d2014-02-17 10:26:12 -070069 }
jeraldabrahame891ac92014-02-16 11:04:01 -070070 }
71
72 void
73 initializeLog( std::string instanceId )
74 {
75 char* variableValue = std::getenv("NDN_TRAFFIC_LOGFOLDER");
76 std::string logFilename;
77 logLocation_ = "";
78 if (variableValue != NULL)
79 logLocation_ = variableValue;
80 if (boost::filesystem::exists(boost::filesystem::path(logLocation_)))
81 {
82 if (boost::filesystem::is_directory(boost::filesystem::path(logLocation_)))
83 {
84 logFilename = logLocation_+"/NDNTrafficClient_"+instanceId+".log";
85 logFile_.open(logFilename.c_str(), std::ofstream::out | std::ofstream::trunc);
86 if (logFile_.is_open())
87 std::cout << "Log File Initialized: " << logFilename << std::endl;
88 else
89 {
90 std::cout << "ERROR - Unable To Initialize A Log File At: " << logLocation_ << std::endl
91 << "Using Default Output For Logging." << std::endl;
92 logLocation_ = "";
93 }
94 }
95 else
96 {
97 std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Should Be A Folder." << std::endl
98 << "Using Default Output For Logging." << std::endl;
99 logLocation_ = "";
100 }
101 }
102 else
103 {
104 std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Not Set." << std::endl
105 << "Using Default Output For Logging." << std::endl;
106 logLocation_ = "";
107 }
108 }
109
110private:
111
112 std::string logLocation_;
113 std::ofstream logFile_;
114
115};
116
jeraldabrahamf9543a42014-02-11 06:37:34 -0700117class NdnTrafficClient
118{
119public:
120
jeraldabraham662266d2014-02-17 10:26:12 -0700121 NdnTrafficClient( char* programName ) : ioService_(new boost::asio::io_service), face_(ioService_)
jeraldabrahamf9543a42014-02-11 06:37:34 -0700122 {
jeraldabrahame891ac92014-02-16 11:04:01 -0700123 std::srand(std::time(0));
124 instanceId_ = toString(std::rand());
jeraldabrahamf9543a42014-02-11 06:37:34 -0700125 programName_ = programName;
126 interestInterval_ = getDefaultInterestInterval();
127 interestCount_ = getDefaultInterestCount();
jeraldabrahamf9543a42014-02-11 06:37:34 -0700128 configurationFile_ = "";
jeraldabraham662266d2014-02-17 10:26:12 -0700129 totalInterestSent_ = 0;
130 totalInterestReceived_ = 0;
131 minimumInterestRoundTripTime_ = std::numeric_limits<double>::max();
132 maximumInterestRoundTripTime_ = 0;
133 totalInterestRoundTripTime_ = 0;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700134 }
135
136 NdnTrafficClient()
137 : keyChain_()
138 {
139 }
140
jeraldabrahame891ac92014-02-16 11:04:01 -0700141 class InterestTrafficConfiguration
142 {
143 public:
144
145 InterestTrafficConfiguration()
146 {
147 trafficPercentage = -1;
148 name = "";
149 nameAppendBytes = -1;
150 nameAppendSequenceNumber = -1;
151 minSuffixComponents = -1;
152 maxSuffixComponents = -1;
153 excludeBefore = "";
154 excludeAfter = "";
155 excludeBeforeBytes = -1;
156 excludeAfterBytes = -1;
157 childSelector = -1;
158 mustBeFresh = -1;
159 nonceDuplicationPercentage = -1;
160 scope = -1;
jeraldabraham662266d2014-02-17 10:26:12 -0700161 interestLifetime = getDefaultInterestLifetime();
162 totalInterestSent = 0;
163 totalInterestReceived = 0;
164 minimumInterestRoundTripTime = std::numeric_limits<double>::max();
165 maximumInterestRoundTripTime = 0;
166 totalInterestRoundTripTime = 0;
167 }
168
169 int
170 getDefaultInterestLifetime()
171 {
172 return 4000;
jeraldabrahame891ac92014-02-16 11:04:01 -0700173 }
174
175 void
176 printTrafficConfiguration( Logger& logger )
177 {
178 std::string detail;
179 detail = "";
180 if (trafficPercentage > 0)
181 detail += "TrafficPercentage="+toString(trafficPercentage)+", ";
182 if (name != "")
183 detail += "Name="+name+", ";
184 if (nameAppendBytes>0)
185 detail += "NameAppendBytes="+toString(nameAppendBytes)+", ";
186 if (nameAppendSequenceNumber>0)
187 detail += "NameAppendSequenceNumber="+toString(nameAppendSequenceNumber)+", ";
188 if (minSuffixComponents>0)
189 detail += "MinSuffixComponents="+toString(minSuffixComponents)+", ";
190 if (maxSuffixComponents>0)
191 detail += "MaxSuffixComponents="+toString(maxSuffixComponents)+", ";
192 if (excludeBefore != "")
193 detail += "ExcludeBefore="+excludeBefore+", ";
194 if (excludeAfter != "")
195 detail += "ExcludeAfter="+excludeAfter+", ";
196 if (excludeBeforeBytes > 0)
197 detail += "ExcludeBeforeBytes="+toString(excludeBeforeBytes)+", ";
198 if (excludeAfterBytes > 0)
199 detail += "ExcludeAfterBytes="+toString(excludeAfterBytes)+", ";
200 if (childSelector > 0)
201 detail += "ChildSelector="+toString(childSelector)+", ";
202 if (mustBeFresh > 0)
203 detail += "MustBeFresh="+toString(mustBeFresh)+", ";
204 if (nonceDuplicationPercentage > 0)
205 detail += "NonceDuplicationPercentage="+toString(nonceDuplicationPercentage)+", ";
206 if (scope > 0)
207 detail += "Scope="+toString(scope)+", ";
208 if (interestLifetime > 0)
209 detail += "InterestLifetime="+toString(interestLifetime)+", ";
210 if (detail.length() >= 0)
211 detail = detail.substr(0, detail.length()-2);
jeraldabraham662266d2014-02-17 10:26:12 -0700212 logger.log(detail, false, false);
jeraldabrahame891ac92014-02-16 11:04:01 -0700213 }
214
215 bool
216 extractParameterValue( std::string detail, std::string& parameter, std::string& value )
217 {
218 int i;
219 std::string allowedCharacters = ":/+._-%";
220 parameter = "";
221 value = "";
222 i = 0;
223 while (detail[i] != '=' && i < detail.length())
224 {
225 parameter += detail[i];
226 i++;
227 }
228 if (i == detail.length())
229 return false;
230 i++;
231 while ((std::isalnum(detail[i]) || allowedCharacters.find(detail[i]) != std::string::npos) && i < detail.length())
232 {
233 value += detail[i];
234 i++;
235 }
236 if(parameter == "" || value == "")
237 return false;
238 return true;
239 }
240
241 bool
242 processConfigurationDetail( std::string detail, Logger& logger, int lineNumber )
243 {
244 std::string parameter, value;
245 if (extractParameterValue(detail, parameter, value))
246 {
247 if (parameter == "TrafficPercentage")
248 trafficPercentage = toInteger(value);
249 else if (parameter == "Name")
250 name = value;
251 else if (parameter == "NameAppendBytes")
252 nameAppendBytes = toInteger(value);
253 else if (parameter == "NameAppendSequenceNumber")
254 nameAppendSequenceNumber = toInteger(value);
255 else if (parameter == "MinSuffixComponents")
256 minSuffixComponents = toInteger(value);
257 else if (parameter == "MaxSuffixComponents")
258 maxSuffixComponents = toInteger(value);
259 else if (parameter == "ExcludeBefore")
260 excludeBefore = value;
261 else if (parameter == "ExcludeAfter")
262 excludeAfter = value;
263 else if (parameter == "ExcludeBeforeBytes")
264 excludeBeforeBytes = toInteger(value);
265 else if (parameter == "ExcludeAfterBytes")
266 excludeAfterBytes = toInteger(value);
267 else if (parameter == "ChildSelector")
268 childSelector = toInteger(value);
269 else if (parameter == "MustBeFresh")
270 mustBeFresh = toInteger(value);
271 else if (parameter == "NonceDuplicationPercentage")
272 nonceDuplicationPercentage = toInteger(value);
273 else if (parameter == "Scope")
274 scope = toInteger(value);
275 else if (parameter == "InterestLifetime")
276 interestLifetime = toInteger(value);
277 else
jeraldabraham662266d2014-02-17 10:26:12 -0700278 logger.log("Line "+toString(lineNumber)+" \t- Invalid Parameter='"+parameter+"'", false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700279 }
280 else
281 {
jeraldabraham662266d2014-02-17 10:26:12 -0700282 logger.log("Line "+toString(lineNumber)+" \t- Improper Traffic Configuration Line- "+detail, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700283 return false;
284 }
285 return true;
286 }
287
288 bool
289 checkTrafficDetailCorrectness()
290 {
291 return true;
292 }
293
294 int trafficPercentage;
295 std::string name;
296 int nameAppendBytes;
297 int nameAppendSequenceNumber;
298 int minSuffixComponents;
299 int maxSuffixComponents;
300 std::string excludeBefore;
301 std::string excludeAfter;
302 int excludeBeforeBytes;
303 int excludeAfterBytes;
304 int childSelector;
305 int mustBeFresh;
306 int nonceDuplicationPercentage;
307 int scope;
308 int interestLifetime;
jeraldabraham662266d2014-02-17 10:26:12 -0700309 int totalInterestSent;
310 int totalInterestReceived;
311 double minimumInterestRoundTripTime;
312 double maximumInterestRoundTripTime;
313 double totalInterestRoundTripTime;
jeraldabrahame891ac92014-02-16 11:04:01 -0700314
315 };
316
317 static std::string
318 toString( int integerValue )
319 {
320 std::stringstream stream;
321 stream << integerValue;
322 return stream.str();
323 }
324
325 static int
326 toInteger( std::string stringValue )
327 {
328 int integerValue;
329 std::stringstream stream(stringValue);
330 stream >> integerValue;
331 return integerValue;
332 }
333
jeraldabrahamf9543a42014-02-11 06:37:34 -0700334 void
335 usage()
336 {
337 std::cout << "\nUsage: " << programName_ << " Printing Usage"
jeraldabrahame891ac92014-02-16 11:04:01 -0700338 << std::endl << std::endl;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700339 exit(1);
340 }
341
342 int
343 getDefaultInterestInterval()
344 {
jeraldabrahame891ac92014-02-16 11:04:01 -0700345 return 1000;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700346 }
347
348 int
349 getDefaultInterestCount()
350 {
351 return -1;
352 }
353
jeraldabrahamf9543a42014-02-11 06:37:34 -0700354 void
355 setInterestInterval( int interestInterval )
356 {
357 if (interestInterval < 0)
358 usage();
359 interestInterval_ = interestInterval;
360 }
361
362 void
363 setInterestCount( int interestCount )
364 {
365 if (interestCount < 0)
366 usage();
367 interestCount_ = interestCount;
368 }
369
370 void
jeraldabrahamf9543a42014-02-11 06:37:34 -0700371 setConfigurationFile( char* configurationFile )
372 {
373 configurationFile_ = configurationFile;
374 }
375
jeraldabrahame891ac92014-02-16 11:04:01 -0700376 void
377 signalHandler()
378 {
379 logger_.shutdownLogger();
380 face_.shutdown();
381 ioService_.reset();
382 exit(1);
383 }
384
385 bool
386 checkTrafficPatternCorrectness()
387 {
388 return true;
389 }
390
391 void
392 analyzeConfigurationFile()
393 {
394 int patternId;
395 int lineNumber;
396 bool skipLine;
397 std::string patternLine;
398 std::ifstream patternFile;
jeraldabraham662266d2014-02-17 10:26:12 -0700399 logger_.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700400 patternFile.open(configurationFile_.c_str());
401 if (patternFile.is_open())
402 {
403 patternId = 0;
404 lineNumber = 0;
405 while (getline(patternFile, patternLine))
406 {
407 lineNumber++;
408 if (std::isalpha(patternLine[0]))
409 {
410 InterestTrafficConfiguration interestData;
411 skipLine = false;
412 patternId++;
413 if (interestData.processConfigurationDetail(patternLine, logger_, lineNumber))
414 {
415 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
416 {
417 lineNumber++;
418 if (!interestData.processConfigurationDetail(patternLine, logger_, lineNumber))
419 {
420 skipLine = true;
421 break;
422 }
423 }
424 lineNumber++;
425 }
426 else
427 skipLine = true;
428 if( !skipLine )
429 {
430 if (interestData.checkTrafficDetailCorrectness())
431 trafficPattern_.push_back(interestData);
432 }
433 }
434 }
435 patternFile.close();
436 if (!checkTrafficPatternCorrectness())
437 {
jeraldabraham662266d2014-02-17 10:26:12 -0700438 logger_.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700439 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700440 exit(1);
441 }
442 for (patternId = 0; patternId < trafficPattern_.size(); patternId++)
443 trafficPattern_[patternId].printTrafficConfiguration(logger_);
444 }
445 else
446 {
jeraldabraham662266d2014-02-17 10:26:12 -0700447 logger_.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700448 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700449 exit(1);
450 }
451 }
452
453 void
454 initializeTrafficConfiguration()
455 {
456 if (boost::filesystem::exists(boost::filesystem::path(configurationFile_)))
457 {
458 if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_)))
459 {
460 analyzeConfigurationFile();
461 }
462 else
463 {
jeraldabraham662266d2014-02-17 10:26:12 -0700464 logger_.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700465 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700466 exit(1);
467 }
468 }
469 else
470 {
jeraldabraham662266d2014-02-17 10:26:12 -0700471 logger_.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true);
jeraldabrahame891ac92014-02-16 11:04:01 -0700472 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700473 exit(1);
474 }
475 }
476
jeraldabraham662266d2014-02-17 10:26:12 -0700477 int
478 getOldNonce()
479 {
480 int randomNonceKey;
481 if (nonceList_.size() == 0)
482 return getNewNonce();
483 std::srand(std::time(0));
484 randomNonceKey = std::rand() % nonceList_.size();
485 return nonceList_[randomNonceKey];
486 }
487
488 int
489 getNewNonce()
490 {
491 int randomNonceKey, i;
492 bool isOld;
493 isOld = true;
494 std::srand(std::time(0));
495 do
496 {
497 randomNonceKey = std::rand();
498 isOld = false;
499 for (i=0; i<nonceList_.size(); i++)
500 if (nonceList_[i] == randomNonceKey)
501 isOld = true;
502 } while(isOld);
503 nonceList_.push_back(randomNonceKey);
504 return randomNonceKey;
505 }
506
507 static std::string
508 getRandomByteString( int randomSize )
509 {
510 int i;
511 std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789";
512 std::string randomData;
513 for (i=0; i<randomSize; i++)
514 randomData += characterSet[std::rand() % characterSet.length()];
515 return randomData;
516 }
517
518 void
519 onData( ndn::Face &face,
520 const ndn::Interest& interest,
521 ndn::Data& data,
522 int globalReference,
523 int localReference,
524 int patternId,
525 boost::posix_time::ptime sentTime )
526 {
527 double roundTripTime;
528 std::string logLine;
529 logLine = "";
530 logLine += "Data Received - GlobalID="+toString(globalReference);
531 logLine += ", LocalID="+toString(localReference);
532 logLine += ", PatternID="+toString(patternId);
533 logLine += ", Name="+interest.getName().toUri();
534 logger_.log(logLine, true, false);
535 boost::posix_time::time_duration roundTripDuration;
536 totalInterestReceived_++;
537 trafficPattern_[patternId].totalInterestReceived++;
538 roundTripDuration = boost::posix_time::microsec_clock::local_time() - sentTime;
539 roundTripTime = roundTripDuration.total_microseconds()/1000.0;
540 if (minimumInterestRoundTripTime_ > roundTripTime)
541 minimumInterestRoundTripTime_ = roundTripTime;
542 if (maximumInterestRoundTripTime_ < roundTripTime)
543 maximumInterestRoundTripTime_ = roundTripTime;
544 if (trafficPattern_[patternId].minimumInterestRoundTripTime > roundTripTime)
545 trafficPattern_[patternId].minimumInterestRoundTripTime = roundTripTime;
546 if (trafficPattern_[patternId].maximumInterestRoundTripTime < roundTripTime)
547 trafficPattern_[patternId].maximumInterestRoundTripTime = roundTripTime;
548 totalInterestRoundTripTime_ += roundTripTime;
549 trafficPattern_[patternId].totalInterestRoundTripTime += roundTripTime;
550 }
551
552 void
553 onTimeout( ndn::Face &face,
554 const ndn::Interest& interest,
555 int globalReference,
556 int localReference,
557 int patternId)
558 {
559 std::string logLine;
560 logLine = "";
561 logLine += "Interest Timed Out - GlobalID="+toString(globalReference);
562 logLine += ", LocalID="+toString(localReference);
563 logLine += ", PatternID="+toString(patternId);
564 logLine += ", Name="+interest.getName().toUri();
565 logger_.log(logLine, true, false);
566 }
567
568 void
569 generateTraffic( const boost::system::error_code& errorCode,
570 boost::asio::deadline_timer* deadlineTimer )
571 {
572 if ((interestCount_ < 0) || (totalInterestSent_ < interestCount_))
573 {
574 int trafficKey, patternId, cumulativePercentage;
575 std::srand(std::time(0));
576 trafficKey = std::rand() % 100;
577 cumulativePercentage = 0;
578 std::cout << trafficKey << std::endl;
579 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
580 {
581 cumulativePercentage += trafficPattern_[patternId].trafficPercentage;
582 if (trafficKey <= cumulativePercentage)
583 {
584 Name interestName(trafficPattern_[patternId].name);
585 if (trafficPattern_[patternId].nameAppendBytes > 0)
586 interestName.append(getRandomByteString(trafficPattern_[patternId].nameAppendBytes));
587 if (trafficPattern_[patternId].nameAppendSequenceNumber >= 0)
588 {
589 interestName.append(toString(trafficPattern_[patternId].nameAppendSequenceNumber));
590 trafficPattern_[patternId].nameAppendSequenceNumber++;
591 }
592 Interest interest(interestName);
593 if (trafficPattern_[patternId].minSuffixComponents > 0)
594 interest.setMinSuffixComponents(trafficPattern_[patternId].minSuffixComponents);
595 if (trafficPattern_[patternId].maxSuffixComponents > 0)
596 interest.setMaxSuffixComponents(trafficPattern_[patternId].maxSuffixComponents);
597 Exclude exclude;
598 if (trafficPattern_[patternId].excludeBefore != "" && trafficPattern_[patternId].excludeAfter != "")
599 {
600 exclude.excludeRange(name::Component(trafficPattern_[patternId].excludeAfter),
601 name::Component(trafficPattern_[patternId].excludeBefore));
602 interest.setExclude(exclude);
603 }
604 else if (trafficPattern_[patternId].excludeBefore != "")
605 {
606 exclude.excludeBefore(name::Component(trafficPattern_[patternId].excludeBefore));
607 interest.setExclude(exclude);
608 }
609 else if (trafficPattern_[patternId].excludeAfter != "")
610 {
611 exclude.excludeAfter(name::Component(trafficPattern_[patternId].excludeAfter));
612 interest.setExclude(exclude);
613 }
614 if (trafficPattern_[patternId].excludeBeforeBytes > 0 && trafficPattern_[patternId].excludeAfterBytes > 0)
615 {
616 exclude.excludeRange(name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)),
617 name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
618 interest.setExclude(exclude);
619 }
620 else if (trafficPattern_[patternId].excludeBeforeBytes > 0)
621 {
622 exclude.excludeBefore(name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
623 interest.setExclude(exclude);
624 }
625 else if (trafficPattern_[patternId].excludeAfterBytes > 0)
626 {
627 exclude.excludeAfter(name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)));
628 interest.setExclude(exclude);
629 }
630
631 if (trafficPattern_[patternId].childSelector >= 0)
632 interest.setChildSelector(trafficPattern_[patternId].childSelector);
633
634 if (trafficPattern_[patternId].mustBeFresh == 0)
635 interest.setMustBeFresh(false);
636 else if (trafficPattern_[patternId].mustBeFresh == 1)
637 interest.setMustBeFresh(true);
638 if (trafficPattern_[patternId].nonceDuplicationPercentage > 0)
639 {
640 int duplicationKey;
641 std::srand(std::time(0));
642 duplicationKey = std::rand() % 100;
643 if (trafficPattern_[patternId].nonceDuplicationPercentage <= duplicationKey)
644 interest.setNonce(getOldNonce());
645 else
646 interest.setNonce(getNewNonce());
647 }
648 else
649 interest.setNonce(getNewNonce());
650 if (trafficPattern_[patternId].scope >= 0)
651 interest.setScope(trafficPattern_[patternId].scope);
652 if (trafficPattern_[patternId].interestLifetime > 0)
653 interest.setInterestLifetime(trafficPattern_[patternId].interestLifetime);
654 try {
655 totalInterestSent_++;
656 trafficPattern_[patternId].totalInterestSent++;
657 boost::posix_time::ptime sentTime;
658 sentTime = boost::posix_time::microsec_clock::local_time();
659 face_.expressInterest(interest,
660 func_lib::bind( &NdnTrafficClient::onData,
661 this, boost::ref(face_),
662 _1, _2, totalInterestSent_,
663 trafficPattern_[patternId].totalInterestSent,
664 patternId,
665 sentTime),
666 func_lib::bind( &NdnTrafficClient::onTimeout,
667 this, boost::ref(face_),
668 _1, totalInterestSent_,
669 trafficPattern_[patternId].totalInterestSent,
670 patternId));
671 std::string logLine;
672 logLine = "";
673 logLine += "Sending Interest - GlobalID="+toString(totalInterestSent_);
674 logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestSent);
675 logLine += ", PatternID="+toString(patternId);
676 logLine += ", Name="+interest.getName().toUri();
677 logger_.log(logLine, true, false);
678 deadlineTimer->expires_at(deadlineTimer->expires_at() +
679 boost::posix_time::millisec(interestInterval_));
680 deadlineTimer->async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
681 this,
682 boost::asio::placeholders::error,
683 deadlineTimer));
684 }
685 catch (std::exception &e) {
686 logger_.log("ERROR: "+(std::string)e.what(), true, true);
687 }
688 break;
689 }
690 }
691 if (patternId==trafficPattern_.size())
692 {
693 deadlineTimer->expires_at(deadlineTimer->expires_at() +
694 boost::posix_time::millisec(interestInterval_));
695 deadlineTimer->async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
696 this,
697 boost::asio::placeholders::error,
698 deadlineTimer));
699 }
700 }
701 }
702
jeraldabrahame891ac92014-02-16 11:04:01 -0700703 void
704 initialize()
705 {
706 boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
707 signalSet.async_wait(boost::bind(&NdnTrafficClient::signalHandler, this));
708 logger_.initializeLog(instanceId_);
709 initializeTrafficConfiguration();
jeraldabraham662266d2014-02-17 10:26:12 -0700710 boost::asio::deadline_timer deadlineTimer(*ioService_,
711 boost::posix_time::millisec(interestInterval_));
712 deadlineTimer.async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
713 this,
714 boost::asio::placeholders::error,
715 &deadlineTimer));
716 try {
717 face_.processEvents();
718 }
719 catch(std::exception &e) {
720 logger_.log("ERROR: "+(std::string)e.what(), true, true);
721 logger_.shutdownLogger();
722 }
jeraldabrahame891ac92014-02-16 11:04:01 -0700723 }
724
jeraldabrahamf9543a42014-02-11 06:37:34 -0700725private:
726
727 KeyChain keyChain_;
728 std::string programName_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700729 std::string instanceId_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700730 int interestInterval_;
731 int interestCount_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700732 Logger logger_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700733 std::string configurationFile_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700734 ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700735 Face face_;
jeraldabraham662266d2014-02-17 10:26:12 -0700736 std::vector<InterestTrafficConfiguration> trafficPattern_;
737 std::vector<int> nonceList_;
738 int totalInterestSent_;
739 int totalInterestReceived_;
740 double minimumInterestRoundTripTime_;
741 double maximumInterestRoundTripTime_;
742 double totalInterestRoundTripTime_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700743
744};
745
746int main( int argc, char* argv[] )
747{
748 int option;
749 NdnTrafficClient ndnTrafficClient (argv[0]);
jeraldabrahame891ac92014-02-16 11:04:01 -0700750 while ((option = getopt(argc, argv, "hi:c:")) != -1) {
jeraldabrahamf9543a42014-02-11 06:37:34 -0700751 switch (option) {
752 case 'h' :
753 ndnTrafficClient.usage();
754 break;
755 case 'i' :
756 ndnTrafficClient.setInterestInterval(atoi(optarg));
757 break;
758 case 'c' :
759 ndnTrafficClient.setInterestCount(atoi(optarg));
760 break;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700761 default :
762 ndnTrafficClient.usage();
763 break;
764 }
765 }
766
767 argc -= optind;
768 argv += optind;
769
jeraldabrahame891ac92014-02-16 11:04:01 -0700770 if (argv[0] == NULL)
jeraldabrahamf9543a42014-02-11 06:37:34 -0700771 ndnTrafficClient.usage();
772
773 ndnTrafficClient.setConfigurationFile(argv[0]);
jeraldabrahame891ac92014-02-16 11:04:01 -0700774 ndnTrafficClient.initialize();
jeraldabrahamf9543a42014-02-11 06:37:34 -0700775
776 return 0;
777}