blob: 45db7021da812d5228413ae3f4b79f8b530bef34 [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
35namespace ndntlvpoke {
36
37class NdnTlvPoke : boost::noncopyable
38{
39public:
40 explicit
41 NdnTlvPoke(char* programName)
42 : m_programName(programName)
43 , m_isForceDataSet(false)
44 , m_isUseDigestSha256Set(false)
45 , m_isLastAsFinalBlockIdSet(false)
46 , m_freshnessPeriod(-1)
47 , m_timeout(-1)
48 , m_isDataSent(false)
49 {
50 }
51
52 void
53 usage()
54 {
55 std::cout << "\n Usage:\n " << m_programName << " "
56 "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n"
57 " Reads payload from stdin and sends it to local NDN forwarder as a "
58 "single Data packet\n"
59 " [-f] - force, send Data without waiting for Interest\n"
60 " [-D] - use DigestSha256 signing method instead of "
61 "SignatureSha256WithRsa\n"
62 " [-i identity] - set identity to be used for signing\n"
63 " [-F] - set FinalBlockId to the last component of Name\n"
64 " [-x] - set FreshnessPeriod in time::milliseconds\n"
65 " [-w timeout] - set Timeout in time::milliseconds\n"
66 " [-h] - print help and exit\n"
67 " [-V] - print version and exit\n"
68 "\n";
69 exit(1);
70 }
71
72 void
73 setForceData()
74 {
75 m_isForceDataSet = true;
76 }
77
78 void
79 setUseDigestSha256()
80 {
81 m_isUseDigestSha256Set = true;
82 }
83
84 void
85 setIdentityName(char* identityName)
86 {
87 m_identityName = ndn::make_shared<ndn::Name>(identityName);
88 }
89
90 void
91 setLastAsFinalBlockId()
92 {
93 m_isLastAsFinalBlockIdSet = true;
94 }
95
96 void
97 setFreshnessPeriod(int freshnessPeriod)
98 {
99 if (freshnessPeriod < 0)
100 usage();
101 m_freshnessPeriod = ndn::time::milliseconds(freshnessPeriod);
102 }
103
104 void
105 setTimeout(int timeout)
106 {
107 if (timeout < 0)
108 usage();
109 m_timeout = ndn::time::milliseconds(timeout);
110 }
111
112 void
113 setPrefixName(char* prefixName)
114 {
115 m_prefixName = ndn::Name(prefixName);
116 }
117
118 ndn::time::milliseconds
119 getDefaultTimeout()
120 {
121 return ndn::time::seconds(10);
122 }
123
124 ndn::Data
125 createDataPacket()
126 {
127 ndn::Data dataPacket(m_prefixName);
128 std::stringstream payloadStream;
129 payloadStream << std::cin.rdbuf();
130 std::string payload = payloadStream.str();
131 dataPacket.setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
132 if (m_freshnessPeriod >= ndn::time::milliseconds::zero())
133 dataPacket.setFreshnessPeriod(m_freshnessPeriod);
134 if (m_isLastAsFinalBlockIdSet)
135 {
136 if (!m_prefixName.empty())
137 dataPacket.setFinalBlockId(m_prefixName.get(-1));
138 else
139 {
140 std::cerr << "Name Provided Has 0 Components" << std::endl;
141 exit(1);
142 }
143 }
144 if (m_isUseDigestSha256Set)
145 m_keyChain.signWithSha256(dataPacket);
146 else
147 {
148 if (!static_cast<bool>(m_identityName))
149 m_keyChain.sign(dataPacket);
150 else
151 m_keyChain.signByIdentity(dataPacket, *m_identityName);
152 }
153 return dataPacket;
154 }
155
156 void
157 onInterest(const ndn::Name& name,
158 const ndn::Interest& interest,
159 const ndn::Data& dataPacket)
160 {
161 m_face.put(dataPacket);
162 m_isDataSent = true;
163 m_face.shutdown();
164 }
165
166 void
167 onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
168 {
169 std::cerr << "Prefix Registration Failure." << std::endl;
170 std::cerr << "Reason = " << reason << std::endl;
171 }
172
173 void
174 run()
175 {
176 try
177 {
178 ndn::Data dataPacket = createDataPacket();
179 if (m_isForceDataSet)
180 {
181 m_face.put(dataPacket);
182 m_isDataSent = true;
183 }
184 else
185 {
186 m_face.setInterestFilter(m_prefixName,
187 bind(&NdnTlvPoke::onInterest, this, _1, _2, dataPacket),
188 ndn::RegisterPrefixSuccessCallback(),
189 bind(&NdnTlvPoke::onRegisterFailed, this, _1, _2));
190 }
191 if (m_timeout < ndn::time::milliseconds::zero())
192 m_face.processEvents(getDefaultTimeout());
193 else
194 m_face.processEvents(m_timeout);
195 }
196 catch (std::exception& e)
197 {
198 std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
199 exit(1);
200 }
201 }
202
203 bool
204 isDataSent() const
205 {
206 return m_isDataSent;
207 }
208
209private:
210
211 ndn::KeyChain m_keyChain;
212 std::string m_programName;
213 bool m_isForceDataSet;
214 bool m_isUseDigestSha256Set;
215 ndn::shared_ptr<ndn::Name> m_identityName;
216 bool m_isLastAsFinalBlockIdSet;
217 ndn::time::milliseconds m_freshnessPeriod;
218 ndn::time::milliseconds m_timeout;
219 ndn::Name m_prefixName;
220 bool m_isDataSent;
221 ndn::Face m_face;
222
223};
224
225}
226
227int
228main(int argc, char* argv[])
229{
230 int option;
231 ndntlvpoke::NdnTlvPoke ndnTlvPoke(argv[0]);
232 while ((option = getopt(argc, argv, "hfDi:Fx:w:V")) != -1) {
233 switch (option) {
234 case 'h':
235 ndnTlvPoke.usage();
236 break;
237 case 'f':
238 ndnTlvPoke.setForceData();
239 break;
240 case 'D':
241 ndnTlvPoke.setUseDigestSha256();
242 break;
243 case 'i':
244 ndnTlvPoke.setIdentityName(optarg);
245 break;
246 case 'F':
247 ndnTlvPoke.setLastAsFinalBlockId();
248 break;
249 case 'x':
250 ndnTlvPoke.setFreshnessPeriod(atoi(optarg));
251 break;
252 case 'w':
253 ndnTlvPoke.setTimeout(atoi(optarg));
254 break;
255 case 'V':
256 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
257 return 0;
258 default:
259 ndnTlvPoke.usage();
260 break;
261 }
262 }
263
264 argc -= optind;
265 argv += optind;
266
267 if (argv[0] == 0)
268 ndnTlvPoke.usage();
269
270 ndnTlvPoke.setPrefixName(argv[0]);
271 ndnTlvPoke.run();
272
273 if (ndnTlvPoke.isDataSent())
274 return 0;
275 else
276 return 1;
277}