blob: 9ef3c53c5b0aa9348f36c55089b5d36fcfc92679 [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
Junxiao Shi1753afb2015-04-17 20:59:50 -070051#include "core/version.hpp"
Junxiao Shi2ac79d92015-03-23 11:16:18 -070052
Junxiao Shi0c75f992015-03-24 21:39:47 -070053namespace ndn {
54namespace peek {
Junxiao Shi2ac79d92015-03-23 11:16:18 -070055
Junxiao Shi0c75f992015-03-24 21:39:47 -070056class NdnPoke : boost::noncopyable
Junxiao Shi2ac79d92015-03-23 11:16:18 -070057{
58public:
59 explicit
Junxiao Shi0c75f992015-03-24 21:39:47 -070060 NdnPoke(char* programName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070061 : m_programName(programName)
62 , m_isForceDataSet(false)
63 , m_isUseDigestSha256Set(false)
64 , m_isLastAsFinalBlockIdSet(false)
65 , m_freshnessPeriod(-1)
66 , m_timeout(-1)
67 , m_isDataSent(false)
68 {
69 }
70
71 void
72 usage()
73 {
74 std::cout << "\n Usage:\n " << m_programName << " "
75 "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n"
76 " Reads payload from stdin and sends it to local NDN forwarder as a "
77 "single Data packet\n"
78 " [-f] - force, send Data without waiting for Interest\n"
79 " [-D] - use DigestSha256 signing method instead of "
80 "SignatureSha256WithRsa\n"
81 " [-i identity] - set identity to be used for signing\n"
82 " [-F] - set FinalBlockId to the last component of Name\n"
83 " [-x] - set FreshnessPeriod in time::milliseconds\n"
84 " [-w timeout] - set Timeout in time::milliseconds\n"
85 " [-h] - print help and exit\n"
86 " [-V] - print version and exit\n"
87 "\n";
88 exit(1);
89 }
90
91 void
92 setForceData()
93 {
94 m_isForceDataSet = true;
95 }
96
97 void
98 setUseDigestSha256()
99 {
100 m_isUseDigestSha256Set = true;
101 }
102
103 void
104 setIdentityName(char* identityName)
105 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700106 m_identityName = make_shared<Name>(identityName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700107 }
108
109 void
110 setLastAsFinalBlockId()
111 {
112 m_isLastAsFinalBlockIdSet = true;
113 }
114
115 void
116 setFreshnessPeriod(int freshnessPeriod)
117 {
118 if (freshnessPeriod < 0)
119 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700120
121 m_freshnessPeriod = time::milliseconds(freshnessPeriod);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700122 }
123
124 void
125 setTimeout(int timeout)
126 {
127 if (timeout < 0)
128 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700129
130 m_timeout = time::milliseconds(timeout);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700131 }
132
133 void
134 setPrefixName(char* prefixName)
135 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700136 m_prefixName = Name(prefixName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700137 }
138
Junxiao Shi0c75f992015-03-24 21:39:47 -0700139 time::milliseconds
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700140 getDefaultTimeout()
141 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700142 return time::seconds(10);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700143 }
144
Junxiao Shi7348ee72015-06-07 20:57:34 -0700145 shared_ptr<Data>
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700146 createDataPacket()
147 {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700148 auto dataPacket = make_shared<Data>(m_prefixName);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700149
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700150 std::stringstream payloadStream;
151 payloadStream << std::cin.rdbuf();
152 std::string payload = payloadStream.str();
Junxiao Shi7348ee72015-06-07 20:57:34 -0700153 dataPacket->setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
Junxiao Shi0c75f992015-03-24 21:39:47 -0700154
155 if (m_freshnessPeriod >= time::milliseconds::zero())
Junxiao Shi7348ee72015-06-07 20:57:34 -0700156 dataPacket->setFreshnessPeriod(m_freshnessPeriod);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700157
158 if (m_isLastAsFinalBlockIdSet) {
159 if (!m_prefixName.empty())
Junxiao Shi7348ee72015-06-07 20:57:34 -0700160 dataPacket->setFinalBlockId(m_prefixName.get(-1));
Junxiao Shi0c75f992015-03-24 21:39:47 -0700161 else {
162 std::cerr << "Name Provided Has 0 Components" << std::endl;
163 exit(1);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700164 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700165 }
166
Eric Newberry38146c52015-06-22 15:11:30 -0700167 if (m_isUseDigestSha256Set) {
168 m_keyChain.sign(*dataPacket, signingWithSha256());
169 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700170 else {
Eric Newberry38146c52015-06-22 15:11:30 -0700171 if (m_identityName == nullptr) {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700172 m_keyChain.sign(*dataPacket);
Eric Newberry38146c52015-06-22 15:11:30 -0700173 }
174 else {
175 m_keyChain.sign(*dataPacket, signingByIdentity(*m_identityName));
176 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700177 }
178
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700179 return dataPacket;
180 }
181
182 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700183 onInterest(const Name& name,
184 const Interest& interest,
Junxiao Shi7348ee72015-06-07 20:57:34 -0700185 shared_ptr<Data> dataPacket)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700186 {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700187 m_face.put(*dataPacket);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700188 m_isDataSent = true;
189 m_face.shutdown();
190 }
191
192 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700193 onRegisterFailed(const Name& prefix, const std::string& reason)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700194 {
195 std::cerr << "Prefix Registration Failure." << std::endl;
196 std::cerr << "Reason = " << reason << std::endl;
197 }
198
199 void
200 run()
201 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700202 try {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700203 shared_ptr<Data> dataPacket = createDataPacket();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700204 if (m_isForceDataSet) {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700205 m_face.put(*dataPacket);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700206 m_isDataSent = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700207 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700208 else {
209 m_face.setInterestFilter(m_prefixName,
210 bind(&NdnPoke::onInterest, this, _1, _2, dataPacket),
211 RegisterPrefixSuccessCallback(),
212 bind(&NdnPoke::onRegisterFailed, this, _1, _2));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700213 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700214
215 if (m_timeout < time::milliseconds::zero())
216 m_face.processEvents(getDefaultTimeout());
217 else
218 m_face.processEvents(m_timeout);
219 }
220 catch (std::exception& e) {
221 std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
222 exit(1);
223 }
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700224 }
225
226 bool
227 isDataSent() const
228 {
229 return m_isDataSent;
230 }
231
232private:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700233 KeyChain m_keyChain;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700234 std::string m_programName;
235 bool m_isForceDataSet;
236 bool m_isUseDigestSha256Set;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700237 shared_ptr<Name> m_identityName;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700238 bool m_isLastAsFinalBlockIdSet;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700239 time::milliseconds m_freshnessPeriod;
240 time::milliseconds m_timeout;
241 Name m_prefixName;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700242 bool m_isDataSent;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700243 Face m_face;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700244};
245
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700246int
247main(int argc, char* argv[])
248{
249 int option;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700250 NdnPoke program(argv[0]);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700251 while ((option = getopt(argc, argv, "hfDi:Fx:w:V")) != -1) {
252 switch (option) {
253 case 'h':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700254 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700255 break;
256 case 'f':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700257 program.setForceData();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700258 break;
259 case 'D':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700260 program.setUseDigestSha256();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700261 break;
262 case 'i':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700263 program.setIdentityName(optarg);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700264 break;
265 case 'F':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700266 program.setLastAsFinalBlockId();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700267 break;
268 case 'x':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700269 program.setFreshnessPeriod(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700270 break;
271 case 'w':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700272 program.setTimeout(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700273 break;
274 case 'V':
Junxiao Shi1753afb2015-04-17 20:59:50 -0700275 std::cout << "ndnpoke " << tools::VERSION << std::endl;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700276 return 0;
277 default:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700278 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700279 break;
280 }
281 }
282
283 argc -= optind;
284 argv += optind;
285
286 if (argv[0] == 0)
Junxiao Shi0c75f992015-03-24 21:39:47 -0700287 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700288
Junxiao Shi0c75f992015-03-24 21:39:47 -0700289 program.setPrefixName(argv[0]);
290 program.run();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700291
Junxiao Shi0c75f992015-03-24 21:39:47 -0700292 if (program.isDataSent())
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700293 return 0;
294 else
295 return 1;
296}
Junxiao Shi0c75f992015-03-24 21:39:47 -0700297
298} // namespace peek
299} // namespace ndn
300
301int
302main(int argc, char** argv)
303{
304 return ndn::peek::main(argc, argv);
305}