blob: b0f572dc88232f4723495fd88637337bc1484c48 [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>
Spencer Leee7a5b742015-10-29 02:18:11 -070035#include <ndn-cxx/security/signing-helpers.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080036
37#include "logger.hpp"
38
39namespace ndn {
40
jeraldabraham420dbf02014-04-25 22:58:31 -070041class NdnTrafficServer : boost::noncopyable
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080042{
43public:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070044 explicit
Davide Pesaventod0b59982015-02-27 19:15:15 +010045 NdnTrafficServer(const char* programName)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070046 : m_logger("NdnTrafficServer")
47 , m_programName(programName)
48 , m_hasError(false)
jeraldabraham420dbf02014-04-25 22:58:31 -070049 , m_hasQuietLogging(false)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070050 , m_nRegistrationsFailed(0)
51 , m_nMaximumInterests(-1)
52 , m_nInterestsReceived(0)
53 , m_contentDelay(time::milliseconds(-1))
Davide Pesaventod0b59982015-02-27 19:15:15 +010054 , m_instanceId(std::to_string(std::rand()))
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070055 , m_face(m_ioService)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080056 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080057 }
58
59 class DataTrafficConfiguration
60 {
61 public:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080062 DataTrafficConfiguration()
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070063 : m_contentType(-1)
64 , m_freshnessPeriod(time::milliseconds(-1))
65 , m_contentBytes(-1)
66 , m_contentDelay(time::milliseconds(-1))
67 , m_nInterestsReceived(0)
Spencer Leee7a5b742015-10-29 02:18:11 -070068 , m_signWithSha256(false)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080069 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080070 }
71
72 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070073 printTrafficConfiguration(Logger& logger)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080074 {
Davide Pesaventod0b59982015-02-27 19:15:15 +010075 std::string detail;
76
77 if (!m_name.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070078 detail += "Name=" + m_name + ", ";
79 if (m_contentType >= 0)
Davide Pesaventod0b59982015-02-27 19:15:15 +010080 detail += "ContentType=" + std::to_string(m_contentType) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070081 if (m_freshnessPeriod >= time::milliseconds(0))
82 detail += "FreshnessPeriod=" +
Davide Pesaventod0b59982015-02-27 19:15:15 +010083 std::to_string(static_cast<int>(m_freshnessPeriod.count())) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070084 if (m_contentBytes >= 0)
Davide Pesaventod0b59982015-02-27 19:15:15 +010085 detail += "ContentBytes=" + std::to_string(m_contentBytes) + ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070086 if (m_contentDelay >= time::milliseconds(0))
Davide Pesaventod0b59982015-02-27 19:15:15 +010087 detail += "ContentDelay=" + std::to_string(m_contentDelay.count()) + ", ";
88 if (!m_content.empty())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070089 detail += "Content=" + m_content + ", ";
Spencer Leee7a5b742015-10-29 02:18:11 -070090 detail += "SignWithSha256=" + std::to_string(m_signWithSha256) + ", ";
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080091 if (detail.length() >= 2)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070092 detail = detail.substr(0, detail.length() - 2);
Davide Pesaventod0b59982015-02-27 19:15:15 +010093
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080094 logger.log(detail, false, false);
95 }
96
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080097 bool
Davide Pesaventod0b59982015-02-27 19:15:15 +010098 extractParameterValue(const std::string& detail, std::string& parameter, std::string& value)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080099 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800100 std::string allowedCharacters = ":/+._-%";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100101 std::size_t i = 0;
102
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800103 parameter = "";
104 value = "";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100105 while (detail[i] != '=' && i < detail.length()) {
106 parameter += detail[i];
107 i++;
108 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800109 if (i == detail.length())
110 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100111
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800112 i++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700113 while ((std::isalnum(detail[i]) ||
114 allowedCharacters.find(detail[i]) != std::string::npos) &&
Davide Pesaventod0b59982015-02-27 19:15:15 +0100115 i < detail.length()) {
116 value += detail[i];
117 i++;
118 }
119
120 if (parameter.empty() || value.empty())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800121 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100122 else
123 return true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800124 }
125
126 bool
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700127 processConfigurationDetail(const std::string& detail,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700128 Logger& logger,
129 int lineNumber)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800130 {
131 std::string parameter, value;
Spencer Leee7a5b742015-10-29 02:18:11 -0700132 if (extractParameterValue(detail, parameter, value)) {
133 if (parameter == "Name") {
134 m_name = value;
135 }
136 else if (parameter == "ContentType") {
137 m_contentType = std::stoi(value);
138 }
139 else if (parameter == "FreshnessPeriod") {
140 m_freshnessPeriod = time::milliseconds(std::stoi(value));
141 }
142 else if (parameter == "ContentDelay") {
143 m_contentDelay = time::milliseconds(std::stoi(value));
144 }
145 else if (parameter == "ContentBytes") {
146 m_contentBytes = std::stoi(value);
147 }
148 else if (parameter == "Content") {
149 m_content = value;
150 }
151 else if (parameter == "SignWithSha256") {
152 if (value == "0") {
153 m_signWithSha256 = false;
154 }
155 else if (value == "1") {
156 m_signWithSha256 = true;
157 }
158 else {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100159 logger.log("Line " + std::to_string(lineNumber) +
Spencer Leee7a5b742015-10-29 02:18:11 -0700160 " \t- Invalid SignWithSha256 Value='" + value + "'", false, true);
161 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800162 }
Spencer Leee7a5b742015-10-29 02:18:11 -0700163 else {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100164 logger.log("Line " + std::to_string(lineNumber) +
Spencer Leee7a5b742015-10-29 02:18:11 -0700165 " \t- Invalid Parameter='" + parameter + "'", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800166 }
Spencer Leee7a5b742015-10-29 02:18:11 -0700167 }
168 else {
169 logger.log("Line " + std::to_string(lineNumber) +
170 " \t- Improper Traffic Configuration Line - " + detail, false, true);
171 return false;
172 }
173
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800174 return true;
175 }
176
177 bool
178 checkTrafficDetailCorrectness()
179 {
180 return true;
181 }
182
Davide Pesaventod0b59982015-02-27 19:15:15 +0100183 private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700184 std::string m_name;
185 int m_contentType;
186 time::milliseconds m_freshnessPeriod;
187 int m_contentBytes;
188 time::milliseconds m_contentDelay;
189 std::string m_content;
190 int m_nInterestsReceived;
Spencer Leee7a5b742015-10-29 02:18:11 -0700191 bool m_signWithSha256;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800192
Davide Pesaventod0b59982015-02-27 19:15:15 +0100193 friend class NdnTrafficServer;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800194 };
195
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800196 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100197 usage() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800198 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100199 std::cout << "Usage:\n"
200 << " " << m_programName << " [options] <Traffic_Configuration_File>\n"
201 << "\n"
202 << "Respond to Interests as per provided Traffic Configuration File.\n"
203 << "Multiple prefixes can be configured for handling.\n"
204 << "Set environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
205 << "\n"
206 << "Options:\n"
207 << " [-d interval] - set delay before responding to interest, in milliseconds\n"
208 << " [-c count] - specify maximum number of interests to be satisfied\n"
209 << " [-q] - quiet mode: no interest reception/data generation logging\n"
210 << " [-h] - print this help text and exit\n";
211 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800212 }
213
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700214 void
215 setMaximumInterests(int maximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800216 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700217 if (maximumInterests < 0)
218 usage();
219 m_nMaximumInterests = maximumInterests;
220 }
221
222 bool
223 hasError() const
224 {
225 return m_hasError;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800226 }
227
228 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700229 setContentDelay(int contentDelay)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800230 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700231 if (contentDelay < 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800232 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700233 m_contentDelay = time::milliseconds(contentDelay);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800234 }
235
236 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100237 setConfigurationFile(const char* configurationFile)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800238 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700239 m_configurationFile = configurationFile;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800240 }
241
242 void
jeraldabraham420dbf02014-04-25 22:58:31 -0700243 setQuietLogging()
244 {
245 m_hasQuietLogging = true;
246 }
247
248 void
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800249 signalHandler()
250 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800251 logStatistics();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100252
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700253 m_logger.shutdownLogger();
254 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300255 m_ioService.stop();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100256
257 exit(m_hasError ? EXIT_FAILURE : EXIT_SUCCESS);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800258 }
259
260 void
261 logStatistics()
262 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800263 m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700264 m_logger.log("Total Traffic Pattern Types = " +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100265 std::to_string(m_trafficPatterns.size()), false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700266 m_logger.log("Total Interests Received = " +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100267 std::to_string(m_nInterestsReceived), false, true);
268
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700269 if (m_nInterestsReceived < m_nMaximumInterests)
270 m_hasError = true;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100271
272 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800273 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100274 m_logger.log("\nTraffic Pattern Type #" + std::to_string(patternId + 1), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700275 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100276 m_logger.log("Total Interests Received = " + std::to_string(
277 m_trafficPatterns[patternId].m_nInterestsReceived) + "\n", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800278 }
279 }
280
281 bool
282 checkTrafficPatternCorrectness()
283 {
284 return true;
285 }
286
287 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700288 parseConfigurationFile()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800289 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800290 std::string patternLine;
291 std::ifstream patternFile;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700292 m_logger.log("Analyzing Traffic Configuration File: " + m_configurationFile, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100293
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700294 patternFile.open(m_configurationFile.c_str());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800295 if (patternFile.is_open())
296 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700297 int lineNumber = 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800298 while (getline(patternFile, patternLine))
299 {
300 lineNumber++;
301 if (std::isalpha(patternLine[0]))
302 {
303 DataTrafficConfiguration dataData;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700304 bool shouldSkipLine = false;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800305 if (dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
306 {
307 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
308 {
309 lineNumber++;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100310 if (!dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800311 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700312 shouldSkipLine = true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800313 break;
314 }
315 }
316 lineNumber++;
317 }
318 else
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700319 shouldSkipLine = true;
320 if (!shouldSkipLine)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800321 {
322 if (dataData.checkTrafficDetailCorrectness())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700323 m_trafficPatterns.push_back(dataData);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800324 }
325 }
326 }
327 patternFile.close();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100328
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800329 if (!checkTrafficPatternCorrectness())
330 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100331 m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper - " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700332 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800333 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100334 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800335 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100336
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800337 m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100338 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800339 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700340 m_logger.log("Traffic Pattern Type #" +
Davide Pesaventod0b59982015-02-27 19:15:15 +0100341 std::to_string(patternId + 1), false, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700342 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800343 m_logger.log("", false, false);
344 }
345 }
346 else
347 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700348 m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700349 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800350 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100351 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800352 }
353 }
354
355 void
356 initializeTrafficConfiguration()
357 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700358 if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800359 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700360 if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800361 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700362 parseConfigurationFile();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800363 }
364 else
365 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700366 m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700367 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800368 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100369 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800370 }
371 }
372 else
373 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700374 m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700375 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800376 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100377 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800378 }
379 }
380
381 static std::string
Davide Pesaventod0b59982015-02-27 19:15:15 +0100382 getRandomByteString(std::size_t randomSize)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800383 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700384 std::string randomString;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100385 for (std::size_t i = 0; i < randomSize; i++)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700386 randomString += static_cast<char>(std::rand() % 128);
387 return randomString;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800388 }
389
390 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700391 onInterest(const Name& name, const Interest& interest, int patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800392 {
Spencer Leee7a5b742015-10-29 02:18:11 -0700393 auto& pattern = m_trafficPatterns[patternId];
394
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700395 if (m_nMaximumInterests < 0 || m_nInterestsReceived < m_nMaximumInterests)
396 {
397 Data data(interest.getName());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800398
Spencer Leee7a5b742015-10-29 02:18:11 -0700399 if (pattern.m_contentType >= 0)
400 data.setContentType(pattern.m_contentType);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700401
Spencer Leee7a5b742015-10-29 02:18:11 -0700402 if (pattern.m_freshnessPeriod >= time::milliseconds(0))
403 data.setFreshnessPeriod(pattern.m_freshnessPeriod);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700404
Davide Pesaventod0b59982015-02-27 19:15:15 +0100405 std::string content;
Spencer Leee7a5b742015-10-29 02:18:11 -0700406 if (pattern.m_contentBytes >= 0)
407 content = getRandomByteString(pattern.m_contentBytes);
408 if (!pattern.m_content.empty())
409 content = pattern.m_content;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700410
411 data.setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.length());
Spencer Leee7a5b742015-10-29 02:18:11 -0700412
413 if (pattern.m_signWithSha256) {
414 m_keyChain.sign(data, security::signingWithSha256());
415 }
416 else {
417 m_keyChain.sign(data);
418 }
419
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700420 m_nInterestsReceived++;
Spencer Leee7a5b742015-10-29 02:18:11 -0700421 pattern.m_nInterestsReceived++;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100422
423 if (!m_hasQuietLogging) {
424 std::string logLine =
425 "Interest Received - PatternType=" + std::to_string(patternId + 1) +
426 ", GlobalID=" + std::to_string(m_nInterestsReceived) +
Spencer Leee7a5b742015-10-29 02:18:11 -0700427 ", LocalID=" + std::to_string(pattern.m_nInterestsReceived) +
428 ", Name=" + pattern.m_name;
jeraldabraham420dbf02014-04-25 22:58:31 -0700429 m_logger.log(logLine, true, false);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100430 }
431
Spencer Leee7a5b742015-10-29 02:18:11 -0700432 if (pattern.m_contentDelay > time::milliseconds(-1))
433 usleep(pattern.m_contentDelay.count() * 1000);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700434 if (m_contentDelay > time::milliseconds(-1))
435 usleep(m_contentDelay.count() * 1000);
436 m_face.put(data);
437 }
438 if (m_nMaximumInterests >= 0 && m_nInterestsReceived == m_nMaximumInterests)
439 {
440 logStatistics();
441 m_logger.shutdownLogger();
442 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300443 m_ioService.stop();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700444 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800445 }
446
447 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700448 onRegisterFailed(const ndn::Name& prefix, const std::string& reason, int patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800449 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100450 std::string logLine;
451 logLine += "Prefix Registration Failed - PatternType=" + std::to_string(patternId + 1);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700452 logLine += ", Name=" + m_trafficPatterns[patternId].m_name;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800453 m_logger.log(logLine, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100454
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700455 m_nRegistrationsFailed++;
456 if (m_nRegistrationsFailed == m_trafficPatterns.size())
457 {
458 m_hasError = true;
459 signalHandler();
460 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800461 }
462
463 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700464 run()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800465 {
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300466 boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700467 signalSet.async_wait(bind(&NdnTrafficServer::signalHandler, this));
Davide Pesaventod0b59982015-02-27 19:15:15 +0100468
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700469 m_logger.initializeLog(m_instanceId);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800470 initializeTrafficConfiguration();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700471 if (m_nMaximumInterests == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800472 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700473 logStatistics();
474 m_logger.shutdownLogger();
475 return;
476 }
477
Davide Pesaventod0b59982015-02-27 19:15:15 +0100478 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
479 m_face.setInterestFilter(m_trafficPatterns[patternId].m_name,
480 bind(&NdnTrafficServer::onInterest, this, _1, _2, patternId),
481 bind(&NdnTrafficServer::onRegisterFailed, this, _1, _2, patternId));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800482
483 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700484 m_face.processEvents();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800485 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100486 catch (const std::exception& e) {
487 m_logger.log("ERROR: " + std::string(e.what()), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800488 m_logger.shutdownLogger();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700489 m_hasError = true;
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300490 m_ioService.stop();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800491 }
492 }
493
494private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700495 KeyChain m_keyChain;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700496 Logger m_logger;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700497 std::string m_programName;
498 bool m_hasError;
jeraldabraham420dbf02014-04-25 22:58:31 -0700499 bool m_hasQuietLogging;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100500 std::size_t m_nRegistrationsFailed;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700501 int m_nMaximumInterests;
502 int m_nInterestsReceived;
503 time::milliseconds m_contentDelay;
504 std::string m_instanceId;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700505 std::string m_configurationFile;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700506
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300507 boost::asio::io_service m_ioService;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700508 Face m_face;
509 std::vector<DataTrafficConfiguration> m_trafficPatterns;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800510};
511
512} // namespace ndn
513
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700514int
515main(int argc, char* argv[])
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800516{
Davide Pesaventod0b59982015-02-27 19:15:15 +0100517 std::srand(std::time(nullptr));
518
519 ndn::NdnTrafficServer server(argv[0]);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800520 int option;
jeraldabraham420dbf02014-04-25 22:58:31 -0700521 while ((option = getopt(argc, argv, "hqc:d:")) != -1) {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800522 switch (option) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700523 case 'h':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100524 server.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800525 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700526 case 'c':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100527 server.setMaximumInterests(atoi(optarg));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800528 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700529 case 'd':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100530 server.setContentDelay(atoi(optarg));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700531 break;
jeraldabraham420dbf02014-04-25 22:58:31 -0700532 case 'q':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100533 server.setQuietLogging();
jeraldabraham420dbf02014-04-25 22:58:31 -0700534 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700535 default:
Davide Pesaventod0b59982015-02-27 19:15:15 +0100536 server.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800537 break;
538 }
539 }
540
541 argc -= optind;
542 argv += optind;
543
Davide Pesaventod0b59982015-02-27 19:15:15 +0100544 if (!argc)
545 server.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800546
Davide Pesaventod0b59982015-02-27 19:15:15 +0100547 server.setConfigurationFile(argv[0]);
548 server.run();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800549
Davide Pesaventod0b59982015-02-27 19:15:15 +0100550 return server.hasError() ? EXIT_FAILURE : EXIT_SUCCESS;
Spencer Leee7a5b742015-10-29 02:18:11 -0700551}