blob: f28b5d6097419643994e560eaa2c6f01b321ed6a [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/filesystem.hpp>
#include <ndn-cpp-dev/face.hpp>
#include <ndn-cpp-dev/security/key-chain.hpp>
using namespace ndn;
class Logger
{
public:
Logger()
{
logLocation_ = "";
}
void
shutdownLogger()
{
if (logFile_.is_open())
logFile_.close();
}
void
log( std::string logLine )
{
if( logLocation_.length() > 0 )
{
logFile_ << logLine << std::endl;
logFile_.flush();
}
else
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 )
{
std::srand(std::time(0));
instanceId_ = toString(std::rand());
programName_ = programName;
interestInterval_ = getDefaultInterestInterval();
interestCount_ = getDefaultInterestCount();
configurationFile_ = "";
ioService_ = ptr_lib::make_shared<boost::asio::io_service>();
face_ = Face(ioService_);
}
NdnTrafficClient()
: keyChain_()
{
}
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;
}
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);
}
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+"'");
}
else
{
logger.log("Line "+toString(lineNumber)+" \t: Improper Traffic Configuration Line- "+detail);
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;
};
static std::string
toString( int integerValue )
{
std::stringstream stream;
stream << integerValue;
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();
exit(1);
}
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_);
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_);
logger_.shutdownLogger();
std::cout << "ERROR - Check Log File For Details." << std::endl;
exit(1);
}
for (patternId = 0; patternId < trafficPattern_.size(); patternId++)
trafficPattern_[patternId].printTrafficConfiguration(logger_);
}
else
{
logger_.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_);
logger_.shutdownLogger();
std::cout << "ERROR - Check Log File For Details." << std::endl;
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_);
logger_.shutdownLogger();
std::cout << "ERROR - Check Log File For Details." << std::endl;
exit(1);
}
}
else
{
logger_.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_);
logger_.shutdownLogger();
std::cout << "ERROR - Check Log File For Details." << std::endl;
exit(1);
}
}
void
initialize()
{
boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
signalSet.async_wait(boost::bind(&NdnTrafficClient::signalHandler, this));
logger_.initializeLog(instanceId_);
initializeTrafficConfiguration();
}
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_;
std::vector<InterestTrafficConfiguration> trafficPattern_;
Face face_;
};
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;
}