blob: 1d3fb6028b872ab9b7bd46fe3ccd314fd982c5cc [file] [log] [blame]
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "common.hpp"
Alexander Afanasyeve289b532014-02-09 22:14:44 -08008#include "ndnd-controller.hpp"
9
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080010#include "../face.hpp"
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080011#include "../security/signature-sha256-with-rsa.hpp"
12#include "../util/random.hpp"
13
14#include "ndnd-forwarding-entry.hpp"
15#include "ndnd-face-instance.hpp"
16#include "ndnd-status-response.hpp"
17
18namespace ndn {
19namespace ndnd {
20
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080021Controller::Controller(Face& face)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080022 : m_face(face)
23 , m_faceId(-1)
24{
25}
26
27void
Alexander Afanasyeve289b532014-02-09 22:14:44 -080028Controller::selfRegisterPrefix(const Name& prefixToRegister,
29 const SuccessCallback& onSuccess,
30 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080031{
32 if (!m_ndndId.hasValue())
33 {
34 if (m_filterRequests.empty())
35 {
36 m_face.expressInterest(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"),
Alexander Afanasyeve289b532014-02-09 22:14:44 -080037 bind(&Controller::onNdnidFetched, this, _1, _2),
38 bind(onFail, "NDNDID fetching timed out"));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080039 }
40 m_filterRequests.push_back(FilterRequest(prefixToRegister, onSuccess, onFail));
41 }
42 else
43 startPrefixAction(ForwardingEntry("selfreg", prefixToRegister),
Alexander Afanasyeve289b532014-02-09 22:14:44 -080044 bind(&Controller::recordSelfRegisteredFaceId, this, _1, onSuccess),
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080045 onFail);
46}
47
48
49void
Alexander Afanasyeve289b532014-02-09 22:14:44 -080050Controller::selfDeregisterPrefix(const Name& prefixToRegister,
51 const SuccessCallback& onSuccess,
52 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080053{
54 if (!m_ndndId.hasValue() || m_faceId == -1)
55 {
56 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -080057 onFail("NDNID is not available (must have been present after a successful registration operation)");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080058 return;
59 }
60
61 startPrefixAction(ForwardingEntry("unreg", prefixToRegister, m_faceId),
62 bind(onSuccess), onFail);
63}
64
65
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -080066void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080067Controller::onNdnidFetched(const Interest& interest, Data& data)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080068{
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080069 if (data.getName().size() > interest.getName().size())
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080070 {
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080071 m_ndndId = data.getName()[interest.getName().size()];
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080072
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -080073 if (m_ndndId.value_size() < 6)
74 {
75 for (FilterRequestList::iterator i = m_filterRequests.begin();
76 i != m_filterRequests.end();
77 ++i)
78 {
79 if (static_cast<bool>(i->m_onFailure))
80 i->m_onFailure("Fetched unrecognized NDNID");
81 }
82
83 return;
84 }
85
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080086 for (FilterRequestList::iterator i = m_filterRequests.begin();
87 i != m_filterRequests.end();
88 ++i)
89 {
90 startPrefixAction(ForwardingEntry("selfreg", i->m_prefixToRegister),
Alexander Afanasyeve289b532014-02-09 22:14:44 -080091 bind(&Controller::recordSelfRegisteredFaceId, this, _1, i->m_onSuccess),
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080092 i->m_onFailure);
93 }
94 }
95 else
96 {
97 for (FilterRequestList::iterator i = m_filterRequests.begin();
98 i != m_filterRequests.end();
99 ++i)
100 {
101 if (static_cast<bool>(i->m_onFailure))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800102 i->m_onFailure("NDNID cannot be fetched");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800103 }
104 }
105 m_filterRequests.clear();
106}
107
108void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800109Controller::recordSelfRegisteredFaceId(const ForwardingEntry& entry,
110 const SuccessCallback& onSuccess)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800111{
112 m_faceId = entry.getFaceId();
113 if (static_cast<bool>(onSuccess))
114 onSuccess();
115}
116
117void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800118Controller::startFaceAction(const FaceInstance& entry,
119 const FaceOperationSucceedCallback& onSuccess,
120 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800121{
122 // Set the ForwardingEntry as the content of a Data packet and sign.
123 Data data;
124 data.setName(Name().appendVersion(ndn::random::generateWord32()));
125 data.setContent(entry.wireEncode());
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800126
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800127 // Create an empty signature, since nobody going to verify it for now
128 // @todo In the future, we may require real signatures to do the registration
129 SignatureSha256WithRsa signature;
130 signature.setValue(Block(Tlv::SignatureValue));
131 data.setSignature(signature);
132
133 // Create an interest where the name has the encoded Data packet.
134 Name interestName;
135 interestName.append("ndnx");
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800136 interestName.append(m_ndndId.value_begin()+6, m_ndndId.value_end());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800137 interestName.append(entry.getAction());
138 interestName.append(data.wireEncode());
139
140 Interest interest(interestName);
141 interest.setScope(1);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700142 interest.setInterestLifetime(time::seconds(1));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800143 interest.setMustBeFresh(true);
144
145 m_face.expressInterest(interest,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800146 bind(&Controller::processFaceActionResponse, this, _2, onSuccess, onFail),
147 bind(onFail, "Command Interest failed"));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800148}
149
150void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800151Controller::startPrefixAction(const ForwardingEntry& entry,
152 const PrefixOperationSucceedCallback& onSuccess,
153 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800154{
155 // Set the ForwardingEntry as the content of a Data packet and sign.
156 Data data;
157 data.setName(Name().appendVersion(random::generateWord32()));
158 data.setContent(entry.wireEncode());
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800159
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800160 // Create an empty signature, since nobody going to verify it for now
161 // @todo In the future, we may require real signatures to do the registration
162 SignatureSha256WithRsa signature;
163 signature.setValue(Block(Tlv::SignatureValue));
164 data.setSignature(signature);
165
166 // Create an interest where the name has the encoded Data packet.
167 Name interestName;
168 interestName.append("ndnx");
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800169 interestName.append(m_ndndId.value_begin()+6, m_ndndId.value_end());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800170 interestName.append(entry.getAction());
171 interestName.append(data.wireEncode());
172
173 Interest interest(interestName);
174 interest.setScope(1);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700175 interest.setInterestLifetime(time::seconds(1));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800176 interest.setMustBeFresh(true);
177
178 m_face.expressInterest(interest,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800179 bind(&Controller::processPrefixActionResponse, this, _2, onSuccess, onFail),
180 bind(onFail, "Command Interest timed out"));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800181}
182
183void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800184Controller::processFaceActionResponse(Data& data,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800185 const FaceOperationSucceedCallback& onSuccess,
186 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800187{
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800188 Block content = data.getContent();
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800189 content.parse();
190
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800191 if (content.elements().empty())
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800192 {
193 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800194 onFail("Empty response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800195 return;
196 }
197
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800198 Block::element_const_iterator val = content.elements_begin();
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800199
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800200 switch(val->type())
201 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800202 case tlv::ndnd::FaceInstance:
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800203 {
204 FaceInstance entry;
205 entry.wireDecode(*val);
206
207 if (static_cast<bool>(onSuccess))
208 onSuccess(entry);
209 return;
210 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800211 case tlv::ndnd::StatusResponse:
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800212 {
213 StatusResponse resp;
214 resp.wireDecode(*val);
215
216 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800217 onFail(resp.getInfo());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800218 return;
219 }
220 default:
221 {
222 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800223 onFail("Invalid response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800224 return;
225 }
226 }
227}
228
229void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800230Controller::processPrefixActionResponse(Data& data,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800231 const PrefixOperationSucceedCallback& onSuccess,
232 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800233{
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800234 Block content = data.getContent();
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800235 content.parse();
236
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800237 if (content.elements().empty())
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800238 {
239 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800240 onFail("Empty response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800241 return;
242 }
243
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800244 Block::element_const_iterator val = content.elements_begin();
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800245
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800246 switch(val->type())
247 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800248 case tlv::ndnd::ForwardingEntry:
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800249 {
250 ForwardingEntry entry;
251 entry.wireDecode(*val);
252
253 if (static_cast<bool>(onSuccess))
254 onSuccess(entry);
255 return;
256 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800257 case tlv::ndnd::StatusResponse:
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800258 {
259 StatusResponse resp;
260 resp.wireDecode(*val);
261
262 // std::cerr << "StatusReponse: " << resp << std::endl;
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800263
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800264 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800265 onFail(resp.getInfo());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800266 return;
267 }
268 default:
269 {
270 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800271 onFail("Invalid response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800272 return;
273 }
274 }
275}
276
277} // namespace ndnd
278} // namespace ndn