blob: d9eeeb33a9629d46e2e3a50bc53c25222a7b6ebd [file] [log] [blame]
Alexander Afanasyev2a655f72015-01-26 18:38:33 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi29b41282016-08-22 03:47:02 +00003 * Copyright (c) 2014-2016, 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
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080028namespace ndn {
29namespace tools {
30namespace autoconfig {
31
32static const Name LOCALHOP_HUB_DISCOVERY_PREFIX = "/localhop/ndn-autoconf/hub";
33
34MulticastDiscovery::MulticastDiscovery(Face& face, KeyChain& keyChain,
35 const NextStageCallback& nextStageOnFailure)
36 : Base(face, keyChain, nextStageOnFailure)
Junxiao Shi52fa45c2016-11-29 21:18:13 +000037 , m_nRequestedRegs(0)
38 , m_nFinishedRegs(0)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080039{
40}
41
42void
43MulticastDiscovery::start()
44{
45 std::cerr << "Trying multicast discovery..." << std::endl;
46
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{
53 ndn::nfd::FaceQueryFilter filter;
54 filter.setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS);
55 m_controller.fetch<ndn::nfd::FaceQueryDataset>(
56 filter,
57 bind(&MulticastDiscovery::registerHubDiscoveryPrefix, this, _1),
58 bind(m_nextStageOnFailure, _2)
59 );
60}
61
62void
63MulticastDiscovery::registerHubDiscoveryPrefix(const std::vector<ndn::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),
67 [] (const ndn::nfd::FaceStatus& faceStatus) { return faceStatus.getFaceId(); });
Alexander Afanasyev2a655f72015-01-26 18:38:33 -080068
69 if (multicastFaces.empty()) {
70 m_nextStageOnFailure("No multicast faces available, skipping multicast discovery stage");
71 }
72 else {
Junxiao Shi52fa45c2016-11-29 21:18:13 +000073 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 Shi52fa45c2016-11-29 21:18:13 +000084 m_controller.start<ndn::nfd::RibRegisterCommand>(
85 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 Shi52fa45c2016-11-29 21:18:13 +0000103MulticastDiscovery::onRegisterFailure(const 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 {
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800113 m_nextStageOnFailure("Failed to register " + LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() +
114 " for all multicast faces, skipping multicast discovery stage");
115 }
116 }
117}
118
119void
120MulticastDiscovery::setStrategy()
121{
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000122 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 Shi52fa45c2016-11-29 21:18:13 +0000127 m_controller.start<ndn::nfd::StrategyChoiceSetCommand>(
128 parameters,
129 bind(&MulticastDiscovery::requestHubData, this),
130 bind(&MulticastDiscovery::onSetStrategyFailure, this, _1));
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800131}
132
133void
Junxiao Shi52fa45c2016-11-29 21:18:13 +0000134MulticastDiscovery::onSetStrategyFailure(const ControlResponse& response)
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800135{
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700136 m_nextStageOnFailure("Failed to set multicast strategy for " +
Junxiao Shi29b41282016-08-22 03:47:02 +0000137 LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() + " namespace (" + response.getText() + "). "
Alexander Afanasyev2a655f72015-01-26 18:38:33 -0800138 "Skipping multicast discovery stage");
139}
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 Shid0e276f2016-12-14 23:13:39 +0000150 bind(m_nextStageOnFailure, "HUB Data not received: nacked"),
151 bind(m_nextStageOnFailure, "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()) {
163 m_nextStageOnFailure("Incorrect reply to multicast discovery stage");
164 return;
165 }
166 std::string hubUri(reinterpret_cast<const char*>(blockValue->value()), blockValue->value_size());
167 this->connectToHub(hubUri);
168}
169
170} // namespace autoconfig
171} // namespace tools
172} // namespace ndn