blob: 7a1eb7b171a3bba3362f14637882edd069465225 [file] [log] [blame]
Junxiao Shi2ac79d92015-03-23 11:16:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento969cd5a2018-04-20 16:27:47 -04002/*
3 * Copyright (c) 2014-2018, Regents of the University of California,
Junxiao Shi1688ded2015-03-29 10:09:26 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of ndn-tools (Named Data Networking Essential Tools).
12 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
13 *
14 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Junxiao Shi2ac79d92015-03-23 11:16:18 -070024 *
25 * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
26 */
27
Junxiao Shi1753afb2015-04-17 20:59:50 -070028#include "core/version.hpp"
Junxiao Shi2ac79d92015-03-23 11:16:18 -070029
Davide Pesavento60f8cc12018-05-10 22:05:21 -040030#include <ndn-cxx/security/signing-helpers.hpp>
31
Davide Pesaventoc0702702017-08-24 22:04:00 -040032#include <sstream>
33
Junxiao Shi0c75f992015-03-24 21:39:47 -070034namespace ndn {
35namespace peek {
Junxiao Shi2ac79d92015-03-23 11:16:18 -070036
Junxiao Shi0c75f992015-03-24 21:39:47 -070037class NdnPoke : boost::noncopyable
Junxiao Shi2ac79d92015-03-23 11:16:18 -070038{
39public:
40 explicit
Davide Pesavento969cd5a2018-04-20 16:27:47 -040041 NdnPoke(const char* programName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070042 : m_programName(programName)
Davide Pesavento969cd5a2018-04-20 16:27:47 -040043 , m_wantForceData(false)
44 , m_wantDigestSha256(false)
45 , m_wantFinalBlockId(false)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070046 , m_freshnessPeriod(-1)
47 , m_timeout(-1)
48 , m_isDataSent(false)
49 {
50 }
51
52 void
53 usage()
54 {
55 std::cout << "\n Usage:\n " << m_programName << " "
56 "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n"
57 " Reads payload from stdin and sends it to local NDN forwarder as a "
58 "single Data packet\n"
59 " [-f] - force, send Data without waiting for Interest\n"
60 " [-D] - use DigestSha256 signing method instead of "
61 "SignatureSha256WithRsa\n"
62 " [-i identity] - set identity to be used for signing\n"
63 " [-F] - set FinalBlockId to the last component of Name\n"
64 " [-x] - set FreshnessPeriod in time::milliseconds\n"
65 " [-w timeout] - set Timeout in time::milliseconds\n"
66 " [-h] - print help and exit\n"
67 " [-V] - print version and exit\n"
68 "\n";
69 exit(1);
70 }
71
72 void
73 setForceData()
74 {
Davide Pesavento969cd5a2018-04-20 16:27:47 -040075 m_wantForceData = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -070076 }
77
78 void
79 setUseDigestSha256()
80 {
Davide Pesavento969cd5a2018-04-20 16:27:47 -040081 m_wantDigestSha256 = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -070082 }
83
84 void
Davide Pesavento969cd5a2018-04-20 16:27:47 -040085 setIdentityName(const char* identityName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070086 {
Junxiao Shi0c75f992015-03-24 21:39:47 -070087 m_identityName = make_shared<Name>(identityName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -070088 }
89
90 void
91 setLastAsFinalBlockId()
92 {
Davide Pesavento969cd5a2018-04-20 16:27:47 -040093 m_wantFinalBlockId = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -070094 }
95
96 void
97 setFreshnessPeriod(int freshnessPeriod)
98 {
99 if (freshnessPeriod < 0)
100 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700101
102 m_freshnessPeriod = time::milliseconds(freshnessPeriod);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700103 }
104
105 void
106 setTimeout(int timeout)
107 {
108 if (timeout < 0)
109 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700110
111 m_timeout = time::milliseconds(timeout);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700112 }
113
114 void
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400115 setPrefixName(const char* prefixName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700116 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700117 m_prefixName = Name(prefixName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700118 }
119
Junxiao Shi0c75f992015-03-24 21:39:47 -0700120 time::milliseconds
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700121 getDefaultTimeout()
122 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700123 return time::seconds(10);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700124 }
125
Junxiao Shi7348ee72015-06-07 20:57:34 -0700126 shared_ptr<Data>
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700127 createDataPacket()
128 {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700129 auto dataPacket = make_shared<Data>(m_prefixName);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700130
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700131 std::stringstream payloadStream;
132 payloadStream << std::cin.rdbuf();
133 std::string payload = payloadStream.str();
Junxiao Shi7348ee72015-06-07 20:57:34 -0700134 dataPacket->setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
Junxiao Shi0c75f992015-03-24 21:39:47 -0700135
136 if (m_freshnessPeriod >= time::milliseconds::zero())
Junxiao Shi7348ee72015-06-07 20:57:34 -0700137 dataPacket->setFreshnessPeriod(m_freshnessPeriod);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700138
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400139 if (m_wantFinalBlockId) {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700140 if (!m_prefixName.empty())
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400141 dataPacket->setFinalBlock(m_prefixName.get(-1));
Junxiao Shi0c75f992015-03-24 21:39:47 -0700142 else {
143 std::cerr << "Name Provided Has 0 Components" << std::endl;
144 exit(1);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700145 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700146 }
147
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400148 if (m_wantDigestSha256) {
Eric Newberry38146c52015-06-22 15:11:30 -0700149 m_keyChain.sign(*dataPacket, signingWithSha256());
150 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700151 else {
Eric Newberry38146c52015-06-22 15:11:30 -0700152 if (m_identityName == nullptr) {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700153 m_keyChain.sign(*dataPacket);
Eric Newberry38146c52015-06-22 15:11:30 -0700154 }
155 else {
156 m_keyChain.sign(*dataPacket, signingByIdentity(*m_identityName));
157 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700158 }
159
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700160 return dataPacket;
161 }
162
163 void
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400164 onInterest(const Name& name, const Interest& interest, const shared_ptr<Data>& data)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700165 {
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400166 m_face.put(*data);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700167 m_isDataSent = true;
168 m_face.shutdown();
169 }
170
171 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700172 onRegisterFailed(const Name& prefix, const std::string& reason)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700173 {
174 std::cerr << "Prefix Registration Failure." << std::endl;
175 std::cerr << "Reason = " << reason << std::endl;
176 }
177
178 void
179 run()
180 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700181 try {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700182 shared_ptr<Data> dataPacket = createDataPacket();
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400183 if (m_wantForceData) {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700184 m_face.put(*dataPacket);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700185 m_isDataSent = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700186 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700187 else {
188 m_face.setInterestFilter(m_prefixName,
189 bind(&NdnPoke::onInterest, this, _1, _2, dataPacket),
190 RegisterPrefixSuccessCallback(),
191 bind(&NdnPoke::onRegisterFailed, this, _1, _2));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700192 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700193
194 if (m_timeout < time::milliseconds::zero())
195 m_face.processEvents(getDefaultTimeout());
196 else
197 m_face.processEvents(m_timeout);
198 }
Davide Pesaventoc0702702017-08-24 22:04:00 -0400199 catch (const std::exception& e) {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700200 std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
201 exit(1);
202 }
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700203 }
204
205 bool
206 isDataSent() const
207 {
208 return m_isDataSent;
209 }
210
211private:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700212 KeyChain m_keyChain;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700213 std::string m_programName;
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400214 bool m_wantForceData;
215 bool m_wantDigestSha256;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700216 shared_ptr<Name> m_identityName;
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400217 bool m_wantFinalBlockId;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700218 time::milliseconds m_freshnessPeriod;
219 time::milliseconds m_timeout;
220 Name m_prefixName;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700221 bool m_isDataSent;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700222 Face m_face;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700223};
224
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700225int
226main(int argc, char* argv[])
227{
Junxiao Shi0c75f992015-03-24 21:39:47 -0700228 NdnPoke program(argv[0]);
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400229
230 int option;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700231 while ((option = getopt(argc, argv, "hfDi:Fx:w:V")) != -1) {
232 switch (option) {
233 case 'h':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700234 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700235 break;
236 case 'f':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700237 program.setForceData();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700238 break;
239 case 'D':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700240 program.setUseDigestSha256();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700241 break;
242 case 'i':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700243 program.setIdentityName(optarg);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700244 break;
245 case 'F':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700246 program.setLastAsFinalBlockId();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700247 break;
248 case 'x':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700249 program.setFreshnessPeriod(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700250 break;
251 case 'w':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700252 program.setTimeout(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700253 break;
254 case 'V':
Junxiao Shi1753afb2015-04-17 20:59:50 -0700255 std::cout << "ndnpoke " << tools::VERSION << std::endl;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700256 return 0;
257 default:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700258 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700259 break;
260 }
261 }
262
263 argc -= optind;
264 argv += optind;
265
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400266 if (!argv[0])
Junxiao Shi0c75f992015-03-24 21:39:47 -0700267 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700268
Junxiao Shi0c75f992015-03-24 21:39:47 -0700269 program.setPrefixName(argv[0]);
270 program.run();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700271
Junxiao Shi0c75f992015-03-24 21:39:47 -0700272 if (program.isDataSent())
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700273 return 0;
274 else
275 return 1;
276}
Junxiao Shi0c75f992015-03-24 21:39:47 -0700277
278} // namespace peek
279} // namespace ndn
280
281int
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400282main(int argc, char* argv[])
Junxiao Shi0c75f992015-03-24 21:39:47 -0700283{
284 return ndn::peek::main(argc, argv);
285}