blob: 09f5dbaa70303e561b4e506a7f3ac6dfcda6256d [file] [log] [blame]
hilatadd50ada2014-03-13 12:48:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev319f2c82015-01-07 14:56:53 -08003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -070024 */
Davide Pesavento6fc750f2014-03-18 19:49:39 +010025
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070026#include "version.hpp"
27
Alexander Afanasyev4a771362014-04-24 21:29:33 -070028#include <ndn-cxx/face.hpp>
Junxiao Shi8e273ca2014-11-12 00:42:29 -070029#include <ndn-cxx/security/key-chain.hpp>
Alexander Afanasyev4a771362014-04-24 21:29:33 -070030#include <ndn-cxx/management/nfd-controller.hpp>
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -070031#include <ndn-cxx/management/nfd-face-status.hpp>
Alexander Afanasyev4a771362014-04-24 21:29:33 -070032#include <ndn-cxx/security/key-chain.hpp>
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -070033#include <ndn-cxx/encoding/buffer-stream.hpp>
Junxiao Shia1937bf2014-11-06 11:43:40 -070034#include <ndn-cxx/util/face-uri.hpp>
hilatadd50ada2014-03-13 12:48:47 -050035
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070036#include <boost/lexical_cast.hpp>
Junxiao Shia1937bf2014-11-06 11:43:40 -070037#include <boost/noncopyable.hpp>
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070038
hilatadd50ada2014-03-13 12:48:47 -050039#include <sys/types.h>
40#include <netinet/in.h>
41#include <arpa/nameser.h>
42#include <resolv.h>
43
44#ifdef __APPLE__
45#include <arpa/nameser_compat.h>
46#endif
47
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -070048namespace ndn {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070049namespace tools {
50
Alexander Afanasyev6fce0782014-06-18 16:59:54 -070051static const Name LOCALHOP_HUB_DISCOVERY_PREFIX = "/localhop/ndn-autoconf/hub";
52
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070053void
54usage(const char* programName)
55{
56 std::cout << "Usage:\n" << programName << " [-h] [-V]\n"
57 << " -h - print usage and exit\n"
58 << " -V - print version number and exit\n"
59 << std::endl;
60}
61
Junxiao Shia1937bf2014-11-06 11:43:40 -070062class NdnAutoconfig : boost::noncopyable
hilatadd50ada2014-03-13 12:48:47 -050063{
64public:
65 union QueryAnswer
66 {
67 HEADER header;
68 uint8_t buf[NS_PACKETSZ];
69 };
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070070
71 class Error : public std::runtime_error
hilatadd50ada2014-03-13 12:48:47 -050072 {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070073 public:
74 explicit
75 Error(const std::string& what)
76 : std::runtime_error(what)
hilatadd50ada2014-03-13 12:48:47 -050077 {
78 }
79 };
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070080
hilatadd50ada2014-03-13 12:48:47 -050081 explicit
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070082 NdnAutoconfig()
Junxiao Shi8e273ca2014-11-12 00:42:29 -070083 : m_controller(m_face, m_keyChain)
hilatadd50ada2014-03-13 12:48:47 -050084 {
85 }
Davide Pesavento6fc750f2014-03-18 19:49:39 +010086
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -070087 void
88 run()
89 {
90 m_face.processEvents();
91 }
92
93 void
94 fetchSegments(const Data& data, const shared_ptr<OBufferStream>& buffer,
95 void (NdnAutoconfig::*onDone)(const shared_ptr<OBufferStream>&))
96 {
97 buffer->write(reinterpret_cast<const char*>(data.getContent().value()),
98 data.getContent().value_size());
99
100 uint64_t currentSegment = data.getName().get(-1).toSegment();
101
102 const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
103 if (finalBlockId.empty() ||
104 finalBlockId.toSegment() > currentSegment)
105 {
106 m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200107 ndn::bind(&NdnAutoconfig::fetchSegments, this, _2, buffer, onDone),
108 ndn::bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700109 }
110 else
111 {
112 return (this->*onDone)(buffer);
113 }
114 }
115
hilatadd50ada2014-03-13 12:48:47 -0500116 void
117 discoverHubStage1()
118 {
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700119 shared_ptr<OBufferStream> buffer = make_shared<OBufferStream>();
120
121 Interest interest("/localhost/nfd/faces/list");
122 interest.setChildSelector(1);
123 interest.setMustBeFresh(true);
124
125 m_face.expressInterest(interest,
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200126 ndn::bind(&NdnAutoconfig::fetchSegments, this, _2, buffer,
127 &NdnAutoconfig::discoverHubStage1_registerHubDiscoveryPrefix),
128 ndn::bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700129 }
130
131 void
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700132 discoverHubStage1_registerHubDiscoveryPrefix(const shared_ptr<OBufferStream>& buffer)
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700133 {
134 ConstBufferPtr buf = buffer->buf();
135 std::vector<uint64_t> multicastFaces;
136
137 size_t offset = 0;
138 while (offset < buf->size())
139 {
140 Block block;
141 bool ok = Block::fromBuffer(buf, offset, block);
142 if (!ok)
143 {
144 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
145 break;
146 }
147
148 offset += block.size();
149
150 nfd::FaceStatus faceStatus(block);
151
Junxiao Shia1937bf2014-11-06 11:43:40 -0700152 ndn::util::FaceUri uri(faceStatus.getRemoteUri());
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700153 if (uri.getScheme() == "udp4") {
154 namespace ip = boost::asio::ip;
155 boost::system::error_code ec;
156 ip::address address = ip::address::from_string(uri.getHost(), ec);
157
158 if (!ec && address.is_multicast()) {
159 multicastFaces.push_back(faceStatus.getFaceId());
160 }
161 else
162 continue;
163 }
164 }
165
166 if (multicastFaces.empty()) {
167 discoverHubStage2("No multicast faces available, skipping stage 1");
168 }
169 else {
170 shared_ptr<nfd::Controller> controller = make_shared<nfd::Controller>(ref(m_face));
171 shared_ptr<std::pair<size_t, size_t> > nRegistrations =
172 make_shared<std::pair<size_t, size_t> >(0, 0);
173
174 nfd::ControlParameters parameters;
175 parameters
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700176 .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
Junxiao Shia753f1b2014-07-01 22:25:14 -0700177 .setCost(1)
178 .setExpirationPeriod(time::seconds(30));
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700179
180 nRegistrations->first = multicastFaces.size();
181
182 for (std::vector<uint64_t>::iterator i = multicastFaces.begin();
183 i != multicastFaces.end(); ++i) {
184 parameters.setFaceId(*i);
185
186 controller->start<nfd::RibRegisterCommand>(parameters,
187 bind(&NdnAutoconfig::discoverHubStage1_onRegisterSuccess,
188 this, controller, nRegistrations),
189 bind(&NdnAutoconfig::discoverHubStage1_onRegisterFailure,
190 this, _1, _2, controller, nRegistrations));
191 }
192 }
193 }
194
195 void
196 discoverHubStage1_onRegisterSuccess(const shared_ptr<nfd::Controller>& controller,
197 const shared_ptr<std::pair<size_t, size_t> >& nRegistrations)
198 {
199 nRegistrations->second++;
200
201 if (nRegistrations->first == nRegistrations->second) {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700202 discoverHubStage1_setStrategy(controller);
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700203 }
204 }
205
206 void
207 discoverHubStage1_onRegisterFailure(uint32_t code, const std::string& error,
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700208 const shared_ptr<nfd::Controller>& controller,
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700209 const shared_ptr<std::pair<size_t, size_t> >& nRegistrations)
210 {
211 std::cerr << "ERROR: " << error << " (code: " << code << ")" << std::endl;
212 nRegistrations->first--;
213
214 if (nRegistrations->first == nRegistrations->second) {
215 if (nRegistrations->first > 0) {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700216 discoverHubStage1_setStrategy(controller);
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700217 } else {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700218 discoverHubStage2("Failed to register " + LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() +
219 " for all multicast faces");
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700220 }
221 }
222 }
223
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700224 void
225 discoverHubStage1_setStrategy(const shared_ptr<nfd::Controller>& controller)
226 {
227 nfd::ControlParameters parameters;
228 parameters
229 .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
230 .setStrategy("/localhost/nfd/strategy/broadcast");
231
232 controller->start<nfd::StrategyChoiceSetCommand>(parameters,
233 bind(&NdnAutoconfig::discoverHubStage1_onSetStrategySuccess,
234 this, controller),
235 bind(&NdnAutoconfig::discoverHubStage1_onSetStrategyFailure,
236 this, _2, controller));
237 }
238
239 void
240 discoverHubStage1_onSetStrategySuccess(const shared_ptr<nfd::Controller>& controller)
241 {
242 discoverHubStage1_requestHubData();
243 }
244
245 void
246 discoverHubStage1_onSetStrategyFailure(const std::string& error,
247 const shared_ptr<nfd::Controller>& controller)
248 {
249 discoverHubStage2("Failed to set broadcast strategy for " +
250 LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() + " namespace (" + error + ")");
251 }
252
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700253 // Start to look for a hub (NDN hub discovery first stage)
254 void
255 discoverHubStage1_requestHubData()
256 {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700257 Interest interest(LOCALHOP_HUB_DISCOVERY_PREFIX);
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700258 interest.setInterestLifetime(time::milliseconds(4000)); // 4 seconds
hilatadd50ada2014-03-13 12:48:47 -0500259 interest.setMustBeFresh(true);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700260
hilata3a4eb5c2014-04-29 00:32:05 -0500261 std::cerr << "Stage 1: Trying multicast discovery..." << std::endl;
hilatadd50ada2014-03-13 12:48:47 -0500262 m_face.expressInterest(interest,
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700263 bind(&NdnAutoconfig::onDiscoverHubStage1Success, this, _1, _2),
264 bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
hilatadd50ada2014-03-13 12:48:47 -0500265 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700266
hilatadd50ada2014-03-13 12:48:47 -0500267 // First stage OnData Callback
268 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700269 onDiscoverHubStage1Success(const Interest& interest, Data& data)
hilatadd50ada2014-03-13 12:48:47 -0500270 {
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700271 const Block& content = data.getContent();
hilatadd50ada2014-03-13 12:48:47 -0500272 content.parse();
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700273
hilatadd50ada2014-03-13 12:48:47 -0500274 // Get Uri
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700275 Block::element_const_iterator blockValue = content.find(tlv::nfd::Uri);
Hila Ben Abraham6cdbdfc2015-01-16 00:52:17 -0600276 if (blockValue == content.elements_end()) {
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700277 discoverHubStage2("Incorrect reply to stage1");
hilatadd50ada2014-03-13 12:48:47 -0500278 return;
279 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700280 std::string faceMgmtUri(reinterpret_cast<const char*>(blockValue->value()),
281 blockValue->value_size());
hilatadd50ada2014-03-13 12:48:47 -0500282 connectToHub(faceMgmtUri);
283 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700284
hilatadd50ada2014-03-13 12:48:47 -0500285 // First stage OnTimeout callback - start 2nd stage
286 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700287 discoverHubStage2(const std::string& message)
hilatadd50ada2014-03-13 12:48:47 -0500288 {
289 std::cerr << message << std::endl;
290 std::cerr << "Stage 2: Trying DNS query with default suffix..." << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700291
292 _res.retry = 2;
hilatadd50ada2014-03-13 12:48:47 -0500293 _res.ndots = 10;
294
295 QueryAnswer queryAnswer;
296
297 int answerSize = res_search("_ndn._udp",
298 ns_c_in,
299 ns_t_srv,
300 queryAnswer.buf,
301 sizeof(queryAnswer));
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700302
hilatadd50ada2014-03-13 12:48:47 -0500303 // 2nd stage failed - move on to the third stage
Hila Ben Abraham6cdbdfc2015-01-16 00:52:17 -0600304 if (answerSize < 0) {
hilatadd50ada2014-03-13 12:48:47 -0500305 discoverHubStage3("Failed to find NDN router using default suffix DNS query");
306 }
307 else
308 {
309 bool isParsed = parseHostAndConnectToHub(queryAnswer, answerSize);
Hila Ben Abraham6cdbdfc2015-01-16 00:52:17 -0600310 if (isParsed == false) {
hilatadd50ada2014-03-13 12:48:47 -0500311 // Failed to parse DNS response, try stage 3
312 discoverHubStage3("Failed to parse DNS response");
313 }
314 }
315 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700316
hilatadd50ada2014-03-13 12:48:47 -0500317 // Second stage OnTimeout callback
318 void
319 discoverHubStage3(const std::string& message)
320 {
321 std::cerr << message << std::endl;
322 std::cerr << "Stage 3: Trying to find home router..." << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700323
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700324 KeyChain keyChain;
325 Name identity = keyChain.getDefaultIdentity();
hilatadd50ada2014-03-13 12:48:47 -0500326 std::string serverName = "_ndn._udp.";
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700327
Hila Ben Abraham6cdbdfc2015-01-16 00:52:17 -0600328 for (Name::const_reverse_iterator i = identity.rbegin(); i != identity.rend(); i++) {
Alexander Afanasyevb3893c92014-05-15 01:49:54 -0700329 serverName.append(i->toUri());
hilatadd50ada2014-03-13 12:48:47 -0500330 serverName.append(".");
331 }
332 serverName += "_homehub._autoconf.named-data.net";
333 std::cerr << "Stage3: About to query for a home router: " << serverName << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700334
hilatadd50ada2014-03-13 12:48:47 -0500335 QueryAnswer queryAnswer;
336
337 int answerSize = res_query(serverName.c_str(),
338 ns_c_in,
339 ns_t_srv,
340 queryAnswer.buf,
341 sizeof(queryAnswer));
342
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700343
hilatadd50ada2014-03-13 12:48:47 -0500344 // 3rd stage failed - abort
Hila Ben Abraham6cdbdfc2015-01-16 00:52:17 -0600345 if (answerSize < 0) {
hilatadd50ada2014-03-13 12:48:47 -0500346 std::cerr << "Failed to find a home router" << std::endl;
347 std::cerr << "exit" << std::endl;
348 }
349 else
350 {
351 bool isParsed = parseHostAndConnectToHub(queryAnswer, answerSize);
Hila Ben Abraham6cdbdfc2015-01-16 00:52:17 -0600352 if (isParsed == false) {
hilatadd50ada2014-03-13 12:48:47 -0500353 // Failed to parse DNS response
354 throw Error("Failed to parse DNS response");
355 }
356 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700357
hilatadd50ada2014-03-13 12:48:47 -0500358 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700359
Hila Ben Abraham6cdbdfc2015-01-16 00:52:17 -0600360 bool
361 parseHostAndConnectToHub(QueryAnswer& queryAnswer, int answerSize)
362 {
363 // The references of the next classes are:
364 // http://www.diablotin.com/librairie/networking/dnsbind/ch14_02.htm
365 // https://gist.github.com/mologie/6027597
366
367 struct rechdr
368 {
369 uint16_t type;
370 uint16_t iclass;
371 uint32_t ttl;
372 uint16_t length;
373 };
374
375 struct srv_t
376 {
377 uint16_t priority;
378 uint16_t weight;
379 uint16_t port;
380 uint8_t* target;
381 };
382
383 if (ntohs(queryAnswer.header.ancount) == 0) {
384 std::cerr << "No records found\n" << std::endl;
385 return false;
386 }
387
388 uint8_t* blob = queryAnswer.buf + NS_HFIXEDSZ;
389
390 blob += dn_skipname(blob, queryAnswer.buf + answerSize) + NS_QFIXEDSZ;
391
392 for (int i = 0; i < ntohs(queryAnswer.header.ancount); i++) {
393 char srvName[NS_MAXDNAME];
394 int serverNameSize = dn_expand(queryAnswer.buf, // message pointer
395 queryAnswer.buf + answerSize, // end of message
396 blob, // compressed server name
397 srvName, // expanded server name
398 NS_MAXDNAME);
399 if (serverNameSize < 0) {
400 return false;
401 }
402
403 srv_t* server = reinterpret_cast<srv_t*>(&blob[sizeof(rechdr)]);
404 uint16_t convertedPort = be16toh(server->port);
405
406 blob += serverNameSize + NS_HFIXEDSZ + NS_QFIXEDSZ;
407
408 char hostName[NS_MAXDNAME];
409 int hostNameSize = dn_expand(queryAnswer.buf, // message pointer
410 queryAnswer.buf + answerSize, // end of message
411 blob, // compressed host name
412 hostName, // expanded host name
413 NS_MAXDNAME);
414 if (hostNameSize < 0) {
415 return false;
416 }
417
418 std::string uri = "udp://";
419 uri.append(hostName);
420 uri.append(":");
421 uri.append(boost::lexical_cast<std::string>(convertedPort));
422
423 connectToHub(uri);
424
425 return true;
426 }
427 return false;
428 }
429
hilatadd50ada2014-03-13 12:48:47 -0500430 void
431 connectToHub(const std::string& uri)
432 {
Hila Ben Abraham6cdbdfc2015-01-16 00:52:17 -0600433 ndn::util::FaceUri faceUri(uri);
434
435 faceUri.canonize(bind(&NdnAutoconfig::onCanonizeSuccess, this, _1),
436 bind(&NdnAutoconfig::onCanonizeFailure, this, _1),
437 m_face.getIoService(), ndn::time::seconds(4));
438
439 }
440
441 void onCanonizeSuccess(const ndn::util::FaceUri& canonicalUri)
442 {
443 std::cerr << "about to connect to: " << canonicalUri.toString() << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700444
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700445 m_controller.start<nfd::FaceCreateCommand>(
446 nfd::ControlParameters()
Hila Ben Abraham6cdbdfc2015-01-16 00:52:17 -0600447 .setUri(canonicalUri.toString()),
hilata3a4eb5c2014-04-29 00:32:05 -0500448 bind(&NdnAutoconfig::onHubConnectSuccess, this, _1),
Hila Ben Abraham6cdbdfc2015-01-16 00:52:17 -0600449 bind(&NdnAutoconfig::onHubConnectError, this, _1, _2));
450 }
451
452 void
453 onCanonizeFailure(const std::string& reason)
454 {
455 std::ostringstream os;
456 os << "Canonize faceUri failed: " << reason;
457 throw Error(os.str());
hilatadd50ada2014-03-13 12:48:47 -0500458 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700459
hilatadd50ada2014-03-13 12:48:47 -0500460 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700461 onHubConnectSuccess(const nfd::ControlParameters& resp)
hilatadd50ada2014-03-13 12:48:47 -0500462 {
hilata3a4eb5c2014-04-29 00:32:05 -0500463 std::cerr << "Successfully created face: " << resp << std::endl;
hilataf4f86732014-05-03 19:06:34 -0500464
465 // Register a prefix in RIB
Junxiao Shia753f1b2014-07-01 22:25:14 -0700466 static const Name TESTBED_PREFIX("/ndn");
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700467 m_controller.start<nfd::RibRegisterCommand>(
Junxiao Shia753f1b2014-07-01 22:25:14 -0700468 nfd::ControlParameters()
469 .setName(TESTBED_PREFIX)
470 .setFaceId(resp.getFaceId())
471 .setOrigin(nfd::ROUTE_ORIGIN_AUTOCONF)
472 .setCost(100)
473 .setExpirationPeriod(time::milliseconds::max()),
hilataf4f86732014-05-03 19:06:34 -0500474 bind(&NdnAutoconfig::onPrefixRegistrationSuccess, this, _1),
475 bind(&NdnAutoconfig::onPrefixRegistrationError, this, _1, _2));
hilatadd50ada2014-03-13 12:48:47 -0500476 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700477
hilatadd50ada2014-03-13 12:48:47 -0500478 void
hilata3a4eb5c2014-04-29 00:32:05 -0500479 onHubConnectError(uint32_t code, const std::string& error)
hilatadd50ada2014-03-13 12:48:47 -0500480 {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700481 std::ostringstream os;
hilata3a4eb5c2014-04-29 00:32:05 -0500482 os << "Failed to create face: " << error << " (code: " << code << ")";
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700483 throw Error(os.str());
hilatadd50ada2014-03-13 12:48:47 -0500484 }
485
hilataf4f86732014-05-03 19:06:34 -0500486 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700487 onPrefixRegistrationSuccess(const nfd::ControlParameters& commandSuccessResult)
hilataf4f86732014-05-03 19:06:34 -0500488 {
489 std::cerr << "Successful in name registration: " << commandSuccessResult << std::endl;
490 }
491
492 void
493 onPrefixRegistrationError(uint32_t code, const std::string& error)
494 {
495 std::ostringstream os;
496 os << "Failed in name registration, " << error << " (code: " << code << ")";
497 throw Error(os.str());
498 }
499
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700500private:
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700501 Face m_face;
Junxiao Shi8e273ca2014-11-12 00:42:29 -0700502 KeyChain m_keyChain;
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700503 nfd::Controller m_controller;
hilatadd50ada2014-03-13 12:48:47 -0500504};
505
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700506} // namespace tools
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700507} // namespace ndn
hilatadd50ada2014-03-13 12:48:47 -0500508
509int
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700510main(int argc, char** argv)
hilatadd50ada2014-03-13 12:48:47 -0500511{
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700512 int opt;
513 const char* programName = argv[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700514
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700515 while ((opt = getopt(argc, argv, "hV")) != -1) {
516 switch (opt) {
517 case 'h':
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700518 ndn::tools::usage(programName);
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700519 return 0;
520 case 'V':
521 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
522 return 0;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700523 }
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700524 }
525
526 try {
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700527 ndn::tools::NdnAutoconfig autoConfigInstance;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700528
529 autoConfigInstance.discoverHubStage1();
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700530 autoConfigInstance.run();
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700531 }
532 catch (const std::exception& error) {
533 std::cerr << "ERROR: " << error.what() << std::endl;
534 return 1;
535 }
hilatadd50ada2014-03-13 12:48:47 -0500536 return 0;
537}