blob: e95d85ea31998e45bde96cfaa108c4ebc2948bf4 [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 Afanasyevc8823bc2014-02-09 19:33:33 -080010#include "../node.hpp"
11#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 Afanasyeve289b532014-02-09 22:14:44 -080021Controller::Controller(Node& 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
66void
Alexander Afanasyeve289b532014-02-09 22:14:44 -080067Controller::onNdnidFetched(const shared_ptr<const Interest>& interest,
68 const shared_ptr<Data>& data)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080069{
70 if (data->getName().size() > interest->getName().size())
71 {
72 m_ndndId = data->getName()[interest->getName().size()];
73
74 for (FilterRequestList::iterator i = m_filterRequests.begin();
75 i != m_filterRequests.end();
76 ++i)
77 {
78 startPrefixAction(ForwardingEntry("selfreg", i->m_prefixToRegister),
Alexander Afanasyeve289b532014-02-09 22:14:44 -080079 bind(&Controller::recordSelfRegisteredFaceId, this, _1, i->m_onSuccess),
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080080 i->m_onFailure);
81 }
82 }
83 else
84 {
85 for (FilterRequestList::iterator i = m_filterRequests.begin();
86 i != m_filterRequests.end();
87 ++i)
88 {
89 if (static_cast<bool>(i->m_onFailure))
Alexander Afanasyeve289b532014-02-09 22:14:44 -080090 i->m_onFailure("NDNID cannot be fetched");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080091 }
92 }
93 m_filterRequests.clear();
94}
95
96void
Alexander Afanasyeve289b532014-02-09 22:14:44 -080097Controller::recordSelfRegisteredFaceId(const ForwardingEntry& entry,
98 const SuccessCallback& onSuccess)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080099{
100 m_faceId = entry.getFaceId();
101 if (static_cast<bool>(onSuccess))
102 onSuccess();
103}
104
105void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800106Controller::startFaceAction(const FaceInstance& entry,
107 const FaceOperationSucceedCallback& onSuccess,
108 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800109{
110 // Set the ForwardingEntry as the content of a Data packet and sign.
111 Data data;
112 data.setName(Name().appendVersion(ndn::random::generateWord32()));
113 data.setContent(entry.wireEncode());
114
115 // Create an empty signature, since nobody going to verify it for now
116 // @todo In the future, we may require real signatures to do the registration
117 SignatureSha256WithRsa signature;
118 signature.setValue(Block(Tlv::SignatureValue));
119 data.setSignature(signature);
120
121 // Create an interest where the name has the encoded Data packet.
122 Name interestName;
123 interestName.append("ndnx");
124 interestName.append(m_ndndId);
125 interestName.append(entry.getAction());
126 interestName.append(data.wireEncode());
127
128 Interest interest(interestName);
129 interest.setScope(1);
130 interest.setInterestLifetime(1000);
131 interest.setMustBeFresh(true);
132
133 m_face.expressInterest(interest,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800134 bind(&Controller::processFaceActionResponse, this, _2, onSuccess, onFail),
135 bind(onFail, "Command Interest failed"));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800136}
137
138void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800139Controller::startPrefixAction(const ForwardingEntry& entry,
140 const PrefixOperationSucceedCallback& onSuccess,
141 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800142{
143 // Set the ForwardingEntry as the content of a Data packet and sign.
144 Data data;
145 data.setName(Name().appendVersion(random::generateWord32()));
146 data.setContent(entry.wireEncode());
147
148 // Create an empty signature, since nobody going to verify it for now
149 // @todo In the future, we may require real signatures to do the registration
150 SignatureSha256WithRsa signature;
151 signature.setValue(Block(Tlv::SignatureValue));
152 data.setSignature(signature);
153
154 // Create an interest where the name has the encoded Data packet.
155 Name interestName;
156 interestName.append("ndnx");
157 interestName.append(m_ndndId);
158 interestName.append(entry.getAction());
159 interestName.append(data.wireEncode());
160
161 Interest interest(interestName);
162 interest.setScope(1);
163 interest.setInterestLifetime(1000);
164 interest.setMustBeFresh(true);
165
166 m_face.expressInterest(interest,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800167 bind(&Controller::processPrefixActionResponse, this, _2, onSuccess, onFail),
168 bind(onFail, "Command Interest timed out"));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800169}
170
171void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800172Controller::processFaceActionResponse(const shared_ptr<Data>& data,
173 const FaceOperationSucceedCallback& onSuccess,
174 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800175{
176 Block content = data->getContent();
177 content.parse();
178
179 if (content.getAll().empty())
180 {
181 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800182 onFail("Empty response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800183 return;
184 }
185
186 Block::element_iterator val = content.getAll().begin();
187
188 switch(val->type())
189 {
190 case Tlv::FaceManagement::FaceInstance:
191 {
192 FaceInstance entry;
193 entry.wireDecode(*val);
194
195 if (static_cast<bool>(onSuccess))
196 onSuccess(entry);
197 return;
198 }
199 case Tlv::FaceManagement::StatusResponse:
200 {
201 StatusResponse resp;
202 resp.wireDecode(*val);
203
204 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800205 onFail(resp.getInfo());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800206 return;
207 }
208 default:
209 {
210 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800211 onFail("Invalid response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800212 return;
213 }
214 }
215}
216
217void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800218Controller::processPrefixActionResponse(const shared_ptr<Data>& data,
219 const PrefixOperationSucceedCallback& onSuccess,
220 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800221{
222 Block content = data->getContent();
223 content.parse();
224
225 if (content.getAll().empty())
226 {
227 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800228 onFail("Empty response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800229 return;
230 }
231
232 Block::element_iterator val = content.getAll().begin();
233
234 switch(val->type())
235 {
236 case Tlv::FaceManagement::ForwardingEntry:
237 {
238 ForwardingEntry entry;
239 entry.wireDecode(*val);
240
241 if (static_cast<bool>(onSuccess))
242 onSuccess(entry);
243 return;
244 }
245 case Tlv::FaceManagement::StatusResponse:
246 {
247 StatusResponse resp;
248 resp.wireDecode(*val);
249
250 // std::cerr << "StatusReponse: " << resp << std::endl;
251
252 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800253 onFail(resp.getInfo());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800254 return;
255 }
256 default:
257 {
258 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800259 onFail("Invalid response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800260 return;
261 }
262 }
263}
264
265} // namespace ndnd
266} // namespace ndn