blob: adfe93ebed49daa06c019a8c9f8d5993fe6a3443 [file] [log] [blame]
Junxiao Shi2ac79d92015-03-23 11:16:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Davide Pesaventoc0702702017-08-24 22:04:00 -04003 * Copyright (c) 2014-2017, 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/>.
24 */
25/**
Junxiao Shi2ac79d92015-03-23 11:16:18 -070026 * Copyright (c) 2014, Regents of the University of California,
27 * Arizona Board of Regents,
28 * Colorado State University,
29 * University Pierre & Marie Curie, Sorbonne University,
30 * Washington University in St. Louis,
31 * Beijing Institute of Technology,
32 * The University of Memphis
33 *
34 * This file is part of NFD (Named Data Networking Forwarding Daemon).
35 * See AUTHORS.md for complete list of NFD authors and contributors.
36 *
37 * NFD is free software: you can redistribute it and/or modify it under the terms
38 * of the GNU General Public License as published by the Free Software Foundation,
39 * either version 3 of the License, or (at your option) any later version.
40 *
41 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
42 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
43 * PURPOSE. See the GNU General Public License for more details.
44 *
45 * You should have received a copy of the GNU General Public License along with
46 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
47 *
48 * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
49 */
50
Junxiao Shi1753afb2015-04-17 20:59:50 -070051#include "core/version.hpp"
Junxiao Shi2ac79d92015-03-23 11:16:18 -070052
Davide Pesaventoc0702702017-08-24 22:04:00 -040053#include <sstream>
54
Junxiao Shi0c75f992015-03-24 21:39:47 -070055namespace ndn {
56namespace peek {
Junxiao Shi2ac79d92015-03-23 11:16:18 -070057
Junxiao Shi0c75f992015-03-24 21:39:47 -070058class NdnPoke : boost::noncopyable
Junxiao Shi2ac79d92015-03-23 11:16:18 -070059{
60public:
61 explicit
Junxiao Shi0c75f992015-03-24 21:39:47 -070062 NdnPoke(char* programName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070063 : m_programName(programName)
64 , m_isForceDataSet(false)
65 , m_isUseDigestSha256Set(false)
66 , m_isLastAsFinalBlockIdSet(false)
67 , m_freshnessPeriod(-1)
68 , m_timeout(-1)
69 , m_isDataSent(false)
70 {
71 }
72
73 void
74 usage()
75 {
76 std::cout << "\n Usage:\n " << m_programName << " "
77 "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n"
78 " Reads payload from stdin and sends it to local NDN forwarder as a "
79 "single Data packet\n"
80 " [-f] - force, send Data without waiting for Interest\n"
81 " [-D] - use DigestSha256 signing method instead of "
82 "SignatureSha256WithRsa\n"
83 " [-i identity] - set identity to be used for signing\n"
84 " [-F] - set FinalBlockId to the last component of Name\n"
85 " [-x] - set FreshnessPeriod in time::milliseconds\n"
86 " [-w timeout] - set Timeout in time::milliseconds\n"
87 " [-h] - print help and exit\n"
88 " [-V] - print version and exit\n"
89 "\n";
90 exit(1);
91 }
92
93 void
94 setForceData()
95 {
96 m_isForceDataSet = true;
97 }
98
99 void
100 setUseDigestSha256()
101 {
102 m_isUseDigestSha256Set = true;
103 }
104
105 void
106 setIdentityName(char* identityName)
107 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700108 m_identityName = make_shared<Name>(identityName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700109 }
110
111 void
112 setLastAsFinalBlockId()
113 {
114 m_isLastAsFinalBlockIdSet = true;
115 }
116
117 void
118 setFreshnessPeriod(int freshnessPeriod)
119 {
120 if (freshnessPeriod < 0)
121 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700122
123 m_freshnessPeriod = time::milliseconds(freshnessPeriod);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700124 }
125
126 void
127 setTimeout(int timeout)
128 {
129 if (timeout < 0)
130 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700131
132 m_timeout = time::milliseconds(timeout);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700133 }
134
135 void
136 setPrefixName(char* prefixName)
137 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700138 m_prefixName = Name(prefixName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700139 }
140
Junxiao Shi0c75f992015-03-24 21:39:47 -0700141 time::milliseconds
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700142 getDefaultTimeout()
143 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700144 return time::seconds(10);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700145 }
146
Junxiao Shi7348ee72015-06-07 20:57:34 -0700147 shared_ptr<Data>
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700148 createDataPacket()
149 {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700150 auto dataPacket = make_shared<Data>(m_prefixName);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700151
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700152 std::stringstream payloadStream;
153 payloadStream << std::cin.rdbuf();
154 std::string payload = payloadStream.str();
Junxiao Shi7348ee72015-06-07 20:57:34 -0700155 dataPacket->setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
Junxiao Shi0c75f992015-03-24 21:39:47 -0700156
157 if (m_freshnessPeriod >= time::milliseconds::zero())
Junxiao Shi7348ee72015-06-07 20:57:34 -0700158 dataPacket->setFreshnessPeriod(m_freshnessPeriod);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700159
160 if (m_isLastAsFinalBlockIdSet) {
161 if (!m_prefixName.empty())
Junxiao Shi7348ee72015-06-07 20:57:34 -0700162 dataPacket->setFinalBlockId(m_prefixName.get(-1));
Junxiao Shi0c75f992015-03-24 21:39:47 -0700163 else {
164 std::cerr << "Name Provided Has 0 Components" << std::endl;
165 exit(1);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700166 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700167 }
168
Eric Newberry38146c52015-06-22 15:11:30 -0700169 if (m_isUseDigestSha256Set) {
170 m_keyChain.sign(*dataPacket, signingWithSha256());
171 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700172 else {
Eric Newberry38146c52015-06-22 15:11:30 -0700173 if (m_identityName == nullptr) {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700174 m_keyChain.sign(*dataPacket);
Eric Newberry38146c52015-06-22 15:11:30 -0700175 }
176 else {
177 m_keyChain.sign(*dataPacket, signingByIdentity(*m_identityName));
178 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700179 }
180
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700181 return dataPacket;
182 }
183
184 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700185 onInterest(const Name& name,
186 const Interest& interest,
Junxiao Shi7348ee72015-06-07 20:57:34 -0700187 shared_ptr<Data> dataPacket)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700188 {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700189 m_face.put(*dataPacket);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700190 m_isDataSent = true;
191 m_face.shutdown();
192 }
193
194 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700195 onRegisterFailed(const Name& prefix, const std::string& reason)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700196 {
197 std::cerr << "Prefix Registration Failure." << std::endl;
198 std::cerr << "Reason = " << reason << std::endl;
199 }
200
201 void
202 run()
203 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700204 try {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700205 shared_ptr<Data> dataPacket = createDataPacket();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700206 if (m_isForceDataSet) {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700207 m_face.put(*dataPacket);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700208 m_isDataSent = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700209 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700210 else {
211 m_face.setInterestFilter(m_prefixName,
212 bind(&NdnPoke::onInterest, this, _1, _2, dataPacket),
213 RegisterPrefixSuccessCallback(),
214 bind(&NdnPoke::onRegisterFailed, this, _1, _2));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700215 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700216
217 if (m_timeout < time::milliseconds::zero())
218 m_face.processEvents(getDefaultTimeout());
219 else
220 m_face.processEvents(m_timeout);
221 }
Davide Pesaventoc0702702017-08-24 22:04:00 -0400222 catch (const std::exception& e) {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700223 std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
224 exit(1);
225 }
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700226 }
227
228 bool
229 isDataSent() const
230 {
231 return m_isDataSent;
232 }
233
234private:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700235 KeyChain m_keyChain;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700236 std::string m_programName;
237 bool m_isForceDataSet;
238 bool m_isUseDigestSha256Set;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700239 shared_ptr<Name> m_identityName;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700240 bool m_isLastAsFinalBlockIdSet;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700241 time::milliseconds m_freshnessPeriod;
242 time::milliseconds m_timeout;
243 Name m_prefixName;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700244 bool m_isDataSent;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700245 Face m_face;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700246};
247
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700248int
249main(int argc, char* argv[])
250{
251 int option;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700252 NdnPoke program(argv[0]);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700253 while ((option = getopt(argc, argv, "hfDi:Fx:w:V")) != -1) {
254 switch (option) {
255 case 'h':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700256 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700257 break;
258 case 'f':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700259 program.setForceData();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700260 break;
261 case 'D':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700262 program.setUseDigestSha256();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700263 break;
264 case 'i':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700265 program.setIdentityName(optarg);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700266 break;
267 case 'F':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700268 program.setLastAsFinalBlockId();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700269 break;
270 case 'x':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700271 program.setFreshnessPeriod(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700272 break;
273 case 'w':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700274 program.setTimeout(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700275 break;
276 case 'V':
Junxiao Shi1753afb2015-04-17 20:59:50 -0700277 std::cout << "ndnpoke " << tools::VERSION << std::endl;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700278 return 0;
279 default:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700280 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700281 break;
282 }
283 }
284
285 argc -= optind;
286 argv += optind;
287
288 if (argv[0] == 0)
Junxiao Shi0c75f992015-03-24 21:39:47 -0700289 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700290
Junxiao Shi0c75f992015-03-24 21:39:47 -0700291 program.setPrefixName(argv[0]);
292 program.run();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700293
Junxiao Shi0c75f992015-03-24 21:39:47 -0700294 if (program.isDataSent())
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700295 return 0;
296 else
297 return 1;
298}
Junxiao Shi0c75f992015-03-24 21:39:47 -0700299
300} // namespace peek
301} // namespace ndn
302
303int
304main(int argc, char** argv)
305{
306 return ndn::peek::main(argc, argv);
307}