blob: ceb49b34d0bc76659bfe1fe7abdf374c8f8489d8 [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 Pesaventoc0702702017-08-24 22:04:00 -040030#include <sstream>
31
Junxiao Shi0c75f992015-03-24 21:39:47 -070032namespace ndn {
33namespace peek {
Junxiao Shi2ac79d92015-03-23 11:16:18 -070034
Junxiao Shi0c75f992015-03-24 21:39:47 -070035class NdnPoke : boost::noncopyable
Junxiao Shi2ac79d92015-03-23 11:16:18 -070036{
37public:
38 explicit
Davide Pesavento969cd5a2018-04-20 16:27:47 -040039 NdnPoke(const char* programName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070040 : m_programName(programName)
Davide Pesavento969cd5a2018-04-20 16:27:47 -040041 , m_wantForceData(false)
42 , m_wantDigestSha256(false)
43 , m_wantFinalBlockId(false)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070044 , m_freshnessPeriod(-1)
45 , m_timeout(-1)
46 , m_isDataSent(false)
47 {
48 }
49
50 void
51 usage()
52 {
53 std::cout << "\n Usage:\n " << m_programName << " "
54 "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n"
55 " Reads payload from stdin and sends it to local NDN forwarder as a "
56 "single Data packet\n"
57 " [-f] - force, send Data without waiting for Interest\n"
58 " [-D] - use DigestSha256 signing method instead of "
59 "SignatureSha256WithRsa\n"
60 " [-i identity] - set identity to be used for signing\n"
61 " [-F] - set FinalBlockId to the last component of Name\n"
62 " [-x] - set FreshnessPeriod in time::milliseconds\n"
63 " [-w timeout] - set Timeout in time::milliseconds\n"
64 " [-h] - print help and exit\n"
65 " [-V] - print version and exit\n"
66 "\n";
67 exit(1);
68 }
69
70 void
71 setForceData()
72 {
Davide Pesavento969cd5a2018-04-20 16:27:47 -040073 m_wantForceData = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -070074 }
75
76 void
77 setUseDigestSha256()
78 {
Davide Pesavento969cd5a2018-04-20 16:27:47 -040079 m_wantDigestSha256 = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -070080 }
81
82 void
Davide Pesavento969cd5a2018-04-20 16:27:47 -040083 setIdentityName(const char* identityName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070084 {
Junxiao Shi0c75f992015-03-24 21:39:47 -070085 m_identityName = make_shared<Name>(identityName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -070086 }
87
88 void
89 setLastAsFinalBlockId()
90 {
Davide Pesavento969cd5a2018-04-20 16:27:47 -040091 m_wantFinalBlockId = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -070092 }
93
94 void
95 setFreshnessPeriod(int freshnessPeriod)
96 {
97 if (freshnessPeriod < 0)
98 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -070099
100 m_freshnessPeriod = time::milliseconds(freshnessPeriod);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700101 }
102
103 void
104 setTimeout(int timeout)
105 {
106 if (timeout < 0)
107 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700108
109 m_timeout = time::milliseconds(timeout);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700110 }
111
112 void
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400113 setPrefixName(const char* prefixName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700114 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700115 m_prefixName = Name(prefixName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700116 }
117
Junxiao Shi0c75f992015-03-24 21:39:47 -0700118 time::milliseconds
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700119 getDefaultTimeout()
120 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700121 return time::seconds(10);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700122 }
123
Junxiao Shi7348ee72015-06-07 20:57:34 -0700124 shared_ptr<Data>
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700125 createDataPacket()
126 {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700127 auto dataPacket = make_shared<Data>(m_prefixName);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700128
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700129 std::stringstream payloadStream;
130 payloadStream << std::cin.rdbuf();
131 std::string payload = payloadStream.str();
Junxiao Shi7348ee72015-06-07 20:57:34 -0700132 dataPacket->setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
Junxiao Shi0c75f992015-03-24 21:39:47 -0700133
134 if (m_freshnessPeriod >= time::milliseconds::zero())
Junxiao Shi7348ee72015-06-07 20:57:34 -0700135 dataPacket->setFreshnessPeriod(m_freshnessPeriod);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700136
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400137 if (m_wantFinalBlockId) {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700138 if (!m_prefixName.empty())
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400139 dataPacket->setFinalBlock(m_prefixName.get(-1));
Junxiao Shi0c75f992015-03-24 21:39:47 -0700140 else {
141 std::cerr << "Name Provided Has 0 Components" << std::endl;
142 exit(1);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700143 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700144 }
145
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400146 if (m_wantDigestSha256) {
Eric Newberry38146c52015-06-22 15:11:30 -0700147 m_keyChain.sign(*dataPacket, signingWithSha256());
148 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700149 else {
Eric Newberry38146c52015-06-22 15:11:30 -0700150 if (m_identityName == nullptr) {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700151 m_keyChain.sign(*dataPacket);
Eric Newberry38146c52015-06-22 15:11:30 -0700152 }
153 else {
154 m_keyChain.sign(*dataPacket, signingByIdentity(*m_identityName));
155 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700156 }
157
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700158 return dataPacket;
159 }
160
161 void
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400162 onInterest(const Name& name, const Interest& interest, const shared_ptr<Data>& data)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700163 {
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400164 m_face.put(*data);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700165 m_isDataSent = true;
166 m_face.shutdown();
167 }
168
169 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700170 onRegisterFailed(const Name& prefix, const std::string& reason)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700171 {
172 std::cerr << "Prefix Registration Failure." << std::endl;
173 std::cerr << "Reason = " << reason << std::endl;
174 }
175
176 void
177 run()
178 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700179 try {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700180 shared_ptr<Data> dataPacket = createDataPacket();
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400181 if (m_wantForceData) {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700182 m_face.put(*dataPacket);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700183 m_isDataSent = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700184 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700185 else {
186 m_face.setInterestFilter(m_prefixName,
187 bind(&NdnPoke::onInterest, this, _1, _2, dataPacket),
188 RegisterPrefixSuccessCallback(),
189 bind(&NdnPoke::onRegisterFailed, this, _1, _2));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700190 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700191
192 if (m_timeout < time::milliseconds::zero())
193 m_face.processEvents(getDefaultTimeout());
194 else
195 m_face.processEvents(m_timeout);
196 }
Davide Pesaventoc0702702017-08-24 22:04:00 -0400197 catch (const std::exception& e) {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700198 std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
199 exit(1);
200 }
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700201 }
202
203 bool
204 isDataSent() const
205 {
206 return m_isDataSent;
207 }
208
209private:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700210 KeyChain m_keyChain;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700211 std::string m_programName;
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400212 bool m_wantForceData;
213 bool m_wantDigestSha256;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700214 shared_ptr<Name> m_identityName;
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400215 bool m_wantFinalBlockId;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700216 time::milliseconds m_freshnessPeriod;
217 time::milliseconds m_timeout;
218 Name m_prefixName;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700219 bool m_isDataSent;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700220 Face m_face;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700221};
222
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700223int
224main(int argc, char* argv[])
225{
Junxiao Shi0c75f992015-03-24 21:39:47 -0700226 NdnPoke program(argv[0]);
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400227
228 int option;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700229 while ((option = getopt(argc, argv, "hfDi:Fx:w:V")) != -1) {
230 switch (option) {
231 case 'h':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700232 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700233 break;
234 case 'f':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700235 program.setForceData();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700236 break;
237 case 'D':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700238 program.setUseDigestSha256();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700239 break;
240 case 'i':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700241 program.setIdentityName(optarg);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700242 break;
243 case 'F':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700244 program.setLastAsFinalBlockId();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700245 break;
246 case 'x':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700247 program.setFreshnessPeriod(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700248 break;
249 case 'w':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700250 program.setTimeout(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700251 break;
252 case 'V':
Junxiao Shi1753afb2015-04-17 20:59:50 -0700253 std::cout << "ndnpoke " << tools::VERSION << std::endl;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700254 return 0;
255 default:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700256 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700257 break;
258 }
259 }
260
261 argc -= optind;
262 argv += optind;
263
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400264 if (!argv[0])
Junxiao Shi0c75f992015-03-24 21:39:47 -0700265 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700266
Junxiao Shi0c75f992015-03-24 21:39:47 -0700267 program.setPrefixName(argv[0]);
268 program.run();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700269
Junxiao Shi0c75f992015-03-24 21:39:47 -0700270 if (program.isDataSent())
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700271 return 0;
272 else
273 return 1;
274}
Junxiao Shi0c75f992015-03-24 21:39:47 -0700275
276} // namespace peek
277} // namespace ndn
278
279int
Davide Pesavento969cd5a2018-04-20 16:27:47 -0400280main(int argc, char* argv[])
Junxiao Shi0c75f992015-03-24 21:39:47 -0700281{
282 return ndn::peek::main(argc, argv);
283}