diff --git a/ndn-traffic-client.conf.sample b/ndn-traffic-client.conf.sample index 9965d3a..1695ec7 100644 --- a/ndn-traffic-client.conf.sample +++ b/ndn-traffic-client.conf.sample @@ -2,20 +2,19 @@ # THIS IS A SAMPLE CLIENT INTEREST TRAFFIC CONFIGURATION FILE # # * TO BE USED TO GENERATE INTEREST MESSAGES BASED ON A PROBABILITY -# PATTERN. -# * EVERY INIVIDUAL PATTERN DESCRIPTION MUST BE SEPARATED BY ONE +# PATTERN +# * EVERY INDIVIDUAL PATTERN DESCRIPTION MUST BE SEPARATED BY ONE # OR MORE '#' CHARACTERS FOR THE TOOL TO DISTINGUISH THEM -# INDIVIDUALLY # * THE FOLLOWING PARAMETERS MAY BE ADDED FOR EVERY TRAFFIC PATTERN -# * (Mandatory) NEXT TO A PARAMETER MEANS EVERY PATTERN SHOULD HAVE -# IT FOR BEING CONSIDERED VALID -# (Optional) MEANS OTHERWISE -# * ALSO PROVIDED ARE VALID VALUES POSSIBLE FOR EACH PARAMETER -# * PLEASE ENSURE THAT THE SUM OF TrafficPercentage FOR ALL DECLARED -# PATTERNS DOES NOT EXCEED 100 IN ORDER TO MAINTAIN CORRECT BEHAVIOR -# * NNI STANDS FOR NON-NEGATIVE INTEGER +# * 'Mandatory' ARE PARAMETERS THAT EVERY PATTERN MUST HAVE IN ORDER +# TO BE CONSIDERED VALID +# * 'Boolean' ACCEPTS EITHER 0/false/no/off OR 1/true/yes/on AS VALUE +# * 'NNI' STANDS FOR NON-NEGATIVE INTEGER # * RANGE OF POSSIBLE VALUES IS SPECIFIED IN [] +# * PLEASE ENSURE THAT THE SUM OF 'TrafficPercentage' FOR ALL DECLARED +# PATTERNS DOES NOT EXCEED 100 IN ORDER TO MAINTAIN CORRECT BEHAVIOR # + # (Mandatory) #TrafficPercentage=NNI [0-100] #Name=NDN Name @@ -23,10 +22,10 @@ # (Optional) #NameAppendBytes=NNI [>0] #NameAppendSequenceNumber=NNI [>=0] -#MustBeFresh=NNI [0-1] +#MustBeFresh=Boolean #NonceDuplicationPercentage=NNI [0-100] -#InterestLifetime=NNI [Milliseconds] -#NextHopFaceId=NNI +#InterestLifetime=Milliseconds [>=0] +#NextHopFaceId=NNI [>0] #ExpectedContent=String ########## diff --git a/ndn-traffic-server.conf.sample b/ndn-traffic-server.conf.sample index 7c8b540..aadc9eb 100644 --- a/ndn-traffic-server.conf.sample +++ b/ndn-traffic-server.conf.sample @@ -3,26 +3,25 @@ # # * TO BE USED TO CONFIGURE RESPONSE TO INTERESTS # * MULTIPLE SERVER PREFIXES CAN BE CONFIGURED FOR BEING HANDLED -# * EVERY INIVIDUAL PATTERN DESCRIPTION MUST BE SEPARATED BY ONE +# * EVERY INDIVIDUAL PATTERN DESCRIPTION MUST BE SEPARATED BY ONE # OR MORE '#' CHARACTERS FOR THE TOOL TO DISTINGUISH THEM -# INDIVIDUALLY # * THE FOLLOWING PARAMETERS MAY BE ADDED FOR EVERY TRAFFIC PATTERN -# * (Mandatory) NEXT TO A PARAMETER MEANS EVERY PATTERN SHOULD HAVE -# IT FOR BEING CONSIDERED VALID -# (Optional) MEANS OTHERWISE -# * ALSO PROVIDED ARE VALID VALUES POSSIBLE FOR EACH PARAMETER -# * NNI STANDS FOR NON-NEGATIVE INTEGER +# * 'Mandatory' ARE PARAMETERS THAT EVERY PATTERN MUST HAVE IN ORDER +# TO BE CONSIDERED VALID +# * 'Boolean' ACCEPTS EITHER 0/false/no/off OR 1/true/yes/on AS VALUE +# * 'NNI' STANDS FOR NON-NEGATIVE INTEGER # * RANGE OF POSSIBLE VALUES IS SPECIFIED IN [] # + # (Mandatory) #Name=NDN Name # # (Optional) +#ContentDelay=Milliseconds [>=0] +#FreshnessPeriod=Milliseconds [>=0] #ContentType=NNI [>=0] -#FreshnessPeriod=NNI [milliseconds] #ContentBytes=NNI [>0] #Content=String -#ContentDelay=NNI [milliseconds] #SigningInfo=String [examples below] ########## diff --git a/src/ndn-traffic-client.cpp b/src/ndn-traffic-client.cpp index adba253..005b8d4 100644 --- a/src/ndn-traffic-client.cpp +++ b/src/ndn-traffic-client.cpp @@ -18,7 +18,6 @@ * Author: Jerald Paul Abraham */ -#include "logger.hpp" #include "util.hpp" #include @@ -27,7 +26,6 @@ #include #include -#include #include #include @@ -36,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -58,12 +55,6 @@ public: { } - bool - hasError() const - { - return m_hasError; - } - void setMaximumInterests(uint64_t maxInterests) { @@ -83,15 +74,30 @@ public: m_wantQuiet = true; } - void + int run() { m_logger.initializeLog(to_string(random::generateWord32())); - initializeTrafficConfiguration(); + + if (!readConfigurationFile(m_configurationFile, m_trafficPatterns, m_logger)) { + return 2; + } + + if (!checkTrafficPatternCorrectness()) { + m_logger.log("ERROR: Traffic configuration provided is not proper", false, true); + return 2; + } + + m_logger.log("Traffic configuration file processing completed.\n", true, false); + for (std::size_t i = 0; i < m_trafficPatterns.size(); i++) { + m_logger.log("Traffic Pattern Type #" + to_string(i + 1), false, false); + m_trafficPatterns[i].printTrafficConfiguration(m_logger); + m_logger.log("", false, false); + } if (m_nMaximumInterests == 0) { logStatistics(); - return; + return 0; } m_signalSet.async_wait([this] (auto&&...) { this->stop(); }); @@ -102,11 +108,12 @@ public: try { m_face.processEvents(); + return m_hasError ? 1 : 0; } catch (const std::exception& e) { m_logger.log("ERROR: "s + e.what(), true, true); - m_hasError = true; m_ioService.stop(); + return 1; } } @@ -120,14 +127,12 @@ private: std::string detail; detail += "TrafficPercentage=" + to_string(m_trafficPercentage) + ", "; - if (!m_name.empty()) - detail += "Name=" + m_name + ", "; + detail += "Name=" + m_name + ", "; if (m_nameAppendBytes) detail += "NameAppendBytes=" + to_string(*m_nameAppendBytes) + ", "; if (m_nameAppendSeqNum) detail += "NameAppendSequenceNumber=" + to_string(*m_nameAppendSeqNum) + ", "; - if (!boost::logic::indeterminate(m_mustBeFresh)) - detail += "MustBeFresh=" + to_string(bool(m_mustBeFresh)) + ", "; + detail += "MustBeFresh=" + to_string(m_mustBeFresh) + ", "; if (m_nonceDuplicationPercentage > 0) detail += "NonceDuplicationPercentage=" + to_string(m_nonceDuplicationPercentage) + ", "; if (m_interestLifetime >= 0_ms) @@ -143,36 +148,45 @@ private: } bool - processConfigurationDetail(const std::string& detail, Logger& logger, int lineNumber) + parseConfigurationLine(const std::string& line, Logger& logger, int lineNumber) { std::string parameter, value; - if (parseParameterAndValue(detail, parameter, value)) { - if (parameter == "TrafficPercentage") - m_trafficPercentage = std::stoul(value); - else if (parameter == "Name") - m_name = value; - else if (parameter == "NameAppendBytes") - m_nameAppendBytes = std::stoul(value); - else if (parameter == "NameAppendSequenceNumber") - m_nameAppendSeqNum = std::stoull(value); - else if (parameter == "MustBeFresh") - m_mustBeFresh = bool(std::stoul(value)); - else if (parameter == "NonceDuplicationPercentage") - m_nonceDuplicationPercentage = std::stoul(value); - else if (parameter == "InterestLifetime") - m_interestLifetime = time::milliseconds(std::stoul(value)); - else if (parameter == "NextHopFaceId") - m_nextHopFaceId = std::stoull(value); - else if (parameter == "ExpectedContent") - m_expectedContent = value; - else - logger.log("Line " + to_string(lineNumber) + - " - Unknown parameter '" + parameter + "'", false, true); + if (!extractParameterAndValue(line, parameter, value)) { + logger.log("Line " + to_string(lineNumber) + " - Invalid syntax: " + line, + false, true); + return false; + } + + if (parameter == "TrafficPercentage") { + m_trafficPercentage = std::stoul(value); + } + else if (parameter == "Name") { + m_name = value; + } + else if (parameter == "NameAppendBytes") { + m_nameAppendBytes = std::stoul(value); + } + else if (parameter == "NameAppendSequenceNumber") { + m_nameAppendSeqNum = std::stoull(value); + } + else if (parameter == "MustBeFresh") { + m_mustBeFresh = parseBoolean(value); + } + else if (parameter == "NonceDuplicationPercentage") { + m_nonceDuplicationPercentage = std::stoul(value); + } + else if (parameter == "InterestLifetime") { + m_interestLifetime = time::milliseconds(std::stoul(value)); + } + else if (parameter == "NextHopFaceId") { + m_nextHopFaceId = std::stoull(value); + } + else if (parameter == "ExpectedContent") { + m_expectedContent = value; } else { - logger.log("Line " + to_string(lineNumber) + - " - Invalid traffic configuration line: " + detail, false, true); - return false; + logger.log("Line " + to_string(lineNumber) + " - Ignoring unknown parameter: " + parameter, + false, true); } return true; } @@ -188,7 +202,7 @@ private: std::string m_name; optional m_nameAppendBytes; optional m_nameAppendSeqNum; - boost::logic::tribool m_mustBeFresh = boost::logic::indeterminate; + bool m_mustBeFresh = false; uint8_t m_nonceDuplicationPercentage = 0; time::milliseconds m_interestLifetime = -1_ms; uint64_t m_nextHopFaceId = 0; @@ -272,88 +286,10 @@ private: bool checkTrafficPatternCorrectness() const { + // TODO return true; } - void - parseConfigurationFile() - { - std::ifstream patternFile; - m_logger.log("Parsing traffic configuration file: " + m_configurationFile, true, true); - - patternFile.open(m_configurationFile.data()); - if (patternFile.is_open()) { - int lineNumber = 0; - std::string patternLine; - while (getline(patternFile, patternLine)) { - lineNumber++; - if (std::isalpha(patternLine[0])) { - InterestTrafficConfiguration interestData; - bool shouldSkipLine = false; - if (interestData.processConfigurationDetail(patternLine, m_logger, lineNumber)) { - while (getline(patternFile, patternLine) && std::isalpha(patternLine[0])) { - lineNumber++; - if (!interestData.processConfigurationDetail(patternLine, m_logger, lineNumber)) { - shouldSkipLine = true; - break; - } - } - lineNumber++; - } - else { - shouldSkipLine = true; - } - if (!shouldSkipLine) { - if (interestData.checkTrafficDetailCorrectness()) { - m_trafficPatterns.push_back(interestData); - } - } - } - } - patternFile.close(); - - if (!checkTrafficPatternCorrectness()) { - m_logger.log("ERROR: Traffic configuration provided is not proper - " + - m_configurationFile, false, true); - exit(2); - } - - m_logger.log("Traffic configuration file processing completed.\n", true, false); - for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) { - m_logger.log("Traffic Pattern Type #" + to_string(patternId + 1), false, false); - m_trafficPatterns[patternId].printTrafficConfiguration(m_logger); - m_logger.log("", false, false); - } - } - else { - m_logger.log("ERROR: Unable to open traffic configuration file: " + m_configurationFile, false, true); - exit(2); - } - } - - void - initializeTrafficConfiguration() - { - namespace fs = boost::filesystem; - - fs::path configPath(m_configurationFile); - if (fs::exists(configPath)) { - if (fs::is_regular_file(configPath)) { - parseConfigurationFile(); - } - else { - m_logger.log("ERROR: Traffic configuration file is not a regular file: " + - m_configurationFile, false, true); - exit(2); - } - } - else { - m_logger.log("ERROR: Traffic configuration file does not exist: " + - m_configurationFile, false, true); - exit(2); - } - } - uint32_t getNewNonce() { @@ -409,10 +345,7 @@ private: } interest.setName(name); - if (pattern.m_mustBeFresh) - interest.setMustBeFresh(true); - else if (!pattern.m_mustBeFresh) - interest.setMustBeFresh(false); + interest.setMustBeFresh(pattern.m_mustBeFresh); static std::uniform_int_distribution<> duplicateNonceDist(1, 100); if (duplicateNonceDist(random::getRandomNumberEngine()) <= pattern.m_nonceDuplicationPercentage) @@ -688,7 +621,5 @@ main(int argc, char* argv[]) client.setQuietLogging(); } - client.run(); - - return client.hasError() ? 1 : 0; + return client.run(); } diff --git a/src/ndn-traffic-server.cpp b/src/ndn-traffic-server.cpp index a6d8fef..25ace67 100644 --- a/src/ndn-traffic-server.cpp +++ b/src/ndn-traffic-server.cpp @@ -18,7 +18,6 @@ * Author: Jerald Paul Abraham */ -#include "logger.hpp" #include "util.hpp" #include @@ -28,7 +27,6 @@ #include #include -#include #include #include #include @@ -57,12 +55,6 @@ public: { } - bool - hasError() const - { - return m_hasError; - } - void setMaximumInterests(uint64_t maxInterests) { @@ -82,15 +74,30 @@ public: m_wantQuiet = true; } - void + int run() { m_logger.initializeLog(to_string(random::generateWord32())); - initializeTrafficConfiguration(); + + if (!readConfigurationFile(m_configurationFile, m_trafficPatterns, m_logger)) { + return 2; + } + + if (!checkTrafficPatternCorrectness()) { + m_logger.log("ERROR: Traffic configuration provided is not proper", false, true); + return 2; + } + + m_logger.log("Traffic configuration file processing completed.\n", true, false); + for (std::size_t i = 0; i < m_trafficPatterns.size(); i++) { + m_logger.log("Traffic Pattern Type #" + to_string(i + 1), false, false); + m_trafficPatterns[i].printTrafficConfiguration(m_logger); + m_logger.log("", false, false); + } if (m_nMaximumInterests == 0) { logStatistics(); - return; + return 0; } m_signalSet.async_wait([this] (const boost::system::error_code&, int) { @@ -110,11 +117,12 @@ public: try { m_face.processEvents(); + return m_hasError ? 1 : 0; } catch (const std::exception& e) { m_logger.log("ERROR: "s + e.what(), true, true); - m_hasError = true; m_ioService.stop(); + return 1; } } @@ -151,40 +159,39 @@ private: } bool - processConfigurationDetail(const std::string& detail, Logger& logger, int lineNumber) + parseConfigurationLine(const std::string& line, Logger& logger, int lineNumber) { std::string parameter, value; - if (parseParameterAndValue(detail, parameter, value)) { - if (parameter == "Name") { - m_name = value; - } - else if (parameter == "ContentDelay") { - m_contentDelay = time::milliseconds(std::stoul(value)); - } - else if (parameter == "FreshnessPeriod") { - m_freshnessPeriod = time::milliseconds(std::stoul(value)); - } - else if (parameter == "ContentType") { - m_contentType = std::stoul(value); - } - else if (parameter == "ContentBytes") { - m_contentLength = std::stoul(value); - } - else if (parameter == "Content") { - m_content = value; - } - else if (parameter == "SigningInfo") { - m_signingInfo = security::SigningInfo(value); - } - else { - logger.log("Line " + to_string(lineNumber) + - " - Unknown parameter '" + parameter + "'", false, true); - } + if (!extractParameterAndValue(line, parameter, value)) { + logger.log("Line " + to_string(lineNumber) + " - Invalid syntax: " + line, + false, true); + return false; + } + + if (parameter == "Name") { + m_name = value; + } + else if (parameter == "ContentDelay") { + m_contentDelay = time::milliseconds(std::stoul(value)); + } + else if (parameter == "FreshnessPeriod") { + m_freshnessPeriod = time::milliseconds(std::stoul(value)); + } + else if (parameter == "ContentType") { + m_contentType = std::stoul(value); + } + else if (parameter == "ContentBytes") { + m_contentLength = std::stoul(value); + } + else if (parameter == "Content") { + m_content = value; + } + else if (parameter == "SigningInfo") { + m_signingInfo = security::SigningInfo(value); } else { - logger.log("Line " + to_string(lineNumber) + - " - Invalid traffic configuration line: " + detail, false, true); - return false; + logger.log("Line " + to_string(lineNumber) + " - Ignoring unknown parameter: " + parameter, + false, true); } return true; } @@ -226,88 +233,10 @@ private: bool checkTrafficPatternCorrectness() const { + // TODO return true; } - void - parseConfigurationFile() - { - std::ifstream patternFile; - m_logger.log("Parsing traffic configuration file: " + m_configurationFile, true, true); - - patternFile.open(m_configurationFile.data()); - if (patternFile.is_open()) { - int lineNumber = 0; - std::string patternLine; - while (getline(patternFile, patternLine)) { - lineNumber++; - if (std::isalpha(patternLine[0])) { - DataTrafficConfiguration dataData; - bool shouldSkipLine = false; - if (dataData.processConfigurationDetail(patternLine, m_logger, lineNumber)) { - while (getline(patternFile, patternLine) && std::isalpha(patternLine[0])) { - lineNumber++; - if (!dataData.processConfigurationDetail(patternLine, m_logger, lineNumber)) { - shouldSkipLine = true; - break; - } - } - lineNumber++; - } - else { - shouldSkipLine = true; - } - if (!shouldSkipLine) { - if (dataData.checkTrafficDetailCorrectness()) { - m_trafficPatterns.push_back(dataData); - } - } - } - } - patternFile.close(); - - if (!checkTrafficPatternCorrectness()) { - m_logger.log("ERROR: Traffic configuration provided is not proper - " + - m_configurationFile, false, true); - exit(2); - } - - m_logger.log("Traffic configuration file processing completed.\n", true, false); - for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) { - m_logger.log("Traffic Pattern Type #" + to_string(patternId + 1), false, false); - m_trafficPatterns[patternId].printTrafficConfiguration(m_logger); - m_logger.log("", false, false); - } - } - else { - m_logger.log("ERROR: Unable to open traffic configuration file: " + m_configurationFile, false, true); - exit(2); - } - } - - void - initializeTrafficConfiguration() - { - namespace fs = boost::filesystem; - - fs::path configPath(m_configurationFile); - if (fs::exists(configPath)) { - if (fs::is_regular_file(configPath)) { - parseConfigurationFile(); - } - else { - m_logger.log("ERROR: Traffic configuration file is not a regular file: " + - m_configurationFile, false, true); - exit(2); - } - } - else { - m_logger.log("ERROR: Traffic configuration file does not exist: " + - m_configurationFile, false, true); - exit(2); - } - } - static std::string getRandomByteString(std::size_t length) { @@ -501,7 +430,5 @@ main(int argc, char* argv[]) server.setQuietLogging(); } - server.run(); - - return server.hasError() ? 1 : 0; + return server.run(); } diff --git a/src/util.hpp b/src/util.hpp index 65052d8..bafdc39 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -21,13 +21,17 @@ #ifndef NTG_UTIL_HPP #define NTG_UTIL_HPP +#include "logger.hpp" + #include #include +#include + namespace ndn { static inline bool -parseParameterAndValue(const std::string& input, std::string& parameter, std::string& value) +extractParameterAndValue(const std::string& input, std::string& parameter, std::string& value) { static const std::string allowedCharacters = ":/+._-%"; parameter = ""; @@ -56,6 +60,65 @@ parseParameterAndValue(const std::string& input, std::string& parameter, std::st return !parameter.empty() && !value.empty() && i == input.length(); } +static inline bool +parseBoolean(const std::string& input) +{ + if (boost::iequals(input, "no") || boost::iequals(input, "off") || + boost::iequals(input, "false") || input == "0") + return false; + + if (boost::iequals(input, "yes") || boost::iequals(input, "on") || + boost::iequals(input, "true") || input == "1") + return true; + + throw std::invalid_argument("'" + input + "' is not a valid boolean value"); +} + +template +static inline bool +readConfigurationFile(const std::string& filename, + std::vector& patterns, + Logger& logger) +{ + std::ifstream patternFile(filename); + if (!patternFile) { + logger.log("ERROR: Unable to open traffic configuration file: " + filename, false, true); + return false; + } + + logger.log("Reading traffic configuration file: " + filename, true, true); + + int lineNumber = 0; + std::string patternLine; + while (getline(patternFile, patternLine)) { + lineNumber++; + if (std::isalpha(patternLine[0])) { + TrafficConfigurationType trafficConf; + bool shouldSkipLine = false; + if (trafficConf.parseConfigurationLine(patternLine, logger, lineNumber)) { + while (getline(patternFile, patternLine) && std::isalpha(patternLine[0])) { + lineNumber++; + if (!trafficConf.parseConfigurationLine(patternLine, logger, lineNumber)) { + shouldSkipLine = true; + break; + } + } + lineNumber++; + } + else { + shouldSkipLine = true; + } + if (!shouldSkipLine) { + if (trafficConf.checkTrafficDetailCorrectness()) { + patterns.push_back(std::move(trafficConf)); + } + } + } + } + + return true; +} + } // namespace ndn #endif // NTG_UTIL_HPP