blob: f73ef949c9fe77a7b7566e6ff3aed8b4d5345928 [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)
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700176 .setCost(1);
177
178 nRegistrations->first = multicastFaces.size();
179
180 for (std::vector<uint64_t>::iterator i = multicastFaces.begin();
181 i != multicastFaces.end(); ++i) {
182 parameters.setFaceId(*i);
183
184 controller->start<nfd::RibRegisterCommand>(parameters,
185 bind(&NdnAutoconfig::discoverHubStage1_onRegisterSuccess,
186 this, controller, nRegistrations),
187 bind(&NdnAutoconfig::discoverHubStage1_onRegisterFailure,
188 this, _1, _2, controller, nRegistrations));
189 }
190 }
191 }
192
193 void
194 discoverHubStage1_onRegisterSuccess(const shared_ptr<nfd::Controller>& controller,
195 const shared_ptr<std::pair<size_t, size_t> >& nRegistrations)
196 {
197 nRegistrations->second++;
198
199 if (nRegistrations->first == nRegistrations->second) {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700200 discoverHubStage1_setStrategy(controller);
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700201 }
202 }
203
204 void
205 discoverHubStage1_onRegisterFailure(uint32_t code, const std::string& error,
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700206 const shared_ptr<nfd::Controller>& controller,
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700207 const shared_ptr<std::pair<size_t, size_t> >& nRegistrations)
208 {
209 std::cerr << "ERROR: " << error << " (code: " << code << ")" << std::endl;
210 nRegistrations->first--;
211
212 if (nRegistrations->first == nRegistrations->second) {
213 if (nRegistrations->first > 0) {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700214 discoverHubStage1_setStrategy(controller);
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700215 } else {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700216 discoverHubStage2("Failed to register " + LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() +
217 " for all multicast faces");
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700218 }
219 }
220 }
221
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700222 void
223 discoverHubStage1_setStrategy(const shared_ptr<nfd::Controller>& controller)
224 {
225 nfd::ControlParameters parameters;
226 parameters
227 .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
228 .setStrategy("/localhost/nfd/strategy/broadcast");
229
230 controller->start<nfd::StrategyChoiceSetCommand>(parameters,
231 bind(&NdnAutoconfig::discoverHubStage1_onSetStrategySuccess,
232 this, controller),
233 bind(&NdnAutoconfig::discoverHubStage1_onSetStrategyFailure,
234 this, _2, controller));
235 }
236
237 void
238 discoverHubStage1_onSetStrategySuccess(const shared_ptr<nfd::Controller>& controller)
239 {
240 discoverHubStage1_requestHubData();
241 }
242
243 void
244 discoverHubStage1_onSetStrategyFailure(const std::string& error,
245 const shared_ptr<nfd::Controller>& controller)
246 {
247 discoverHubStage2("Failed to set broadcast strategy for " +
248 LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() + " namespace (" + error + ")");
249 }
250
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700251 // Start to look for a hub (NDN hub discovery first stage)
252 void
253 discoverHubStage1_requestHubData()
254 {
Alexander Afanasyev6fce0782014-06-18 16:59:54 -0700255 Interest interest(LOCALHOP_HUB_DISCOVERY_PREFIX);
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700256 interest.setInterestLifetime(time::milliseconds(4000)); // 4 seconds
hilatadd50ada2014-03-13 12:48:47 -0500257 interest.setMustBeFresh(true);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700258
hilata3a4eb5c2014-04-29 00:32:05 -0500259 std::cerr << "Stage 1: Trying multicast discovery..." << std::endl;
hilatadd50ada2014-03-13 12:48:47 -0500260 m_face.expressInterest(interest,
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700261 bind(&NdnAutoconfig::onDiscoverHubStage1Success, this, _1, _2),
262 bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
hilatadd50ada2014-03-13 12:48:47 -0500263 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700264
hilatadd50ada2014-03-13 12:48:47 -0500265 // First stage OnData Callback
266 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700267 onDiscoverHubStage1Success(const Interest& interest, Data& data)
hilatadd50ada2014-03-13 12:48:47 -0500268 {
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700269 const Block& content = data.getContent();
hilatadd50ada2014-03-13 12:48:47 -0500270 content.parse();
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700271
hilatadd50ada2014-03-13 12:48:47 -0500272 // Get Uri
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700273 Block::element_const_iterator blockValue = content.find(tlv::nfd::Uri);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700274 if (blockValue == content.elements_end())
hilatadd50ada2014-03-13 12:48:47 -0500275 {
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700276 discoverHubStage2("Incorrect reply to stage1");
hilatadd50ada2014-03-13 12:48:47 -0500277 return;
278 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700279 std::string faceMgmtUri(reinterpret_cast<const char*>(blockValue->value()),
280 blockValue->value_size());
hilatadd50ada2014-03-13 12:48:47 -0500281 connectToHub(faceMgmtUri);
282 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700283
hilatadd50ada2014-03-13 12:48:47 -0500284 // First stage OnTimeout callback - start 2nd stage
285 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700286 discoverHubStage2(const std::string& message)
hilatadd50ada2014-03-13 12:48:47 -0500287 {
288 std::cerr << message << std::endl;
289 std::cerr << "Stage 2: Trying DNS query with default suffix..." << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700290
291 _res.retry = 2;
hilatadd50ada2014-03-13 12:48:47 -0500292 _res.ndots = 10;
293
294 QueryAnswer queryAnswer;
295
296 int answerSize = res_search("_ndn._udp",
297 ns_c_in,
298 ns_t_srv,
299 queryAnswer.buf,
300 sizeof(queryAnswer));
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700301
hilatadd50ada2014-03-13 12:48:47 -0500302 // 2nd stage failed - move on to the third stage
303 if (answerSize < 0)
304 {
305 discoverHubStage3("Failed to find NDN router using default suffix DNS query");
306 }
307 else
308 {
309 bool isParsed = parseHostAndConnectToHub(queryAnswer, answerSize);
310 if (isParsed == false)
311 {
312 // Failed to parse DNS response, try stage 3
313 discoverHubStage3("Failed to parse DNS response");
314 }
315 }
316 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700317
hilatadd50ada2014-03-13 12:48:47 -0500318 // Second stage OnTimeout callback
319 void
320 discoverHubStage3(const std::string& message)
321 {
322 std::cerr << message << std::endl;
323 std::cerr << "Stage 3: Trying to find home router..." << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700324
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700325 KeyChain keyChain;
326 Name identity = keyChain.getDefaultIdentity();
hilatadd50ada2014-03-13 12:48:47 -0500327 std::string serverName = "_ndn._udp.";
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700328
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700329 for (Name::const_reverse_iterator i = identity.rbegin(); i != identity.rend(); i++)
hilatadd50ada2014-03-13 12:48:47 -0500330 {
Alexander Afanasyevb3893c92014-05-15 01:49:54 -0700331 serverName.append(i->toUri());
hilatadd50ada2014-03-13 12:48:47 -0500332 serverName.append(".");
333 }
334 serverName += "_homehub._autoconf.named-data.net";
335 std::cerr << "Stage3: About to query for a home router: " << serverName << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700336
hilatadd50ada2014-03-13 12:48:47 -0500337 QueryAnswer queryAnswer;
338
339 int answerSize = res_query(serverName.c_str(),
340 ns_c_in,
341 ns_t_srv,
342 queryAnswer.buf,
343 sizeof(queryAnswer));
344
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700345
hilatadd50ada2014-03-13 12:48:47 -0500346 // 3rd stage failed - abort
347 if (answerSize < 0)
348 {
349 std::cerr << "Failed to find a home router" << std::endl;
350 std::cerr << "exit" << std::endl;
351 }
352 else
353 {
354 bool isParsed = parseHostAndConnectToHub(queryAnswer, answerSize);
355 if (isParsed == false)
356 {
357 // Failed to parse DNS response
358 throw Error("Failed to parse DNS response");
359 }
360 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700361
hilatadd50ada2014-03-13 12:48:47 -0500362 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700363
hilatadd50ada2014-03-13 12:48:47 -0500364 void
365 connectToHub(const std::string& uri)
366 {
367 std::cerr << "about to connect to: " << uri << std::endl;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700368
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700369 m_controller.start<nfd::FaceCreateCommand>(
370 nfd::ControlParameters()
hilata3a4eb5c2014-04-29 00:32:05 -0500371 .setUri(uri),
372 bind(&NdnAutoconfig::onHubConnectSuccess, this, _1),
373 bind(&NdnAutoconfig::onHubConnectError, this, _1, _2)
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700374 );
hilatadd50ada2014-03-13 12:48:47 -0500375 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700376
hilatadd50ada2014-03-13 12:48:47 -0500377 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700378 onHubConnectSuccess(const nfd::ControlParameters& resp)
hilatadd50ada2014-03-13 12:48:47 -0500379 {
hilata3a4eb5c2014-04-29 00:32:05 -0500380 std::cerr << "Successfully created face: " << resp << std::endl;
hilataf4f86732014-05-03 19:06:34 -0500381
382 // Register a prefix in RIB
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700383 nfd::ControlParameters ribParameters;
hilataf4f86732014-05-03 19:06:34 -0500384 ribParameters
385 .setName("/ndn")
386 .setFaceId(resp.getFaceId());
387
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700388 m_controller.start<nfd::RibRegisterCommand>(
hilataf4f86732014-05-03 19:06:34 -0500389 ribParameters,
390 bind(&NdnAutoconfig::onPrefixRegistrationSuccess, this, _1),
391 bind(&NdnAutoconfig::onPrefixRegistrationError, this, _1, _2));
hilatadd50ada2014-03-13 12:48:47 -0500392 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700393
hilatadd50ada2014-03-13 12:48:47 -0500394 void
hilata3a4eb5c2014-04-29 00:32:05 -0500395 onHubConnectError(uint32_t code, const std::string& error)
hilatadd50ada2014-03-13 12:48:47 -0500396 {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700397 std::ostringstream os;
hilata3a4eb5c2014-04-29 00:32:05 -0500398 os << "Failed to create face: " << error << " (code: " << code << ")";
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700399 throw Error(os.str());
hilatadd50ada2014-03-13 12:48:47 -0500400 }
401
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700402
hilatadd50ada2014-03-13 12:48:47 -0500403 bool parseHostAndConnectToHub(QueryAnswer& queryAnswer, int answerSize)
404 {
405 // The references of the next classes are:
406 // http://www.diablotin.com/librairie/networking/dnsbind/ch14_02.htm
407 // https://gist.github.com/mologie/6027597
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700408
409 struct rechdr
hilatadd50ada2014-03-13 12:48:47 -0500410 {
hilatadd50ada2014-03-13 12:48:47 -0500411 uint16_t type;
412 uint16_t iclass;
413 uint32_t ttl;
414 uint16_t length;
415 };
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700416
417 struct srv_t
hilatadd50ada2014-03-13 12:48:47 -0500418 {
hilatadd50ada2014-03-13 12:48:47 -0500419 uint16_t priority;
420 uint16_t weight;
421 uint16_t port;
422 uint8_t* target;
423 };
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700424
hilatadd50ada2014-03-13 12:48:47 -0500425 if (ntohs(queryAnswer.header.ancount) == 0)
426 {
427 std::cerr << "No records found\n" << std::endl;
428 return false;
429 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700430
hilatadd50ada2014-03-13 12:48:47 -0500431 uint8_t* blob = queryAnswer.buf + NS_HFIXEDSZ;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700432
hilatadd50ada2014-03-13 12:48:47 -0500433 blob += dn_skipname(blob, queryAnswer.buf + answerSize) + NS_QFIXEDSZ;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700434
hilatadd50ada2014-03-13 12:48:47 -0500435 for (int i = 0; i < ntohs(queryAnswer.header.ancount); i++)
436 {
hilata3a4eb5c2014-04-29 00:32:05 -0500437 char srvName[NS_MAXDNAME];
438 int serverNameSize = dn_expand(queryAnswer.buf, // message pointer
439 queryAnswer.buf + answerSize, // end of message
440 blob, // compressed server name
441 srvName, // expanded server name
hilatadd50ada2014-03-13 12:48:47 -0500442 NS_MAXDNAME);
hilata3a4eb5c2014-04-29 00:32:05 -0500443 if (serverNameSize < 0)
hilatadd50ada2014-03-13 12:48:47 -0500444 {
445 return false;
446 }
Davide Pesavento6fc750f2014-03-18 19:49:39 +0100447
448 srv_t* server = reinterpret_cast<srv_t*>(&blob[sizeof(rechdr)]);
hilatadd50ada2014-03-13 12:48:47 -0500449 uint16_t convertedPort = be16toh(server->port);
hilata3a4eb5c2014-04-29 00:32:05 -0500450
451 blob += serverNameSize + NS_HFIXEDSZ + NS_QFIXEDSZ;
452
453 char hostName[NS_MAXDNAME];
454 int hostNameSize = dn_expand(queryAnswer.buf, // message pointer
455 queryAnswer.buf + answerSize, // end of message
456 blob, // compressed host name
457 hostName, // expanded host name
458 NS_MAXDNAME);
459 if (hostNameSize < 0)
460 {
461 return false;
462 }
463
hilatadd50ada2014-03-13 12:48:47 -0500464 std::string uri = "udp://";
465 uri.append(hostName);
466 uri.append(":");
467 uri.append(boost::lexical_cast<std::string>(convertedPort));
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700468
hilatadd50ada2014-03-13 12:48:47 -0500469 connectToHub(uri);
470 return true;
471 }
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700472
473 return false;
hilatadd50ada2014-03-13 12:48:47 -0500474 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700475
hilataf4f86732014-05-03 19:06:34 -0500476 void
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700477 onPrefixRegistrationSuccess(const nfd::ControlParameters& commandSuccessResult)
hilataf4f86732014-05-03 19:06:34 -0500478 {
479 std::cerr << "Successful in name registration: " << commandSuccessResult << std::endl;
480 }
481
482 void
483 onPrefixRegistrationError(uint32_t code, const std::string& error)
484 {
485 std::ostringstream os;
486 os << "Failed in name registration, " << error << " (code: " << code << ")";
487 throw Error(os.str());
488 }
489
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700490private:
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700491 Face m_face;
492 nfd::Controller m_controller;
hilatadd50ada2014-03-13 12:48:47 -0500493};
494
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700495} // namespace tools
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700496} // namespace ndn
hilatadd50ada2014-03-13 12:48:47 -0500497
498int
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700499main(int argc, char** argv)
hilatadd50ada2014-03-13 12:48:47 -0500500{
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700501 int opt;
502 const char* programName = argv[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700503
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700504 while ((opt = getopt(argc, argv, "hV")) != -1) {
505 switch (opt) {
506 case 'h':
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700507 ndn::tools::usage(programName);
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700508 return 0;
509 case 'V':
510 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
511 return 0;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700512 }
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700513 }
514
515 try {
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700516 ndn::tools::NdnAutoconfig autoConfigInstance;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700517
518 autoConfigInstance.discoverHubStage1();
Alexander Afanasyev554ef7a2014-06-15 16:10:43 -0700519 autoConfigInstance.run();
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700520 }
521 catch (const std::exception& error) {
522 std::cerr << "ERROR: " << error.what() << std::endl;
523 return 1;
524 }
hilatadd50ada2014-03-13 12:48:47 -0500525 return 0;
526}