blob: 73e4a5635214f00e36550b692fef2f29220542d3 [file] [log] [blame]
Junxiao Shi2ac79d92015-03-23 11:16:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi1688ded2015-03-29 10:09:26 -07003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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
51#include "version.hpp"
52
53#include <boost/noncopyable.hpp>
54
55#include <ndn-cxx/face.hpp>
56#include <ndn-cxx/security/key-chain.hpp>
57
Junxiao Shi0c75f992015-03-24 21:39:47 -070058namespace ndn {
59namespace peek {
Junxiao Shi2ac79d92015-03-23 11:16:18 -070060
Junxiao Shi0c75f992015-03-24 21:39:47 -070061class NdnPoke : boost::noncopyable
Junxiao Shi2ac79d92015-03-23 11:16:18 -070062{
63public:
64 explicit
Junxiao Shi0c75f992015-03-24 21:39:47 -070065 NdnPoke(char* programName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070066 : m_programName(programName)
67 , m_isForceDataSet(false)
68 , m_isUseDigestSha256Set(false)
69 , m_isLastAsFinalBlockIdSet(false)
70 , m_freshnessPeriod(-1)
71 , m_timeout(-1)
72 , m_isDataSent(false)
73 {
74 }
75
76 void
77 usage()
78 {
79 std::cout << "\n Usage:\n " << m_programName << " "
80 "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n"
81 " Reads payload from stdin and sends it to local NDN forwarder as a "
82 "single Data packet\n"
83 " [-f] - force, send Data without waiting for Interest\n"
84 " [-D] - use DigestSha256 signing method instead of "
85 "SignatureSha256WithRsa\n"
86 " [-i identity] - set identity to be used for signing\n"
87 " [-F] - set FinalBlockId to the last component of Name\n"
88 " [-x] - set FreshnessPeriod in time::milliseconds\n"
89 " [-w timeout] - set Timeout in time::milliseconds\n"
90 " [-h] - print help and exit\n"
91 " [-V] - print version and exit\n"
92 "\n";
93 exit(1);
94 }
95
96 void
97 setForceData()
98 {
99 m_isForceDataSet = true;
100 }
101
102 void
103 setUseDigestSha256()
104 {
105 m_isUseDigestSha256Set = true;
106 }
107
108 void
109 setIdentityName(char* identityName)
110 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700111 m_identityName = make_shared<Name>(identityName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700112 }
113
114 void
115 setLastAsFinalBlockId()
116 {
117 m_isLastAsFinalBlockIdSet = true;
118 }
119
120 void
121 setFreshnessPeriod(int freshnessPeriod)
122 {
123 if (freshnessPeriod < 0)
124 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700125
126 m_freshnessPeriod = time::milliseconds(freshnessPeriod);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700127 }
128
129 void
130 setTimeout(int timeout)
131 {
132 if (timeout < 0)
133 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700134
135 m_timeout = time::milliseconds(timeout);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700136 }
137
138 void
139 setPrefixName(char* prefixName)
140 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700141 m_prefixName = Name(prefixName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700142 }
143
Junxiao Shi0c75f992015-03-24 21:39:47 -0700144 time::milliseconds
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700145 getDefaultTimeout()
146 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700147 return time::seconds(10);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700148 }
149
Junxiao Shi0c75f992015-03-24 21:39:47 -0700150 Data
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700151 createDataPacket()
152 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700153 Data dataPacket(m_prefixName);
154
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700155 std::stringstream payloadStream;
156 payloadStream << std::cin.rdbuf();
157 std::string payload = payloadStream.str();
158 dataPacket.setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
Junxiao Shi0c75f992015-03-24 21:39:47 -0700159
160 if (m_freshnessPeriod >= time::milliseconds::zero())
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700161 dataPacket.setFreshnessPeriod(m_freshnessPeriod);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700162
163 if (m_isLastAsFinalBlockIdSet) {
164 if (!m_prefixName.empty())
165 dataPacket.setFinalBlockId(m_prefixName.get(-1));
166 else {
167 std::cerr << "Name Provided Has 0 Components" << std::endl;
168 exit(1);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700169 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700170 }
171
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700172 if (m_isUseDigestSha256Set)
173 m_keyChain.signWithSha256(dataPacket);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700174 else {
175 if (m_identityName == nullptr)
176 m_keyChain.sign(dataPacket);
177 else
178 m_keyChain.signByIdentity(dataPacket, *m_identityName);
179 }
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,
187 const Data& dataPacket)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700188 {
189 m_face.put(dataPacket);
190 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 {
205 Data dataPacket = createDataPacket();
206 if (m_isForceDataSet) {
207 m_face.put(dataPacket);
208 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 }
222 catch (std::exception& e) {
223 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':
277 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
278 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}