blob: 6e917b0e3c9c1603bfe3fd3db1d3eb73ecc19741 [file] [log] [blame]
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080011 */
12
13#include "common.hpp"
Alexander Afanasyeve289b532014-02-09 22:14:44 -080014#include "ndnd-controller.hpp"
15
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080016#include "../face.hpp"
Yingdi Yue66bf2a2014-04-28 17:07:36 -070017#include "../security/identity-certificate.hpp"
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080018#include "../security/signature-sha256-with-rsa.hpp"
19#include "../util/random.hpp"
20
21#include "ndnd-forwarding-entry.hpp"
22#include "ndnd-face-instance.hpp"
23#include "ndnd-status-response.hpp"
24
25namespace ndn {
26namespace ndnd {
27
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080028Controller::Controller(Face& face)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080029 : m_face(face)
30 , m_faceId(-1)
31{
32}
33
34void
Alexander Afanasyeve289b532014-02-09 22:14:44 -080035Controller::selfRegisterPrefix(const Name& prefixToRegister,
36 const SuccessCallback& onSuccess,
37 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080038{
39 if (!m_ndndId.hasValue())
40 {
41 if (m_filterRequests.empty())
42 {
43 m_face.expressInterest(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"),
Alexander Afanasyeve289b532014-02-09 22:14:44 -080044 bind(&Controller::onNdnidFetched, this, _1, _2),
45 bind(onFail, "NDNDID fetching timed out"));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080046 }
47 m_filterRequests.push_back(FilterRequest(prefixToRegister, onSuccess, onFail));
48 }
49 else
50 startPrefixAction(ForwardingEntry("selfreg", prefixToRegister),
Alexander Afanasyeve289b532014-02-09 22:14:44 -080051 bind(&Controller::recordSelfRegisteredFaceId, this, _1, onSuccess),
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080052 onFail);
53}
54
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080055void
Alexander Afanasyeve289b532014-02-09 22:14:44 -080056Controller::selfDeregisterPrefix(const Name& prefixToRegister,
57 const SuccessCallback& onSuccess,
58 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080059{
60 if (!m_ndndId.hasValue() || m_faceId == -1)
61 {
62 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -080063 onFail("NDNID is not available (must have been present after a successful registration operation)");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080064 return;
65 }
66
67 startPrefixAction(ForwardingEntry("unreg", prefixToRegister, m_faceId),
68 bind(onSuccess), onFail);
69}
70
71
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -080072void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080073Controller::onNdnidFetched(const Interest& interest, Data& data)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080074{
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080075 if (data.getName().size() > interest.getName().size())
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080076 {
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080077 m_ndndId = data.getName()[interest.getName().size()];
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080078
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -080079 if (m_ndndId.value_size() < 6)
80 {
81 for (FilterRequestList::iterator i = m_filterRequests.begin();
82 i != m_filterRequests.end();
83 ++i)
84 {
85 if (static_cast<bool>(i->m_onFailure))
86 i->m_onFailure("Fetched unrecognized NDNID");
87 }
88
89 return;
90 }
91
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080092 for (FilterRequestList::iterator i = m_filterRequests.begin();
93 i != m_filterRequests.end();
94 ++i)
95 {
96 startPrefixAction(ForwardingEntry("selfreg", i->m_prefixToRegister),
Alexander Afanasyeve289b532014-02-09 22:14:44 -080097 bind(&Controller::recordSelfRegisteredFaceId, this, _1, i->m_onSuccess),
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080098 i->m_onFailure);
99 }
100 }
101 else
102 {
103 for (FilterRequestList::iterator i = m_filterRequests.begin();
104 i != m_filterRequests.end();
105 ++i)
106 {
107 if (static_cast<bool>(i->m_onFailure))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800108 i->m_onFailure("NDNID cannot be fetched");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800109 }
110 }
111 m_filterRequests.clear();
112}
113
114void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800115Controller::recordSelfRegisteredFaceId(const ForwardingEntry& entry,
116 const SuccessCallback& onSuccess)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800117{
118 m_faceId = entry.getFaceId();
119 if (static_cast<bool>(onSuccess))
120 onSuccess();
121}
122
123void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800124Controller::startFaceAction(const FaceInstance& entry,
125 const FaceOperationSucceedCallback& onSuccess,
126 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800127{
128 // Set the ForwardingEntry as the content of a Data packet and sign.
129 Data data;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700130 data.setName(Name().appendVersion(random::generateWord32()));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800131 data.setContent(entry.wireEncode());
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800132
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800133 // Create an empty signature, since nobody going to verify it for now
134 // @todo In the future, we may require real signatures to do the registration
135 SignatureSha256WithRsa signature;
136 signature.setValue(Block(Tlv::SignatureValue));
137 data.setSignature(signature);
138
139 // Create an interest where the name has the encoded Data packet.
140 Name interestName;
141 interestName.append("ndnx");
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800142 interestName.append(m_ndndId.value_begin()+6, m_ndndId.value_end());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800143 interestName.append(entry.getAction());
144 interestName.append(data.wireEncode());
145
146 Interest interest(interestName);
147 interest.setScope(1);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700148 interest.setInterestLifetime(time::seconds(1));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800149 interest.setMustBeFresh(true);
150
151 m_face.expressInterest(interest,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800152 bind(&Controller::processFaceActionResponse, this, _2, onSuccess, onFail),
153 bind(onFail, "Command Interest failed"));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800154}
155
156void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800157Controller::startPrefixAction(const ForwardingEntry& entry,
158 const PrefixOperationSucceedCallback& onSuccess,
159 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800160{
161 // Set the ForwardingEntry as the content of a Data packet and sign.
162 Data data;
163 data.setName(Name().appendVersion(random::generateWord32()));
164 data.setContent(entry.wireEncode());
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800165
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800166 // Create an empty signature, since nobody going to verify it for now
167 // @todo In the future, we may require real signatures to do the registration
168 SignatureSha256WithRsa signature;
169 signature.setValue(Block(Tlv::SignatureValue));
170 data.setSignature(signature);
171
172 // Create an interest where the name has the encoded Data packet.
173 Name interestName;
174 interestName.append("ndnx");
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700175 interestName.append(m_ndndId.value_begin() + 6, m_ndndId.value_end());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800176 interestName.append(entry.getAction());
177 interestName.append(data.wireEncode());
178
179 Interest interest(interestName);
180 interest.setScope(1);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700181 interest.setInterestLifetime(time::seconds(1));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800182 interest.setMustBeFresh(true);
183
184 m_face.expressInterest(interest,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800185 bind(&Controller::processPrefixActionResponse, this, _2, onSuccess, onFail),
186 bind(onFail, "Command Interest timed out"));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800187}
188
189void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800190Controller::processFaceActionResponse(Data& data,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800191 const FaceOperationSucceedCallback& onSuccess,
192 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800193{
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800194 Block content = data.getContent();
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800195 content.parse();
196
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800197 if (content.elements().empty())
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800198 {
199 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800200 onFail("Empty response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800201 return;
202 }
203
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800204 Block::element_const_iterator val = content.elements_begin();
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800205
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700206 switch (val->type())
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800207 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800208 case tlv::ndnd::FaceInstance:
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800209 {
210 FaceInstance entry;
211 entry.wireDecode(*val);
212
213 if (static_cast<bool>(onSuccess))
214 onSuccess(entry);
215 return;
216 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800217 case tlv::ndnd::StatusResponse:
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800218 {
219 StatusResponse resp;
220 resp.wireDecode(*val);
221
222 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800223 onFail(resp.getInfo());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800224 return;
225 }
226 default:
227 {
228 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800229 onFail("Invalid response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800230 return;
231 }
232 }
233}
234
235void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800236Controller::processPrefixActionResponse(Data& data,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800237 const PrefixOperationSucceedCallback& onSuccess,
238 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800239{
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800240 Block content = data.getContent();
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800241 content.parse();
242
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800243 if (content.elements().empty())
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800244 {
245 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800246 onFail("Empty response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800247 return;
248 }
249
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800250 Block::element_const_iterator val = content.elements_begin();
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800251
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700252 switch (val->type())
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800253 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800254 case tlv::ndnd::ForwardingEntry:
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800255 {
256 ForwardingEntry entry;
257 entry.wireDecode(*val);
258
259 if (static_cast<bool>(onSuccess))
260 onSuccess(entry);
261 return;
262 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800263 case tlv::ndnd::StatusResponse:
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800264 {
265 StatusResponse resp;
266 resp.wireDecode(*val);
267
268 // std::cerr << "StatusReponse: " << resp << std::endl;
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800269
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800270 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800271 onFail(resp.getInfo());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800272 return;
273 }
274 default:
275 {
276 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800277 onFail("Invalid response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800278 return;
279 }
280 }
281}
282
283} // namespace ndnd
284} // namespace ndn