blob: f4c9feabe833ac018da298409b6fe09c85f7a142 [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 Pesavento35185332019-01-14 04:00:15 -050031#include <limits>
Davide Pesaventoef064892022-04-05 02:26:03 -040032#include <optional>
Davide Pesavento35185332019-01-14 04:00:15 -050033#include <sstream>
34#include <vector>
jeraldabraham420dbf02014-04-25 22:58:31 -070035
Davide Pesavento915ce802023-09-17 18:10:52 -040036#include <boost/asio/io_context.hpp>
Davide Pesaventod0b59982015-02-27 19:15:15 +010037#include <boost/asio/signal_set.hpp>
Alexander Lanee9fe1872023-07-25 20:00:23 -040038#include <boost/core/noncopyable.hpp>
Davide Pesavento35185332019-01-14 04:00:15 -050039#include <boost/program_options/options_description.hpp>
40#include <boost/program_options/parsers.hpp>
41#include <boost/program_options/variables_map.hpp>
42#include <boost/thread/thread.hpp>
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080043
Davide Pesaventoef064892022-04-05 02:26:03 -040044using namespace ndn::time_literals;
45using namespace std::string_literals;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080046
Davide Pesaventoef064892022-04-05 02:26:03 -040047namespace ndntg {
48
49namespace time = ndn::time;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080050
jeraldabraham420dbf02014-04-25 22:58:31 -070051class NdnTrafficServer : boost::noncopyable
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080052{
53public:
jeraldabrahamcc3c6c92014-03-28 02:21:45 -070054 explicit
Alexander Lanee9fe1872023-07-25 20:00:23 -040055 NdnTrafficServer(std::string configFile)
56 : m_configurationFile(std::move(configFile))
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080057 {
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080058 }
59
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080060 void
Davide Pesavento35185332019-01-14 04:00:15 -050061 setMaximumInterests(uint64_t maxInterests)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080062 {
Davide Pesavento35185332019-01-14 04:00:15 -050063 m_nMaximumInterests = maxInterests;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080064 }
65
66 void
Davide Pesavento35185332019-01-14 04:00:15 -050067 setContentDelay(time::milliseconds delay)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080068 {
Davide Pesavento35185332019-01-14 04:00:15 -050069 BOOST_ASSERT(delay >= 0_ms);
70 m_contentDelay = delay;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080071 }
72
73 void
Alexander Lanee9fe1872023-07-25 20:00:23 -040074 setTimestampFormat(std::string format)
75 {
76 m_timestampFormat = std::move(format);
77 }
78
79 void
jeraldabraham420dbf02014-04-25 22:58:31 -070080 setQuietLogging()
81 {
Davide Pesavento35185332019-01-14 04:00:15 -050082 m_wantQuiet = true;
jeraldabraham420dbf02014-04-25 22:58:31 -070083 }
84
Davide Pesavento306e5bc2019-01-26 16:20:34 -050085 int
Davide Pesavento35185332019-01-14 04:00:15 -050086 run()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -080087 {
Alexander Lanee9fe1872023-07-25 20:00:23 -040088 m_logger.initialize(std::to_string(ndn::random::generateWord32()), m_timestampFormat);
Davide Pesavento306e5bc2019-01-26 16:20:34 -050089
90 if (!readConfigurationFile(m_configurationFile, m_trafficPatterns, m_logger)) {
91 return 2;
92 }
93
94 if (!checkTrafficPatternCorrectness()) {
95 m_logger.log("ERROR: Traffic configuration provided is not proper", false, true);
96 return 2;
97 }
98
Alexander Lanee9fe1872023-07-25 20:00:23 -040099 m_logger.log("Traffic configuration file processing completed\n", true, false);
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500100 for (std::size_t i = 0; i < m_trafficPatterns.size(); i++) {
Davide Pesaventoef064892022-04-05 02:26:03 -0400101 m_logger.log("Traffic Pattern Type #" + std::to_string(i + 1), false, false);
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500102 m_trafficPatterns[i].printTrafficConfiguration(m_logger);
103 m_logger.log("", false, false);
104 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100105
Davide Pesavento35185332019-01-14 04:00:15 -0500106 if (m_nMaximumInterests == 0) {
107 logStatistics();
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500108 return 0;
Davide Pesavento35185332019-01-14 04:00:15 -0500109 }
Davide Pesaventod0b59982015-02-27 19:15:15 +0100110
Davide Pesavento35185332019-01-14 04:00:15 -0500111 m_signalSet.async_wait([this] (const boost::system::error_code&, int) {
112 if (m_nMaximumInterests && m_nInterestsReceived < *m_nMaximumInterests) {
113 m_hasError = true;
114 }
115 stop();
116 });
117
118 for (std::size_t id = 0; id < m_trafficPatterns.size(); id++) {
119 m_registeredPrefixes.push_back(
120 m_face.setInterestFilter(m_trafficPatterns[id].m_name,
Davide Pesaventoef064892022-04-05 02:26:03 -0400121 [this, id] (auto&&, const auto& interest) { onInterest(interest, id); },
Davide Pesavento35185332019-01-14 04:00:15 -0500122 nullptr,
Davide Pesaventoef064892022-04-05 02:26:03 -0400123 [this, id] (auto&&, const auto& reason) { onRegisterFailed(reason, id); }));
Davide Pesavento35185332019-01-14 04:00:15 -0500124 }
125
126 try {
127 m_face.processEvents();
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500128 return m_hasError ? 1 : 0;
Davide Pesavento35185332019-01-14 04:00:15 -0500129 }
130 catch (const std::exception& e) {
131 m_logger.log("ERROR: "s + e.what(), true, true);
Davide Pesavento915ce802023-09-17 18:10:52 -0400132 m_io.stop();
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500133 return 1;
Davide Pesavento35185332019-01-14 04:00:15 -0500134 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800135 }
136
Davide Pesavento35185332019-01-14 04:00:15 -0500137private:
138 class DataTrafficConfiguration
139 {
140 public:
141 void
142 printTrafficConfiguration(Logger& logger) const
143 {
144 std::ostringstream os;
145
146 if (!m_name.empty()) {
147 os << "Name=" << m_name << ", ";
148 }
149 if (m_contentDelay >= 0_ms) {
150 os << "ContentDelay=" << m_contentDelay.count() << ", ";
151 }
152 if (m_freshnessPeriod >= 0_ms) {
153 os << "FreshnessPeriod=" << m_freshnessPeriod.count() << ", ";
154 }
155 if (m_contentType) {
156 os << "ContentType=" << *m_contentType << ", ";
157 }
158 if (m_contentLength) {
159 os << "ContentBytes=" << *m_contentLength << ", ";
160 }
161 if (!m_content.empty()) {
162 os << "Content=" << m_content << ", ";
163 }
164 os << "SigningInfo=" << m_signingInfo;
165
166 logger.log(os.str(), false, false);
167 }
168
169 bool
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500170 parseConfigurationLine(const std::string& line, Logger& logger, int lineNumber)
Davide Pesavento35185332019-01-14 04:00:15 -0500171 {
172 std::string parameter, value;
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500173 if (!extractParameterAndValue(line, parameter, value)) {
Davide Pesaventoef064892022-04-05 02:26:03 -0400174 logger.log("Line " + std::to_string(lineNumber) + " - Invalid syntax: " + line,
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500175 false, true);
176 return false;
177 }
178
179 if (parameter == "Name") {
180 m_name = value;
181 }
182 else if (parameter == "ContentDelay") {
183 m_contentDelay = time::milliseconds(std::stoul(value));
184 }
185 else if (parameter == "FreshnessPeriod") {
186 m_freshnessPeriod = time::milliseconds(std::stoul(value));
187 }
188 else if (parameter == "ContentType") {
189 m_contentType = std::stoul(value);
190 }
191 else if (parameter == "ContentBytes") {
192 m_contentLength = std::stoul(value);
193 }
194 else if (parameter == "Content") {
195 m_content = value;
196 }
197 else if (parameter == "SigningInfo") {
Davide Pesaventoef064892022-04-05 02:26:03 -0400198 m_signingInfo = ndn::security::SigningInfo(value);
Davide Pesavento35185332019-01-14 04:00:15 -0500199 }
200 else {
Davide Pesaventoef064892022-04-05 02:26:03 -0400201 logger.log("Line " + std::to_string(lineNumber) + " - Ignoring unknown parameter: " + parameter,
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500202 false, true);
Davide Pesavento35185332019-01-14 04:00:15 -0500203 }
204 return true;
205 }
206
207 bool
208 checkTrafficDetailCorrectness() const
209 {
210 return true;
211 }
212
213 public:
214 std::string m_name;
215 time::milliseconds m_contentDelay = -1_ms;
216 time::milliseconds m_freshnessPeriod = -1_ms;
Davide Pesaventoef064892022-04-05 02:26:03 -0400217 std::optional<uint32_t> m_contentType;
218 std::optional<std::size_t> m_contentLength;
Davide Pesavento35185332019-01-14 04:00:15 -0500219 std::string m_content;
Davide Pesaventoef064892022-04-05 02:26:03 -0400220 ndn::security::SigningInfo m_signingInfo;
Davide Pesavento35185332019-01-14 04:00:15 -0500221 uint64_t m_nInterestsReceived = 0;
222 };
223
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800224 void
225 logStatistics()
226 {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400227 using std::to_string;
228
229 m_logger.log("\n\n== Traffic Report ==\n", false, true);
230 m_logger.log("Total Traffic Pattern Types = " + to_string(m_trafficPatterns.size()), false, true);
231 m_logger.log("Total Interests Received = " + to_string(m_nInterestsReceived) + "\n", false, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100232
Eric Newberryc8e18582018-05-31 19:27:01 -0700233 for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400234 const auto& pattern = m_trafficPatterns[patternId];
235
236 m_logger.log("Traffic Pattern Type #" + to_string(patternId + 1), false, true);
237 pattern.printTrafficConfiguration(m_logger);
Davide Pesavento35185332019-01-14 04:00:15 -0500238 m_logger.log("Total Interests Received = " +
Alexander Lanee9fe1872023-07-25 20:00:23 -0400239 to_string(pattern.m_nInterestsReceived) + "\n", false, true);
Eric Newberryc8e18582018-05-31 19:27:01 -0700240 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800241 }
242
243 bool
Davide Pesavento35185332019-01-14 04:00:15 -0500244 checkTrafficPatternCorrectness() const
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800245 {
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500246 // TODO
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800247 return true;
248 }
249
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800250 static std::string
Davide Pesavento35185332019-01-14 04:00:15 -0500251 getRandomByteString(std::size_t length)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800252 {
Davide Pesavento35185332019-01-14 04:00:15 -0500253 // per ISO C++ std, cannot instantiate uniform_int_distribution with char
254 static std::uniform_int_distribution<short> dist(std::numeric_limits<char>::min(),
255 std::numeric_limits<char>::max());
256
257 std::string s;
258 s.reserve(length);
259 for (std::size_t i = 0; i < length; i++) {
Davide Pesaventoef064892022-04-05 02:26:03 -0400260 s += static_cast<char>(dist(ndn::random::getRandomNumberEngine()));
Eric Newberryc8e18582018-05-31 19:27:01 -0700261 }
Davide Pesavento35185332019-01-14 04:00:15 -0500262 return s;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800263 }
264
265 void
Davide Pesaventoef064892022-04-05 02:26:03 -0400266 onInterest(const ndn::Interest& interest, std::size_t patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800267 {
Spencer Leee7a5b742015-10-29 02:18:11 -0700268 auto& pattern = m_trafficPatterns[patternId];
269
Davide Pesavento35185332019-01-14 04:00:15 -0500270 if (!m_nMaximumInterests || m_nInterestsReceived < *m_nMaximumInterests) {
Davide Pesaventoef064892022-04-05 02:26:03 -0400271 ndn::Data data(interest.getName());
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800272
Davide Pesavento35185332019-01-14 04:00:15 -0500273 if (pattern.m_freshnessPeriod >= 0_ms)
Eric Newberryc8e18582018-05-31 19:27:01 -0700274 data.setFreshnessPeriod(pattern.m_freshnessPeriod);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700275
Davide Pesavento35185332019-01-14 04:00:15 -0500276 if (pattern.m_contentType)
277 data.setContentType(*pattern.m_contentType);
278
Eric Newberryc8e18582018-05-31 19:27:01 -0700279 std::string content;
Davide Pesavento35185332019-01-14 04:00:15 -0500280 if (pattern.m_contentLength > 0)
281 content = getRandomByteString(*pattern.m_contentLength);
Eric Newberryc8e18582018-05-31 19:27:01 -0700282 if (!pattern.m_content.empty())
283 content = pattern.m_content;
Davide Pesaventoef064892022-04-05 02:26:03 -0400284 data.setContent(ndn::makeStringBlock(ndn::tlv::Content, content));
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700285
Eric Newberryc8e18582018-05-31 19:27:01 -0700286 m_keyChain.sign(data, pattern.m_signingInfo);
Spencer Leee7a5b742015-10-29 02:18:11 -0700287
Eric Newberryc8e18582018-05-31 19:27:01 -0700288 m_nInterestsReceived++;
289 pattern.m_nInterestsReceived++;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100290
Davide Pesavento35185332019-01-14 04:00:15 -0500291 if (!m_wantQuiet) {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400292 auto logLine = "Interest Received - PatternType=" + std::to_string(patternId + 1) +
Davide Pesaventoef064892022-04-05 02:26:03 -0400293 ", GlobalID=" + std::to_string(m_nInterestsReceived) +
294 ", LocalID=" + std::to_string(pattern.m_nInterestsReceived) +
Alexander Lanee9fe1872023-07-25 20:00:23 -0400295 ", Name=" + interest.getName().toUri();
Eric Newberryc8e18582018-05-31 19:27:01 -0700296 m_logger.log(logLine, true, false);
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700297 }
Eric Newberryc8e18582018-05-31 19:27:01 -0700298
Davide Pesavento35185332019-01-14 04:00:15 -0500299 if (pattern.m_contentDelay > 0_ms)
300 boost::this_thread::sleep_for(pattern.m_contentDelay);
301 if (m_contentDelay > 0_ms)
302 boost::this_thread::sleep_for(m_contentDelay);
303
Eric Newberryc8e18582018-05-31 19:27:01 -0700304 m_face.put(data);
305 }
Davide Pesavento35185332019-01-14 04:00:15 -0500306
307 if (m_nMaximumInterests && m_nInterestsReceived >= *m_nMaximumInterests) {
Eric Newberryc8e18582018-05-31 19:27:01 -0700308 logStatistics();
Davide Pesavento35185332019-01-14 04:00:15 -0500309 m_registeredPrefixes.clear();
Eric Newberry51459402018-06-28 00:06:18 -0700310 m_signalSet.cancel();
Eric Newberryc8e18582018-05-31 19:27:01 -0700311 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800312 }
313
314 void
Davide Pesavento35185332019-01-14 04:00:15 -0500315 onRegisterFailed(const std::string& reason, std::size_t patternId)
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800316 {
Davide Pesaventoef064892022-04-05 02:26:03 -0400317 auto logLine = "Prefix registration failed - PatternType=" + std::to_string(patternId + 1) +
Davide Pesavento35185332019-01-14 04:00:15 -0500318 ", Name=" + m_trafficPatterns[patternId].m_name +
319 ", Reason=" + reason;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800320 m_logger.log(logLine, true, true);
Davide Pesaventod0b59982015-02-27 19:15:15 +0100321
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700322 m_nRegistrationsFailed++;
Eric Newberryc8e18582018-05-31 19:27:01 -0700323 if (m_nRegistrationsFailed == m_trafficPatterns.size()) {
324 m_hasError = true;
Davide Pesavento35185332019-01-14 04:00:15 -0500325 stop();
Eric Newberryc8e18582018-05-31 19:27:01 -0700326 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800327 }
328
329 void
Davide Pesavento35185332019-01-14 04:00:15 -0500330 stop()
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800331 {
Davide Pesavento35185332019-01-14 04:00:15 -0500332 logStatistics();
333 m_face.shutdown();
Davide Pesavento915ce802023-09-17 18:10:52 -0400334 m_io.stop();
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800335 }
336
337private:
Alexander Lanee9fe1872023-07-25 20:00:23 -0400338 Logger m_logger{"NdnTrafficServer"};
Davide Pesavento915ce802023-09-17 18:10:52 -0400339 boost::asio::io_context m_io;
340 boost::asio::signal_set m_signalSet{m_io, SIGINT, SIGTERM};
341 ndn::Face m_face{m_io};
Davide Pesaventoef064892022-04-05 02:26:03 -0400342 ndn::KeyChain m_keyChain;
Davide Pesavento35185332019-01-14 04:00:15 -0500343
344 std::string m_configurationFile;
Alexander Lanee9fe1872023-07-25 20:00:23 -0400345 std::string m_timestampFormat;
Davide Pesaventoef064892022-04-05 02:26:03 -0400346 std::optional<uint64_t> m_nMaximumInterests;
Davide Pesavento35185332019-01-14 04:00:15 -0500347 time::milliseconds m_contentDelay = 0_ms;
Davide Pesavento35185332019-01-14 04:00:15 -0500348
jeraldabrahamcc3c6c92014-03-28 02:21:45 -0700349 std::vector<DataTrafficConfiguration> m_trafficPatterns;
Davide Pesaventoef064892022-04-05 02:26:03 -0400350 std::vector<ndn::ScopedRegisteredPrefixHandle> m_registeredPrefixes;
Davide Pesavento35185332019-01-14 04:00:15 -0500351 uint64_t m_nRegistrationsFailed = 0;
352 uint64_t m_nInterestsReceived = 0;
Davide Pesaventoef064892022-04-05 02:26:03 -0400353
354 bool m_wantQuiet = false;
Davide Pesavento35185332019-01-14 04:00:15 -0500355 bool m_hasError = false;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800356};
357
Davide Pesaventoef064892022-04-05 02:26:03 -0400358} // namespace ndntg
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800359
Alexander Lanee9fe1872023-07-25 20:00:23 -0400360namespace po = boost::program_options;
361
Davide Pesavento35185332019-01-14 04:00:15 -0500362static void
Davide Pesaventoef064892022-04-05 02:26:03 -0400363usage(std::ostream& os, std::string_view programName, const po::options_description& desc)
Davide Pesavento35185332019-01-14 04:00:15 -0500364{
365 os << "Usage: " << programName << " [options] <Traffic_Configuration_File>\n"
366 << "\n"
367 << "Respond to Interests as per provided Traffic_Configuration_File.\n"
368 << "Multiple prefixes can be configured for handling.\n"
369 << "Set the environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
370 << "\n"
371 << desc;
372}
373
Alexander Afanasyevfda32a32014-03-20 10:50:00 -0700374int
375main(int argc, char* argv[])
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800376{
Davide Pesavento35185332019-01-14 04:00:15 -0500377 std::string configFile;
Alexander Lanee9fe1872023-07-25 20:00:23 -0400378 std::string timestampFormat;
Davide Pesaventod0b59982015-02-27 19:15:15 +0100379
Davide Pesavento35185332019-01-14 04:00:15 -0500380 po::options_description visibleOptions("Options");
381 visibleOptions.add_options()
382 ("help,h", "print this help message and exit")
Alexander Lanee9fe1872023-07-25 20:00:23 -0400383 ("count,c", po::value<int64_t>(), "maximum number of Interests to respond to")
Davide Pesavento35185332019-01-14 04:00:15 -0500384 ("delay,d", po::value<ndn::time::milliseconds::rep>()->default_value(0),
385 "wait this amount of milliseconds before responding to each Interest")
Alexander Lanee9fe1872023-07-25 20:00:23 -0400386 ("timestamp-format,t", po::value<std::string>(&timestampFormat), "format string for timestamp output")
387 ("quiet,q", po::bool_switch(), "turn off logging of Interest reception and Data generation")
Davide Pesavento35185332019-01-14 04:00:15 -0500388 ;
389
390 po::options_description hiddenOptions;
391 hiddenOptions.add_options()
392 ("config-file", po::value<std::string>(&configFile))
393 ;
394
395 po::positional_options_description posOptions;
396 posOptions.add("config-file", -1);
397
398 po::options_description allOptions;
399 allOptions.add(visibleOptions).add(hiddenOptions);
400
401 po::variables_map vm;
402 try {
403 po::store(po::command_line_parser(argc, argv).options(allOptions).positional(posOptions).run(), vm);
404 po::notify(vm);
405 }
406 catch (const po::error& e) {
407 std::cerr << "ERROR: " << e.what() << std::endl;
408 return 2;
409 }
410 catch (const boost::bad_any_cast& e) {
411 std::cerr << "ERROR: " << e.what() << std::endl;
412 return 2;
413 }
414
415 if (vm.count("help") > 0) {
416 usage(std::cout, argv[0], visibleOptions);
417 return 0;
418 }
419
420 if (configFile.empty()) {
421 usage(std::cerr, argv[0], visibleOptions);
422 return 2;
423 }
424
Alexander Lanee9fe1872023-07-25 20:00:23 -0400425 ndntg::NdnTrafficServer server(std::move(configFile));
Davide Pesavento35185332019-01-14 04:00:15 -0500426
427 if (vm.count("count") > 0) {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400428 auto count = vm["count"].as<int64_t>();
Davide Pesavento35185332019-01-14 04:00:15 -0500429 if (count < 0) {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400430 std::cerr << "ERROR: the argument for option '--count' cannot be negative\n";
Davide Pesavento35185332019-01-14 04:00:15 -0500431 return 2;
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800432 }
Davide Pesavento35185332019-01-14 04:00:15 -0500433 server.setMaximumInterests(static_cast<uint64_t>(count));
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800434 }
435
Davide Pesavento35185332019-01-14 04:00:15 -0500436 if (vm.count("delay") > 0) {
437 ndn::time::milliseconds delay(vm["delay"].as<ndn::time::milliseconds::rep>());
Davide Pesaventoef064892022-04-05 02:26:03 -0400438 if (delay < 0_ms) {
Alexander Lanee9fe1872023-07-25 20:00:23 -0400439 std::cerr << "ERROR: the argument for option '--delay' cannot be negative\n";
Davide Pesavento35185332019-01-14 04:00:15 -0500440 return 2;
441 }
442 server.setContentDelay(delay);
Eric Newberryc8e18582018-05-31 19:27:01 -0700443 }
Alexander Afanasyeva8f2a922014-02-26 14:21:56 -0800444
Alexander Lanee9fe1872023-07-25 20:00:23 -0400445 if (!timestampFormat.empty()) {
446 server.setTimestampFormat(std::move(timestampFormat));
447 }
448
Davide Pesavento35185332019-01-14 04:00:15 -0500449 if (vm["quiet"].as<bool>()) {
450 server.setQuietLogging();
451 }
452
Davide Pesavento306e5bc2019-01-26 16:20:34 -0500453 return server.run();
Eric Newberryc8e18582018-05-31 19:27:01 -0700454}