blob: f9b47971d56f427f6af1d8cbafe26022faf72ea5 [file] [log] [blame]
Alexander Afanasyev2a655f72015-01-26 18:38:33 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shif748a4e2017-07-05 23:41:48 +00002/*
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
Junxiao Shicb766862017-07-07 22:21:04 +000036MulticastDiscovery::MulticastDiscovery(Face& face, nfd::Controller& controller)
37 : m_face(face)
38 , m_controller(controller)
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
Junxiao Shicb766862017-07-07 22:21:04 +000045MulticastDiscovery::doStart()
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080046{
Junxiao Shia8891112016-12-06 21:11:33 +000047 this->collectMulticastFaces();
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080048}
49
50void
Junxiao Shia8891112016-12-06 21:11:33 +000051MulticastDiscovery::collectMulticastFaces()
52{
Junxiao Shicb766862017-07-07 22:21:04 +000053 nfd::FaceQueryFilter filter;
54 filter.setLinkType(nfd::LINK_TYPE_MULTI_ACCESS);
55 m_controller.fetch<nfd::FaceQueryDataset>(
Junxiao Shia8891112016-12-06 21:11:33 +000056 filter,
57 bind(&MulticastDiscovery::registerHubDiscoveryPrefix, this, _1),
Junxiao Shicb766862017-07-07 22:21:04 +000058 bind(&MulticastDiscovery::fail, this, _2)
Junxiao Shia8891112016-12-06 21:11:33 +000059 );
60}
61
62void
Junxiao Shicb766862017-07-07 22:21:04 +000063MulticastDiscovery::registerHubDiscoveryPrefix(const std::vector<nfd::FaceStatus>& dataset)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080064{
65 std::vector<uint64_t> multicastFaces;
Junxiao Shia8891112016-12-06 21:11:33 +000066 std::transform(dataset.begin(), dataset.end(), std::back_inserter(multicastFaces),
Junxiao Shicb766862017-07-07 22:21:04 +000067 [] (const nfd::FaceStatus& faceStatus) { return faceStatus.getFaceId(); });
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080068
69 if (multicastFaces.empty()) {
Junxiao Shicb766862017-07-07 22:21:04 +000070 this->fail("No multicast faces available, skipping multicast discovery stage");
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080071 }
72 else {
Junxiao Shicb766862017-07-07 22:21:04 +000073 nfd::ControlParameters parameters;
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080074 parameters
75 .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
76 .setCost(1)
77 .setExpirationPeriod(time::seconds(30));
78
Junxiao Shi52fa45c2016-11-29 21:18:13 +000079 m_nRequestedRegs = multicastFaces.size();
80 m_nFinishedRegs = 0;
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080081
82 for (const auto& face : multicastFaces) {
83 parameters.setFaceId(face);
Junxiao Shicb766862017-07-07 22:21:04 +000084 m_controller.start<nfd::RibRegisterCommand>(
Junxiao Shi52fa45c2016-11-29 21:18:13 +000085 parameters,
86 bind(&MulticastDiscovery::onRegisterSuccess, this),
87 bind(&MulticastDiscovery::onRegisterFailure, this, _1));
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080088 }
89 }
90}
91
92void
93MulticastDiscovery::onRegisterSuccess()
94{
Junxiao Shi52fa45c2016-11-29 21:18:13 +000095 ++m_nFinishedRegs;
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080096
Junxiao Shi52fa45c2016-11-29 21:18:13 +000097 if (m_nRequestedRegs == m_nFinishedRegs) {
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080098 MulticastDiscovery::setStrategy();
99 }
100}
101
102void
Junxiao Shicb766862017-07-07 22:21:04 +0000103MulticastDiscovery::onRegisterFailure(const nfd::ControlResponse& response)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800104{
Junxiao Shi29b41282016-08-22 03:47:02 +0000105 std::cerr << "ERROR: " << response.getText() << " (code: " << response.getCode() << ")" << std::endl;
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000106 --m_nRequestedRegs;
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800107
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000108 if (m_nRequestedRegs == m_nFinishedRegs) {
109 if (m_nRequestedRegs > 0) {
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800110 MulticastDiscovery::setStrategy();
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000111 }
112 else {
Junxiao Shicb766862017-07-07 22:21:04 +0000113 this->fail("Failed to register " + LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() +
114 " for all multicast faces, skipping multicast discovery stage");
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800115 }
116 }
117}
118
119void
120MulticastDiscovery::setStrategy()
121{
Junxiao Shicb766862017-07-07 22:21:04 +0000122 nfd::ControlParameters parameters;
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800123 parameters
124 .setName(LOCALHOP_HUB_DISCOVERY_PREFIX)
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700125 .setStrategy("/localhost/nfd/strategy/multicast");
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800126
Junxiao Shicb766862017-07-07 22:21:04 +0000127 m_controller.start<nfd::StrategyChoiceSetCommand>(
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000128 parameters,
129 bind(&MulticastDiscovery::requestHubData, this),
130 bind(&MulticastDiscovery::onSetStrategyFailure, this, _1));
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800131}
132
133void
Junxiao Shicb766862017-07-07 22:21:04 +0000134MulticastDiscovery::onSetStrategyFailure(const nfd::ControlResponse& response)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800135{
Junxiao Shicb766862017-07-07 22:21:04 +0000136 this->fail("Failed to set multicast strategy for " +
137 LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() + " namespace (" + response.getText() + "). "
138 "Skipping multicast discovery stage");
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800139}
140
141void
142MulticastDiscovery::requestHubData()
143{
144 Interest interest(LOCALHOP_HUB_DISCOVERY_PREFIX);
145 interest.setInterestLifetime(time::milliseconds(4000)); // 4 seconds
146 interest.setMustBeFresh(true);
147
148 m_face.expressInterest(interest,
149 bind(&MulticastDiscovery::onSuccess, this, _2),
Junxiao Shicb766862017-07-07 22:21:04 +0000150 bind(&MulticastDiscovery::fail, this, "HUB Data not received: nacked"),
151 bind(&MulticastDiscovery::fail, this, "HUB Data not received: timeout"));
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800152}
153
154void
Junxiao Shid0e276f2016-12-14 23:13:39 +0000155MulticastDiscovery::onSuccess(const Data& data)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800156{
157 const Block& content = data.getContent();
158 content.parse();
159
160 // Get Uri
161 Block::element_const_iterator blockValue = content.find(tlv::nfd::Uri);
162 if (blockValue == content.elements_end()) {
Junxiao Shicb766862017-07-07 22:21:04 +0000163 this->fail("Incorrect reply to multicast discovery stage");
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800164 return;
165 }
Junxiao Shicb766862017-07-07 22:21:04 +0000166 this->provideHubFaceUri(std::string(reinterpret_cast<const char*>(blockValue->value()), blockValue->value_size()));
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800167}
168
169} // namespace autoconfig
170} // namespace tools
171} // namespace ndn