blob: c82b873d40cf3f54aaef510976669b3726bf6416 [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:
31
32 NdnTrafficClient( char* programName )
33 : m_logger("NDNTrafficClient")
34 , ioService_(new boost::asio::io_service)
35 , face_(ioService_)
36 , keyChain_()
37 {
38 std::srand(std::time(0));
39 instanceId_ = toString(std::rand());
40 programName_ = programName;
41 interestInterval_ = getDefaultInterestInterval();
42 interestCount_ = getDefaultInterestCount();
43 configurationFile_ = "";
44 totalInterestSent_ = 0;
45 totalInterestReceived_ = 0;
46 minimumInterestRoundTripTime_ = std::numeric_limits<double>::max();
47 maximumInterestRoundTripTime_ = 0;
48 totalInterestRoundTripTime_ = 0;
49 }
50
51 class InterestTrafficConfiguration
52 {
53 public:
54
55 InterestTrafficConfiguration()
56 {
57 trafficPercentage = -1;
58 name = "";
59 nameAppendBytes = -1;
60 nameAppendSequenceNumber = -1;
61 minSuffixComponents = -1;
62 maxSuffixComponents = -1;
63 excludeBefore = "";
64 excludeAfter = "";
65 excludeBeforeBytes = -1;
66 excludeAfterBytes = -1;
67 childSelector = -1;
68 mustBeFresh = -1;
69 nonceDuplicationPercentage = -1;
70 scope = -1;
71 interestLifetime = -1;
72 totalInterestSent = 0;
73 totalInterestReceived = 0;
74 minimumInterestRoundTripTime = std::numeric_limits<double>::max();
75 maximumInterestRoundTripTime = 0;
76 totalInterestRoundTripTime = 0;
77 }
78
79 void
80 printTrafficConfiguration( Logger& logger )
81 {
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)+", ";
114 if (detail.length() >= 2)
115 detail = detail.substr(0, detail.length()-2);
116 logger.log(detail, false, false);
117 }
118
119 bool
120 extractParameterValue( std::string detail, std::string& parameter, std::string& value )
121 {
122 int i;
123 std::string allowedCharacters = ":/+._-%";
124 parameter = "";
125 value = "";
126 i = 0;
127 while (detail[i] != '=' && i < detail.length())
128 {
129 parameter += detail[i];
130 i++;
131 }
132 if (i == detail.length())
133 return false;
134 i++;
135 while ((std::isalnum(detail[i]) || allowedCharacters.find(detail[i]) != std::string::npos) && i < detail.length())
136 {
137 value += detail[i];
138 i++;
139 }
140 if(parameter == "" || value == "")
141 return false;
142 return true;
143 }
144
145 bool
146 processConfigurationDetail( std::string detail, Logger& logger, int lineNumber )
147 {
148 std::string parameter, value;
149 if (extractParameterValue(detail, parameter, value))
150 {
151 if (parameter == "TrafficPercentage")
152 trafficPercentage = toInteger(value);
153 else if (parameter == "Name")
154 name = value;
155 else if (parameter == "NameAppendBytes")
156 nameAppendBytes = toInteger(value);
157 else if (parameter == "NameAppendSequenceNumber")
158 nameAppendSequenceNumber = toInteger(value);
159 else if (parameter == "MinSuffixComponents")
160 minSuffixComponents = toInteger(value);
161 else if (parameter == "MaxSuffixComponents")
162 maxSuffixComponents = toInteger(value);
163 else if (parameter == "ExcludeBefore")
164 excludeBefore = value;
165 else if (parameter == "ExcludeAfter")
166 excludeAfter = value;
167 else if (parameter == "ExcludeBeforeBytes")
168 excludeBeforeBytes = toInteger(value);
169 else if (parameter == "ExcludeAfterBytes")
170 excludeAfterBytes = toInteger(value);
171 else if (parameter == "ChildSelector")
172 childSelector = toInteger(value);
173 else if (parameter == "MustBeFresh")
174 mustBeFresh = toInteger(value);
175 else if (parameter == "NonceDuplicationPercentage")
176 nonceDuplicationPercentage = toInteger(value);
177 else if (parameter == "Scope")
178 scope = toInteger(value);
179 else if (parameter == "InterestLifetime")
180 interestLifetime = toInteger(value);
181 else
182 logger.log("Line "+toString(lineNumber)+" \t- Invalid Parameter='"+parameter+"'", false, true);
183 }
184 else
185 {
186 logger.log("Line "+toString(lineNumber)+" \t- Improper Traffic Configuration Line- "+detail, false, true);
187 return false;
188 }
189 return true;
190 }
191
192 bool
193 checkTrafficDetailCorrectness()
194 {
195 return true;
196 }
197
198 int trafficPercentage;
199 std::string name;
200 int nameAppendBytes;
201 int nameAppendSequenceNumber;
202 int minSuffixComponents;
203 int maxSuffixComponents;
204 std::string excludeBefore;
205 std::string excludeAfter;
206 int excludeBeforeBytes;
207 int excludeAfterBytes;
208 int childSelector;
209 int mustBeFresh;
210 int nonceDuplicationPercentage;
211 int scope;
212 int interestLifetime;
213 int totalInterestSent;
214 int totalInterestReceived;
215 double minimumInterestRoundTripTime;
216 double maximumInterestRoundTripTime;
217 double totalInterestRoundTripTime;
218
219 };
220
221 int
222 getDefaultInterestLifetime()
223 {
224 return 4000;
225 }
226
227 static std::string
228 toString( int integerValue )
229 {
230 std::stringstream stream;
231 stream << integerValue;
232 return stream.str();
233 }
234
235 static std::string
236 toString( double doubleValue )
237 {
238 std::stringstream stream;
239 stream << doubleValue;
240 return stream.str();
241 }
242
243 static int
244 toInteger( std::string stringValue )
245 {
246 int integerValue;
247 std::stringstream stream(stringValue);
248 stream >> integerValue;
249 return integerValue;
250 }
251
252 void
253 usage()
254 {
255
256 std::cout << "\nUsage: " << programName_ << " [options] <Traffic_Configuration_File>\n"
257 "Generate Interest Traffic as per provided Traffic Configuration File\n"
258 "Interests are continuously generated unless a total number is specified.\n"
259 "Set environment variable NDN_TRAFFIC_LOGFOLDER for redirecting output to a log.\n"
260 " [-i interval] - set interest generation interval in milliseconds (minimum "
261 << getDefaultInterestInterval() << " milliseconds)\n"
262 " [-c count] - set total number of interests to be generated\n"
263 " [-h] - print help and exit\n\n";
264 exit(1);
265
266 }
267
268 int
269 getDefaultInterestInterval()
270 {
271 return 1000;
272 }
273
274 int
275 getDefaultInterestCount()
276 {
277 return -1;
278 }
279
280 void
281 setInterestInterval( int interestInterval )
282 {
283 if (interestInterval < 0)
284 usage();
285 interestInterval_ = interestInterval;
286 }
287
288 void
289 setInterestCount( int interestCount )
290 {
291 if (interestCount < 0)
292 usage();
293 interestCount_ = interestCount;
294 }
295
296 void
297 setConfigurationFile( char* configurationFile )
298 {
299 configurationFile_ = configurationFile;
300 }
301
302 void
303 signalHandler()
304 {
305 m_logger.shutdownLogger();
306 face_.shutdown();
307 ioService_.reset();
308 logStatistics();
309 exit(1);
310 }
311
312 void
313 logStatistics()
314 {
315 int patternId;
316 double loss, average;
317
318 m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
319 m_logger.log("Total Traffic Pattern Types = "+toString((int)trafficPattern_.size()), false, true);
320 m_logger.log("Total Interests Sent = "+toString(totalInterestSent_), false, true);
321 m_logger.log("Total Responses Received = "+toString(totalInterestReceived_), false, true);
322 if (totalInterestSent_ > 0)
323 loss = (totalInterestSent_-totalInterestReceived_)*100.0/totalInterestSent_;
324 else
325 loss = 0;
326 m_logger.log("Total Interest Loss = "+toString(loss)+"%", false, true);
327 if (totalInterestReceived_ > 0)
328 average = totalInterestRoundTripTime_/totalInterestReceived_;
329 else
330 average = 0;
331 m_logger.log("Total Round Trip Time = "+toString(totalInterestRoundTripTime_)+"ms", false, true);
332 m_logger.log("Average Round Trip Time = "+toString(average)+"ms\n", false, true);
333
334 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
335 {
336 m_logger.log("Traffic Pattern Type #"+toString(patternId+1), false, true);
337 trafficPattern_[patternId].printTrafficConfiguration(m_logger);
338 m_logger.log("Total Interests Sent = "+toString(trafficPattern_[patternId].totalInterestSent), false, true);
339 m_logger.log("Total Responses Received = "+toString(trafficPattern_[patternId].totalInterestReceived), false, true);
340 if (trafficPattern_[patternId].totalInterestSent > 0)
341 {
342 loss = (trafficPattern_[patternId].totalInterestSent-trafficPattern_[patternId].totalInterestReceived);
343 loss *= 100.0;
344 loss /= trafficPattern_[patternId].totalInterestSent;
345 }
346 else
347 loss = 0;
348 m_logger.log("Total Interest Loss = "+toString(loss)+"%", false, true);
349 if (trafficPattern_[patternId].totalInterestReceived > 0)
350 average = trafficPattern_[patternId].totalInterestRoundTripTime/trafficPattern_[patternId].totalInterestReceived;
351 else
352 average = 0;
353 m_logger.log("Total Round Trip Time = "+toString(trafficPattern_[patternId].totalInterestRoundTripTime)+"ms", false, true);
354 m_logger.log("Average Round Trip Time = "+toString(average)+"ms\n", false, true);
355 }
356 }
357
358 bool
359 checkTrafficPatternCorrectness()
360 {
361 return true;
362 }
363
364 void
365 analyzeConfigurationFile()
366 {
367 int patternId;
368 int lineNumber;
369 bool skipLine;
370 std::string patternLine;
371 std::ifstream patternFile;
372 m_logger.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true);
373 patternFile.open(configurationFile_.c_str());
374 if (patternFile.is_open())
375 {
376 patternId = 0;
377 lineNumber = 0;
378 while (getline(patternFile, patternLine))
379 {
380 lineNumber++;
381 if (std::isalpha(patternLine[0]))
382 {
383 InterestTrafficConfiguration interestData;
384 skipLine = false;
385 patternId++;
386 if (interestData.processConfigurationDetail(patternLine, m_logger, lineNumber))
387 {
388 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
389 {
390 lineNumber++;
391 if (!interestData.processConfigurationDetail(patternLine, m_logger, lineNumber))
392 {
393 skipLine = true;
394 break;
395 }
396 }
397 lineNumber++;
398 }
399 else
400 skipLine = true;
401 if( !skipLine )
402 {
403 if (interestData.checkTrafficDetailCorrectness())
404 trafficPattern_.push_back(interestData);
405 }
406 }
407 }
408 patternFile.close();
409 if (!checkTrafficPatternCorrectness())
410 {
411 m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true);
412 m_logger.shutdownLogger();
413 exit(1);
414 }
415 m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
416 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
417 {
418 m_logger.log("Traffic Pattern Type #"+toString(patternId+1), false, false);
419 trafficPattern_[patternId].printTrafficConfiguration(m_logger);
420 m_logger.log("", false, false);
421 }
422 }
423 else
424 {
425 m_logger.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);
426 m_logger.shutdownLogger();
427 exit(1);
428 }
429 }
430
431 void
432 initializeTrafficConfiguration()
433 {
434 if (boost::filesystem::exists(boost::filesystem::path(configurationFile_)))
435 {
436 if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_)))
437 {
438 analyzeConfigurationFile();
439 }
440 else
441 {
442 m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true);
443 m_logger.shutdownLogger();
444 exit(1);
445 }
446 }
447 else
448 {
449 m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true);
450 m_logger.shutdownLogger();
451 exit(1);
452 }
453 }
454
455 int
456 getOldNonce()
457 {
458 int randomNonceKey;
459 if (nonceList_.size() == 0)
460 return getNewNonce();
461 std::srand(std::time(0));
462 randomNonceKey = std::rand() % nonceList_.size();
463 return nonceList_[randomNonceKey];
464 }
465
466 int
467 getNewNonce()
468 {
469 int randomNonceKey, i;
470 bool isOld;
471 isOld = true;
472 std::srand(std::time(0));
473 do
474 {
475 randomNonceKey = std::rand();
476 isOld = false;
477 for (i=0; i<nonceList_.size(); i++)
478 if (nonceList_[i] == randomNonceKey)
479 isOld = true;
480 } while(isOld);
481 nonceList_.push_back(randomNonceKey);
482 return randomNonceKey;
483 }
484
485 static std::string
486 getRandomByteString( int randomSize )
487 {
488 int i;
489 std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789";
490 std::string randomData;
491 for (i=0; i<randomSize; i++)
492 randomData += characterSet[std::rand() % characterSet.length()];
493 return randomData;
494 }
495
496 void
497 onData( ndn::Face &face,
498 const ndn::Interest& interest,
499 ndn::Data& data,
500 int globalReference,
501 int localReference,
502 int patternId,
503 boost::posix_time::ptime sentTime )
504 {
505 double roundTripTime;
506 std::string logLine;
507 logLine = "";
508 logLine += "Data Received - PatternType="+toString(patternId+1);
509 logLine += ", GlobalID="+toString(globalReference);
510 logLine += ", LocalID="+toString(localReference);
511 logLine += ", Name="+interest.getName().toUri();
512 m_logger.log(logLine, true, false);
513 boost::posix_time::time_duration roundTripDuration;
514 totalInterestReceived_++;
515 trafficPattern_[patternId].totalInterestReceived++;
516 roundTripDuration = boost::posix_time::microsec_clock::local_time() - sentTime;
517 roundTripTime = roundTripDuration.total_microseconds()/1000.0;
518 if (minimumInterestRoundTripTime_ > roundTripTime)
519 minimumInterestRoundTripTime_ = roundTripTime;
520 if (maximumInterestRoundTripTime_ < roundTripTime)
521 maximumInterestRoundTripTime_ = roundTripTime;
522 if (trafficPattern_[patternId].minimumInterestRoundTripTime > roundTripTime)
523 trafficPattern_[patternId].minimumInterestRoundTripTime = roundTripTime;
524 if (trafficPattern_[patternId].maximumInterestRoundTripTime < roundTripTime)
525 trafficPattern_[patternId].maximumInterestRoundTripTime = roundTripTime;
526 totalInterestRoundTripTime_ += roundTripTime;
527 trafficPattern_[patternId].totalInterestRoundTripTime += roundTripTime;
528 if (totalInterestSent_ == interestCount_)
529 signalHandler();
530 }
531
532 void
533 onTimeout( ndn::Face &face,
534 const ndn::Interest& interest,
535 int globalReference,
536 int localReference,
537 int patternId)
538 {
539 std::string logLine;
540 logLine = "";
541 logLine += "Interest Timed Out - PatternType="+toString(patternId+1);
542 logLine += ", GlobalID="+toString(globalReference);
543 logLine += ", LocalID="+toString(localReference);
544 logLine += ", Name="+interest.getName().toUri();
545 m_logger.log(logLine, true, false);
546 if (totalInterestSent_ == interestCount_)
547 signalHandler();
548 }
549
550 void
551 generateTraffic( const boost::system::error_code& errorCode,
552 boost::asio::deadline_timer* deadlineTimer )
553 {
554 if ((interestCount_ < 0) || (totalInterestSent_ < interestCount_))
555 {
556 int trafficKey, patternId, cumulativePercentage;
557 std::srand(std::time(0));
558 trafficKey = std::rand() % 100;
559 cumulativePercentage = 0;
560 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
561 {
562 cumulativePercentage += trafficPattern_[patternId].trafficPercentage;
563 if (trafficKey <= cumulativePercentage)
564 {
565 Name interestName(trafficPattern_[patternId].name);
566 if (trafficPattern_[patternId].nameAppendBytes > 0)
567 interestName.append(getRandomByteString(trafficPattern_[patternId].nameAppendBytes));
568 if (trafficPattern_[patternId].nameAppendSequenceNumber >= 0)
569 {
570 interestName.append(toString(trafficPattern_[patternId].nameAppendSequenceNumber));
571 trafficPattern_[patternId].nameAppendSequenceNumber++;
572 }
573 Interest interest(interestName);
574 if (trafficPattern_[patternId].minSuffixComponents >= 0)
575 interest.setMinSuffixComponents(trafficPattern_[patternId].minSuffixComponents);
576 if (trafficPattern_[patternId].maxSuffixComponents >= 0)
577 interest.setMaxSuffixComponents(trafficPattern_[patternId].maxSuffixComponents);
578 Exclude exclude;
579 if (trafficPattern_[patternId].excludeBefore != "" && trafficPattern_[patternId].excludeAfter != "")
580 {
581 exclude.excludeRange(name::Component(trafficPattern_[patternId].excludeAfter),
582 name::Component(trafficPattern_[patternId].excludeBefore));
583 interest.setExclude(exclude);
584 }
585 else if (trafficPattern_[patternId].excludeBefore != "")
586 {
587 exclude.excludeBefore(name::Component(trafficPattern_[patternId].excludeBefore));
588 interest.setExclude(exclude);
589 }
590 else if (trafficPattern_[patternId].excludeAfter != "")
591 {
592 exclude.excludeAfter(name::Component(trafficPattern_[patternId].excludeAfter));
593 interest.setExclude(exclude);
594 }
595 if (trafficPattern_[patternId].excludeBeforeBytes > 0 && trafficPattern_[patternId].excludeAfterBytes > 0)
596 {
597 exclude.excludeRange(name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)),
598 name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
599 interest.setExclude(exclude);
600 }
601 else if (trafficPattern_[patternId].excludeBeforeBytes > 0)
602 {
603 exclude.excludeBefore(name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes)));
604 interest.setExclude(exclude);
605 }
606 else if (trafficPattern_[patternId].excludeAfterBytes > 0)
607 {
608 exclude.excludeAfter(name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)));
609 interest.setExclude(exclude);
610 }
611
612 if (trafficPattern_[patternId].childSelector >= 0)
613 interest.setChildSelector(trafficPattern_[patternId].childSelector);
614
615 if (trafficPattern_[patternId].mustBeFresh == 0)
616 interest.setMustBeFresh(false);
617 else if (trafficPattern_[patternId].mustBeFresh > 0)
618 interest.setMustBeFresh(true);
619 if (trafficPattern_[patternId].nonceDuplicationPercentage > 0)
620 {
621 int duplicationKey;
622 std::srand(std::time(0));
623 duplicationKey = std::rand() % 100;
624 if (trafficPattern_[patternId].nonceDuplicationPercentage <= duplicationKey)
625 interest.setNonce(getOldNonce());
626 else
627 interest.setNonce(getNewNonce());
628 }
629 else
630 interest.setNonce(getNewNonce());
631 if (trafficPattern_[patternId].scope >= 0)
632 interest.setScope(trafficPattern_[patternId].scope);
633 if (trafficPattern_[patternId].interestLifetime >= 0)
634 interest.setInterestLifetime(trafficPattern_[patternId].interestLifetime);
635 else
636 interest.setInterestLifetime(getDefaultInterestLifetime());
637 try {
638 totalInterestSent_++;
639 trafficPattern_[patternId].totalInterestSent++;
640 boost::posix_time::ptime sentTime;
641 sentTime = boost::posix_time::microsec_clock::local_time();
642 face_.expressInterest(interest,
643 func_lib::bind( &NdnTrafficClient::onData,
644 this, boost::ref(face_),
645 _1, _2, totalInterestSent_,
646 trafficPattern_[patternId].totalInterestSent,
647 patternId,
648 sentTime),
649 func_lib::bind( &NdnTrafficClient::onTimeout,
650 this, boost::ref(face_),
651 _1, totalInterestSent_,
652 trafficPattern_[patternId].totalInterestSent,
653 patternId));
654 std::string logLine;
655 logLine = "";
656 logLine += "Sending Interest - PatternType="+toString(patternId+1);
657 logLine += ", GlobalID="+toString(totalInterestSent_);
658 logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestSent);
659 logLine += ", Name="+interest.getName().toUri();
660 m_logger.log(logLine, true, false);
661 deadlineTimer->expires_at(deadlineTimer->expires_at() +
662 boost::posix_time::millisec(interestInterval_));
663 deadlineTimer->async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
664 this,
665 boost::asio::placeholders::error,
666 deadlineTimer));
667 }
668 catch (std::exception &e) {
669 m_logger.log("ERROR: "+(std::string)e.what(), true, true);
670 }
671 break;
672 }
673 }
674 if (patternId==trafficPattern_.size())
675 {
676 deadlineTimer->expires_at(deadlineTimer->expires_at() +
677 boost::posix_time::millisec(interestInterval_));
678 deadlineTimer->async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
679 this,
680 boost::asio::placeholders::error,
681 deadlineTimer));
682 }
683 }
684 }
685
686 void
687 initialize()
688 {
689 boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
690 signalSet.async_wait(boost::bind(&NdnTrafficClient::signalHandler, this));
691 m_logger.initializeLog(instanceId_);
692 initializeTrafficConfiguration();
693 boost::asio::deadline_timer deadlineTimer(*ioService_,
694 boost::posix_time::millisec(interestInterval_));
695 deadlineTimer.async_wait(boost::bind(&NdnTrafficClient::generateTraffic,
696 this,
697 boost::asio::placeholders::error,
698 &deadlineTimer));
699 try {
700 face_.processEvents();
701 }
702 catch(std::exception &e) {
703 m_logger.log("ERROR: "+(std::string)e.what(), true, true);
704 m_logger.shutdownLogger();
705 }
706 }
707
708private:
709
710 KeyChain keyChain_;
711 std::string programName_;
712 std::string instanceId_;
713 int interestInterval_;
714 int interestCount_;
715 Logger m_logger;
716 std::string configurationFile_;
717 ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
718 Face face_;
719 std::vector<InterestTrafficConfiguration> trafficPattern_;
720 std::vector<int> nonceList_;
721 int totalInterestSent_;
722 int totalInterestReceived_;
723 double minimumInterestRoundTripTime_;
724 double maximumInterestRoundTripTime_;
725 double totalInterestRoundTripTime_;
726
727};
728
729} // namespace ndn
730
731int main( int argc, char* argv[] )
732{
733 int option;
734 ndn::NdnTrafficClient ndnTrafficClient (argv[0]);
735 while ((option = getopt(argc, argv, "hi:c:")) != -1) {
736 switch (option) {
737 case 'h' :
738 ndnTrafficClient.usage();
739 break;
740 case 'i' :
741 ndnTrafficClient.setInterestInterval(atoi(optarg));
742 break;
743 case 'c' :
744 ndnTrafficClient.setInterestCount(atoi(optarg));
745 break;
746 default :
747 ndnTrafficClient.usage();
748 break;
749 }
750 }
751
752 argc -= optind;
753 argv += optind;
754
755 if (argv[0] == NULL)
756 ndnTrafficClient.usage();
757
758 ndnTrafficClient.setConfigurationFile(argv[0]);
759 ndnTrafficClient.initialize();
760
761 return 0;
762}