blob: 71bca2f454a5fded0ec68d6ca0a74f933de387f3 [file] [log] [blame]
hilatadd50ada2014-03-13 12:48:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -07003 * Copyright (c) 2014, 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 Afanasyev554ef7a2014-06-15 16:10:43 -070028#include "core/face-uri.hpp"
29
Alexander Afanasyev4a771362014-04-24 21:29:33 -070030#include <ndn-cxx/face.hpp>
31#include <ndn-cxx/management/nfd-controller.hpp>
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -070032#include <ndn-cxx/management/nfd-face-status.hpp>
Alexander Afanasyev4a771362014-04-24 21:29:33 -070033#include <ndn-cxx/security/key-chain.hpp>
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -070034#include <ndn-cxx/encoding/buffer-stream.hpp>
hilatadd50ada2014-03-13 12:48:47 -050035
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070036#include <boost/lexical_cast.hpp>
37
hilatadd50ada2014-03-13 12:48:47 -050038#include <sys/types.h>
39#include <netinet/in.h>
40#include <arpa/nameser.h>
41#include <resolv.h>
42
43#ifdef __APPLE__
44#include <arpa/nameser_compat.h>
45#endif
46
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -070047namespace ndn {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070048namespace tools {
49
Alexander Afanasyev6fce0782014-06-18 16:59:54 -070050static const Name LOCALHOP_HUB_DISCOVERY_PREFIX = "/localhop/ndn-autoconf/hub";
51
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070052void
53usage(const char* programName)
54{
55 std::cout << "Usage:\n" << programName << " [-h] [-V]\n"
56 << " -h - print usage and exit\n"
57 << " -V - print version number and exit\n"
58 << std::endl;
59}
60
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070061class NdnAutoconfig
hilatadd50ada2014-03-13 12:48:47 -050062{
63public:
64 union QueryAnswer
65 {
66 HEADER header;
67 uint8_t buf[NS_PACKETSZ];
68 };
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070069
70 class Error : public std::runtime_error
hilatadd50ada2014-03-13 12:48:47 -050071 {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070072 public:
73 explicit
74 Error(const std::string& what)
75 : std::runtime_error(what)
hilatadd50ada2014-03-13 12:48:47 -050076 {
77 }
78 };
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070079
hilatadd50ada2014-03-13 12:48:47 -050080 explicit
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070081 NdnAutoconfig()
82 : m_controller(m_face)
hilatadd50ada2014-03-13 12:48:47 -050083 {
84 }
Davide Pesavento6fc750f2014-03-18 19:49:39 +010085
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -070086 void
87 run()
88 {
89 m_face.processEvents();
90 }
91
92 void
93 fetchSegments(const Data& data, const shared_ptr<OBufferStream>& buffer,
94 void (NdnAutoconfig::*onDone)(const shared_ptr<OBufferStream>&))
95 {
96 buffer->write(reinterpret_cast<const char*>(data.getContent().value()),
97 data.getContent().value_size());
98
99 uint64_t currentSegment = data.getName().get(-1).toSegment();
100
101 const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
102 if (finalBlockId.empty() ||
103 finalBlockId.toSegment() > currentSegment)
104 {
105 m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
106 bind(&NdnAutoconfig::fetchSegments, this, _2, buffer, onDone),
107 bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
108 }
109 else
110 {
111 return (this->*onDone)(buffer);
112 }
113 }
114
hilatadd50ada2014-03-13 12:48:47 -0500115 void
116 discoverHubStage1()
117 {
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700118 shared_ptr<OBufferStream> buffer = make_shared<OBufferStream>();
119
120 Interest interest("/localhost/nfd/faces/list");
121 interest.setChildSelector(1);
122 interest.setMustBeFresh(true);
123
124 m_face.expressInterest(interest,
125 bind(&NdnAutoconfig::fetchSegments, this, _2, buffer,
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700126 &NdnAutoconfig::discoverHubStage1_registerHubDiscoveryPrefix),
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700127 bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
128 }
129
130 void
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700131 discoverHubStage1_registerHubDiscoveryPrefix(const shared_ptr<OBufferStream>& buffer)
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700132 {
133 ConstBufferPtr buf = buffer->buf();
134 std::vector<uint64_t> multicastFaces;
135
136 size_t offset = 0;
137 while (offset < buf->size())
138 {
139 Block block;
140 bool ok = Block::fromBuffer(buf, offset, block);
141 if (!ok)
142 {
143 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
144 break;
145 }
146
147 offset += block.size();
148
149 nfd::FaceStatus faceStatus(block);
150
151 ::nfd::FaceUri uri(faceStatus.getRemoteUri());
152 if (uri.getScheme() == "udp4") {
153 namespace ip = boost::asio::ip;
154 boost::system::error_code ec;
155 ip::address address = ip::address::from_string(uri.getHost(), ec);
156
157 if (!ec && address.is_multicast()) {
158 multicastFaces.push_back(faceStatus.getFaceId());
159 }
160 else
161 continue;
162 }
163 }
164
165 if (multicastFaces.empty()) {
166 discoverHubStage2("No multicast faces available, skipping stage 1");
167 }
168 else {
169 shared_ptr<nfd::Controller> controller = make_shared<nfd::Controller>(ref(m_face));
170 shared_ptr<std::pair<size_t, size_t> > nRegistrations =
171 make_shared<std::pair<size_t, size_t> >(0, 0);
172
173 nfd::ControlParameters parameters;
174 parameters
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700175 .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
Junxiao Shia753f1b2014-07-01 22:25:14 -0700176 .setCost(1)
177 .setExpirationPeriod(time::seconds(30));
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700178
179 nRegistrations->first = multicastFaces.size();
180
181 for (std::vector<uint64_t>::iterator i = multicastFaces.begin();
182 i != multicastFaces.end(); ++i) {
183 parameters.setFaceId(*i);
184
185 controller->start<nfd::RibRegisterCommand>(parameters,
186 bind(&NdnAutoconfig::discoverHubStage1_onRegisterSuccess,
187 this, controller, nRegistrations),
188 bind(&NdnAutoconfig::discoverHubStage1_onRegisterFailure,
189 this, _1, _2, controller, nRegistrations));
190 }
191 }
192 }
193
194 void
195 discoverHubStage1_onRegisterSuccess(const shared_ptr<nfd::Controller>& controller,
196 const shared_ptr<std::pair<size_t, size_t> >& nRegistrations)
197 {
198 nRegistrations->second++;
199
200 if (nRegistrations->first == nRegistrations->second) {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700201 discoverHubStage1_setStrategy(controller);
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700202 }
203 }
204
205 void
206 discoverHubStage1_onRegisterFailure(uint32_t code, const std::string& error,
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700207 const shared_ptr<nfd::Controller>& controller,
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700208 const shared_ptr<std::pair<size_t, size_t> >& nRegistrations)
209 {
210 std::cerr << "ERROR: " << error << " (code: " << code << ")" << std::endl;
211 nRegistrations->first--;
212
213 if (nRegistrations->first == nRegistrations->second) {
214 if (nRegistrations->first > 0) {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700215 discoverHubStage1_setStrategy(controller);
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700216 } else {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700217 discoverHubStage2("Failed to register " + LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() +
218 " for all multicast faces");
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700219 }
220 }
221 }
222
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700223 void
224 discoverHubStage1_setStrategy(const shared_ptr<nfd::Controller>& controller)
225 {
226 nfd::ControlParameters parameters;
227 parameters
228 .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
229 .setStrategy("/localhost/nfd/strategy/broadcast");
230
231 controller->start<nfd::StrategyChoiceSetCommand>(parameters,
232 bind(&NdnAutoconfig::discoverHubStage1_onSetStrategySuccess,
233 this, controller),
234 bind(&NdnAutoconfig::discoverHubStage1_onSetStrategyFailure,
235 this, _2, controller));
236 }
237
238 void
239 discoverHubStage1_onSetStrategySuccess(const shared_ptr<nfd::Controller>& controller)
240 {
241 discoverHubStage1_requestHubData();
242 }
243
244 void
245 discoverHubStage1_onSetStrategyFailure(const std::string& error,
246 const shared_ptr<nfd::Controller>& controller)
247 {
248 discoverHubStage2("Failed to set broadcast strategy for " +
249 LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() + " namespace (" + error + ")");
250 }
251
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700252 // Start to look for a hub (NDN hub discovery first stage)
253 void
254 discoverHubStage1_requestHubData()
255 {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700256 Interest interest(LOCALHOP_HUB_DISCOVERY_PREFIX);
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700257 interest.setInterestLifetime(time::milliseconds(4000)); // 4 seconds
hilatadd50ada2014-03-13 12:48:47 -0500258 interest.setMustBeFresh(true);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700259
hilata3a4eb5c2014-04-29 00:32:05 -0500260 std::cerr << "Stage 1: Trying multicast discovery..." << std::endl;
hilatadd50ada2014-03-13 12:48:47 -0500261 m_face.expressInterest(interest,
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700262 bind(&NdnAutoconfig::onDiscoverHubStage1Success, this, _1, _2),
263 bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
hilatadd50ada2014-03-13 12:48:47 -0500264 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700265
hilatadd50ada2014-03-13 12:48:47 -0500266 // First stage OnData Callback
267 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700268 onDiscoverHubStage1Success(const Interest& interest, Data& data)
hilatadd50ada2014-03-13 12:48:47 -0500269 {
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700270 const Block& content = data.getContent();
hilatadd50ada2014-03-13 12:48:47 -0500271 content.parse();
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700272
hilatadd50ada2014-03-13 12:48:47 -0500273 // Get Uri
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700274 Block::element_const_iterator blockValue = content.find(tlv::nfd::Uri);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700275 if (blockValue == content.elements_end())
hilatadd50ada2014-03-13 12:48:47 -0500276 {
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
304 if (answerSize < 0)
305 {
306 discoverHubStage3("Failed to find NDN router using default suffix DNS query");
307 }
308 else
309 {
310 bool isParsed = parseHostAndConnectToHub(queryAnswer, answerSize);
311 if (isParsed == false)
312 {
313 // Failed to parse DNS response, try stage 3
314 discoverHubStage3("Failed to parse DNS response");
315 }
316 }
317 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700318
hilatadd50ada2014-03-13 12:48:47 -0500319 // Second stage OnTimeout callback
320 void
321 discoverHubStage3(const std::string& message)
322 {
323 std::cerr << message << std::endl;
324 std::cerr << "Stage 3: Trying to find home router..." << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700325
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700326 KeyChain keyChain;
327 Name identity = keyChain.getDefaultIdentity();
hilatadd50ada2014-03-13 12:48:47 -0500328 std::string serverName = "_ndn._udp.";
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700329
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700330 for (Name::const_reverse_iterator i = identity.rbegin(); i != identity.rend(); i++)
hilatadd50ada2014-03-13 12:48:47 -0500331 {
Alexander Afanasyevb3893c92014-05-15 01:49:54 -0700332 serverName.append(i->toUri());
hilatadd50ada2014-03-13 12:48:47 -0500333 serverName.append(".");
334 }
335 serverName += "_homehub._autoconf.named-data.net";
336 std::cerr << "Stage3: About to query for a home router: " << serverName << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700337
hilatadd50ada2014-03-13 12:48:47 -0500338 QueryAnswer queryAnswer;
339
340 int answerSize = res_query(serverName.c_str(),
341 ns_c_in,
342 ns_t_srv,
343 queryAnswer.buf,
344 sizeof(queryAnswer));
345
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700346
hilatadd50ada2014-03-13 12:48:47 -0500347 // 3rd stage failed - abort
348 if (answerSize < 0)
349 {
350 std::cerr << "Failed to find a home router" << std::endl;
351 std::cerr << "exit" << std::endl;
352 }
353 else
354 {
355 bool isParsed = parseHostAndConnectToHub(queryAnswer, answerSize);
356 if (isParsed == false)
357 {
358 // Failed to parse DNS response
359 throw Error("Failed to parse DNS response");
360 }
361 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700362
hilatadd50ada2014-03-13 12:48:47 -0500363 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700364
hilatadd50ada2014-03-13 12:48:47 -0500365 void
366 connectToHub(const std::string& uri)
367 {
368 std::cerr << "about to connect to: " << uri << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700369
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700370 m_controller.start<nfd::FaceCreateCommand>(
371 nfd::ControlParameters()
hilata3a4eb5c2014-04-29 00:32:05 -0500372 .setUri(uri),
373 bind(&NdnAutoconfig::onHubConnectSuccess, this, _1),
374 bind(&NdnAutoconfig::onHubConnectError, this, _1, _2)
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700375 );
hilatadd50ada2014-03-13 12:48:47 -0500376 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700377
hilatadd50ada2014-03-13 12:48:47 -0500378 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700379 onHubConnectSuccess(const nfd::ControlParameters& resp)
hilatadd50ada2014-03-13 12:48:47 -0500380 {
hilata3a4eb5c2014-04-29 00:32:05 -0500381 std::cerr << "Successfully created face: " << resp << std::endl;
hilataf4f86732014-05-03 19:06:34 -0500382
383 // Register a prefix in RIB
Junxiao Shia753f1b2014-07-01 22:25:14 -0700384 static const Name TESTBED_PREFIX("/ndn");
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700385 m_controller.start<nfd::RibRegisterCommand>(
Junxiao Shia753f1b2014-07-01 22:25:14 -0700386 nfd::ControlParameters()
387 .setName(TESTBED_PREFIX)
388 .setFaceId(resp.getFaceId())
389 .setOrigin(nfd::ROUTE_ORIGIN_AUTOCONF)
390 .setCost(100)
391 .setExpirationPeriod(time::milliseconds::max()),
hilataf4f86732014-05-03 19:06:34 -0500392 bind(&NdnAutoconfig::onPrefixRegistrationSuccess, this, _1),
393 bind(&NdnAutoconfig::onPrefixRegistrationError, this, _1, _2));
hilatadd50ada2014-03-13 12:48:47 -0500394 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700395
hilatadd50ada2014-03-13 12:48:47 -0500396 void
hilata3a4eb5c2014-04-29 00:32:05 -0500397 onHubConnectError(uint32_t code, const std::string& error)
hilatadd50ada2014-03-13 12:48:47 -0500398 {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700399 std::ostringstream os;
hilata3a4eb5c2014-04-29 00:32:05 -0500400 os << "Failed to create face: " << error << " (code: " << code << ")";
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700401 throw Error(os.str());
hilatadd50ada2014-03-13 12:48:47 -0500402 }
403
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700404
hilatadd50ada2014-03-13 12:48:47 -0500405 bool parseHostAndConnectToHub(QueryAnswer& queryAnswer, int answerSize)
406 {
407 // The references of the next classes are:
408 // http://www.diablotin.com/librairie/networking/dnsbind/ch14_02.htm
409 // https://gist.github.com/mologie/6027597
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700410
411 struct rechdr
hilatadd50ada2014-03-13 12:48:47 -0500412 {
hilatadd50ada2014-03-13 12:48:47 -0500413 uint16_t type;
414 uint16_t iclass;
415 uint32_t ttl;
416 uint16_t length;
417 };
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700418
419 struct srv_t
hilatadd50ada2014-03-13 12:48:47 -0500420 {
hilatadd50ada2014-03-13 12:48:47 -0500421 uint16_t priority;
422 uint16_t weight;
423 uint16_t port;
424 uint8_t* target;
425 };
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700426
hilatadd50ada2014-03-13 12:48:47 -0500427 if (ntohs(queryAnswer.header.ancount) == 0)
428 {
429 std::cerr << "No records found\n" << std::endl;
430 return false;
431 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700432
hilatadd50ada2014-03-13 12:48:47 -0500433 uint8_t* blob = queryAnswer.buf + NS_HFIXEDSZ;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700434
hilatadd50ada2014-03-13 12:48:47 -0500435 blob += dn_skipname(blob, queryAnswer.buf + answerSize) + NS_QFIXEDSZ;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700436
hilatadd50ada2014-03-13 12:48:47 -0500437 for (int i = 0; i < ntohs(queryAnswer.header.ancount); i++)
438 {
hilata3a4eb5c2014-04-29 00:32:05 -0500439 char srvName[NS_MAXDNAME];
440 int serverNameSize = dn_expand(queryAnswer.buf, // message pointer
441 queryAnswer.buf + answerSize, // end of message
442 blob, // compressed server name
443 srvName, // expanded server name
hilatadd50ada2014-03-13 12:48:47 -0500444 NS_MAXDNAME);
hilata3a4eb5c2014-04-29 00:32:05 -0500445 if (serverNameSize < 0)
hilatadd50ada2014-03-13 12:48:47 -0500446 {
447 return false;
448 }
Davide Pesavento6fc750f2014-03-18 19:49:39 +0100449
450 srv_t* server = reinterpret_cast<srv_t*>(&blob[sizeof(rechdr)]);
hilatadd50ada2014-03-13 12:48:47 -0500451 uint16_t convertedPort = be16toh(server->port);
hilata3a4eb5c2014-04-29 00:32:05 -0500452
453 blob += serverNameSize + NS_HFIXEDSZ + NS_QFIXEDSZ;
454
455 char hostName[NS_MAXDNAME];
456 int hostNameSize = dn_expand(queryAnswer.buf, // message pointer
457 queryAnswer.buf + answerSize, // end of message
458 blob, // compressed host name
459 hostName, // expanded host name
460 NS_MAXDNAME);
461 if (hostNameSize < 0)
462 {
463 return false;
464 }
465
hilatadd50ada2014-03-13 12:48:47 -0500466 std::string uri = "udp://";
467 uri.append(hostName);
468 uri.append(":");
469 uri.append(boost::lexical_cast<std::string>(convertedPort));
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700470
hilatadd50ada2014-03-13 12:48:47 -0500471 connectToHub(uri);
472 return true;
473 }
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700474
475 return false;
hilatadd50ada2014-03-13 12:48:47 -0500476 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700477
hilataf4f86732014-05-03 19:06:34 -0500478 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700479 onPrefixRegistrationSuccess(const nfd::ControlParameters& commandSuccessResult)
hilataf4f86732014-05-03 19:06:34 -0500480 {
481 std::cerr << "Successful in name registration: " << commandSuccessResult << std::endl;
482 }
483
484 void
485 onPrefixRegistrationError(uint32_t code, const std::string& error)
486 {
487 std::ostringstream os;
488 os << "Failed in name registration, " << error << " (code: " << code << ")";
489 throw Error(os.str());
490 }
491
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700492private:
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700493 Face m_face;
494 nfd::Controller m_controller;
hilatadd50ada2014-03-13 12:48:47 -0500495};
496
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700497} // namespace tools
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700498} // namespace ndn
hilatadd50ada2014-03-13 12:48:47 -0500499
500int
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700501main(int argc, char** argv)
hilatadd50ada2014-03-13 12:48:47 -0500502{
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700503 int opt;
504 const char* programName = argv[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700505
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700506 while ((opt = getopt(argc, argv, "hV")) != -1) {
507 switch (opt) {
508 case 'h':
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700509 ndn::tools::usage(programName);
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700510 return 0;
511 case 'V':
512 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
513 return 0;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700514 }
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700515 }
516
517 try {
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700518 ndn::tools::NdnAutoconfig autoConfigInstance;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700519
520 autoConfigInstance.discoverHubStage1();
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700521 autoConfigInstance.run();
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700522 }
523 catch (const std::exception& error) {
524 std::cerr << "ERROR: " << error.what() << std::endl;
525 return 1;
526 }
hilatadd50ada2014-03-13 12:48:47 -0500527 return 0;
528}