blob: 9351f75298713608c53090458472a30cf3c6f919 [file] [log] [blame]
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Davide Pesaventod0b59982015-02-27 19:15:15 +01003 * Copyright (C) 2014-2015 University of Arizona.
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -08004 *
Davide Pesaventod0b59982015-02-27 19:15:15 +01005 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080017 *
18 * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
19 */
20
Davide Pesaventod0b59982015-02-27 19:15:15 +010021#include <cctype>
22#include <cstdlib>
23#include <fstream>
24#include <string>
25#include <unistd.h>
26#include <vector>
jeraldabraham420dbf02014-04-25 22:58:31 -070027
Davide Pesaventod0b59982015-02-27 19:15:15 +010028#include <boost/asio/io_service.hpp>
29#include <boost/asio/signal_set.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080030#include <boost/filesystem.hpp>
jeraldabraham420dbf02014-04-25 22:58:31 -070031#include <boost/noncopyable.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080032
jeraldabraham420dbf02014-04-25 22:58:31 -070033#include <ndn-cxx/face.hpp>
34#include <ndn-cxx/security/key-chain.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080035
36#include "logger.hpp"
37
38namespace ndn {
39
jeraldabraham420dbf02014-04-25 22:58:31 -070040class NdnTrafficServer : boost::noncopyable
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080041{
42public:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070043 explicit
Davide Pesaventod0b59982015-02-27 19:15:15 +010044 NdnTrafficServer(const char* programName)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070045 : m_logger("NdnTrafficServer")
46 , m_programName(programName)
47 , m_hasError(false)
jeraldabraham420dbf02014-04-25 22:58:31 -070048 , m_hasQuietLogging(false)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070049 , m_nRegistrationsFailed(0)
50 , m_nMaximumInterests(-1)
51 , m_nInterestsReceived(0)
52 , m_contentDelay(time::milliseconds(-1))
Davide Pesaventod0b59982015-02-27 19:15:15 +010053 , m_instanceId(std::to_string(std::rand()))
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070054 , m_face(m_ioService)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080055 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080056 }
57
58 class DataTrafficConfiguration
59 {
60 public:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080061 DataTrafficConfiguration()
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070062 : m_contentType(-1)
63 , m_freshnessPeriod(time::milliseconds(-1))
64 , m_contentBytes(-1)
65 , m_contentDelay(time::milliseconds(-1))
66 , m_nInterestsReceived(0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080067 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080068 }
69
70 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070071 printTrafficConfiguration(Logger& logger)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080072 {
Davide Pesaventod0b59982015-02-27 19:15:15 +010073 std::string detail;
74
75 if (!m_name.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070076 detail += "Name=" + m_name + ", ";
77 if (m_contentType >= 0)
Davide Pesaventod0b59982015-02-27 19:15:15 +010078 detail += "ContentType=" + std::to_string(m_contentType) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070079 if (m_freshnessPeriod >= time::milliseconds(0))
80 detail += "FreshnessPeriod=" +
Davide Pesaventod0b59982015-02-27 19:15:15 +010081 std::to_string(static_cast<int>(m_freshnessPeriod.count())) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070082 if (m_contentBytes >= 0)
Davide Pesaventod0b59982015-02-27 19:15:15 +010083 detail += "ContentBytes=" + std::to_string(m_contentBytes) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070084 if (m_contentDelay >= time::milliseconds(0))
Davide Pesaventod0b59982015-02-27 19:15:15 +010085 detail += "ContentDelay=" + std::to_string(m_contentDelay.count()) + ", ";
86 if (!m_content.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070087 detail += "Content=" + m_content + ", ";
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080088 if (detail.length() >= 2)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070089 detail = detail.substr(0, detail.length() - 2);
Davide Pesaventod0b59982015-02-27 19:15:15 +010090
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080091 logger.log(detail, false, false);
92 }
93
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080094 bool
Davide Pesaventod0b59982015-02-27 19:15:15 +010095 extractParameterValue(const std::string& detail, std::string& parameter, std::string& value)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080096 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080097 std::string allowedCharacters = ":/+._-%";
Davide Pesaventod0b59982015-02-27 19:15:15 +010098 std::size_t i = 0;
99
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800100 parameter = "";
101 value = "";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100102 while (detail[i] != '=' && i < detail.length()) {
103 parameter += detail[i];
104 i++;
105 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800106 if (i == detail.length())
107 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100108
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800109 i++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700110 while ((std::isalnum(detail[i]) ||
111 allowedCharacters.find(detail[i]) != std::string::npos) &&
Davide Pesaventod0b59982015-02-27 19:15:15 +0100112 i < detail.length()) {
113 value += detail[i];
114 i++;
115 }
116
117 if (parameter.empty() || value.empty())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800118 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100119 else
120 return true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800121 }
122
123 bool
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700124 processConfigurationDetail(const std::string& detail,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700125 Logger& logger,
126 int lineNumber)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800127 {
128 std::string parameter, value;
129 if (extractParameterValue(detail, parameter, value))
130 {
131 if (parameter == "Name")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700132 m_name = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800133 else if (parameter == "ContentType")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100134 m_contentType = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800135 else if (parameter == "FreshnessPeriod")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100136 m_freshnessPeriod = time::milliseconds(std::stoi(value));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700137 else if (parameter == "ContentDelay")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100138 m_contentDelay = time::milliseconds(std::stoi(value));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800139 else if (parameter == "ContentBytes")
Davide Pesaventod0b59982015-02-27 19:15:15 +0100140 m_contentBytes = std::stoi(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800141 else if (parameter == "Content")
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700142 m_content = value;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800143 else
Davide Pesaventod0b59982015-02-27 19:15:15 +0100144 logger.log("Line " + std::to_string(lineNumber) +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700145 " \t- Invalid Parameter='" + parameter + "'", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800146 }
147 else
148 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100149 logger.log("Line " + std::to_string(lineNumber) +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700150 " \t- Improper Traffic Configuration Line - " + detail, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800151 return false;
152 }
153 return true;
154 }
155
156 bool
157 checkTrafficDetailCorrectness()
158 {
159 return true;
160 }
161
Davide Pesaventod0b59982015-02-27 19:15:15 +0100162 private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700163 std::string m_name;
164 int m_contentType;
165 time::milliseconds m_freshnessPeriod;
166 int m_contentBytes;
167 time::milliseconds m_contentDelay;
168 std::string m_content;
169 int m_nInterestsReceived;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800170
Davide Pesaventod0b59982015-02-27 19:15:15 +0100171 friend class NdnTrafficServer;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800172 };
173
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800174 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100175 usage() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800176 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100177 std::cout << "Usage:\n"
178 << " " << m_programName << " [options] <Traffic_Configuration_File>\n"
179 << "\n"
180 << "Respond to Interests as per provided Traffic Configuration File.\n"
181 << "Multiple prefixes can be configured for handling.\n"
182 << "Set environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
183 << "\n"
184 << "Options:\n"
185 << " [-d interval] - set delay before responding to interest, in milliseconds\n"
186 << " [-c count] - specify maximum number of interests to be satisfied\n"
187 << " [-q] - quiet mode: no interest reception/data generation logging\n"
188 << " [-h] - print this help text and exit\n";
189 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800190 }
191
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700192 void
193 setMaximumInterests(int maximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800194 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700195 if (maximumInterests < 0)
196 usage();
197 m_nMaximumInterests = maximumInterests;
198 }
199
200 bool
201 hasError() const
202 {
203 return m_hasError;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800204 }
205
206 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700207 setContentDelay(int contentDelay)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800208 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700209 if (contentDelay < 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800210 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700211 m_contentDelay = time::milliseconds(contentDelay);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800212 }
213
214 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100215 setConfigurationFile(const char* configurationFile)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800216 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700217 m_configurationFile = configurationFile;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800218 }
219
220 void
jeraldabraham420dbf02014-04-25 22:58:31 -0700221 setQuietLogging()
222 {
223 m_hasQuietLogging = true;
224 }
225
226 void
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800227 signalHandler()
228 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800229 logStatistics();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100230
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700231 m_logger.shutdownLogger();
232 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300233 m_ioService.stop();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100234
235 exit(m_hasError ? EXIT_FAILURE : EXIT_SUCCESS);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800236 }
237
238 void
239 logStatistics()
240 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800241 m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700242 m_logger.log("Total Traffic Pattern Types = " +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100243 std::to_string(m_trafficPatterns.size()), false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700244 m_logger.log("Total Interests Received = " +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100245 std::to_string(m_nInterestsReceived), false, true);
246
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700247 if (m_nInterestsReceived < m_nMaximumInterests)
248 m_hasError = true;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100249
250 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800251 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100252 m_logger.log("\nTraffic Pattern Type #" + std::to_string(patternId + 1), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700253 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100254 m_logger.log("Total Interests Received = " + std::to_string(
255 m_trafficPatterns[patternId].m_nInterestsReceived) + "\n", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800256 }
257 }
258
259 bool
260 checkTrafficPatternCorrectness()
261 {
262 return true;
263 }
264
265 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700266 parseConfigurationFile()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800267 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800268 std::string patternLine;
269 std::ifstream patternFile;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700270 m_logger.log("Analyzing Traffic Configuration File: " + m_configurationFile, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100271
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700272 patternFile.open(m_configurationFile.c_str());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800273 if (patternFile.is_open())
274 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700275 int lineNumber = 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800276 while (getline(patternFile, patternLine))
277 {
278 lineNumber++;
279 if (std::isalpha(patternLine[0]))
280 {
281 DataTrafficConfiguration dataData;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700282 bool shouldSkipLine = false;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800283 if (dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
284 {
285 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
286 {
287 lineNumber++;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100288 if (!dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800289 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700290 shouldSkipLine = true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800291 break;
292 }
293 }
294 lineNumber++;
295 }
296 else
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700297 shouldSkipLine = true;
298 if (!shouldSkipLine)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800299 {
300 if (dataData.checkTrafficDetailCorrectness())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700301 m_trafficPatterns.push_back(dataData);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800302 }
303 }
304 }
305 patternFile.close();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100306
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800307 if (!checkTrafficPatternCorrectness())
308 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100309 m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper - " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700310 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800311 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100312 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800313 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100314
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800315 m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100316 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800317 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700318 m_logger.log("Traffic Pattern Type #" +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100319 std::to_string(patternId + 1), false, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700320 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800321 m_logger.log("", false, false);
322 }
323 }
324 else
325 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700326 m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700327 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800328 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100329 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800330 }
331 }
332
333 void
334 initializeTrafficConfiguration()
335 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700336 if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800337 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700338 if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800339 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700340 parseConfigurationFile();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800341 }
342 else
343 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700344 m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700345 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800346 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100347 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800348 }
349 }
350 else
351 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700352 m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700353 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800354 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100355 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800356 }
357 }
358
359 static std::string
Davide Pesaventod0b59982015-02-27 19:15:15 +0100360 getRandomByteString(std::size_t randomSize)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800361 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700362 std::string randomString;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100363 for (std::size_t i = 0; i < randomSize; i++)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700364 randomString += static_cast<char>(std::rand() % 128);
365 return randomString;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800366 }
367
368 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700369 onInterest(const Name& name, const Interest& interest, int patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800370 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700371 if (m_nMaximumInterests < 0 || m_nInterestsReceived < m_nMaximumInterests)
372 {
373 Data data(interest.getName());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800374
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700375 if (m_trafficPatterns[patternId].m_contentType >= 0)
376 data.setContentType(m_trafficPatterns[patternId].m_contentType);
377
378 if (m_trafficPatterns[patternId].m_freshnessPeriod >= time::milliseconds(0))
379 data.setFreshnessPeriod(m_trafficPatterns[patternId].m_freshnessPeriod);
380
Davide Pesaventod0b59982015-02-27 19:15:15 +0100381 std::string content;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700382 if (m_trafficPatterns[patternId].m_contentBytes >= 0)
383 content = getRandomByteString(m_trafficPatterns[patternId].m_contentBytes);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100384 if (!m_trafficPatterns[patternId].m_content.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700385 content = m_trafficPatterns[patternId].m_content;
386
387 data.setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.length());
388 m_keyChain.sign(data);
389 m_nInterestsReceived++;
390 m_trafficPatterns[patternId].m_nInterestsReceived++;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100391
392 if (!m_hasQuietLogging) {
393 std::string logLine =
394 "Interest Received - PatternType=" + std::to_string(patternId + 1) +
395 ", GlobalID=" + std::to_string(m_nInterestsReceived) +
396 ", LocalID=" + std::to_string(m_trafficPatterns[patternId].m_nInterestsReceived) +
397 ", Name=" + m_trafficPatterns[patternId].m_name;
jeraldabraham420dbf02014-04-25 22:58:31 -0700398 m_logger.log(logLine, true, false);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100399 }
400
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700401 if (m_trafficPatterns[patternId].m_contentDelay > time::milliseconds(-1))
402 usleep(m_trafficPatterns[patternId].m_contentDelay.count() * 1000);
403 if (m_contentDelay > time::milliseconds(-1))
404 usleep(m_contentDelay.count() * 1000);
405 m_face.put(data);
406 }
407 if (m_nMaximumInterests >= 0 && m_nInterestsReceived == m_nMaximumInterests)
408 {
409 logStatistics();
410 m_logger.shutdownLogger();
411 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300412 m_ioService.stop();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700413 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800414 }
415
416 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700417 onRegisterFailed(const ndn::Name& prefix, const std::string& reason, int patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800418 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100419 std::string logLine;
420 logLine += "Prefix Registration Failed - PatternType=" + std::to_string(patternId + 1);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700421 logLine += ", Name=" + m_trafficPatterns[patternId].m_name;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800422 m_logger.log(logLine, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100423
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700424 m_nRegistrationsFailed++;
425 if (m_nRegistrationsFailed == m_trafficPatterns.size())
426 {
427 m_hasError = true;
428 signalHandler();
429 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800430 }
431
432 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700433 run()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800434 {
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300435 boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700436 signalSet.async_wait(bind(&NdnTrafficServer::signalHandler, this));
Davide Pesaventod0b59982015-02-27 19:15:15 +0100437
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700438 m_logger.initializeLog(m_instanceId);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800439 initializeTrafficConfiguration();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700440 if (m_nMaximumInterests == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800441 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700442 logStatistics();
443 m_logger.shutdownLogger();
444 return;
445 }
446
Davide Pesaventod0b59982015-02-27 19:15:15 +0100447 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
448 m_face.setInterestFilter(m_trafficPatterns[patternId].m_name,
449 bind(&NdnTrafficServer::onInterest, this, _1, _2, patternId),
450 bind(&NdnTrafficServer::onRegisterFailed, this, _1, _2, patternId));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800451
452 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700453 m_face.processEvents();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800454 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100455 catch (const std::exception& e) {
456 m_logger.log("ERROR: " + std::string(e.what()), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800457 m_logger.shutdownLogger();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700458 m_hasError = true;
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300459 m_ioService.stop();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800460 }
461 }
462
463private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700464 KeyChain m_keyChain;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700465 Logger m_logger;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700466 std::string m_programName;
467 bool m_hasError;
jeraldabraham420dbf02014-04-25 22:58:31 -0700468 bool m_hasQuietLogging;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100469 std::size_t m_nRegistrationsFailed;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700470 int m_nMaximumInterests;
471 int m_nInterestsReceived;
472 time::milliseconds m_contentDelay;
473 std::string m_instanceId;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700474 std::string m_configurationFile;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700475
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300476 boost::asio::io_service m_ioService;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700477 Face m_face;
478 std::vector<DataTrafficConfiguration> m_trafficPatterns;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800479};
480
481} // namespace ndn
482
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700483int
484main(int argc, char* argv[])
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800485{
Davide Pesaventod0b59982015-02-27 19:15:15 +0100486 std::srand(std::time(nullptr));
487
488 ndn::NdnTrafficServer server(argv[0]);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800489 int option;
jeraldabraham420dbf02014-04-25 22:58:31 -0700490 while ((option = getopt(argc, argv, "hqc:d:")) != -1) {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800491 switch (option) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700492 case 'h':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100493 server.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800494 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700495 case 'c':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100496 server.setMaximumInterests(atoi(optarg));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800497 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700498 case 'd':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100499 server.setContentDelay(atoi(optarg));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700500 break;
jeraldabraham420dbf02014-04-25 22:58:31 -0700501 case 'q':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100502 server.setQuietLogging();
jeraldabraham420dbf02014-04-25 22:58:31 -0700503 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700504 default:
Davide Pesaventod0b59982015-02-27 19:15:15 +0100505 server.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800506 break;
507 }
508 }
509
510 argc -= optind;
511 argv += optind;
512
Davide Pesaventod0b59982015-02-27 19:15:15 +0100513 if (!argc)
514 server.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800515
Davide Pesaventod0b59982015-02-27 19:15:15 +0100516 server.setConfigurationFile(argv[0]);
517 server.run();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800518
Davide Pesaventod0b59982015-02-27 19:15:15 +0100519 return server.hasError() ? EXIT_FAILURE : EXIT_SUCCESS;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800520}