All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ndnd-controller.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
7 #include "common.hpp"
8 #include "ndnd-controller.hpp"
9 
10 #include "../face.hpp"
11 #include "../security/signature-sha256-with-rsa.hpp"
12 #include "../util/random.hpp"
13 
15 #include "ndnd-face-instance.hpp"
16 #include "ndnd-status-response.hpp"
17 
18 namespace ndn {
19 namespace ndnd {
20 
22  : m_face(face)
23  , m_faceId(-1)
24 {
25 }
26 
27 void
28 Controller::selfRegisterPrefix(const Name& prefixToRegister,
29  const SuccessCallback& onSuccess,
30  const FailCallback& onFail)
31 {
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"),
37  bind(&Controller::onNdnidFetched, this, _1, _2),
38  bind(onFail, "NDNDID fetching timed out"));
39  }
40  m_filterRequests.push_back(FilterRequest(prefixToRegister, onSuccess, onFail));
41  }
42  else
43  startPrefixAction(ForwardingEntry("selfreg", prefixToRegister),
44  bind(&Controller::recordSelfRegisteredFaceId, this, _1, onSuccess),
45  onFail);
46 }
47 
48 
49 void
50 Controller::selfDeregisterPrefix(const Name& prefixToRegister,
51  const SuccessCallback& onSuccess,
52  const FailCallback& onFail)
53 {
54  if (!m_ndndId.hasValue() || m_faceId == -1)
55  {
56  if (static_cast<bool>(onFail))
57  onFail("NDNID is not available (must have been present after a successful registration operation)");
58  return;
59  }
60 
61  startPrefixAction(ForwardingEntry("unreg", prefixToRegister, m_faceId),
62  bind(onSuccess), onFail);
63 }
64 
65 
66 void
67 Controller::onNdnidFetched(const Interest& interest, Data& data)
68 {
69  if (data.getName().size() > interest.getName().size())
70  {
71  m_ndndId = data.getName()[interest.getName().size()];
72 
73  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 
86  for (FilterRequestList::iterator i = m_filterRequests.begin();
87  i != m_filterRequests.end();
88  ++i)
89  {
90  startPrefixAction(ForwardingEntry("selfreg", i->m_prefixToRegister),
91  bind(&Controller::recordSelfRegisteredFaceId, this, _1, i->m_onSuccess),
92  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))
102  i->m_onFailure("NDNID cannot be fetched");
103  }
104  }
105  m_filterRequests.clear();
106 }
107 
108 void
109 Controller::recordSelfRegisteredFaceId(const ForwardingEntry& entry,
110  const SuccessCallback& onSuccess)
111 {
112  m_faceId = entry.getFaceId();
113  if (static_cast<bool>(onSuccess))
114  onSuccess();
115 }
116 
117 void
119  const FaceOperationSucceedCallback& onSuccess,
120  const FailCallback& onFail)
121 {
122  // Set the ForwardingEntry as the content of a Data packet and sign.
123  Data data;
124  data.setName(Name().appendVersion(random::generateWord32()));
125  data.setContent(entry.wireEncode());
126 
127  // 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");
136  interestName.append(m_ndndId.value_begin()+6, m_ndndId.value_end());
137  interestName.append(entry.getAction());
138  interestName.append(data.wireEncode());
139 
140  Interest interest(interestName);
141  interest.setScope(1);
142  interest.setInterestLifetime(time::seconds(1));
143  interest.setMustBeFresh(true);
144 
145  m_face.expressInterest(interest,
146  bind(&Controller::processFaceActionResponse, this, _2, onSuccess, onFail),
147  bind(onFail, "Command Interest failed"));
148 }
149 
150 void
152  const PrefixOperationSucceedCallback& onSuccess,
153  const FailCallback& onFail)
154 {
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());
159 
160  // 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");
169  interestName.append(m_ndndId.value_begin() + 6, m_ndndId.value_end());
170  interestName.append(entry.getAction());
171  interestName.append(data.wireEncode());
172 
173  Interest interest(interestName);
174  interest.setScope(1);
175  interest.setInterestLifetime(time::seconds(1));
176  interest.setMustBeFresh(true);
177 
178  m_face.expressInterest(interest,
179  bind(&Controller::processPrefixActionResponse, this, _2, onSuccess, onFail),
180  bind(onFail, "Command Interest timed out"));
181 }
182 
183 void
184 Controller::processFaceActionResponse(Data& data,
185  const FaceOperationSucceedCallback& onSuccess,
186  const FailCallback& onFail)
187 {
188  Block content = data.getContent();
189  content.parse();
190 
191  if (content.elements().empty())
192  {
193  if (static_cast<bool>(onFail))
194  onFail("Empty response");
195  return;
196  }
197 
199 
200  switch (val->type())
201  {
203  {
204  FaceInstance entry;
205  entry.wireDecode(*val);
206 
207  if (static_cast<bool>(onSuccess))
208  onSuccess(entry);
209  return;
210  }
212  {
213  StatusResponse resp;
214  resp.wireDecode(*val);
215 
216  if (static_cast<bool>(onFail))
217  onFail(resp.getInfo());
218  return;
219  }
220  default:
221  {
222  if (static_cast<bool>(onFail))
223  onFail("Invalid response");
224  return;
225  }
226  }
227 }
228 
229 void
230 Controller::processPrefixActionResponse(Data& data,
231  const PrefixOperationSucceedCallback& onSuccess,
232  const FailCallback& onFail)
233 {
234  Block content = data.getContent();
235  content.parse();
236 
237  if (content.elements().empty())
238  {
239  if (static_cast<bool>(onFail))
240  onFail("Empty response");
241  return;
242  }
243 
244  Block::element_const_iterator val = content.elements_begin();
245 
246  switch (val->type())
247  {
249  {
250  ForwardingEntry entry;
251  entry.wireDecode(*val);
252 
253  if (static_cast<bool>(onSuccess))
254  onSuccess(entry);
255  return;
256  }
258  {
259  StatusResponse resp;
260  resp.wireDecode(*val);
261 
262  // std::cerr << "StatusReponse: " << resp << std::endl;
263 
264  if (static_cast<bool>(onFail))
265  onFail(resp.getInfo());
266  return;
267  }
268  default:
269  {
270  if (static_cast<bool>(onFail))
271  onFail("Invalid response");
272  return;
273  }
274  }
275 }
276 
277 } // namespace ndnd
278 } // namespace ndn
Representing of SHA256-with-RSA signature in a data packet.
const Name & getName() const
Definition: interest.hpp:182
bool hasValue() const
Check if the Block has value block (no type and length are encoded)
Definition: block.hpp:294
virtual void selfDeregisterPrefix(const Name &prefixToRegister, const SuccessCallback &onSuccess, const FailCallback &onFail)
const std::string & getAction() const
Interest & setMustBeFresh(bool mustBeFresh)
Definition: interest.hpp:406
const std::string & getAction() const
function< void(const FaceInstance &)> FaceOperationSucceedCallback
Interest & setScope(int scope)
Definition: interest.hpp:220
const element_container & elements() const
Get all subelements.
Definition: block.hpp:464
function< void()> SuccessCallback
Definition: controller.hpp:23
Class representing wire element of the NDN packet.
Definition: block.hpp:26
An Interest holds a Name and other fields for an interest.
Definition: interest.hpp:24
Controller(Face &face)
Construct ndnd::Control object.
Buffer::const_iterator value_begin() const
Definition: block.hpp:425
Buffer::const_iterator value_end() const
Definition: block.hpp:431
void startFaceAction(const FaceInstance &entry, const FaceOperationSucceedCallback &onSuccess, const FailCallback &onFailure)
size_t wireEncode(EncodingImpl< T > &block, bool unsignedPortion=false) const
Fast encoding or block size estimation.
Definition: data.hpp:242
const Name & getName() const
Definition: data.hpp:346
void startPrefixAction(const ForwardingEntry &entry, const PrefixOperationSucceedCallback &onSuccess, const FailCallback &onFailure)
element_const_iterator elements_begin() const
Definition: block.hpp:470
uint32_t generateWord32()
Definition: random.cpp:17
virtual void selfRegisterPrefix(const Name &prefixToRegister, const SuccessCallback &onSuccess, const FailCallback &onFail)
void setValue(const Block &value)
Definition: signature.hpp:86
void setContent(const uint8_t *content, size_t contentLength)
Set the content to a copy of the data in the vector.
Definition: data.hpp:422
function< void(const std::string &)> FailCallback
Definition: controller.hpp:24
An ForwardingEntry holds an action and Name prefix and other fields for an forwarding entry...
Abstraction to communicate with local or remote NDN forwarder.
Definition: face.hpp:54
const Block & wireEncode() const
An FaceInstance holds an action and Name prefix and other fields for an forwarding entry...
function< void(const ForwardingEntry &)> PrefixOperationSucceedCallback
element_container::const_iterator element_const_iterator
Definition: block.hpp:31
size_t size() const
Get the number of components.
Definition: name.hpp:329
A Name holds an array of Name::Component and represents an NDN name.
Definition: name.hpp:26
const PendingInterestId * expressInterest(const Interest &interest, const OnData &onData, const OnTimeout &onTimeout=OnTimeout())
Express Interest.
Definition: face.cpp:125
const Block & wireEncode() const
size_t value_size() const
Definition: block.hpp:455
void parse() const
Parse wire buffer into subblocks.
Definition: block.cpp:265
const Block & getContent() const
Get content Block.
Definition: data.hpp:411
Name & append(const uint8_t *value, size_t valueLength)
Append a new component, copying from value of length valueLength.
Definition: name.hpp:142
void setName(const Name &name)
Set name to a copy of the given Name.
Definition: data.hpp:352
Interest & setInterestLifetime(const time::milliseconds &interestLifetime)
Definition: interest.hpp:236
void setSignature(const Signature &signature)
Set the signature to a copy of the given signature.
Definition: data.hpp:456