blob: 9f285a0069167e64def334172ebc621cd9d3dc5e [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
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700167 if (m_isUseDigestSha256Set)
Junxiao Shi7348ee72015-06-07 20:57:34 -0700168 m_keyChain.signWithSha256(*dataPacket);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700169 else {
170 if (m_identityName == nullptr)
Junxiao Shi7348ee72015-06-07 20:57:34 -0700171 m_keyChain.sign(*dataPacket);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700172 else
Junxiao Shi7348ee72015-06-07 20:57:34 -0700173 m_keyChain.signByIdentity(*dataPacket, *m_identityName);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700174 }
175
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700176 return dataPacket;
177 }
178
179 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700180 onInterest(const Name& name,
181 const Interest& interest,
Junxiao Shi7348ee72015-06-07 20:57:34 -0700182 shared_ptr<Data> dataPacket)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700183 {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700184 m_face.put(*dataPacket);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700185 m_isDataSent = true;
186 m_face.shutdown();
187 }
188
189 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700190 onRegisterFailed(const Name& prefix, const std::string& reason)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700191 {
192 std::cerr << "Prefix Registration Failure." << std::endl;
193 std::cerr << "Reason = " << reason << std::endl;
194 }
195
196 void
197 run()
198 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700199 try {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700200 shared_ptr<Data> dataPacket = createDataPacket();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700201 if (m_isForceDataSet) {
Junxiao Shi7348ee72015-06-07 20:57:34 -0700202 m_face.put(*dataPacket);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700203 m_isDataSent = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700204 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700205 else {
206 m_face.setInterestFilter(m_prefixName,
207 bind(&NdnPoke::onInterest, this, _1, _2, dataPacket),
208 RegisterPrefixSuccessCallback(),
209 bind(&NdnPoke::onRegisterFailed, this, _1, _2));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700210 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700211
212 if (m_timeout < time::milliseconds::zero())
213 m_face.processEvents(getDefaultTimeout());
214 else
215 m_face.processEvents(m_timeout);
216 }
217 catch (std::exception& e) {
218 std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
219 exit(1);
220 }
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700221 }
222
223 bool
224 isDataSent() const
225 {
226 return m_isDataSent;
227 }
228
229private:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700230 KeyChain m_keyChain;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700231 std::string m_programName;
232 bool m_isForceDataSet;
233 bool m_isUseDigestSha256Set;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700234 shared_ptr<Name> m_identityName;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700235 bool m_isLastAsFinalBlockIdSet;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700236 time::milliseconds m_freshnessPeriod;
237 time::milliseconds m_timeout;
238 Name m_prefixName;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700239 bool m_isDataSent;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700240 Face m_face;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700241};
242
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700243int
244main(int argc, char* argv[])
245{
246 int option;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700247 NdnPoke program(argv[0]);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700248 while ((option = getopt(argc, argv, "hfDi:Fx:w:V")) != -1) {
249 switch (option) {
250 case 'h':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700251 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700252 break;
253 case 'f':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700254 program.setForceData();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700255 break;
256 case 'D':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700257 program.setUseDigestSha256();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700258 break;
259 case 'i':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700260 program.setIdentityName(optarg);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700261 break;
262 case 'F':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700263 program.setLastAsFinalBlockId();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700264 break;
265 case 'x':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700266 program.setFreshnessPeriod(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700267 break;
268 case 'w':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700269 program.setTimeout(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700270 break;
271 case 'V':
Junxiao Shi1753afb2015-04-17 20:59:50 -0700272 std::cout << "ndnpoke " << tools::VERSION << std::endl;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700273 return 0;
274 default:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700275 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700276 break;
277 }
278 }
279
280 argc -= optind;
281 argv += optind;
282
283 if (argv[0] == 0)
Junxiao Shi0c75f992015-03-24 21:39:47 -0700284 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700285
Junxiao Shi0c75f992015-03-24 21:39:47 -0700286 program.setPrefixName(argv[0]);
287 program.run();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700288
Junxiao Shi0c75f992015-03-24 21:39:47 -0700289 if (program.isDataSent())
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700290 return 0;
291 else
292 return 1;
293}
Junxiao Shi0c75f992015-03-24 21:39:47 -0700294
295} // namespace peek
296} // namespace ndn
297
298int
299main(int argc, char** argv)
300{
301 return ndn::peek::main(argc, argv);
302}