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