blob: e7a0cb6706b379b2c6febfb02f73a8368b1f0391 [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 Leeef561432015-12-13 19:40:22 -070035#include <ndn-cxx/security/signing-info.hpp>
Spencer Lee8e990232015-11-27 03:54:39 -070036#include <ndn-cxx/util/backports.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080037
38#include "logger.hpp"
39
40namespace ndn {
41
jeraldabraham420dbf02014-04-25 22:58:31 -070042class NdnTrafficServer : boost::noncopyable
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080043{
44public:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070045 explicit
Davide Pesaventod0b59982015-02-27 19:15:15 +010046 NdnTrafficServer(const char* programName)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070047 : m_logger("NdnTrafficServer")
48 , m_programName(programName)
49 , m_hasError(false)
jeraldabraham420dbf02014-04-25 22:58:31 -070050 , m_hasQuietLogging(false)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070051 , m_nRegistrationsFailed(0)
52 , m_nMaximumInterests(-1)
53 , m_nInterestsReceived(0)
54 , m_contentDelay(time::milliseconds(-1))
Spencer Lee8e990232015-11-27 03:54:39 -070055 , m_instanceId(to_string(std::rand()))
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070056 , m_face(m_ioService)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080057 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080058 }
59
60 class DataTrafficConfiguration
61 {
62 public:
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080063 DataTrafficConfiguration()
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070064 : m_contentType(-1)
65 , m_freshnessPeriod(time::milliseconds(-1))
66 , m_contentBytes(-1)
67 , m_contentDelay(time::milliseconds(-1))
68 , m_nInterestsReceived(0)
Spencer Leeef561432015-12-13 19:40:22 -070069 , m_signingInfo()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080070 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080071 }
72
73 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -070074 printTrafficConfiguration(Logger& logger)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080075 {
Spencer Leeef561432015-12-13 19:40:22 -070076 std::stringstream detail;
Davide Pesaventod0b59982015-02-27 19:15:15 +010077
78 if (!m_name.empty())
Spencer Leeef561432015-12-13 19:40:22 -070079 detail << "Name=" << m_name << ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070080 if (m_contentType >= 0)
Spencer Leeef561432015-12-13 19:40:22 -070081 detail << "ContentType=" << to_string(m_contentType) << ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070082 if (m_freshnessPeriod >= time::milliseconds(0))
Spencer Leeef561432015-12-13 19:40:22 -070083 detail << "FreshnessPeriod=" <<
84 to_string(static_cast<int>(m_freshnessPeriod.count())) << ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070085 if (m_contentBytes >= 0)
Spencer Leeef561432015-12-13 19:40:22 -070086 detail << "ContentBytes=" << to_string(m_contentBytes) << ", ";
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070087 if (m_contentDelay >= time::milliseconds(0))
Spencer Leeef561432015-12-13 19:40:22 -070088 detail << "ContentDelay=" << to_string(m_contentDelay.count()) << ", ";
Davide Pesaventod0b59982015-02-27 19:15:15 +010089 if (!m_content.empty())
Spencer Leeef561432015-12-13 19:40:22 -070090 detail << "Content=" << m_content << ", ";
91 detail << "SigningInfo=" << m_signingInfo;
Davide Pesaventod0b59982015-02-27 19:15:15 +010092
Spencer Leeef561432015-12-13 19:40:22 -070093 logger.log(detail.str(), false, false);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080094 }
95
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080096 bool
Davide Pesaventod0b59982015-02-27 19:15:15 +010097 extractParameterValue(const std::string& detail, std::string& parameter, std::string& value)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080098 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080099 std::string allowedCharacters = ":/+._-%";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100100 std::size_t i = 0;
101
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800102 parameter = "";
103 value = "";
Davide Pesaventod0b59982015-02-27 19:15:15 +0100104 while (detail[i] != '=' && i < detail.length()) {
105 parameter += detail[i];
106 i++;
107 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800108 if (i == detail.length())
109 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100110
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800111 i++;
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700112 while ((std::isalnum(detail[i]) ||
113 allowedCharacters.find(detail[i]) != std::string::npos) &&
Davide Pesaventod0b59982015-02-27 19:15:15 +0100114 i < detail.length()) {
115 value += detail[i];
116 i++;
117 }
118
119 if (parameter.empty() || value.empty())
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800120 return false;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100121 else
122 return true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800123 }
124
125 bool
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700126 processConfigurationDetail(const std::string& detail,
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700127 Logger& logger,
128 int lineNumber)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800129 {
130 std::string parameter, value;
Spencer Leee7a5b742015-10-29 02:18:11 -0700131 if (extractParameterValue(detail, parameter, value)) {
132 if (parameter == "Name") {
133 m_name = value;
134 }
135 else if (parameter == "ContentType") {
136 m_contentType = std::stoi(value);
137 }
138 else if (parameter == "FreshnessPeriod") {
139 m_freshnessPeriod = time::milliseconds(std::stoi(value));
140 }
141 else if (parameter == "ContentDelay") {
142 m_contentDelay = time::milliseconds(std::stoi(value));
143 }
144 else if (parameter == "ContentBytes") {
145 m_contentBytes = std::stoi(value);
146 }
147 else if (parameter == "Content") {
148 m_content = value;
149 }
Spencer Leeef561432015-12-13 19:40:22 -0700150 else if (parameter == "SigningInfo") {
151 m_signingInfo = security::SigningInfo(value);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800152 }
Spencer Leee7a5b742015-10-29 02:18:11 -0700153 else {
Spencer Lee8e990232015-11-27 03:54:39 -0700154 logger.log("Line " + to_string(lineNumber) +
Spencer Leee7a5b742015-10-29 02:18:11 -0700155 " \t- Invalid Parameter='" + parameter + "'", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800156 }
Spencer Leee7a5b742015-10-29 02:18:11 -0700157 }
158 else {
Spencer Lee8e990232015-11-27 03:54:39 -0700159 logger.log("Line " + to_string(lineNumber) +
Spencer Leee7a5b742015-10-29 02:18:11 -0700160 " \t- Improper Traffic Configuration Line - " + detail, false, true);
161 return false;
162 }
163
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800164 return true;
165 }
166
167 bool
168 checkTrafficDetailCorrectness()
169 {
170 return true;
171 }
172
Davide Pesaventod0b59982015-02-27 19:15:15 +0100173 private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700174 std::string m_name;
175 int m_contentType;
176 time::milliseconds m_freshnessPeriod;
177 int m_contentBytes;
178 time::milliseconds m_contentDelay;
179 std::string m_content;
180 int m_nInterestsReceived;
Spencer Leeef561432015-12-13 19:40:22 -0700181 security::SigningInfo m_signingInfo;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800182
Davide Pesaventod0b59982015-02-27 19:15:15 +0100183 friend class NdnTrafficServer;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800184 };
185
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800186 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100187 usage() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800188 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100189 std::cout << "Usage:\n"
190 << " " << m_programName << " [options] <Traffic_Configuration_File>\n"
191 << "\n"
192 << "Respond to Interests as per provided Traffic Configuration File.\n"
193 << "Multiple prefixes can be configured for handling.\n"
194 << "Set environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
195 << "\n"
196 << "Options:\n"
197 << " [-d interval] - set delay before responding to interest, in milliseconds\n"
198 << " [-c count] - specify maximum number of interests to be satisfied\n"
199 << " [-q] - quiet mode: no interest reception/data generation logging\n"
200 << " [-h] - print this help text and exit\n";
201 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800202 }
203
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700204 void
205 setMaximumInterests(int maximumInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800206 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700207 if (maximumInterests < 0)
208 usage();
209 m_nMaximumInterests = maximumInterests;
210 }
211
212 bool
213 hasError() const
214 {
215 return m_hasError;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800216 }
217
218 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700219 setContentDelay(int contentDelay)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800220 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700221 if (contentDelay < 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800222 usage();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700223 m_contentDelay = time::milliseconds(contentDelay);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800224 }
225
226 void
Davide Pesaventod0b59982015-02-27 19:15:15 +0100227 setConfigurationFile(const char* configurationFile)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800228 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700229 m_configurationFile = configurationFile;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800230 }
231
232 void
jeraldabraham420dbf02014-04-25 22:58:31 -0700233 setQuietLogging()
234 {
235 m_hasQuietLogging = true;
236 }
237
238 void
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800239 signalHandler()
240 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800241 logStatistics();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100242
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700243 m_logger.shutdownLogger();
244 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300245 m_ioService.stop();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100246
247 exit(m_hasError ? EXIT_FAILURE : EXIT_SUCCESS);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800248 }
249
250 void
251 logStatistics()
252 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800253 m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700254 m_logger.log("Total Traffic Pattern Types = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700255 to_string(m_trafficPatterns.size()), false, true);
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700256 m_logger.log("Total Interests Received = " +
Spencer Lee8e990232015-11-27 03:54:39 -0700257 to_string(m_nInterestsReceived), false, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100258
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700259 if (m_nInterestsReceived < m_nMaximumInterests)
260 m_hasError = true;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100261
262 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800263 {
Spencer Lee8e990232015-11-27 03:54:39 -0700264 m_logger.log("\nTraffic Pattern Type #" + to_string(patternId + 1), false, true);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700265 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
Spencer Lee8e990232015-11-27 03:54:39 -0700266 m_logger.log("Total Interests Received = " + to_string(
Davide Pesaventod0b59982015-02-27 19:15:15 +0100267 m_trafficPatterns[patternId].m_nInterestsReceived) + "\n", false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800268 }
269 }
270
271 bool
272 checkTrafficPatternCorrectness()
273 {
274 return true;
275 }
276
277 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700278 parseConfigurationFile()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800279 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800280 std::string patternLine;
281 std::ifstream patternFile;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700282 m_logger.log("Analyzing Traffic Configuration File: " + m_configurationFile, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100283
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700284 patternFile.open(m_configurationFile.c_str());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800285 if (patternFile.is_open())
286 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700287 int lineNumber = 0;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800288 while (getline(patternFile, patternLine))
289 {
290 lineNumber++;
291 if (std::isalpha(patternLine[0]))
292 {
293 DataTrafficConfiguration dataData;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700294 bool shouldSkipLine = false;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800295 if (dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
296 {
297 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
298 {
299 lineNumber++;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100300 if (!dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800301 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700302 shouldSkipLine = true;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800303 break;
304 }
305 }
306 lineNumber++;
307 }
308 else
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700309 shouldSkipLine = true;
310 if (!shouldSkipLine)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800311 {
312 if (dataData.checkTrafficDetailCorrectness())
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700313 m_trafficPatterns.push_back(dataData);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800314 }
315 }
316 }
317 patternFile.close();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100318
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800319 if (!checkTrafficPatternCorrectness())
320 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100321 m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper - " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700322 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800323 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100324 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800325 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100326
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800327 m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100328 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800329 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700330 m_logger.log("Traffic Pattern Type #" +
Spencer Lee8e990232015-11-27 03:54:39 -0700331 to_string(patternId + 1), false, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700332 m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800333 m_logger.log("", false, false);
334 }
335 }
336 else
337 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700338 m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700339 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800340 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100341 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800342 }
343 }
344
345 void
346 initializeTrafficConfiguration()
347 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700348 if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800349 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700350 if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile)))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800351 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700352 parseConfigurationFile();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800353 }
354 else
355 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700356 m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700357 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800358 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100359 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800360 }
361 }
362 else
363 {
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700364 m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700365 m_configurationFile, false, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800366 m_logger.shutdownLogger();
Davide Pesaventod0b59982015-02-27 19:15:15 +0100367 exit(EXIT_FAILURE);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800368 }
369 }
370
371 static std::string
Davide Pesaventod0b59982015-02-27 19:15:15 +0100372 getRandomByteString(std::size_t randomSize)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800373 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700374 std::string randomString;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100375 for (std::size_t i = 0; i < randomSize; i++)
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700376 randomString += static_cast<char>(std::rand() % 128);
377 return randomString;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800378 }
379
380 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700381 onInterest(const Name& name, const Interest& interest, int patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800382 {
Spencer Leee7a5b742015-10-29 02:18:11 -0700383 auto& pattern = m_trafficPatterns[patternId];
384
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700385 if (m_nMaximumInterests < 0 || m_nInterestsReceived < m_nMaximumInterests)
386 {
387 Data data(interest.getName());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800388
Spencer Leee7a5b742015-10-29 02:18:11 -0700389 if (pattern.m_contentType >= 0)
390 data.setContentType(pattern.m_contentType);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700391
Spencer Leee7a5b742015-10-29 02:18:11 -0700392 if (pattern.m_freshnessPeriod >= time::milliseconds(0))
393 data.setFreshnessPeriod(pattern.m_freshnessPeriod);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700394
Davide Pesaventod0b59982015-02-27 19:15:15 +0100395 std::string content;
Spencer Leee7a5b742015-10-29 02:18:11 -0700396 if (pattern.m_contentBytes >= 0)
397 content = getRandomByteString(pattern.m_contentBytes);
398 if (!pattern.m_content.empty())
399 content = pattern.m_content;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700400
401 data.setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.length());
Spencer Leeef561432015-12-13 19:40:22 -0700402 m_keyChain.sign(data, pattern.m_signingInfo);
Spencer Leee7a5b742015-10-29 02:18:11 -0700403
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700404 m_nInterestsReceived++;
Spencer Leee7a5b742015-10-29 02:18:11 -0700405 pattern.m_nInterestsReceived++;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100406
407 if (!m_hasQuietLogging) {
408 std::string logLine =
Spencer Lee8e990232015-11-27 03:54:39 -0700409 "Interest Received - PatternType=" + to_string(patternId + 1) +
410 ", GlobalID=" + to_string(m_nInterestsReceived) +
411 ", LocalID=" + to_string(pattern.m_nInterestsReceived) +
Spencer Leee7a5b742015-10-29 02:18:11 -0700412 ", Name=" + pattern.m_name;
jeraldabraham420dbf02014-04-25 22:58:31 -0700413 m_logger.log(logLine, true, false);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100414 }
415
Spencer Leee7a5b742015-10-29 02:18:11 -0700416 if (pattern.m_contentDelay > time::milliseconds(-1))
417 usleep(pattern.m_contentDelay.count() * 1000);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700418 if (m_contentDelay > time::milliseconds(-1))
419 usleep(m_contentDelay.count() * 1000);
420 m_face.put(data);
421 }
422 if (m_nMaximumInterests >= 0 && m_nInterestsReceived == m_nMaximumInterests)
423 {
424 logStatistics();
425 m_logger.shutdownLogger();
426 m_face.shutdown();
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300427 m_ioService.stop();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700428 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800429 }
430
431 void
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700432 onRegisterFailed(const ndn::Name& prefix, const std::string& reason, int patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800433 {
Davide Pesaventod0b59982015-02-27 19:15:15 +0100434 std::string logLine;
Spencer Lee8e990232015-11-27 03:54:39 -0700435 logLine += "Prefix Registration Failed - PatternType=" + to_string(patternId + 1);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700436 logLine += ", Name=" + m_trafficPatterns[patternId].m_name;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800437 m_logger.log(logLine, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100438
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700439 m_nRegistrationsFailed++;
440 if (m_nRegistrationsFailed == m_trafficPatterns.size())
441 {
442 m_hasError = true;
443 signalHandler();
444 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800445 }
446
447 void
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700448 run()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800449 {
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300450 boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700451 signalSet.async_wait(bind(&NdnTrafficServer::signalHandler, this));
Davide Pesaventod0b59982015-02-27 19:15:15 +0100452
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700453 m_logger.initializeLog(m_instanceId);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800454 initializeTrafficConfiguration();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700455 if (m_nMaximumInterests == 0)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800456 {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700457 logStatistics();
458 m_logger.shutdownLogger();
459 return;
460 }
461
Davide Pesaventod0b59982015-02-27 19:15:15 +0100462 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
463 m_face.setInterestFilter(m_trafficPatterns[patternId].m_name,
464 bind(&NdnTrafficServer::onInterest, this, _1, _2, patternId),
465 bind(&NdnTrafficServer::onRegisterFailed, this, _1, _2, patternId));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800466
467 try {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700468 m_face.processEvents();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800469 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100470 catch (const std::exception& e) {
471 m_logger.log("ERROR: " + std::string(e.what()), true, true);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800472 m_logger.shutdownLogger();
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700473 m_hasError = true;
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300474 m_ioService.stop();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800475 }
476 }
477
478private:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700479 KeyChain m_keyChain;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700480 Logger m_logger;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700481 std::string m_programName;
482 bool m_hasError;
jeraldabraham420dbf02014-04-25 22:58:31 -0700483 bool m_hasQuietLogging;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100484 std::size_t m_nRegistrationsFailed;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700485 int m_nMaximumInterests;
486 int m_nInterestsReceived;
487 time::milliseconds m_contentDelay;
488 std::string m_instanceId;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700489 std::string m_configurationFile;
Alexander Afanasyev740812e2014-10-30 15:37:45 -0700490
Alexander Afanasyev976c3972014-05-26 17:03:40 +0300491 boost::asio::io_service m_ioService;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700492 Face m_face;
493 std::vector<DataTrafficConfiguration> m_trafficPatterns;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800494};
495
496} // namespace ndn
497
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700498int
499main(int argc, char* argv[])
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800500{
Davide Pesaventod0b59982015-02-27 19:15:15 +0100501 std::srand(std::time(nullptr));
502
503 ndn::NdnTrafficServer server(argv[0]);
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800504 int option;
jeraldabraham420dbf02014-04-25 22:58:31 -0700505 while ((option = getopt(argc, argv, "hqc:d:")) != -1) {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800506 switch (option) {
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700507 case 'h':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100508 server.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800509 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700510 case 'c':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100511 server.setMaximumInterests(atoi(optarg));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800512 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700513 case 'd':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100514 server.setContentDelay(atoi(optarg));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700515 break;
jeraldabraham420dbf02014-04-25 22:58:31 -0700516 case 'q':
Davide Pesaventod0b59982015-02-27 19:15:15 +0100517 server.setQuietLogging();
jeraldabraham420dbf02014-04-25 22:58:31 -0700518 break;
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700519 default:
Davide Pesaventod0b59982015-02-27 19:15:15 +0100520 server.usage();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800521 break;
522 }
523 }
524
525 argc -= optind;
526 argv += optind;
527
Davide Pesaventod0b59982015-02-27 19:15:15 +0100528 if (!argc)
529 server.usage();
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;
Spencer Leee7a5b742015-10-29 02:18:11 -0700535}