blob: 302699e1c9c610709187381d134a759fa260da8c [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
66void
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
73 for (FilterRequestList::iterator i = m_filterRequests.begin();
74 i != m_filterRequests.end();
75 ++i)
76 {
77 startPrefixAction(ForwardingEntry("selfreg", i->m_prefixToRegister),
Alexander Afanasyeve289b532014-02-09 22:14:44 -080078 bind(&Controller::recordSelfRegisteredFaceId, this, _1, i->m_onSuccess),
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080079 i->m_onFailure);
80 }
81 }
82 else
83 {
84 for (FilterRequestList::iterator i = m_filterRequests.begin();
85 i != m_filterRequests.end();
86 ++i)
87 {
88 if (static_cast<bool>(i->m_onFailure))
Alexander Afanasyeve289b532014-02-09 22:14:44 -080089 i->m_onFailure("NDNID cannot be fetched");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080090 }
91 }
92 m_filterRequests.clear();
93}
94
95void
Alexander Afanasyeve289b532014-02-09 22:14:44 -080096Controller::recordSelfRegisteredFaceId(const ForwardingEntry& entry,
97 const SuccessCallback& onSuccess)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080098{
99 m_faceId = entry.getFaceId();
100 if (static_cast<bool>(onSuccess))
101 onSuccess();
102}
103
104void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800105Controller::startFaceAction(const FaceInstance& entry,
106 const FaceOperationSucceedCallback& onSuccess,
107 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800108{
109 // Set the ForwardingEntry as the content of a Data packet and sign.
110 Data data;
111 data.setName(Name().appendVersion(ndn::random::generateWord32()));
112 data.setContent(entry.wireEncode());
113
114 // Create an empty signature, since nobody going to verify it for now
115 // @todo In the future, we may require real signatures to do the registration
116 SignatureSha256WithRsa signature;
117 signature.setValue(Block(Tlv::SignatureValue));
118 data.setSignature(signature);
119
120 // Create an interest where the name has the encoded Data packet.
121 Name interestName;
122 interestName.append("ndnx");
123 interestName.append(m_ndndId);
124 interestName.append(entry.getAction());
125 interestName.append(data.wireEncode());
126
127 Interest interest(interestName);
128 interest.setScope(1);
129 interest.setInterestLifetime(1000);
130 interest.setMustBeFresh(true);
131
132 m_face.expressInterest(interest,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800133 bind(&Controller::processFaceActionResponse, this, _2, onSuccess, onFail),
134 bind(onFail, "Command Interest failed"));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800135}
136
137void
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800138Controller::startPrefixAction(const ForwardingEntry& entry,
139 const PrefixOperationSucceedCallback& onSuccess,
140 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800141{
142 // Set the ForwardingEntry as the content of a Data packet and sign.
143 Data data;
144 data.setName(Name().appendVersion(random::generateWord32()));
145 data.setContent(entry.wireEncode());
146
147 // Create an empty signature, since nobody going to verify it for now
148 // @todo In the future, we may require real signatures to do the registration
149 SignatureSha256WithRsa signature;
150 signature.setValue(Block(Tlv::SignatureValue));
151 data.setSignature(signature);
152
153 // Create an interest where the name has the encoded Data packet.
154 Name interestName;
155 interestName.append("ndnx");
156 interestName.append(m_ndndId);
157 interestName.append(entry.getAction());
158 interestName.append(data.wireEncode());
159
160 Interest interest(interestName);
161 interest.setScope(1);
162 interest.setInterestLifetime(1000);
163 interest.setMustBeFresh(true);
164
165 m_face.expressInterest(interest,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800166 bind(&Controller::processPrefixActionResponse, this, _2, onSuccess, onFail),
167 bind(onFail, "Command Interest timed out"));
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800168}
169
170void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800171Controller::processFaceActionResponse(Data& data,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800172 const FaceOperationSucceedCallback& onSuccess,
173 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800174{
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800175 Block content = data.getContent();
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800176 content.parse();
177
178 if (content.getAll().empty())
179 {
180 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800181 onFail("Empty response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800182 return;
183 }
184
185 Block::element_iterator val = content.getAll().begin();
186
187 switch(val->type())
188 {
189 case Tlv::FaceManagement::FaceInstance:
190 {
191 FaceInstance entry;
192 entry.wireDecode(*val);
193
194 if (static_cast<bool>(onSuccess))
195 onSuccess(entry);
196 return;
197 }
198 case Tlv::FaceManagement::StatusResponse:
199 {
200 StatusResponse resp;
201 resp.wireDecode(*val);
202
203 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800204 onFail(resp.getInfo());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800205 return;
206 }
207 default:
208 {
209 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800210 onFail("Invalid response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800211 return;
212 }
213 }
214}
215
216void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800217Controller::processPrefixActionResponse(Data& data,
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800218 const PrefixOperationSucceedCallback& onSuccess,
219 const FailCallback& onFail)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800220{
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800221 Block content = data.getContent();
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800222 content.parse();
223
224 if (content.getAll().empty())
225 {
226 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800227 onFail("Empty response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800228 return;
229 }
230
231 Block::element_iterator val = content.getAll().begin();
232
233 switch(val->type())
234 {
235 case Tlv::FaceManagement::ForwardingEntry:
236 {
237 ForwardingEntry entry;
238 entry.wireDecode(*val);
239
240 if (static_cast<bool>(onSuccess))
241 onSuccess(entry);
242 return;
243 }
244 case Tlv::FaceManagement::StatusResponse:
245 {
246 StatusResponse resp;
247 resp.wireDecode(*val);
248
249 // std::cerr << "StatusReponse: " << resp << std::endl;
250
251 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800252 onFail(resp.getInfo());
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800253 return;
254 }
255 default:
256 {
257 if (static_cast<bool>(onFail))
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800258 onFail("Invalid response");
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800259 return;
260 }
261 }
262}
263
264} // namespace ndnd
265} // namespace ndn