blob: 8c594c7466805c02f5822e5e7ea73b04b533d11f [file] [log] [blame]
Alexander Afanasyev2a655f72015-01-26 18:38:33 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Davide Pesavento7a294d42017-02-21 21:46:44 -05003 * Copyright (c) 2014-2017, Regents of the University of California,
Alexander Afanasyev2a655f72015-01-26 18:38:33 -08004 * 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.
10 *
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/>.
24 */
25
26#include "multicast-discovery.hpp"
27
Davide Pesavento7a294d42017-02-21 21:46:44 -050028#include <ndn-cxx/encoding/tlv-nfd.hpp>
29
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080030namespace ndn {
31namespace tools {
32namespace autoconfig {
33
34static const Name LOCALHOP_HUB_DISCOVERY_PREFIX = "/localhop/ndn-autoconf/hub";
35
36MulticastDiscovery::MulticastDiscovery(Face& face, KeyChain& keyChain,
37 const NextStageCallback& nextStageOnFailure)
38 : Base(face, keyChain, nextStageOnFailure)
Junxiao Shi52fa45c2016-11-29 21:18:13 +000039 , m_nRequestedRegs(0)
40 , m_nFinishedRegs(0)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080041{
42}
43
44void
45MulticastDiscovery::start()
46{
47 std::cerr << "Trying multicast discovery..." << std::endl;
48
Junxiao Shia8891112016-12-06 21:11:33 +000049 this->collectMulticastFaces();
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080050}
51
52void
Junxiao Shia8891112016-12-06 21:11:33 +000053MulticastDiscovery::collectMulticastFaces()
54{
55 ndn::nfd::FaceQueryFilter filter;
56 filter.setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS);
57 m_controller.fetch<ndn::nfd::FaceQueryDataset>(
58 filter,
59 bind(&MulticastDiscovery::registerHubDiscoveryPrefix, this, _1),
60 bind(m_nextStageOnFailure, _2)
61 );
62}
63
64void
65MulticastDiscovery::registerHubDiscoveryPrefix(const std::vector<ndn::nfd::FaceStatus>& dataset)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080066{
67 std::vector<uint64_t> multicastFaces;
Junxiao Shia8891112016-12-06 21:11:33 +000068 std::transform(dataset.begin(), dataset.end(), std::back_inserter(multicastFaces),
69 [] (const ndn::nfd::FaceStatus& faceStatus) { return faceStatus.getFaceId(); });
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080070
71 if (multicastFaces.empty()) {
72 m_nextStageOnFailure("No multicast faces available, skipping multicast discovery stage");
73 }
74 else {
Junxiao Shi52fa45c2016-11-29 21:18:13 +000075 ControlParameters parameters;
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080076 parameters
77 .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
78 .setCost(1)
79 .setExpirationPeriod(time::seconds(30));
80
Junxiao Shi52fa45c2016-11-29 21:18:13 +000081 m_nRequestedRegs = multicastFaces.size();
82 m_nFinishedRegs = 0;
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080083
84 for (const auto& face : multicastFaces) {
85 parameters.setFaceId(face);
Junxiao Shi52fa45c2016-11-29 21:18:13 +000086 m_controller.start<ndn::nfd::RibRegisterCommand>(
87 parameters,
88 bind(&MulticastDiscovery::onRegisterSuccess, this),
89 bind(&MulticastDiscovery::onRegisterFailure, this, _1));
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080090 }
91 }
92}
93
94void
95MulticastDiscovery::onRegisterSuccess()
96{
Junxiao Shi52fa45c2016-11-29 21:18:13 +000097 ++m_nFinishedRegs;
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080098
Junxiao Shi52fa45c2016-11-29 21:18:13 +000099 if (m_nRequestedRegs == m_nFinishedRegs) {
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800100 MulticastDiscovery::setStrategy();
101 }
102}
103
104void
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000105MulticastDiscovery::onRegisterFailure(const ControlResponse& response)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800106{
Junxiao Shi29b41282016-08-22 03:47:02 +0000107 std::cerr << "ERROR: " << response.getText() << " (code: " << response.getCode() << ")" << std::endl;
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000108 --m_nRequestedRegs;
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800109
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000110 if (m_nRequestedRegs == m_nFinishedRegs) {
111 if (m_nRequestedRegs > 0) {
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800112 MulticastDiscovery::setStrategy();
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000113 }
114 else {
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800115 m_nextStageOnFailure("Failed to register " + LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() +
116 " for all multicast faces, skipping multicast discovery stage");
117 }
118 }
119}
120
121void
122MulticastDiscovery::setStrategy()
123{
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000124 ControlParameters parameters;
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800125 parameters
126 .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700127 .setStrategy("/localhost/nfd/strategy/multicast");
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800128
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000129 m_controller.start<ndn::nfd::StrategyChoiceSetCommand>(
130 parameters,
131 bind(&MulticastDiscovery::requestHubData, this),
132 bind(&MulticastDiscovery::onSetStrategyFailure, this, _1));
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800133}
134
135void
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000136MulticastDiscovery::onSetStrategyFailure(const ControlResponse& response)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800137{
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700138 m_nextStageOnFailure("Failed to set multicast strategy for " +
Junxiao Shi29b41282016-08-22 03:47:02 +0000139 LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() + " namespace (" + response.getText() + "). "
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800140 "Skipping multicast discovery stage");
141}
142
143void
144MulticastDiscovery::requestHubData()
145{
146 Interest interest(LOCALHOP_HUB_DISCOVERY_PREFIX);
147 interest.setInterestLifetime(time::milliseconds(4000)); // 4 seconds
148 interest.setMustBeFresh(true);
149
150 m_face.expressInterest(interest,
151 bind(&MulticastDiscovery::onSuccess, this, _2),
Junxiao Shid0e276f2016-12-14 23:13:39 +0000152 bind(m_nextStageOnFailure, "HUB Data not received: nacked"),
153 bind(m_nextStageOnFailure, "HUB Data not received: timeout"));
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800154}
155
156void
Junxiao Shid0e276f2016-12-14 23:13:39 +0000157MulticastDiscovery::onSuccess(const Data& data)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800158{
159 const Block& content = data.getContent();
160 content.parse();
161
162 // Get Uri
163 Block::element_const_iterator blockValue = content.find(tlv::nfd::Uri);
164 if (blockValue == content.elements_end()) {
165 m_nextStageOnFailure("Incorrect reply to multicast discovery stage");
166 return;
167 }
168 std::string hubUri(reinterpret_cast<const char*>(blockValue->value()), blockValue->value_size());
169 this->connectToHub(hubUri);
170}
171
172} // namespace autoconfig
173} // namespace tools
174} // namespace ndn