blob: 6f482312f79298a2916c449fe7801b445c3745d3 [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"
8#include "../node.hpp"
9#include "../security/signature-sha256-with-rsa.hpp"
10#include "../util/random.hpp"
11
12#include "ndnd-forwarding-entry.hpp"
13#include "ndnd-face-instance.hpp"
14#include "ndnd-status-response.hpp"
15
16namespace ndn {
17namespace ndnd {
18
19Control::Control(Node& face)
20 : m_face(face)
21 , m_faceId(-1)
22{
23}
24
25void
26Control::selfRegisterPrefix(const Name& prefixToRegister,
27 const SuccessCallback& onSuccess,
28 const FailCallback& onFail)
29{
30 if (!m_ndndId.hasValue())
31 {
32 if (m_filterRequests.empty())
33 {
34 m_face.expressInterest(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"),
35 bind(&Control::onNdnidFetched, this, _1, _2),
36 bind(onFail));
37 }
38 m_filterRequests.push_back(FilterRequest(prefixToRegister, onSuccess, onFail));
39 }
40 else
41 startPrefixAction(ForwardingEntry("selfreg", prefixToRegister),
42 bind(&Control::recordSelfRegisteredFaceId, this, _1, onSuccess),
43 onFail);
44}
45
46
47void
48Control::selfDeregisterPrefix(const Name& prefixToRegister,
49 const SuccessCallback& onSuccess,
50 const FailCallback& onFail)
51{
52 if (!m_ndndId.hasValue() || m_faceId == -1)
53 {
54 if (static_cast<bool>(onFail))
55 onFail();
56 return;
57 }
58
59 startPrefixAction(ForwardingEntry("unreg", prefixToRegister, m_faceId),
60 bind(onSuccess), onFail);
61}
62
63
64void
65Control::onNdnidFetched(const shared_ptr<const Interest>& interest,
66 const shared_ptr<Data>& data)
67{
68 if (data->getName().size() > interest->getName().size())
69 {
70 m_ndndId = data->getName()[interest->getName().size()];
71
72 for (FilterRequestList::iterator i = m_filterRequests.begin();
73 i != m_filterRequests.end();
74 ++i)
75 {
76 startPrefixAction(ForwardingEntry("selfreg", i->m_prefixToRegister),
77 bind(&Control::recordSelfRegisteredFaceId, this, _1, i->m_onSuccess),
78 i->m_onFailure);
79 }
80 }
81 else
82 {
83 for (FilterRequestList::iterator i = m_filterRequests.begin();
84 i != m_filterRequests.end();
85 ++i)
86 {
87 if (static_cast<bool>(i->m_onFailure))
88 i->m_onFailure();
89 }
90 }
91 m_filterRequests.clear();
92}
93
94void
95Control::recordSelfRegisteredFaceId(const ForwardingEntry& entry,
96 const SuccessCallback& onSuccess)
97{
98 m_faceId = entry.getFaceId();
99 if (static_cast<bool>(onSuccess))
100 onSuccess();
101}
102
103void
104Control::startFaceAction(const FaceInstance& entry,
105 const FaceOperationSucceedCallback& onSuccess,
106 const FailCallback& onFailure)
107{
108 // Set the ForwardingEntry as the content of a Data packet and sign.
109 Data data;
110 data.setName(Name().appendVersion(ndn::random::generateWord32()));
111 data.setContent(entry.wireEncode());
112
113 // Create an empty signature, since nobody going to verify it for now
114 // @todo In the future, we may require real signatures to do the registration
115 SignatureSha256WithRsa signature;
116 signature.setValue(Block(Tlv::SignatureValue));
117 data.setSignature(signature);
118
119 // Create an interest where the name has the encoded Data packet.
120 Name interestName;
121 interestName.append("ndnx");
122 interestName.append(m_ndndId);
123 interestName.append(entry.getAction());
124 interestName.append(data.wireEncode());
125
126 Interest interest(interestName);
127 interest.setScope(1);
128 interest.setInterestLifetime(1000);
129 interest.setMustBeFresh(true);
130
131 m_face.expressInterest(interest,
132 bind(&Control::processFaceActionResponse, this, _2, onSuccess, onFailure),
133 bind(onFailure));
134}
135
136void
137Control::startPrefixAction(const ForwardingEntry& entry,
138 const PrefixOperationSucceedCallback& onSuccess,
139 const FailCallback& onFailure)
140{
141 // Set the ForwardingEntry as the content of a Data packet and sign.
142 Data data;
143 data.setName(Name().appendVersion(random::generateWord32()));
144 data.setContent(entry.wireEncode());
145
146 // Create an empty signature, since nobody going to verify it for now
147 // @todo In the future, we may require real signatures to do the registration
148 SignatureSha256WithRsa signature;
149 signature.setValue(Block(Tlv::SignatureValue));
150 data.setSignature(signature);
151
152 // Create an interest where the name has the encoded Data packet.
153 Name interestName;
154 interestName.append("ndnx");
155 interestName.append(m_ndndId);
156 interestName.append(entry.getAction());
157 interestName.append(data.wireEncode());
158
159 Interest interest(interestName);
160 interest.setScope(1);
161 interest.setInterestLifetime(1000);
162 interest.setMustBeFresh(true);
163
164 m_face.expressInterest(interest,
165 bind(&Control::processPrefixActionResponse, this, _2, onSuccess, onFailure),
166 bind(onFailure));
167}
168
169void
170Control::processFaceActionResponse(const shared_ptr<Data>& data,
171 const FaceOperationSucceedCallback& onSuccess,
172 const FailCallback& onFail)
173{
174 Block content = data->getContent();
175 content.parse();
176
177 if (content.getAll().empty())
178 {
179 if (static_cast<bool>(onFail))
180 onFail();
181 return;
182 }
183
184 Block::element_iterator val = content.getAll().begin();
185
186 switch(val->type())
187 {
188 case Tlv::FaceManagement::FaceInstance:
189 {
190 FaceInstance entry;
191 entry.wireDecode(*val);
192
193 if (static_cast<bool>(onSuccess))
194 onSuccess(entry);
195 return;
196 }
197 case Tlv::FaceManagement::StatusResponse:
198 {
199 StatusResponse resp;
200 resp.wireDecode(*val);
201
202 if (static_cast<bool>(onFail))
203 onFail();
204 return;
205 }
206 default:
207 {
208 if (static_cast<bool>(onFail))
209 onFail();
210 return;
211 }
212 }
213}
214
215void
216Control::processPrefixActionResponse(const shared_ptr<Data>& data,
217 const PrefixOperationSucceedCallback& onSuccess,
218 const FailCallback& onFail)
219{
220 Block content = data->getContent();
221 content.parse();
222
223 if (content.getAll().empty())
224 {
225 if (static_cast<bool>(onFail))
226 onFail();
227 return;
228 }
229
230 Block::element_iterator val = content.getAll().begin();
231
232 switch(val->type())
233 {
234 case Tlv::FaceManagement::ForwardingEntry:
235 {
236 ForwardingEntry entry;
237 entry.wireDecode(*val);
238
239 if (static_cast<bool>(onSuccess))
240 onSuccess(entry);
241 return;
242 }
243 case Tlv::FaceManagement::StatusResponse:
244 {
245 StatusResponse resp;
246 resp.wireDecode(*val);
247
248 // std::cerr << "StatusReponse: " << resp << std::endl;
249
250 if (static_cast<bool>(onFail))
251 onFail();
252 return;
253 }
254 default:
255 {
256 if (static_cast<bool>(onFail))
257 onFail();
258 return;
259 }
260 }
261}
262
263} // namespace ndnd
264} // namespace ndn