/** | |
* | |
* Copyright (C) 2014 University of Arizona. | |
* @author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu> | |
* | |
*/ | |
#include <string> | |
#include <sstream> | |
#include <fstream> | |
#include <vector> | |
#include <boost/asio.hpp> | |
#include <boost/bind.hpp> | |
#include <boost/filesystem.hpp> | |
#include <boost/date_time/posix_time/posix_time.hpp> | |
#include <ndn-cpp-dev/face.hpp> | |
#include <ndn-cpp-dev/exclude.hpp> | |
#include <ndn-cpp-dev/name-component.hpp> | |
#include <ndn-cpp-dev/security/key-chain.hpp> | |
using namespace ndn; | |
class Logger | |
{ | |
public: | |
Logger() | |
{ | |
logLocation_ = ""; | |
} | |
void | |
shutdownLogger() | |
{ | |
if (logFile_.is_open()) | |
{ | |
log("Terminating Logging Operations" , true, true); | |
logFile_.close(); | |
} | |
} | |
static std::string | |
getTimestamp() | |
{ | |
boost::posix_time::ptime now; | |
now = boost::posix_time::second_clock::local_time(); | |
return to_simple_string(now); | |
} | |
void | |
log( std::string logLine, bool printTime, bool printToConsole ) | |
{ | |
if( logLocation_.length() > 0 ) | |
{ | |
if (printTime) | |
logFile_ << getTimestamp() << " - "; | |
logFile_ << logLine << std::endl; | |
logFile_.flush(); | |
if (printToConsole) | |
{ | |
if (printTime) | |
std::cout << getTimestamp() << " - "; | |
std::cout << logLine << std::endl; | |
} | |
} | |
else | |
{ | |
if (printTime) | |
std::cout << getTimestamp() << " - "; | |
std::cout << logLine << std::endl; | |
} | |
} | |
void | |
initializeLog( std::string instanceId ) | |
{ | |
char* variableValue = std::getenv("NDN_TRAFFIC_LOGFOLDER"); | |
std::string logFilename; | |
logLocation_ = ""; | |
if (variableValue != NULL) | |
logLocation_ = variableValue; | |
if (boost::filesystem::exists(boost::filesystem::path(logLocation_))) | |
{ | |
if (boost::filesystem::is_directory(boost::filesystem::path(logLocation_))) | |
{ | |
logFilename = logLocation_+"/NDNTrafficClient_"+instanceId+".log"; | |
logFile_.open(logFilename.c_str(), std::ofstream::out | std::ofstream::trunc); | |
if (logFile_.is_open()) | |
std::cout << "Log File Initialized: " << logFilename << std::endl; | |
else | |
{ | |
std::cout << "ERROR - Unable To Initialize A Log File At: " << logLocation_ << std::endl | |
<< "Using Default Output For Logging." << std::endl; | |
logLocation_ = ""; | |
} | |
} | |
else | |
{ | |
std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Should Be A Folder." << std::endl | |
<< "Using Default Output For Logging." << std::endl; | |
logLocation_ = ""; | |
} | |
} | |
else | |
{ | |
std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Not Set." << std::endl | |
<< "Using Default Output For Logging." << std::endl; | |
logLocation_ = ""; | |
} | |
} | |
private: | |
std::string logLocation_; | |
std::ofstream logFile_; | |
}; | |
class NdnTrafficClient | |
{ | |
public: | |
NdnTrafficClient( char* programName ) : ioService_(new boost::asio::io_service), face_(ioService_), keyChain_() | |
{ | |
std::srand(std::time(0)); | |
instanceId_ = toString(std::rand()); | |
programName_ = programName; | |
interestInterval_ = getDefaultInterestInterval(); | |
interestCount_ = getDefaultInterestCount(); | |
configurationFile_ = ""; | |
totalInterestSent_ = 0; | |
totalInterestReceived_ = 0; | |
minimumInterestRoundTripTime_ = std::numeric_limits<double>::max(); | |
maximumInterestRoundTripTime_ = 0; | |
totalInterestRoundTripTime_ = 0; | |
} | |
class InterestTrafficConfiguration | |
{ | |
public: | |
InterestTrafficConfiguration() | |
{ | |
trafficPercentage = -1; | |
name = ""; | |
nameAppendBytes = -1; | |
nameAppendSequenceNumber = -1; | |
minSuffixComponents = -1; | |
maxSuffixComponents = -1; | |
excludeBefore = ""; | |
excludeAfter = ""; | |
excludeBeforeBytes = -1; | |
excludeAfterBytes = -1; | |
childSelector = -1; | |
mustBeFresh = -1; | |
nonceDuplicationPercentage = -1; | |
scope = -1; | |
interestLifetime = -1; | |
totalInterestSent = 0; | |
totalInterestReceived = 0; | |
minimumInterestRoundTripTime = std::numeric_limits<double>::max(); | |
maximumInterestRoundTripTime = 0; | |
totalInterestRoundTripTime = 0; | |
} | |
void | |
printTrafficConfiguration( Logger& logger ) | |
{ | |
std::string detail; | |
detail = ""; | |
if (trafficPercentage > 0) | |
detail += "TrafficPercentage="+toString(trafficPercentage)+", "; | |
if (name != "") | |
detail += "Name="+name+", "; | |
if (nameAppendBytes > 0) | |
detail += "NameAppendBytes="+toString(nameAppendBytes)+", "; | |
if (nameAppendSequenceNumber > 0) | |
detail += "NameAppendSequenceNumber="+toString(nameAppendSequenceNumber)+", "; | |
if (minSuffixComponents >= 0) | |
detail += "MinSuffixComponents="+toString(minSuffixComponents)+", "; | |
if (maxSuffixComponents >= 0) | |
detail += "MaxSuffixComponents="+toString(maxSuffixComponents)+", "; | |
if (excludeBefore != "") | |
detail += "ExcludeBefore="+excludeBefore+", "; | |
if (excludeAfter != "") | |
detail += "ExcludeAfter="+excludeAfter+", "; | |
if (excludeBeforeBytes > 0) | |
detail += "ExcludeBeforeBytes="+toString(excludeBeforeBytes)+", "; | |
if (excludeAfterBytes > 0) | |
detail += "ExcludeAfterBytes="+toString(excludeAfterBytes)+", "; | |
if (childSelector >= 0) | |
detail += "ChildSelector="+toString(childSelector)+", "; | |
if (mustBeFresh >= 0) | |
detail += "MustBeFresh="+toString(mustBeFresh)+", "; | |
if (nonceDuplicationPercentage > 0) | |
detail += "NonceDuplicationPercentage="+toString(nonceDuplicationPercentage)+", "; | |
if (scope >= 0) | |
detail += "Scope="+toString(scope)+", "; | |
if (interestLifetime >= 0) | |
detail += "InterestLifetime="+toString(interestLifetime)+", "; | |
if (detail.length() >= 0) | |
detail = detail.substr(0, detail.length()-2); | |
logger.log(detail, false, false); | |
} | |
bool | |
extractParameterValue( std::string detail, std::string& parameter, std::string& value ) | |
{ | |
int i; | |
std::string allowedCharacters = ":/+._-%"; | |
parameter = ""; | |
value = ""; | |
i = 0; | |
while (detail[i] != '=' && i < detail.length()) | |
{ | |
parameter += detail[i]; | |
i++; | |
} | |
if (i == detail.length()) | |
return false; | |
i++; | |
while ((std::isalnum(detail[i]) || allowedCharacters.find(detail[i]) != std::string::npos) && i < detail.length()) | |
{ | |
value += detail[i]; | |
i++; | |
} | |
if(parameter == "" || value == "") | |
return false; | |
return true; | |
} | |
bool | |
processConfigurationDetail( std::string detail, Logger& logger, int lineNumber ) | |
{ | |
std::string parameter, value; | |
if (extractParameterValue(detail, parameter, value)) | |
{ | |
if (parameter == "TrafficPercentage") | |
trafficPercentage = toInteger(value); | |
else if (parameter == "Name") | |
name = value; | |
else if (parameter == "NameAppendBytes") | |
nameAppendBytes = toInteger(value); | |
else if (parameter == "NameAppendSequenceNumber") | |
nameAppendSequenceNumber = toInteger(value); | |
else if (parameter == "MinSuffixComponents") | |
minSuffixComponents = toInteger(value); | |
else if (parameter == "MaxSuffixComponents") | |
maxSuffixComponents = toInteger(value); | |
else if (parameter == "ExcludeBefore") | |
excludeBefore = value; | |
else if (parameter == "ExcludeAfter") | |
excludeAfter = value; | |
else if (parameter == "ExcludeBeforeBytes") | |
excludeBeforeBytes = toInteger(value); | |
else if (parameter == "ExcludeAfterBytes") | |
excludeAfterBytes = toInteger(value); | |
else if (parameter == "ChildSelector") | |
childSelector = toInteger(value); | |
else if (parameter == "MustBeFresh") | |
mustBeFresh = toInteger(value); | |
else if (parameter == "NonceDuplicationPercentage") | |
nonceDuplicationPercentage = toInteger(value); | |
else if (parameter == "Scope") | |
scope = toInteger(value); | |
else if (parameter == "InterestLifetime") | |
interestLifetime = toInteger(value); | |
else | |
logger.log("Line "+toString(lineNumber)+" \t- Invalid Parameter='"+parameter+"'", false, true); | |
} | |
else | |
{ | |
logger.log("Line "+toString(lineNumber)+" \t- Improper Traffic Configuration Line- "+detail, false, true); | |
return false; | |
} | |
return true; | |
} | |
bool | |
checkTrafficDetailCorrectness() | |
{ | |
return true; | |
} | |
int trafficPercentage; | |
std::string name; | |
int nameAppendBytes; | |
int nameAppendSequenceNumber; | |
int minSuffixComponents; | |
int maxSuffixComponents; | |
std::string excludeBefore; | |
std::string excludeAfter; | |
int excludeBeforeBytes; | |
int excludeAfterBytes; | |
int childSelector; | |
int mustBeFresh; | |
int nonceDuplicationPercentage; | |
int scope; | |
int interestLifetime; | |
int totalInterestSent; | |
int totalInterestReceived; | |
double minimumInterestRoundTripTime; | |
double maximumInterestRoundTripTime; | |
double totalInterestRoundTripTime; | |
}; | |
int | |
getDefaultInterestLifetime() | |
{ | |
return 4000; | |
} | |
static std::string | |
toString( int integerValue ) | |
{ | |
std::stringstream stream; | |
stream << integerValue; | |
return stream.str(); | |
} | |
static std::string | |
toString( double doubleValue ) | |
{ | |
std::stringstream stream; | |
stream << doubleValue; | |
return stream.str(); | |
} | |
static int | |
toInteger( std::string stringValue ) | |
{ | |
int integerValue; | |
std::stringstream stream(stringValue); | |
stream >> integerValue; | |
return integerValue; | |
} | |
void | |
usage() | |
{ | |
std::cout << "\nUsage: " << programName_ << " Printing Usage" | |
<< std::endl << std::endl; | |
exit(1); | |
} | |
int | |
getDefaultInterestInterval() | |
{ | |
return 1000; | |
} | |
int | |
getDefaultInterestCount() | |
{ | |
return -1; | |
} | |
void | |
setInterestInterval( int interestInterval ) | |
{ | |
if (interestInterval < 0) | |
usage(); | |
interestInterval_ = interestInterval; | |
} | |
void | |
setInterestCount( int interestCount ) | |
{ | |
if (interestCount < 0) | |
usage(); | |
interestCount_ = interestCount; | |
} | |
void | |
setConfigurationFile( char* configurationFile ) | |
{ | |
configurationFile_ = configurationFile; | |
} | |
void | |
signalHandler() | |
{ | |
logger_.shutdownLogger(); | |
face_.shutdown(); | |
ioService_.reset(); | |
logStatistics(); | |
exit(1); | |
} | |
void | |
logStatistics() | |
{ | |
int patternId; | |
double loss, average; | |
logger_.log("\n\n== Interest Traffic Report ==\n", false, true); | |
logger_.log("Total Traffic Pattern Types = "+toString((int)trafficPattern_.size()), false, true); | |
logger_.log("Total Interests Sent = "+toString(totalInterestSent_), false, true); | |
logger_.log("Total Responses Received = "+toString(totalInterestReceived_), false, true); | |
if (totalInterestSent_ > 0) | |
loss = (totalInterestSent_-totalInterestReceived_)*100.0/totalInterestSent_; | |
else | |
loss = 0; | |
logger_.log("Total Interest Loss = "+toString(loss)+"%", false, true); | |
if (totalInterestReceived_ > 0) | |
average = totalInterestRoundTripTime_/totalInterestReceived_; | |
else | |
average = 0; | |
logger_.log("Total Round Trip Time = "+toString(totalInterestRoundTripTime_)+"ms", false, true); | |
logger_.log("Average Round Trip Time = "+toString(average)+"ms\n", false, true); | |
for (patternId=0; patternId<trafficPattern_.size(); patternId++) | |
{ | |
logger_.log("Traffic Pattern Type #"+toString(patternId+1), false, true); | |
trafficPattern_[patternId].printTrafficConfiguration(logger_); | |
logger_.log("Total Interests Sent = "+toString(trafficPattern_[patternId].totalInterestSent), false, true); | |
logger_.log("Total Responses Received = "+toString(trafficPattern_[patternId].totalInterestReceived), false, true); | |
if (trafficPattern_[patternId].totalInterestSent > 0) | |
{ | |
loss = (trafficPattern_[patternId].totalInterestSent-trafficPattern_[patternId].totalInterestReceived); | |
loss *= 100.0; | |
loss /= trafficPattern_[patternId].totalInterestSent; | |
} | |
else | |
loss = 0; | |
logger_.log("Total Interest Loss = "+toString(loss)+"%", false, true); | |
if (trafficPattern_[patternId].totalInterestReceived > 0) | |
average = trafficPattern_[patternId].totalInterestRoundTripTime/trafficPattern_[patternId].totalInterestReceived; | |
else | |
average = 0; | |
logger_.log("Total Round Trip Time = "+toString(trafficPattern_[patternId].totalInterestRoundTripTime)+"ms", false, true); | |
logger_.log("Average Round Trip Time = "+toString(average)+"ms\n", false, true); | |
} | |
} | |
bool | |
checkTrafficPatternCorrectness() | |
{ | |
return true; | |
} | |
void | |
analyzeConfigurationFile() | |
{ | |
int patternId; | |
int lineNumber; | |
bool skipLine; | |
std::string patternLine; | |
std::ifstream patternFile; | |
logger_.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true); | |
patternFile.open(configurationFile_.c_str()); | |
if (patternFile.is_open()) | |
{ | |
patternId = 0; | |
lineNumber = 0; | |
while (getline(patternFile, patternLine)) | |
{ | |
lineNumber++; | |
if (std::isalpha(patternLine[0])) | |
{ | |
InterestTrafficConfiguration interestData; | |
skipLine = false; | |
patternId++; | |
if (interestData.processConfigurationDetail(patternLine, logger_, lineNumber)) | |
{ | |
while (getline(patternFile, patternLine) && std::isalpha(patternLine[0])) | |
{ | |
lineNumber++; | |
if (!interestData.processConfigurationDetail(patternLine, logger_, lineNumber)) | |
{ | |
skipLine = true; | |
break; | |
} | |
} | |
lineNumber++; | |
} | |
else | |
skipLine = true; | |
if( !skipLine ) | |
{ | |
if (interestData.checkTrafficDetailCorrectness()) | |
trafficPattern_.push_back(interestData); | |
} | |
} | |
} | |
patternFile.close(); | |
if (!checkTrafficPatternCorrectness()) | |
{ | |
logger_.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true); | |
logger_.shutdownLogger(); | |
exit(1); | |
} | |
logger_.log("Traffic Configuration File Processing Completed\n", true, false); | |
for (patternId=0; patternId<trafficPattern_.size(); patternId++) | |
{ | |
logger_.log("Traffic Pattern Type #"+toString(patternId+1), false, false); | |
trafficPattern_[patternId].printTrafficConfiguration(logger_); | |
logger_.log("", false, false); | |
} | |
} | |
else | |
{ | |
logger_.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true); | |
logger_.shutdownLogger(); | |
exit(1); | |
} | |
} | |
void | |
initializeTrafficConfiguration() | |
{ | |
if (boost::filesystem::exists(boost::filesystem::path(configurationFile_))) | |
{ | |
if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_))) | |
{ | |
analyzeConfigurationFile(); | |
} | |
else | |
{ | |
logger_.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true); | |
logger_.shutdownLogger(); | |
exit(1); | |
} | |
} | |
else | |
{ | |
logger_.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true); | |
logger_.shutdownLogger(); | |
exit(1); | |
} | |
} | |
int | |
getOldNonce() | |
{ | |
int randomNonceKey; | |
if (nonceList_.size() == 0) | |
return getNewNonce(); | |
std::srand(std::time(0)); | |
randomNonceKey = std::rand() % nonceList_.size(); | |
return nonceList_[randomNonceKey]; | |
} | |
int | |
getNewNonce() | |
{ | |
int randomNonceKey, i; | |
bool isOld; | |
isOld = true; | |
std::srand(std::time(0)); | |
do | |
{ | |
randomNonceKey = std::rand(); | |
isOld = false; | |
for (i=0; i<nonceList_.size(); i++) | |
if (nonceList_[i] == randomNonceKey) | |
isOld = true; | |
} while(isOld); | |
nonceList_.push_back(randomNonceKey); | |
return randomNonceKey; | |
} | |
static std::string | |
getRandomByteString( int randomSize ) | |
{ | |
int i; | |
std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789"; | |
std::string randomData; | |
for (i=0; i<randomSize; i++) | |
randomData += characterSet[std::rand() % characterSet.length()]; | |
return randomData; | |
} | |
void | |
onData( ndn::Face &face, | |
const ndn::Interest& interest, | |
ndn::Data& data, | |
int globalReference, | |
int localReference, | |
int patternId, | |
boost::posix_time::ptime sentTime ) | |
{ | |
double roundTripTime; | |
std::string logLine; | |
logLine = ""; | |
logLine += "Data Received - GlobalID="+toString(globalReference); | |
logLine += ", LocalID="+toString(localReference); | |
logLine += ", PatternID="+toString(patternId); | |
logLine += ", Name="+interest.getName().toUri(); | |
logger_.log(logLine, true, false); | |
boost::posix_time::time_duration roundTripDuration; | |
totalInterestReceived_++; | |
trafficPattern_[patternId].totalInterestReceived++; | |
roundTripDuration = boost::posix_time::microsec_clock::local_time() - sentTime; | |
roundTripTime = roundTripDuration.total_microseconds()/1000.0; | |
if (minimumInterestRoundTripTime_ > roundTripTime) | |
minimumInterestRoundTripTime_ = roundTripTime; | |
if (maximumInterestRoundTripTime_ < roundTripTime) | |
maximumInterestRoundTripTime_ = roundTripTime; | |
if (trafficPattern_[patternId].minimumInterestRoundTripTime > roundTripTime) | |
trafficPattern_[patternId].minimumInterestRoundTripTime = roundTripTime; | |
if (trafficPattern_[patternId].maximumInterestRoundTripTime < roundTripTime) | |
trafficPattern_[patternId].maximumInterestRoundTripTime = roundTripTime; | |
totalInterestRoundTripTime_ += roundTripTime; | |
trafficPattern_[patternId].totalInterestRoundTripTime += roundTripTime; | |
if (totalInterestSent_ == interestCount_) | |
signalHandler(); | |
} | |
void | |
onTimeout( ndn::Face &face, | |
const ndn::Interest& interest, | |
int globalReference, | |
int localReference, | |
int patternId) | |
{ | |
std::string logLine; | |
logLine = ""; | |
logLine += "Interest Timed Out - GlobalID="+toString(globalReference); | |
logLine += ", LocalID="+toString(localReference); | |
logLine += ", PatternID="+toString(patternId); | |
logLine += ", Name="+interest.getName().toUri(); | |
logger_.log(logLine, true, false); | |
if (totalInterestSent_ == interestCount_) | |
signalHandler(); | |
} | |
void | |
generateTraffic( const boost::system::error_code& errorCode, | |
boost::asio::deadline_timer* deadlineTimer ) | |
{ | |
if ((interestCount_ < 0) || (totalInterestSent_ < interestCount_)) | |
{ | |
int trafficKey, patternId, cumulativePercentage; | |
std::srand(std::time(0)); | |
trafficKey = std::rand() % 100; | |
cumulativePercentage = 0; | |
for (patternId=0; patternId<trafficPattern_.size(); patternId++) | |
{ | |
cumulativePercentage += trafficPattern_[patternId].trafficPercentage; | |
if (trafficKey <= cumulativePercentage) | |
{ | |
Name interestName(trafficPattern_[patternId].name); | |
if (trafficPattern_[patternId].nameAppendBytes > 0) | |
interestName.append(getRandomByteString(trafficPattern_[patternId].nameAppendBytes)); | |
if (trafficPattern_[patternId].nameAppendSequenceNumber >= 0) | |
{ | |
interestName.append(toString(trafficPattern_[patternId].nameAppendSequenceNumber)); | |
trafficPattern_[patternId].nameAppendSequenceNumber++; | |
} | |
Interest interest(interestName); | |
if (trafficPattern_[patternId].minSuffixComponents >= 0) | |
interest.setMinSuffixComponents(trafficPattern_[patternId].minSuffixComponents); | |
if (trafficPattern_[patternId].maxSuffixComponents >= 0) | |
interest.setMaxSuffixComponents(trafficPattern_[patternId].maxSuffixComponents); | |
Exclude exclude; | |
if (trafficPattern_[patternId].excludeBefore != "" && trafficPattern_[patternId].excludeAfter != "") | |
{ | |
exclude.excludeRange(name::Component(trafficPattern_[patternId].excludeAfter), | |
name::Component(trafficPattern_[patternId].excludeBefore)); | |
interest.setExclude(exclude); | |
} | |
else if (trafficPattern_[patternId].excludeBefore != "") | |
{ | |
exclude.excludeBefore(name::Component(trafficPattern_[patternId].excludeBefore)); | |
interest.setExclude(exclude); | |
} | |
else if (trafficPattern_[patternId].excludeAfter != "") | |
{ | |
exclude.excludeAfter(name::Component(trafficPattern_[patternId].excludeAfter)); | |
interest.setExclude(exclude); | |
} | |
if (trafficPattern_[patternId].excludeBeforeBytes > 0 && trafficPattern_[patternId].excludeAfterBytes > 0) | |
{ | |
exclude.excludeRange(name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes)), | |
name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes))); | |
interest.setExclude(exclude); | |
} | |
else if (trafficPattern_[patternId].excludeBeforeBytes > 0) | |
{ | |
exclude.excludeBefore(name::Component(getRandomByteString(trafficPattern_[patternId].excludeBeforeBytes))); | |
interest.setExclude(exclude); | |
} | |
else if (trafficPattern_[patternId].excludeAfterBytes > 0) | |
{ | |
exclude.excludeAfter(name::Component(getRandomByteString(trafficPattern_[patternId].excludeAfterBytes))); | |
interest.setExclude(exclude); | |
} | |
if (trafficPattern_[patternId].childSelector >= 0) | |
interest.setChildSelector(trafficPattern_[patternId].childSelector); | |
if (trafficPattern_[patternId].mustBeFresh == 0) | |
interest.setMustBeFresh(false); | |
else if (trafficPattern_[patternId].mustBeFresh > 0) | |
interest.setMustBeFresh(true); | |
if (trafficPattern_[patternId].nonceDuplicationPercentage > 0) | |
{ | |
int duplicationKey; | |
std::srand(std::time(0)); | |
duplicationKey = std::rand() % 100; | |
if (trafficPattern_[patternId].nonceDuplicationPercentage <= duplicationKey) | |
interest.setNonce(getOldNonce()); | |
else | |
interest.setNonce(getNewNonce()); | |
} | |
else | |
interest.setNonce(getNewNonce()); | |
if (trafficPattern_[patternId].scope >= 0) | |
interest.setScope(trafficPattern_[patternId].scope); | |
if (trafficPattern_[patternId].interestLifetime >= 0) | |
interest.setInterestLifetime(trafficPattern_[patternId].interestLifetime); | |
else | |
interest.setInterestLifetime(getDefaultInterestLifetime()); | |
try { | |
totalInterestSent_++; | |
trafficPattern_[patternId].totalInterestSent++; | |
boost::posix_time::ptime sentTime; | |
sentTime = boost::posix_time::microsec_clock::local_time(); | |
face_.expressInterest(interest, | |
func_lib::bind( &NdnTrafficClient::onData, | |
this, boost::ref(face_), | |
_1, _2, totalInterestSent_, | |
trafficPattern_[patternId].totalInterestSent, | |
patternId, | |
sentTime), | |
func_lib::bind( &NdnTrafficClient::onTimeout, | |
this, boost::ref(face_), | |
_1, totalInterestSent_, | |
trafficPattern_[patternId].totalInterestSent, | |
patternId)); | |
std::string logLine; | |
logLine = ""; | |
logLine += "Sending Interest - GlobalID="+toString(totalInterestSent_); | |
logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestSent); | |
logLine += ", PatternID="+toString(patternId); | |
logLine += ", Name="+interest.getName().toUri(); | |
logger_.log(logLine, true, false); | |
deadlineTimer->expires_at(deadlineTimer->expires_at() + | |
boost::posix_time::millisec(interestInterval_)); | |
deadlineTimer->async_wait(boost::bind(&NdnTrafficClient::generateTraffic, | |
this, | |
boost::asio::placeholders::error, | |
deadlineTimer)); | |
} | |
catch (std::exception &e) { | |
logger_.log("ERROR: "+(std::string)e.what(), true, true); | |
} | |
break; | |
} | |
} | |
if (patternId==trafficPattern_.size()) | |
{ | |
deadlineTimer->expires_at(deadlineTimer->expires_at() + | |
boost::posix_time::millisec(interestInterval_)); | |
deadlineTimer->async_wait(boost::bind(&NdnTrafficClient::generateTraffic, | |
this, | |
boost::asio::placeholders::error, | |
deadlineTimer)); | |
} | |
} | |
} | |
void | |
initialize() | |
{ | |
boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM); | |
signalSet.async_wait(boost::bind(&NdnTrafficClient::signalHandler, this)); | |
logger_.initializeLog(instanceId_); | |
initializeTrafficConfiguration(); | |
boost::asio::deadline_timer deadlineTimer(*ioService_, | |
boost::posix_time::millisec(interestInterval_)); | |
deadlineTimer.async_wait(boost::bind(&NdnTrafficClient::generateTraffic, | |
this, | |
boost::asio::placeholders::error, | |
&deadlineTimer)); | |
try { | |
face_.processEvents(); | |
} | |
catch(std::exception &e) { | |
logger_.log("ERROR: "+(std::string)e.what(), true, true); | |
logger_.shutdownLogger(); | |
} | |
} | |
private: | |
KeyChain keyChain_; | |
std::string programName_; | |
std::string instanceId_; | |
int interestInterval_; | |
int interestCount_; | |
Logger logger_; | |
std::string configurationFile_; | |
ptr_lib::shared_ptr<boost::asio::io_service> ioService_; | |
Face face_; | |
std::vector<InterestTrafficConfiguration> trafficPattern_; | |
std::vector<int> nonceList_; | |
int totalInterestSent_; | |
int totalInterestReceived_; | |
double minimumInterestRoundTripTime_; | |
double maximumInterestRoundTripTime_; | |
double totalInterestRoundTripTime_; | |
}; | |
int main( int argc, char* argv[] ) | |
{ | |
int option; | |
NdnTrafficClient ndnTrafficClient (argv[0]); | |
while ((option = getopt(argc, argv, "hi:c:")) != -1) { | |
switch (option) { | |
case 'h' : | |
ndnTrafficClient.usage(); | |
break; | |
case 'i' : | |
ndnTrafficClient.setInterestInterval(atoi(optarg)); | |
break; | |
case 'c' : | |
ndnTrafficClient.setInterestCount(atoi(optarg)); | |
break; | |
default : | |
ndnTrafficClient.usage(); | |
break; | |
} | |
} | |
argc -= optind; | |
argv += optind; | |
if (argv[0] == NULL) | |
ndnTrafficClient.usage(); | |
ndnTrafficClient.setConfigurationFile(argv[0]); | |
ndnTrafficClient.initialize(); | |
return 0; | |
} |