blob: a51519c5dc95d3b618b8f529b96217ef012482f6 [file] [log] [blame]
Eric Newberry94996d62015-05-07 13:48:46 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento5923bf82018-08-09 01:55:44 -04002/*
3 * Copyright (c) 2015-2018, Arizona Board of Regents.
Eric Newberry94996d62015-05-07 13:48:46 -07004 *
5 * This file is part of ndn-tools (Named Data Networking Essential Tools).
6 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
7 *
8 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Eric Newberry <enewberry@email.arizona.edu>
20 * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
21 */
22
23#include "core/common.hpp"
24#include "core/version.hpp"
25
26#include "ping-server.hpp"
27#include "tracer.hpp"
28
29namespace ndn {
30namespace ping {
31namespace server {
32
Davide Pesavento5923bf82018-08-09 01:55:44 -040033namespace po = boost::program_options;
34
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -070035class Runner : noncopyable
36{
37public:
38 explicit
39 Runner(const Options& options)
40 : m_options(options)
41 , m_pingServer(m_face, m_keyChain, options)
42 , m_tracer(m_pingServer, options)
Davide Pesavento5923bf82018-08-09 01:55:44 -040043 , m_signalSet(m_face.getIoService(), SIGINT)
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -070044 {
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -070045 m_pingServer.afterFinish.connect([this] {
Davide Pesavento5923bf82018-08-09 01:55:44 -040046 m_pingServer.stop();
47 m_signalSet.cancel();
48 });
49
50 m_signalSet.async_wait([this] (const auto& ec, auto) {
51 if (ec != boost::asio::error::operation_aborted) {
52 m_pingServer.stop();
53 }
54 });
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -070055 }
56
57 int
58 run()
59 {
Davide Pesavento5923bf82018-08-09 01:55:44 -040060 std::cout << "PING SERVER " << m_options.prefix << std::endl;
61
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -070062 try {
63 m_pingServer.start();
64 m_face.processEvents();
65 }
Davide Pesavento5923bf82018-08-09 01:55:44 -040066 catch (const std::exception& e) {
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -070067 std::cerr << "ERROR: " << e.what() << std::endl;
68 return 1;
69 }
70
Davide Pesavento5923bf82018-08-09 01:55:44 -040071 std::cout << "\n--- " << m_options.prefix << " ping server statistics ---\n"
72 << m_pingServer.getNPings() << " packets processed" << std::endl;
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -070073 return 0;
74 }
75
76private:
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -070077 const Options& m_options;
Davide Pesavento5923bf82018-08-09 01:55:44 -040078
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -070079 Face m_face;
80 KeyChain m_keyChain;
81 PingServer m_pingServer;
82 Tracer m_tracer;
83
Davide Pesavento5923bf82018-08-09 01:55:44 -040084 boost::asio::signal_set m_signalSet;
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -070085};
86
Eric Newberry94996d62015-05-07 13:48:46 -070087static void
Davide Pesavento5923bf82018-08-09 01:55:44 -040088usage(std::ostream& os, const std::string& programName, const po::options_description& options)
Eric Newberry94996d62015-05-07 13:48:46 -070089{
Davide Pesavento5923bf82018-08-09 01:55:44 -040090 os << "Usage: " << programName << " [options] <prefix>\n"
91 << "\n"
92 << "Starts a NDN ping server that responds to Interests under name ndn:<prefix>/ping\n"
93 << "\n"
94 << options;
Eric Newberry94996d62015-05-07 13:48:46 -070095}
96
Davide Pesavento5923bf82018-08-09 01:55:44 -040097static int
Eric Newberry94996d62015-05-07 13:48:46 -070098main(int argc, char* argv[])
99{
100 Options options;
Davide Pesavento5923bf82018-08-09 01:55:44 -0400101 std::string prefix;
102 auto nMaxPings = static_cast<std::make_signed_t<size_t>>(options.nMaxPings);
103 auto payloadSize = static_cast<std::make_signed_t<size_t>>(options.payloadSize);
Eric Newberry94996d62015-05-07 13:48:46 -0700104
Davide Pesavento5923bf82018-08-09 01:55:44 -0400105 po::options_description visibleDesc("Options");
106 visibleDesc.add_options()
107 ("help,h", "print this help message and exit")
108 ("freshness,x", po::value<time::milliseconds::rep>()->default_value(options.freshnessPeriod.count()),
109 "FreshnessPeriod of the ping response, in milliseconds")
110 ("satisfy,p", po::value(&nMaxPings)->default_value(nMaxPings),
111 "maximum number of pings to be satisfied (0=infinite)")
112 ("size,s", po::value(&payloadSize)->default_value(payloadSize),
113 "size of response payload")
114 ("timestamp,t", po::bool_switch(&options.wantTimestamp), "log timestamp with responses")
115 ("version,V", "print program version and exit")
116 ;
Eric Newberry94996d62015-05-07 13:48:46 -0700117
Davide Pesavento5923bf82018-08-09 01:55:44 -0400118 po::options_description hiddenDesc;
119 hiddenDesc.add_options()
120 ("prefix", po::value<std::string>(&prefix));
Eric Newberry94996d62015-05-07 13:48:46 -0700121
Davide Pesavento5923bf82018-08-09 01:55:44 -0400122 po::positional_options_description posDesc;
123 posDesc.add("prefix", -1);
Eric Newberry94996d62015-05-07 13:48:46 -0700124
Davide Pesavento5923bf82018-08-09 01:55:44 -0400125 po::options_description optDesc;
126 optDesc.add(visibleDesc).add(hiddenDesc);
127
128 po::variables_map vm;
Eric Newberry94996d62015-05-07 13:48:46 -0700129 try {
Davide Pesavento5923bf82018-08-09 01:55:44 -0400130 po::store(po::command_line_parser(argc, argv).options(optDesc).positional(posDesc).run(), vm);
131 po::notify(vm);
Eric Newberry94996d62015-05-07 13:48:46 -0700132 }
133 catch (const po::error& e) {
Davide Pesavento5923bf82018-08-09 01:55:44 -0400134 std::cerr << "ERROR: " << e.what() << "\n\n";
135 usage(std::cerr, argv[0], visibleDesc);
136 return 2;
137 }
138 catch (const boost::bad_any_cast& e) {
139 std::cerr << "ERROR: " << e.what() << "\n\n";
140 usage(std::cerr, argv[0], visibleDesc);
141 return 2;
Eric Newberry94996d62015-05-07 13:48:46 -0700142 }
143
Davide Pesavento5923bf82018-08-09 01:55:44 -0400144 if (vm.count("help") > 0) {
145 usage(std::cout, argv[0], visibleDesc);
146 return 0;
147 }
148
149 if (vm.count("version") > 0) {
150 std::cout << "ndnpingserver " << tools::VERSION << std::endl;
151 return 0;
152 }
153
154 if (prefix.empty()) {
155 std::cerr << "ERROR: no name prefix specified\n\n";
156 usage(std::cerr, argv[0], visibleDesc);
157 return 2;
158 }
159 options.prefix = prefix;
160
161 options.freshnessPeriod = time::milliseconds(vm["freshness"].as<time::milliseconds::rep>());
162 if (options.freshnessPeriod < 0_ms) {
163 std::cerr << "ERROR: FreshnessPeriod cannot be negative" << std::endl;
164 return 2;
165 }
166
167 if (nMaxPings < 0) {
168 std::cerr << "ERROR: maximum number of pings to satisfy cannot be negative" << std::endl;
169 return 2;
170 }
171 options.nMaxPings = static_cast<size_t>(nMaxPings);
172
173 if (payloadSize < 0) {
174 std::cerr << "ERROR: payload size cannot be negative" << std::endl;
175 return 2;
176 }
177 options.payloadSize = static_cast<size_t>(payloadSize);
178
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -0700179 return Runner(options).run();
Eric Newberry94996d62015-05-07 13:48:46 -0700180}
181
182} // namespace server
183} // namespace ping
184} // namespace ndn
185
186int
187main(int argc, char** argv)
188{
189 return ndn::ping::server::main(argc, argv);
Alexander Afanasyev1e7a7b22015-08-26 15:35:26 -0700190}