blob: 437c52964fcf141f253b8716f6b2259d664d5149 [file] [log] [blame]
Junxiao Shi1688ded2015-03-29 10:09:26 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Arizona Board of Regents.
4 *
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 */
Junxiao Shi11b2ae92015-03-21 11:29:19 -070019/**
20 * Copyright (C) 2014 Arizona Board of Regents
21 *
22 * This file is part of ndn-tlv-ping (Ping Application for Named Data Networking).
23 *
24 * ndn-tlv-ping is a free software: you can redistribute it and/or modify it under
25 * the terms of the GNU General Public License as published by the Free Software
26 * Foundation, either version 3 of the License, or (at your option) any later version.
27 *
28 * ndn-tlv-ping is distributed in the hope that it will be useful, but WITHOUT ANY
29 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
30 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License along with
33 * ndn-tlv-ping, e.g., in LICENSE file. If not, see <http://www.gnu.org/licenses/>.
34 *
35 * @author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
36 */
37
Junxiao Shi1753afb2015-04-17 20:59:50 -070038#include "core/version.hpp"
Junxiao Shi11b2ae92015-03-21 11:29:19 -070039
40namespace ndn {
Junxiao Shi0c75f992015-03-24 21:39:47 -070041namespace ping {
Junxiao Shi11b2ae92015-03-21 11:29:19 -070042
Junxiao Shi0c75f992015-03-24 21:39:47 -070043class NdnPingServer : boost::noncopyable
Junxiao Shi11b2ae92015-03-21 11:29:19 -070044{
45public:
Junxiao Shi11b2ae92015-03-21 11:29:19 -070046 explicit
Junxiao Shi0c75f992015-03-24 21:39:47 -070047 NdnPingServer(char* programName)
Junxiao Shi11b2ae92015-03-21 11:29:19 -070048 : m_programName(programName)
49 , m_hasError(false)
50 , m_isPrintTimestampSet(false)
51 , m_freshnessPeriod(getMinimumFreshnessPeriod())
52 , m_maximumPings(-1)
53 , m_totalPings(0)
54 , m_face(m_ioService)
55 {
56 }
57
58 void
59 usage()
60 {
61 std::cout << "\n Usage:\n " << m_programName << " ndn:/name/prefix [options]\n"
62 " Starts a NDN ping server that responds to Interests with name"
63 " ndn:/name/prefix/ping/number.\n"
64 " [-x freshness] - set FreshnessSeconds\n"
65 " [-p] - specify number of pings to be satisfied (>=1)\n"
66 " [-t] - print timestamp\n"
67 " [-h] - print this message and exit\n\n";
68 exit(1);
69 }
70
71 time::milliseconds
72 getMinimumFreshnessPeriod()
73 {
74 return time::milliseconds(1000);
75 }
76
77 void
78 setFreshnessPeriod(int freshnessPeriod)
79 {
80 if (freshnessPeriod <= 0)
Junxiao Shi0c75f992015-03-24 21:39:47 -070081 usage();
Junxiao Shi11b2ae92015-03-21 11:29:19 -070082
83 m_freshnessPeriod = time::milliseconds(freshnessPeriod);
84 }
85
86 void
87 setMaximumPings(int maximumPings)
88 {
89 if (maximumPings <= 0)
90 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -070091
Junxiao Shi11b2ae92015-03-21 11:29:19 -070092 m_maximumPings = maximumPings;
93 }
94
95 void
96 setPrefix(char* prefix)
97 {
98 m_prefix = prefix;
99 }
100
101 void
102 setPrintTimestamp()
103 {
104 m_isPrintTimestampSet = true;
105 }
106
107 bool
108 hasError() const
109 {
110 return m_hasError;
111 }
112
113 void
114 onInterest(const Name& name, const Interest& interest)
115 {
116 Name interestName = interest.getName();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700117
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700118 if (m_isPrintTimestampSet)
119 std::cout << time::toIsoString(time::system_clock::now()) << " - ";
120 std::cout << "Interest Received - Ping Reference = "
121 << interestName.at(-1).toUri() << std::endl;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700122
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700123 char responseContent[] = "NDN TLV Ping Response";
124 shared_ptr<Data> data = make_shared<Data>(interestName);
125 data->setFreshnessPeriod(m_freshnessPeriod);
126 data->setContent(reinterpret_cast<const uint8_t*>(responseContent),
127 sizeof(responseContent));
128 m_keyChain.sign(*data);
129 m_face.put(*data);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700130
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700131 ++m_totalPings;
132 if (m_maximumPings > 0 && m_maximumPings == m_totalPings) {
133 std::cout << "\n\nTotal Ping Interests Processed = " << m_totalPings << std::endl;
134 std::cout << "Shutting Down Ping Server (" << m_name << ").\n" << std::endl;
135 m_face.shutdown();
136 m_ioService.stop();
137 }
138 }
139
140 void
141 onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
142 {
143 std::cerr << "ERROR: Failed to register prefix in local hub's daemon" << std::endl;
144 std::cerr << "REASON: " << reason << std::endl;
145 m_hasError = true;
146 m_face.shutdown();
147 m_ioService.stop();
148 }
149
150 void
151 signalHandler()
152 {
153 std::cout << "\n\nTotal Ping Interests Processed = " << m_totalPings << std::endl;
154 std::cout << "Shutting Down Ping Server (" << m_name.toUri() << ").\n" << std::endl;
155 m_face.shutdown();
156 exit(1);
157 }
158
159 void
160 run()
161 {
162 std::cout << "\n=== Ping Server " << m_prefix <<" ===\n" << std::endl;
163
164 boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
165 signalSet.async_wait(bind([this]() { signalHandler(); }));
Junxiao Shi0c75f992015-03-24 21:39:47 -0700166
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700167 m_name = m_prefix;
168 m_name.append("ping");
169 m_face.setInterestFilter(m_name,
Junxiao Shi0c75f992015-03-24 21:39:47 -0700170 bind(&NdnPingServer::onInterest,
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700171 this, _1, _2),
Junxiao Shi0c75f992015-03-24 21:39:47 -0700172 bind(&NdnPingServer::onRegisterFailed,
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700173 this, _1,_2));
Junxiao Shi0c75f992015-03-24 21:39:47 -0700174
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700175 try {
176 m_face.processEvents();
177 }
178 catch (std::exception& e) {
179 std::cerr << "ERROR: " << e.what() << std::endl;
180 m_hasError = true;
181 m_ioService.stop();
182 }
183 }
184
185private:
186 char* m_programName;
187 bool m_hasError;
188 bool m_isPrintTimestampSet;
189 time::milliseconds m_freshnessPeriod;
190 int m_maximumPings;
191 int m_totalPings;
192
193 char* m_prefix;
194 Name m_name;
195
196 boost::asio::io_service m_ioService;
197 KeyChain m_keyChain;
198 Face m_face;
199};
200
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700201int
202main(int argc, char* argv[])
203{
204 int res;
205
Junxiao Shi0c75f992015-03-24 21:39:47 -0700206 NdnPingServer program(argv[0]);
Junxiao Shi1753afb2015-04-17 20:59:50 -0700207 while ((res = getopt(argc, argv, "hdtp:x:V")) != -1)
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700208 {
209 switch (res) {
210 case 'h':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700211 program.usage();
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700212 break;
213 case 'p':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700214 program.setMaximumPings(atoi(optarg));
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700215 break;
216 case 'x':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700217 program.setFreshnessPeriod(atoi(optarg));
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700218 break;
219 case 't':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700220 program.setPrintTimestamp();
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700221 break;
Junxiao Shi1753afb2015-04-17 20:59:50 -0700222 case 'V':
223 std::cout << "ndnpingserver " << tools::VERSION << std::endl;
224 return 0;
225 default:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700226 program.usage();
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700227 break;
228 }
229 }
230
231 argc -= optind;
232 argv += optind;
233
234 if (argv[0] == 0)
Junxiao Shi0c75f992015-03-24 21:39:47 -0700235 program.usage();
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700236
Junxiao Shi0c75f992015-03-24 21:39:47 -0700237 program.setPrefix(argv[0]);
238 program.run();
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700239
240 std::cout << std::endl;
241
Junxiao Shi0c75f992015-03-24 21:39:47 -0700242 if (program.hasError())
Junxiao Shi11b2ae92015-03-21 11:29:19 -0700243 return 1;
244 else
245 return 0;
246}
Junxiao Shi0c75f992015-03-24 21:39:47 -0700247
248} // namespace ping
249} // namespace ndn
250
251int
252main(int argc, char** argv)
253{
254 return ndn::ping::main(argc, argv);
255}