blob: ce2c2e3e7962227bdc299331b5fee4e215582e26 [file] [log] [blame]
Davide Pesavento35185332019-01-14 04:00:15 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberryc8e18582018-05-31 19:27:01 -07002/*
Alexander Lanee9fe1872023-07-25 20:00:23 -04003 * Copyright (c) 2014-2023, 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
Davide Pesavento35185332019-01-14 04:00:15 -050021#include "util.hpp"
Eric Newberryc8e18582018-05-31 19:27:01 -070022
Davide Pesavento35185332019-01-14 04:00:15 -050023#include <ndn-cxx/data.hpp>
Eric Newberryc8e18582018-05-31 19:27:01 -070024#include <ndn-cxx/face.hpp>
Davide Pesaventoef064892022-04-05 02:26:03 -040025#include <ndn-cxx/interest.hpp>
Eric Newberryc8e18582018-05-31 19:27:01 -070026#include <ndn-cxx/security/key-chain.hpp>
27#include <ndn-cxx/security/signing-info.hpp>
Davide Pesavento35185332019-01-14 04:00:15 -050028#include <ndn-cxx/util/random.hpp>
Davide Pesaventoef064892022-04-05 02:26:03 -040029#include <ndn-cxx/util/time.hpp>
Davide Pesavento35185332019-01-14 04:00:15 -050030
Davide Pesavento42db0292023-09-19 15:48:33 -040031#include <chrono>
Davide Pesavento35185332019-01-14 04:00:15 -050032#include <limits>
Davide Pesaventoef064892022-04-05 02:26:03 -040033#include <optional>
Davide Pesavento35185332019-01-14 04:00:15 -050034#include <sstream>
Davide Pesavento42db0292023-09-19 15:48:33 -040035#include <thread>
Davide Pesavento35185332019-01-14 04:00:15 -050036#include <vector>
jeraldabraham420dbf02014-04-25 22:58:31 -070037
Davide Pesavento915ce802023-09-17 18:10:52 -040038#include <boost/asio/io_context.hpp>
Davide Pesaventod0b59982015-02-27 19:15:15 +010039#include <boost/asio/signal_set.hpp>
Alexander Lanee9fe1872023-07-25 20:00:23 -040040#include <boost/core/noncopyable.hpp>
Davide Pesavento35185332019-01-14 04:00:15 -050041#include <boost/program_options/options_description.hpp>
42#include <boost/program_options/parsers.hpp>
43#include <boost/program_options/variables_map.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080044
Davide Pesavento42db0292023-09-19 15:48:33 -040045using namespace std::chrono_literals;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080046
Davide Pesaventoef064892022-04-05 02:26:03 -040047namespace ndntg {
48
Davide Pesavento42db0292023-09-19 15:48:33 -040049using namespace ndn::time_literals;
50using namespace std::string_literals;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080051
jeraldabraham420dbf02014-04-25 22:58:31 -070052class NdnTrafficServer : boost::noncopyable
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080053{
54public:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070055 explicit
Alexander Lanee9fe1872023-07-25 20:00:23 -040056 NdnTrafficServer(std::string configFile)
57 : m_configurationFile(std::move(configFile))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080058 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080059 }
60
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080061 void
Davide Pesavento35185332019-01-14 04:00:15 -050062 setMaximumInterests(uint64_t maxInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080063 {
Davide Pesavento35185332019-01-14 04:00:15 -050064 m_nMaximumInterests = maxInterests;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080065 }
66
67 void
Davide Pesavento42db0292023-09-19 15:48:33 -040068 setContentDelay(std::chrono::milliseconds delay)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080069 {
Davide Pesavento42db0292023-09-19 15:48:33 -040070 BOOST_ASSERT(delay >= 0ms);
Davide Pesavento35185332019-01-14 04:00:15 -050071 m_contentDelay = delay;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080072 }
73
74 void
Alexander Lanee9fe1872023-07-25 20:00:23 -040075 setTimestampFormat(std::string format)
76 {
77 m_timestampFormat = std::move(format);
78 }
79
80 void
jeraldabraham420dbf02014-04-25 22:58:31 -070081 setQuietLogging()
82 {
Davide Pesavento35185332019-01-14 04:00:15 -050083 m_wantQuiet = true;
jeraldabraham420dbf02014-04-25 22:58:31 -070084 }
85
Davide Pesavento306e5bc2019-01-26 16:20:34 -050086 int
Davide Pesavento35185332019-01-14 04:00:15 -050087 run()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080088 {
Alexander Lanee9fe1872023-07-25 20:00:23 -040089 m_logger.initialize(std::to_string(ndn::random::generateWord32()), m_timestampFormat);
Davide Pesavento306e5bc2019-01-26 16:20:34 -050090
91 if (!readConfigurationFile(m_configurationFile, m_trafficPatterns, m_logger)) {
92 return 2;
93 }
94
95 if (!checkTrafficPatternCorrectness()) {
96 m_logger.log("ERROR: Traffic configuration provided is not proper", false, true);
97 return 2;
98 }
99
Alexander Lanee9fe1872023-07-25 20:00:23 -0400100 m_logger.log("Traffic configuration file processing completed\n", true, false);
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500101 for (std::size_t i = 0; i < m_trafficPatterns.size(); i++) {
Davide Pesaventoef064892022-04-05 02:26:03 -0400102 m_logger.log("Traffic Pattern Type #" + std::to_string(i + 1), false, false);
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500103 m_trafficPatterns[i].printTrafficConfiguration(m_logger);
104 m_logger.log("", false, false);
105 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100106
Davide Pesavento35185332019-01-14 04:00:15 -0500107 if (m_nMaximumInterests == 0) {
108 logStatistics();
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500109 return 0;
Davide Pesavento35185332019-01-14 04:00:15 -0500110 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100111
Davide Pesavento35185332019-01-14 04:00:15 -0500112 m_signalSet.async_wait([this] (const boost::system::error_code&, int) {
113 if (m_nMaximumInterests && m_nInterestsReceived < *m_nMaximumInterests) {
114 m_hasError = true;
115 }
116 stop();
117 });
118
119 for (std::size_t id = 0; id < m_trafficPatterns.size(); id++) {
120 m_registeredPrefixes.push_back(
121 m_face.setInterestFilter(m_trafficPatterns[id].m_name,
Davide Pesaventoef064892022-04-05 02:26:03 -0400122 [this, id] (auto&&, const auto& interest) { onInterest(interest, id); },
Davide Pesavento35185332019-01-14 04:00:15 -0500123 nullptr,
Davide Pesaventoef064892022-04-05 02:26:03 -0400124 [this, id] (auto&&, const auto& reason) { onRegisterFailed(reason, id); }));
Davide Pesavento35185332019-01-14 04:00:15 -0500125 }
126
127 try {
128 m_face.processEvents();
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500129 return m_hasError ? 1 : 0;
Davide Pesavento35185332019-01-14 04:00:15 -0500130 }
131 catch (const std::exception& e) {
132 m_logger.log("ERROR: "s + e.what(), true, true);
Davide Pesavento915ce802023-09-17 18:10:52 -0400133 m_io.stop();
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500134 return 1;
Davide Pesavento35185332019-01-14 04:00:15 -0500135 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800136 }
137
Davide Pesavento35185332019-01-14 04:00:15 -0500138private:
139 class DataTrafficConfiguration
140 {
141 public:
142 void
143 printTrafficConfiguration(Logger& logger) const
144 {
145 std::ostringstream os;
146
147 if (!m_name.empty()) {
148 os << "Name=" << m_name << ", ";
149 }
Davide Pesavento42db0292023-09-19 15:48:33 -0400150 if (m_contentDelay >= 0ms) {
Davide Pesavento35185332019-01-14 04:00:15 -0500151 os << "ContentDelay=" << m_contentDelay.count() << ", ";
152 }
153 if (m_freshnessPeriod >= 0_ms) {
154 os << "FreshnessPeriod=" << m_freshnessPeriod.count() << ", ";
155 }
156 if (m_contentType) {
157 os << "ContentType=" << *m_contentType << ", ";
158 }
159 if (m_contentLength) {
160 os << "ContentBytes=" << *m_contentLength << ", ";
161 }
162 if (!m_content.empty()) {
163 os << "Content=" << m_content << ", ";
164 }
165 os << "SigningInfo=" << m_signingInfo;
166
167 logger.log(os.str(), false, false);
168 }
169
170 bool
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500171 parseConfigurationLine(const std::string& line, Logger& logger, int lineNumber)
Davide Pesavento35185332019-01-14 04:00:15 -0500172 {
173 std::string parameter, value;
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500174 if (!extractParameterAndValue(line, parameter, value)) {
Davide Pesaventoef064892022-04-05 02:26:03 -0400175 logger.log("Line " + std::to_string(lineNumber) + " - Invalid syntax: " + line,
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500176 false, true);
177 return false;
178 }
179
180 if (parameter == "Name") {
181 m_name = value;
182 }
183 else if (parameter == "ContentDelay") {
Davide Pesavento42db0292023-09-19 15:48:33 -0400184 m_contentDelay = std::chrono::milliseconds(std::stoul(value));
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500185 }
186 else if (parameter == "FreshnessPeriod") {
Davide Pesavento42db0292023-09-19 15:48:33 -0400187 m_freshnessPeriod = ndn::time::milliseconds(std::stoul(value));
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500188 }
189 else if (parameter == "ContentType") {
190 m_contentType = std::stoul(value);
191 }
192 else if (parameter == "ContentBytes") {
193 m_contentLength = std::stoul(value);
194 }
195 else if (parameter == "Content") {
196 m_content = value;
197 }
198 else if (parameter == "SigningInfo") {
Davide Pesaventoef064892022-04-05 02:26:03 -0400199 m_signingInfo = ndn::security::SigningInfo(value);
Davide Pesavento35185332019-01-14 04:00:15 -0500200 }
201 else {
Davide Pesaventoef064892022-04-05 02:26:03 -0400202 logger.log("Line " + std::to_string(lineNumber) + " - Ignoring unknown parameter: " + parameter,
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500203 false, true);
Davide Pesavento35185332019-01-14 04:00:15 -0500204 }
205 return true;
206 }
207
208 bool
209 checkTrafficDetailCorrectness() const
210 {
211 return true;
212 }
213
214 public:
215 std::string m_name;
Davide Pesavento42db0292023-09-19 15:48:33 -0400216 std::chrono::milliseconds m_contentDelay{-1};
217 ndn::time::milliseconds m_freshnessPeriod{-1};
Davide Pesaventoef064892022-04-05 02:26:03 -0400218 std::optional<uint32_t> m_contentType;
219 std::optional<std::size_t> m_contentLength;
Davide Pesavento35185332019-01-14 04:00:15 -0500220 std::string m_content;
Davide Pesaventoef064892022-04-05 02:26:03 -0400221 ndn::security::SigningInfo m_signingInfo;
Davide Pesavento35185332019-01-14 04:00:15 -0500222 uint64_t m_nInterestsReceived = 0;
223 };
224
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800225 void
226 logStatistics()
227 {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400228 using std::to_string;
229
230 m_logger.log("\n\n== Traffic Report ==\n", false, true);
231 m_logger.log("Total Traffic Pattern Types = " + to_string(m_trafficPatterns.size()), false, true);
232 m_logger.log("Total Interests Received = " + to_string(m_nInterestsReceived) + "\n", false, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100233
Eric Newberryc8e18582018-05-31 19:27:01 -0700234 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400235 const auto& pattern = m_trafficPatterns[patternId];
236
237 m_logger.log("Traffic Pattern Type #" + to_string(patternId + 1), false, true);
238 pattern.printTrafficConfiguration(m_logger);
Davide Pesavento35185332019-01-14 04:00:15 -0500239 m_logger.log("Total Interests Received = " +
Alexander Lanee9fe1872023-07-25 20:00:23 -0400240 to_string(pattern.m_nInterestsReceived) + "\n", false, true);
Eric Newberryc8e18582018-05-31 19:27:01 -0700241 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800242 }
243
244 bool
Davide Pesavento35185332019-01-14 04:00:15 -0500245 checkTrafficPatternCorrectness() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800246 {
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500247 // TODO
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800248 return true;
249 }
250
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800251 static std::string
Davide Pesavento35185332019-01-14 04:00:15 -0500252 getRandomByteString(std::size_t length)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800253 {
Davide Pesavento35185332019-01-14 04:00:15 -0500254 // per ISO C++ std, cannot instantiate uniform_int_distribution with char
255 static std::uniform_int_distribution<short> dist(std::numeric_limits<char>::min(),
256 std::numeric_limits<char>::max());
257
258 std::string s;
259 s.reserve(length);
260 for (std::size_t i = 0; i < length; i++) {
Davide Pesaventoef064892022-04-05 02:26:03 -0400261 s += static_cast<char>(dist(ndn::random::getRandomNumberEngine()));
Eric Newberryc8e18582018-05-31 19:27:01 -0700262 }
Davide Pesavento35185332019-01-14 04:00:15 -0500263 return s;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800264 }
265
266 void
Davide Pesaventoef064892022-04-05 02:26:03 -0400267 onInterest(const ndn::Interest& interest, std::size_t patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800268 {
Spencer Leee7a5b742015-10-29 02:18:11 -0700269 auto& pattern = m_trafficPatterns[patternId];
270
Davide Pesavento35185332019-01-14 04:00:15 -0500271 if (!m_nMaximumInterests || m_nInterestsReceived < *m_nMaximumInterests) {
Davide Pesaventoef064892022-04-05 02:26:03 -0400272 ndn::Data data(interest.getName());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800273
Davide Pesavento35185332019-01-14 04:00:15 -0500274 if (pattern.m_freshnessPeriod >= 0_ms)
Eric Newberryc8e18582018-05-31 19:27:01 -0700275 data.setFreshnessPeriod(pattern.m_freshnessPeriod);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700276
Davide Pesavento35185332019-01-14 04:00:15 -0500277 if (pattern.m_contentType)
278 data.setContentType(*pattern.m_contentType);
279
Eric Newberryc8e18582018-05-31 19:27:01 -0700280 std::string content;
Davide Pesavento35185332019-01-14 04:00:15 -0500281 if (pattern.m_contentLength > 0)
282 content = getRandomByteString(*pattern.m_contentLength);
Eric Newberryc8e18582018-05-31 19:27:01 -0700283 if (!pattern.m_content.empty())
284 content = pattern.m_content;
Davide Pesaventoef064892022-04-05 02:26:03 -0400285 data.setContent(ndn::makeStringBlock(ndn::tlv::Content, content));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700286
Eric Newberryc8e18582018-05-31 19:27:01 -0700287 m_keyChain.sign(data, pattern.m_signingInfo);
Spencer Leee7a5b742015-10-29 02:18:11 -0700288
Eric Newberryc8e18582018-05-31 19:27:01 -0700289 m_nInterestsReceived++;
290 pattern.m_nInterestsReceived++;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100291
Davide Pesavento35185332019-01-14 04:00:15 -0500292 if (!m_wantQuiet) {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400293 auto logLine = "Interest Received - PatternType=" + std::to_string(patternId + 1) +
Davide Pesaventoef064892022-04-05 02:26:03 -0400294 ", GlobalID=" + std::to_string(m_nInterestsReceived) +
295 ", LocalID=" + std::to_string(pattern.m_nInterestsReceived) +
Alexander Lanee9fe1872023-07-25 20:00:23 -0400296 ", Name=" + interest.getName().toUri();
Eric Newberryc8e18582018-05-31 19:27:01 -0700297 m_logger.log(logLine, true, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700298 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700299
Davide Pesavento42db0292023-09-19 15:48:33 -0400300 if (pattern.m_contentDelay > 0ms)
301 std::this_thread::sleep_for(pattern.m_contentDelay);
302 if (m_contentDelay > 0ms)
303 std::this_thread::sleep_for(m_contentDelay);
Davide Pesavento35185332019-01-14 04:00:15 -0500304
Eric Newberryc8e18582018-05-31 19:27:01 -0700305 m_face.put(data);
306 }
Davide Pesavento35185332019-01-14 04:00:15 -0500307
308 if (m_nMaximumInterests && m_nInterestsReceived >= *m_nMaximumInterests) {
Eric Newberryc8e18582018-05-31 19:27:01 -0700309 logStatistics();
Davide Pesavento35185332019-01-14 04:00:15 -0500310 m_registeredPrefixes.clear();
Eric Newberry51459402018-06-28 00:06:18 -0700311 m_signalSet.cancel();
Eric Newberryc8e18582018-05-31 19:27:01 -0700312 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800313 }
314
315 void
Davide Pesavento35185332019-01-14 04:00:15 -0500316 onRegisterFailed(const std::string& reason, std::size_t patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800317 {
Davide Pesaventoef064892022-04-05 02:26:03 -0400318 auto logLine = "Prefix registration failed - PatternType=" + std::to_string(patternId + 1) +
Davide Pesavento35185332019-01-14 04:00:15 -0500319 ", Name=" + m_trafficPatterns[patternId].m_name +
320 ", Reason=" + reason;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800321 m_logger.log(logLine, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100322
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700323 m_nRegistrationsFailed++;
Eric Newberryc8e18582018-05-31 19:27:01 -0700324 if (m_nRegistrationsFailed == m_trafficPatterns.size()) {
325 m_hasError = true;
Davide Pesavento35185332019-01-14 04:00:15 -0500326 stop();
Eric Newberryc8e18582018-05-31 19:27:01 -0700327 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800328 }
329
330 void
Davide Pesavento35185332019-01-14 04:00:15 -0500331 stop()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800332 {
Davide Pesavento35185332019-01-14 04:00:15 -0500333 logStatistics();
334 m_face.shutdown();
Davide Pesavento915ce802023-09-17 18:10:52 -0400335 m_io.stop();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800336 }
337
338private:
Alexander Lanee9fe1872023-07-25 20:00:23 -0400339 Logger m_logger{"NdnTrafficServer"};
Davide Pesavento915ce802023-09-17 18:10:52 -0400340 boost::asio::io_context m_io;
341 boost::asio::signal_set m_signalSet{m_io, SIGINT, SIGTERM};
342 ndn::Face m_face{m_io};
Davide Pesaventoef064892022-04-05 02:26:03 -0400343 ndn::KeyChain m_keyChain;
Davide Pesavento35185332019-01-14 04:00:15 -0500344
345 std::string m_configurationFile;
Alexander Lanee9fe1872023-07-25 20:00:23 -0400346 std::string m_timestampFormat;
Davide Pesaventoef064892022-04-05 02:26:03 -0400347 std::optional<uint64_t> m_nMaximumInterests;
Davide Pesavento42db0292023-09-19 15:48:33 -0400348 std::chrono::milliseconds m_contentDelay{0};
Davide Pesavento35185332019-01-14 04:00:15 -0500349
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700350 std::vector<DataTrafficConfiguration> m_trafficPatterns;
Davide Pesaventoef064892022-04-05 02:26:03 -0400351 std::vector<ndn::ScopedRegisteredPrefixHandle> m_registeredPrefixes;
Davide Pesavento35185332019-01-14 04:00:15 -0500352 uint64_t m_nRegistrationsFailed = 0;
353 uint64_t m_nInterestsReceived = 0;
Davide Pesaventoef064892022-04-05 02:26:03 -0400354
355 bool m_wantQuiet = false;
Davide Pesavento35185332019-01-14 04:00:15 -0500356 bool m_hasError = false;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800357};
358
Davide Pesaventoef064892022-04-05 02:26:03 -0400359} // namespace ndntg
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800360
Alexander Lanee9fe1872023-07-25 20:00:23 -0400361namespace po = boost::program_options;
362
Davide Pesavento35185332019-01-14 04:00:15 -0500363static void
Davide Pesaventoef064892022-04-05 02:26:03 -0400364usage(std::ostream& os, std::string_view programName, const po::options_description& desc)
Davide Pesavento35185332019-01-14 04:00:15 -0500365{
366 os << "Usage: " << programName << " [options] <Traffic_Configuration_File>\n"
367 << "\n"
368 << "Respond to Interests as per provided Traffic_Configuration_File.\n"
369 << "Multiple prefixes can be configured for handling.\n"
370 << "Set the environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
371 << "\n"
372 << desc;
373}
374
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700375int
376main(int argc, char* argv[])
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800377{
Davide Pesavento35185332019-01-14 04:00:15 -0500378 std::string configFile;
Alexander Lanee9fe1872023-07-25 20:00:23 -0400379 std::string timestampFormat;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100380
Davide Pesavento35185332019-01-14 04:00:15 -0500381 po::options_description visibleOptions("Options");
382 visibleOptions.add_options()
383 ("help,h", "print this help message and exit")
Alexander Lanee9fe1872023-07-25 20:00:23 -0400384 ("count,c", po::value<int64_t>(), "maximum number of Interests to respond to")
Davide Pesavento42db0292023-09-19 15:48:33 -0400385 ("delay,d", po::value<std::chrono::milliseconds::rep>()->default_value(0),
Davide Pesavento35185332019-01-14 04:00:15 -0500386 "wait this amount of milliseconds before responding to each Interest")
Alexander Lanee9fe1872023-07-25 20:00:23 -0400387 ("timestamp-format,t", po::value<std::string>(&timestampFormat), "format string for timestamp output")
388 ("quiet,q", po::bool_switch(), "turn off logging of Interest reception and Data generation")
Davide Pesavento35185332019-01-14 04:00:15 -0500389 ;
390
391 po::options_description hiddenOptions;
392 hiddenOptions.add_options()
393 ("config-file", po::value<std::string>(&configFile))
394 ;
395
396 po::positional_options_description posOptions;
397 posOptions.add("config-file", -1);
398
399 po::options_description allOptions;
400 allOptions.add(visibleOptions).add(hiddenOptions);
401
402 po::variables_map vm;
403 try {
404 po::store(po::command_line_parser(argc, argv).options(allOptions).positional(posOptions).run(), vm);
405 po::notify(vm);
406 }
407 catch (const po::error& e) {
408 std::cerr << "ERROR: " << e.what() << std::endl;
409 return 2;
410 }
411 catch (const boost::bad_any_cast& e) {
412 std::cerr << "ERROR: " << e.what() << std::endl;
413 return 2;
414 }
415
416 if (vm.count("help") > 0) {
417 usage(std::cout, argv[0], visibleOptions);
418 return 0;
419 }
420
421 if (configFile.empty()) {
422 usage(std::cerr, argv[0], visibleOptions);
423 return 2;
424 }
425
Alexander Lanee9fe1872023-07-25 20:00:23 -0400426 ndntg::NdnTrafficServer server(std::move(configFile));
Davide Pesavento35185332019-01-14 04:00:15 -0500427
428 if (vm.count("count") > 0) {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400429 auto count = vm["count"].as<int64_t>();
Davide Pesavento35185332019-01-14 04:00:15 -0500430 if (count < 0) {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400431 std::cerr << "ERROR: the argument for option '--count' cannot be negative\n";
Davide Pesavento35185332019-01-14 04:00:15 -0500432 return 2;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800433 }
Davide Pesavento35185332019-01-14 04:00:15 -0500434 server.setMaximumInterests(static_cast<uint64_t>(count));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800435 }
436
Davide Pesavento35185332019-01-14 04:00:15 -0500437 if (vm.count("delay") > 0) {
Davide Pesavento42db0292023-09-19 15:48:33 -0400438 std::chrono::milliseconds delay(vm["delay"].as<std::chrono::milliseconds::rep>());
439 if (delay < 0ms) {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400440 std::cerr << "ERROR: the argument for option '--delay' cannot be negative\n";
Davide Pesavento35185332019-01-14 04:00:15 -0500441 return 2;
442 }
443 server.setContentDelay(delay);
Eric Newberryc8e18582018-05-31 19:27:01 -0700444 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800445
Alexander Lanee9fe1872023-07-25 20:00:23 -0400446 if (!timestampFormat.empty()) {
447 server.setTimestampFormat(std::move(timestampFormat));
448 }
449
Davide Pesavento35185332019-01-14 04:00:15 -0500450 if (vm["quiet"].as<bool>()) {
451 server.setQuietLogging();
452 }
453
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500454 return server.run();
Eric Newberryc8e18582018-05-31 19:27:01 -0700455}