blob: b58a880caa28438b33da4afdde7b6cab29713323 [file] [log] [blame]
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Eric Newberryc8e18582018-05-31 19:27:01 -07002/*
3 * Copyright (C) 2014-2018 Arizona Board of Regents.
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
Eric Newberryc8e18582018-05-31 19:27:01 -070021#include "logger.hpp"
22
23#include <ndn-cxx/face.hpp>
24#include <ndn-cxx/security/key-chain.hpp>
25#include <ndn-cxx/security/signing-info.hpp>
26#include <ndn-cxx/util/backports.hpp>
27#include <ndn-cxx/util/scheduler.hpp>
jeraldabraham420dbf02014-04-25 22:58:31 -070028
Davide Pesaventod0b59982015-02-27 19:15:15 +010029#include <boost/asio/io_service.hpp>
30#include <boost/asio/signal_set.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080031#include <boost/filesystem.hpp>
jeraldabraham420dbf02014-04-25 22:58:31 -070032#include <boost/noncopyable.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080033
Eric Newberryc8e18582018-05-31 19:27:01 -070034#include <cctype>
35#include <cstdlib>
36#include <fstream>
37#include <string>
38#include <unistd.h>
39#include <vector>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080040
41namespace ndn {
42
jeraldabraham420dbf02014-04-25 22:58:31 -070043class NdnTrafficServer : boost::noncopyable
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080044{
45public:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070046 explicit
Davide Pesaventod0b59982015-02-27 19:15:15 +010047 NdnTrafficServer(const char* programName)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070048 : m_logger("NdnTrafficServer")
49 , m_programName(programName)
50 , m_hasError(false)
jeraldabraham420dbf02014-04-25 22:58:31 -070051 , m_hasQuietLogging(false)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070052 , m_nRegistrationsFailed(0)
53 , m_nMaximumInterests(-1)
54 , m_nInterestsReceived(0)
55 , m_contentDelay(time::milliseconds(-1))
Spencer Lee8e990232015-11-27 03:54:39 -070056 , m_instanceId(to_string(std::rand()))
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070057 , m_face(m_ioService)
Eric Newberryc8e18582018-05-31 19:27:01 -070058 , m_scheduler(m_ioService)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080059 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080060 }
61
62 class DataTrafficConfiguration
63 {
64 public:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080065 DataTrafficConfiguration()
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070066 : m_contentType(-1)
67 , m_freshnessPeriod(time::milliseconds(-1))
68 , m_contentBytes(-1)
69 , m_contentDelay(time::milliseconds(-1))
70 , m_nInterestsReceived(0)
Spencer Leeef561432015-12-13 19:40:22 -070071 , m_signingInfo()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080072 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080073 }
74
75 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070076 printTrafficConfiguration(Logger& logger)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080077 {
Spencer Leeef561432015-12-13 19:40:22 -070078 std::stringstream detail;
Davide Pesaventod0b59982015-02-27 19:15:15 +010079
Eric Newberryc8e18582018-05-31 19:27:01 -070080 if (!m_name.empty()) {
Spencer Leeef561432015-12-13 19:40:22 -070081 detail << "Name=" << m_name << ", ";
Eric Newberryc8e18582018-05-31 19:27:01 -070082 }
83 if (m_contentType >= 0) {
Spencer Leeef561432015-12-13 19:40:22 -070084 detail << "ContentType=" << to_string(m_contentType) << ", ";
Eric Newberryc8e18582018-05-31 19:27:01 -070085 }
86 if (m_freshnessPeriod >= time::milliseconds(0)) {
Spencer Leeef561432015-12-13 19:40:22 -070087 detail << "FreshnessPeriod=" <<
88 to_string(static_cast<int>(m_freshnessPeriod.count())) << ", ";
Eric Newberryc8e18582018-05-31 19:27:01 -070089 }
90 if (m_contentBytes >= 0) {
Spencer Leeef561432015-12-13 19:40:22 -070091 detail << "ContentBytes=" << to_string(m_contentBytes) << ", ";
Eric Newberryc8e18582018-05-31 19:27:01 -070092 }
93 if (m_contentDelay >= time::milliseconds(0)) {
Spencer Leeef561432015-12-13 19:40:22 -070094 detail << "ContentDelay=" << to_string(m_contentDelay.count()) << ", ";
Eric Newberryc8e18582018-05-31 19:27:01 -070095 }
96 if (!m_content.empty()) {
Spencer Leeef561432015-12-13 19:40:22 -070097 detail << "Content=" << m_content << ", ";
Eric Newberryc8e18582018-05-31 19:27:01 -070098 }
Spencer Leeef561432015-12-13 19:40:22 -070099 detail << "SigningInfo=" << m_signingInfo;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100100
Spencer Leeef561432015-12-13 19:40:22 -0700101 logger.log(detail.str(), false, false);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800102 }
103
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800104 bool
Davide Pesaventod0b59982015-02-27 19:15:15 +0100105 extractParameterValue(const std::string& detail, std::string& parameter, std::string& value)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800106 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800107 std::string allowedCharacters = ":/+._-%";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100108 std::size_t i = 0;
109
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800110 parameter = "";
111 value = "";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100112 while (detail[i] != '=' && i < detail.length()) {
113 parameter += detail[i];
114 i++;
115 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800116 if (i == detail.length())
117 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100118
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800119 i++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700120 while ((std::isalnum(detail[i]) ||
121 allowedCharacters.find(detail[i]) != std::string::npos) &&
Davide Pesaventod0b59982015-02-27 19:15:15 +0100122 i < detail.length()) {
123 value += detail[i];
124 i++;
125 }
126
127 if (parameter.empty() || value.empty())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800128 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100129 else
130 return true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800131 }
132
133 bool
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700134 processConfigurationDetail(const std::string& detail,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700135 Logger& logger,
136 int lineNumber)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800137 {
138 std::string parameter, value;
Spencer Leee7a5b742015-10-29 02:18:11 -0700139 if (extractParameterValue(detail, parameter, value)) {
140 if (parameter == "Name") {
141 m_name = value;
142 }
143 else if (parameter == "ContentType") {
144 m_contentType = std::stoi(value);
145 }
146 else if (parameter == "FreshnessPeriod") {
147 m_freshnessPeriod = time::milliseconds(std::stoi(value));
148 }
149 else if (parameter == "ContentDelay") {
150 m_contentDelay = time::milliseconds(std::stoi(value));
151 }
152 else if (parameter == "ContentBytes") {
153 m_contentBytes = std::stoi(value);
154 }
155 else if (parameter == "Content") {
156 m_content = value;
157 }
Spencer Leeef561432015-12-13 19:40:22 -0700158 else if (parameter == "SigningInfo") {
159 m_signingInfo = security::SigningInfo(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800160 }
Spencer Leee7a5b742015-10-29 02:18:11 -0700161 else {
Spencer Lee8e990232015-11-27 03:54:39 -0700162 logger.log("Line " + to_string(lineNumber) +
Spencer Leee7a5b742015-10-29 02:18:11 -0700163 " \t- Invalid Parameter='" + parameter + "'", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800164 }
Spencer Leee7a5b742015-10-29 02:18:11 -0700165 }
166 else {
Spencer Lee8e990232015-11-27 03:54:39 -0700167 logger.log("Line " + to_string(lineNumber) +
Spencer Leee7a5b742015-10-29 02:18:11 -0700168 " \t- Improper Traffic Configuration Line - " + detail, false, true);
169 return false;
170 }
171
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800172 return true;
173 }
174
175 bool
176 checkTrafficDetailCorrectness()
177 {
178 return true;
179 }
180
Davide Pesaventod0b59982015-02-27 19:15:15 +0100181 private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700182 std::string m_name;
183 int m_contentType;
184 time::milliseconds m_freshnessPeriod;
185 int m_contentBytes;
186 time::milliseconds m_contentDelay;
187 std::string m_content;
188 int m_nInterestsReceived;
Spencer Leeef561432015-12-13 19:40:22 -0700189 security::SigningInfo m_signingInfo;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800190
Davide Pesaventod0b59982015-02-27 19:15:15 +0100191 friend class NdnTrafficServer;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800192 };
193
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800194 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100195 usage() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800196 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100197 std::cout << "Usage:\n"
198 << " " << m_programName << " [options] <Traffic_Configuration_File>\n"
199 << "\n"
200 << "Respond to Interests as per provided Traffic Configuration File.\n"
201 << "Multiple prefixes can be configured for handling.\n"
202 << "Set environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
203 << "\n"
204 << "Options:\n"
205 << " [-d interval] - set delay before responding to interest, in milliseconds\n"
206 << " [-c count] - specify maximum number of interests to be satisfied\n"
207 << " [-q] - quiet mode: no interest reception/data generation logging\n"
208 << " [-h] - print this help text and exit\n";
209 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800210 }
211
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700212 void
213 setMaximumInterests(int maximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800214 {
Eric Newberryc8e18582018-05-31 19:27:01 -0700215 if (maximumInterests < 0) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700216 usage();
Eric Newberryc8e18582018-05-31 19:27:01 -0700217 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700218 m_nMaximumInterests = maximumInterests;
219 }
220
221 bool
222 hasError() const
223 {
224 return m_hasError;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800225 }
226
227 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700228 setContentDelay(int contentDelay)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800229 {
Eric Newberryc8e18582018-05-31 19:27:01 -0700230 if (contentDelay < 0) {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800231 usage();
Eric Newberryc8e18582018-05-31 19:27:01 -0700232 }
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 = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700265 to_string(m_trafficPatterns.size()), false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700266 m_logger.log("Total Interests Received = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700267 to_string(m_nInterestsReceived), false, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100268
Eric Newberryc8e18582018-05-31 19:27:01 -0700269 if (m_nInterestsReceived < m_nMaximumInterests) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700270 m_hasError = true;
Eric Newberryc8e18582018-05-31 19:27:01 -0700271 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100272
Eric Newberryc8e18582018-05-31 19:27:01 -0700273 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) {
274 m_logger.log("\nTraffic Pattern Type #" + to_string(patternId + 1), false, true);
275 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
276 m_logger.log("Total Interests Received = " + to_string(
277 m_trafficPatterns[patternId].m_nInterestsReceived) + "\n", false, true);
278 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800279 }
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());
Eric Newberryc8e18582018-05-31 19:27:01 -0700295 if (patternFile.is_open()) {
296 int lineNumber = 0;
297 while (getline(patternFile, patternLine)) {
298 lineNumber++;
299 if (std::isalpha(patternLine[0])) {
300 DataTrafficConfiguration dataData;
301 bool shouldSkipLine = false;
302 if (dataData.processConfigurationDetail(patternLine, m_logger, lineNumber)) {
303 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0])) {
304 lineNumber++;
305 if (!dataData.processConfigurationDetail(patternLine, m_logger, lineNumber)) {
306 shouldSkipLine = true;
307 break;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800308 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700309 }
310 lineNumber++;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800311 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700312 else {
313 shouldSkipLine = true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800314 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700315 if (!shouldSkipLine) {
316 if (dataData.checkTrafficDetailCorrectness()) {
317 m_trafficPatterns.push_back(dataData);
318 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800319 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700320 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800321 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700322 patternFile.close();
323
324 if (!checkTrafficPatternCorrectness()) {
325 m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper - " +
326 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800327 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100328 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800329 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700330
331 m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
332 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) {
333 m_logger.log("Traffic Pattern Type #" +
334 to_string(patternId + 1), false, false);
335 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
336 m_logger.log("", false, false);
337 }
338 }
339 else {
340 m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
341 m_configurationFile, false, true);
342 m_logger.shutdownLogger();
343 exit(EXIT_FAILURE);
344 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800345 }
346
347 void
348 initializeTrafficConfiguration()
349 {
Eric Newberryc8e18582018-05-31 19:27:01 -0700350 if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile))) {
351 if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile))) {
352 parseConfigurationFile();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800353 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700354 else {
355 m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
356 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800357 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100358 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800359 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700360 }
361 else {
362 m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
363 m_configurationFile, false, true);
364 m_logger.shutdownLogger();
365 exit(EXIT_FAILURE);
366 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800367 }
368
369 static std::string
Davide Pesaventod0b59982015-02-27 19:15:15 +0100370 getRandomByteString(std::size_t randomSize)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800371 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700372 std::string randomString;
Eric Newberryc8e18582018-05-31 19:27:01 -0700373 for (std::size_t i = 0; i < randomSize; i++) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700374 randomString += static_cast<char>(std::rand() % 128);
Eric Newberryc8e18582018-05-31 19:27:01 -0700375 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700376 return randomString;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800377 }
378
379 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700380 onInterest(const Name& name, const Interest& interest, int patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800381 {
Spencer Leee7a5b742015-10-29 02:18:11 -0700382 auto& pattern = m_trafficPatterns[patternId];
383
Eric Newberryc8e18582018-05-31 19:27:01 -0700384 if (m_nMaximumInterests < 0 || m_nInterestsReceived < m_nMaximumInterests) {
385 Data data(interest.getName());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800386
Eric Newberryc8e18582018-05-31 19:27:01 -0700387 if (pattern.m_contentType >= 0)
388 data.setContentType(pattern.m_contentType);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700389
Eric Newberryc8e18582018-05-31 19:27:01 -0700390 if (pattern.m_freshnessPeriod >= time::milliseconds(0))
391 data.setFreshnessPeriod(pattern.m_freshnessPeriod);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700392
Eric Newberryc8e18582018-05-31 19:27:01 -0700393 std::string content;
394 if (pattern.m_contentBytes >= 0)
395 content = getRandomByteString(pattern.m_contentBytes);
396 if (!pattern.m_content.empty())
397 content = pattern.m_content;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700398
Eric Newberryc8e18582018-05-31 19:27:01 -0700399 data.setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.length());
400 m_keyChain.sign(data, pattern.m_signingInfo);
Spencer Leee7a5b742015-10-29 02:18:11 -0700401
Eric Newberryc8e18582018-05-31 19:27:01 -0700402 m_nInterestsReceived++;
403 pattern.m_nInterestsReceived++;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100404
Eric Newberryc8e18582018-05-31 19:27:01 -0700405 if (!m_hasQuietLogging) {
406 std::string logLine =
407 "Interest Received - PatternType=" + to_string(patternId + 1) +
408 ", GlobalID=" + to_string(m_nInterestsReceived) +
409 ", LocalID=" + to_string(pattern.m_nInterestsReceived) +
410 ", Name=" + pattern.m_name;
411 m_logger.log(logLine, true, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700412 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700413
414 if (pattern.m_contentDelay > time::milliseconds(-1))
415 usleep(pattern.m_contentDelay.count() * 1000);
416 if (m_contentDelay > time::milliseconds(-1))
417 usleep(m_contentDelay.count() * 1000);
418 m_face.put(data);
419 }
420 if (m_nMaximumInterests >= 0 && m_nInterestsReceived == m_nMaximumInterests) {
421 logStatistics();
422 m_scheduler.scheduleEvent(2_s, [this] {
423 m_logger.shutdownLogger();
424 m_face.shutdown();
425 m_ioService.stop();
426 });
427 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800428 }
429
430 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700431 onRegisterFailed(const ndn::Name& prefix, const std::string& reason, int patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800432 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100433 std::string logLine;
Spencer Lee8e990232015-11-27 03:54:39 -0700434 logLine += "Prefix Registration Failed - PatternType=" + to_string(patternId + 1);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700435 logLine += ", Name=" + m_trafficPatterns[patternId].m_name;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800436 m_logger.log(logLine, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100437
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700438 m_nRegistrationsFailed++;
Eric Newberryc8e18582018-05-31 19:27:01 -0700439 if (m_nRegistrationsFailed == m_trafficPatterns.size()) {
440 m_hasError = true;
441 signalHandler();
442 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800443 }
444
445 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700446 run()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800447 {
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300448 boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700449 signalSet.async_wait(bind(&NdnTrafficServer::signalHandler, this));
Davide Pesaventod0b59982015-02-27 19:15:15 +0100450
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700451 m_logger.initializeLog(m_instanceId);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800452 initializeTrafficConfiguration();
Eric Newberryc8e18582018-05-31 19:27:01 -0700453 if (m_nMaximumInterests == 0) {
454 logStatistics();
455 m_logger.shutdownLogger();
456 return;
457 }
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700458
Eric Newberryc8e18582018-05-31 19:27:01 -0700459 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100460 m_face.setInterestFilter(m_trafficPatterns[patternId].m_name,
461 bind(&NdnTrafficServer::onInterest, this, _1, _2, patternId),
462 bind(&NdnTrafficServer::onRegisterFailed, this, _1, _2, patternId));
Eric Newberryc8e18582018-05-31 19:27:01 -0700463 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800464
465 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700466 m_face.processEvents();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800467 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100468 catch (const std::exception& e) {
469 m_logger.log("ERROR: " + std::string(e.what()), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800470 m_logger.shutdownLogger();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700471 m_hasError = true;
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300472 m_ioService.stop();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800473 }
474 }
475
476private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700477 KeyChain m_keyChain;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700478 Logger m_logger;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700479 std::string m_programName;
480 bool m_hasError;
jeraldabraham420dbf02014-04-25 22:58:31 -0700481 bool m_hasQuietLogging;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100482 std::size_t m_nRegistrationsFailed;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700483 int m_nMaximumInterests;
484 int m_nInterestsReceived;
485 time::milliseconds m_contentDelay;
486 std::string m_instanceId;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700487 std::string m_configurationFile;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700488
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300489 boost::asio::io_service m_ioService;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700490 Face m_face;
Eric Newberryc8e18582018-05-31 19:27:01 -0700491 util::scheduler::Scheduler m_scheduler;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700492 std::vector<DataTrafficConfiguration> m_trafficPatterns;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800493};
494
495} // namespace ndn
496
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700497int
498main(int argc, char* argv[])
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800499{
Davide Pesaventod0b59982015-02-27 19:15:15 +0100500 std::srand(std::time(nullptr));
501
502 ndn::NdnTrafficServer server(argv[0]);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800503 int option;
jeraldabraham420dbf02014-04-25 22:58:31 -0700504 while ((option = getopt(argc, argv, "hqc:d:")) != -1) {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800505 switch (option) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700506 case 'h':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100507 server.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800508 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700509 case 'c':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100510 server.setMaximumInterests(atoi(optarg));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800511 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700512 case 'd':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100513 server.setContentDelay(atoi(optarg));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700514 break;
jeraldabraham420dbf02014-04-25 22:58:31 -0700515 case 'q':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100516 server.setQuietLogging();
jeraldabraham420dbf02014-04-25 22:58:31 -0700517 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700518 default:
Davide Pesaventod0b59982015-02-27 19:15:15 +0100519 server.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800520 break;
521 }
522 }
523
524 argc -= optind;
525 argv += optind;
526
Eric Newberryc8e18582018-05-31 19:27:01 -0700527 if (!argc) {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100528 server.usage();
Eric Newberryc8e18582018-05-31 19:27:01 -0700529 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800530
Davide Pesaventod0b59982015-02-27 19:15:15 +0100531 server.setConfigurationFile(argv[0]);
532 server.run();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800533
Davide Pesaventod0b59982015-02-27 19:15:15 +0100534 return server.hasError() ? EXIT_FAILURE : EXIT_SUCCESS;
Eric Newberryc8e18582018-05-31 19:27:01 -0700535}