blob: b617b1cc207adbcf0e1bea7d8bfa3376102842b9 [file] [log] [blame]
/**
*
* 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;
}