blob: a4a635d0e73e48c808475c487a7360783e3b1b59 [file] [log] [blame]
Junxiao Shi2ac79d92015-03-23 11:16:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014, 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 NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD 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 * NFD 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 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 *
25 * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
26 */
27
28#include "version.hpp"
29
30#include <boost/noncopyable.hpp>
31
32#include <ndn-cxx/face.hpp>
33#include <ndn-cxx/security/key-chain.hpp>
34
Junxiao Shi0c75f992015-03-24 21:39:47 -070035namespace ndn {
36namespace peek {
Junxiao Shi2ac79d92015-03-23 11:16:18 -070037
Junxiao Shi0c75f992015-03-24 21:39:47 -070038class NdnPoke : boost::noncopyable
Junxiao Shi2ac79d92015-03-23 11:16:18 -070039{
40public:
41 explicit
Junxiao Shi0c75f992015-03-24 21:39:47 -070042 NdnPoke(char* programName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070043 : m_programName(programName)
44 , m_isForceDataSet(false)
45 , m_isUseDigestSha256Set(false)
46 , m_isLastAsFinalBlockIdSet(false)
47 , m_freshnessPeriod(-1)
48 , m_timeout(-1)
49 , m_isDataSent(false)
50 {
51 }
52
53 void
54 usage()
55 {
56 std::cout << "\n Usage:\n " << m_programName << " "
57 "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n"
58 " Reads payload from stdin and sends it to local NDN forwarder as a "
59 "single Data packet\n"
60 " [-f] - force, send Data without waiting for Interest\n"
61 " [-D] - use DigestSha256 signing method instead of "
62 "SignatureSha256WithRsa\n"
63 " [-i identity] - set identity to be used for signing\n"
64 " [-F] - set FinalBlockId to the last component of Name\n"
65 " [-x] - set FreshnessPeriod in time::milliseconds\n"
66 " [-w timeout] - set Timeout in time::milliseconds\n"
67 " [-h] - print help and exit\n"
68 " [-V] - print version and exit\n"
69 "\n";
70 exit(1);
71 }
72
73 void
74 setForceData()
75 {
76 m_isForceDataSet = true;
77 }
78
79 void
80 setUseDigestSha256()
81 {
82 m_isUseDigestSha256Set = true;
83 }
84
85 void
86 setIdentityName(char* identityName)
87 {
Junxiao Shi0c75f992015-03-24 21:39:47 -070088 m_identityName = make_shared<Name>(identityName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -070089 }
90
91 void
92 setLastAsFinalBlockId()
93 {
94 m_isLastAsFinalBlockIdSet = true;
95 }
96
97 void
98 setFreshnessPeriod(int freshnessPeriod)
99 {
100 if (freshnessPeriod < 0)
101 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700102
103 m_freshnessPeriod = time::milliseconds(freshnessPeriod);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700104 }
105
106 void
107 setTimeout(int timeout)
108 {
109 if (timeout < 0)
110 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700111
112 m_timeout = time::milliseconds(timeout);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700113 }
114
115 void
116 setPrefixName(char* prefixName)
117 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700118 m_prefixName = Name(prefixName);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700119 }
120
Junxiao Shi0c75f992015-03-24 21:39:47 -0700121 time::milliseconds
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700122 getDefaultTimeout()
123 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700124 return time::seconds(10);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700125 }
126
Junxiao Shi0c75f992015-03-24 21:39:47 -0700127 Data
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700128 createDataPacket()
129 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700130 Data dataPacket(m_prefixName);
131
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700132 std::stringstream payloadStream;
133 payloadStream << std::cin.rdbuf();
134 std::string payload = payloadStream.str();
135 dataPacket.setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
Junxiao Shi0c75f992015-03-24 21:39:47 -0700136
137 if (m_freshnessPeriod >= time::milliseconds::zero())
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700138 dataPacket.setFreshnessPeriod(m_freshnessPeriod);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700139
140 if (m_isLastAsFinalBlockIdSet) {
141 if (!m_prefixName.empty())
142 dataPacket.setFinalBlockId(m_prefixName.get(-1));
143 else {
144 std::cerr << "Name Provided Has 0 Components" << std::endl;
145 exit(1);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700146 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700147 }
148
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700149 if (m_isUseDigestSha256Set)
150 m_keyChain.signWithSha256(dataPacket);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700151 else {
152 if (m_identityName == nullptr)
153 m_keyChain.sign(dataPacket);
154 else
155 m_keyChain.signByIdentity(dataPacket, *m_identityName);
156 }
157
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700158 return dataPacket;
159 }
160
161 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700162 onInterest(const Name& name,
163 const Interest& interest,
164 const Data& dataPacket)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700165 {
166 m_face.put(dataPacket);
167 m_isDataSent = true;
168 m_face.shutdown();
169 }
170
171 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700172 onRegisterFailed(const Name& prefix, const std::string& reason)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700173 {
174 std::cerr << "Prefix Registration Failure." << std::endl;
175 std::cerr << "Reason = " << reason << std::endl;
176 }
177
178 void
179 run()
180 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700181 try {
182 Data dataPacket = createDataPacket();
183 if (m_isForceDataSet) {
184 m_face.put(dataPacket);
185 m_isDataSent = true;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700186 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700187 else {
188 m_face.setInterestFilter(m_prefixName,
189 bind(&NdnPoke::onInterest, this, _1, _2, dataPacket),
190 RegisterPrefixSuccessCallback(),
191 bind(&NdnPoke::onRegisterFailed, this, _1, _2));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700192 }
Junxiao Shi0c75f992015-03-24 21:39:47 -0700193
194 if (m_timeout < time::milliseconds::zero())
195 m_face.processEvents(getDefaultTimeout());
196 else
197 m_face.processEvents(m_timeout);
198 }
199 catch (std::exception& e) {
200 std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
201 exit(1);
202 }
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700203 }
204
205 bool
206 isDataSent() const
207 {
208 return m_isDataSent;
209 }
210
211private:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700212 KeyChain m_keyChain;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700213 std::string m_programName;
214 bool m_isForceDataSet;
215 bool m_isUseDigestSha256Set;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700216 shared_ptr<Name> m_identityName;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700217 bool m_isLastAsFinalBlockIdSet;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700218 time::milliseconds m_freshnessPeriod;
219 time::milliseconds m_timeout;
220 Name m_prefixName;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700221 bool m_isDataSent;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700222 Face m_face;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700223};
224
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700225int
226main(int argc, char* argv[])
227{
228 int option;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700229 NdnPoke program(argv[0]);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700230 while ((option = getopt(argc, argv, "hfDi:Fx:w:V")) != -1) {
231 switch (option) {
232 case 'h':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700233 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700234 break;
235 case 'f':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700236 program.setForceData();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700237 break;
238 case 'D':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700239 program.setUseDigestSha256();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700240 break;
241 case 'i':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700242 program.setIdentityName(optarg);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700243 break;
244 case 'F':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700245 program.setLastAsFinalBlockId();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700246 break;
247 case 'x':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700248 program.setFreshnessPeriod(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700249 break;
250 case 'w':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700251 program.setTimeout(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700252 break;
253 case 'V':
254 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
255 return 0;
256 default:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700257 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700258 break;
259 }
260 }
261
262 argc -= optind;
263 argv += optind;
264
265 if (argv[0] == 0)
Junxiao Shi0c75f992015-03-24 21:39:47 -0700266 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700267
Junxiao Shi0c75f992015-03-24 21:39:47 -0700268 program.setPrefixName(argv[0]);
269 program.run();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700270
Junxiao Shi0c75f992015-03-24 21:39:47 -0700271 if (program.isDataSent())
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700272 return 0;
273 else
274 return 1;
275}
Junxiao Shi0c75f992015-03-24 21:39:47 -0700276
277} // namespace peek
278} // namespace ndn
279
280int
281main(int argc, char** argv)
282{
283 return ndn::peek::main(argc, argv);
284}