multicast-discovery.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014-2019, 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.
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 
28 #include <boost/lexical_cast.hpp>
29 
30 #include <ndn-cxx/encoding/tlv-nfd.hpp>
31 
32 namespace ndn {
33 namespace tools {
34 namespace autoconfig {
35 
36 using nfd::ControlParameters;
37 using nfd::ControlResponse;
38 
39 const Name HUB_DISCOVERY_PREFIX("/localhop/ndn-autoconf/hub");
40 const uint64_t HUB_DISCOVERY_ROUTE_COST(1);
41 const time::milliseconds HUB_DISCOVERY_ROUTE_EXPIRATION = 30_s;
42 const time::milliseconds HUB_DISCOVERY_INTEREST_LIFETIME = 4_s;
43 
44 MulticastDiscovery::MulticastDiscovery(Face& face, nfd::Controller& controller)
45  : m_face(face)
46  , m_controller(controller)
47 {
48 }
49 
50 void
51 MulticastDiscovery::doStart()
52 {
53  nfd::FaceQueryFilter filter;
54  filter.setLinkType(nfd::LINK_TYPE_MULTI_ACCESS);
55 
56  m_controller.fetch<nfd::FaceQueryDataset>(
57  filter,
58  bind(&MulticastDiscovery::registerHubDiscoveryPrefix, this, _1),
59  [this] (uint32_t code, const std::string& reason) {
60  this->fail("Error " + to_string(code) + " when querying multi-access faces: " + reason);
61  });
62 }
63 
64 void
65 MulticastDiscovery::registerHubDiscoveryPrefix(const std::vector<nfd::FaceStatus>& dataset)
66 {
67  if (dataset.empty()) {
68  this->fail("No multi-access faces available");
69  return;
70  }
71 
72  m_nRegs = dataset.size();
73  m_nRegSuccess = 0;
74  m_nRegFailure = 0;
75 
76  for (const auto& faceStatus : dataset) {
77  ControlParameters parameters;
78  parameters.setName(HUB_DISCOVERY_PREFIX)
79  .setFaceId(faceStatus.getFaceId())
80  .setCost(HUB_DISCOVERY_ROUTE_COST)
81  .setExpirationPeriod(HUB_DISCOVERY_ROUTE_EXPIRATION);
82 
83  m_controller.start<nfd::RibRegisterCommand>(
84  parameters,
85  [this] (const ControlParameters&) {
86  ++m_nRegSuccess;
87  afterReg();
88  },
89  [this, faceStatus] (const ControlResponse& resp) {
90  std::cerr << "Error " << resp.getCode() << " when registering hub discovery prefix "
91  << "for face " << faceStatus.getFaceId() << " (" << faceStatus.getRemoteUri()
92  << "): " << resp.getText() << std::endl;
93  ++m_nRegFailure;
94  afterReg();
95  });
96  }
97 }
98 
99 void
100 MulticastDiscovery::afterReg()
101 {
102  if (m_nRegSuccess + m_nRegFailure < m_nRegs) {
103  return; // continue waiting
104  }
105  if (m_nRegSuccess > 0) {
106  this->setStrategy();
107  }
108  else {
109  this->fail("Cannot register hub discovery prefix for any face");
110  }
111 }
112 
113 void
114 MulticastDiscovery::setStrategy()
115 {
116  ControlParameters parameters;
117  parameters.setName(HUB_DISCOVERY_PREFIX)
118  .setStrategy("/localhost/nfd/strategy/multicast"),
119 
120  m_controller.start<nfd::StrategyChoiceSetCommand>(
121  parameters,
122  bind(&MulticastDiscovery::requestHubData, this),
123  [this] (const ControlResponse& resp) {
124  this->fail("Error " + to_string(resp.getCode()) + " when setting multicast strategy: " +
125  resp.getText());
126  });
127 }
128 
129 void
130 MulticastDiscovery::requestHubData()
131 {
132  Interest interest(HUB_DISCOVERY_PREFIX);
133  interest.setCanBePrefix(true);
134  interest.setMustBeFresh(true);
135  interest.setInterestLifetime(HUB_DISCOVERY_INTEREST_LIFETIME);
136 
137  m_face.expressInterest(interest,
138  [this] (const Interest&, const Data& data) {
139  const Block& content = data.getContent();
140  content.parse();
141 
142  auto i = content.find(tlv::nfd::Uri);
143  if (i == content.elements_end()) {
144  this->fail("Malformed hub Data: missing Uri element");
145  return;
146  }
147 
148  this->provideHubFaceUri(std::string(reinterpret_cast<const char*>(i->value()), i->value_size()));
149  },
150  [this] (const Interest&, const lp::Nack& nack) {
151  this->fail("Nack-" + boost::lexical_cast<std::string>(nack.getReason()) + " when retrieving hub Data");
152  },
153  [this] (const Interest&) {
154  this->fail("Timeout when retrieving hub Data");
155  });
156 }
157 
158 } // namespace autoconfig
159 } // namespace tools
160 } // namespace ndn
Copyright (c) 2014-2017, Regents of the University of California, Arizona Board of Regents...
Definition: dns-srv.cpp:41
const Name HUB_DISCOVERY_PREFIX("/localhop/ndn-autoconf/hub")
void fail(const std::string &msg)
Definition: stage.cpp:65
const time::milliseconds HUB_DISCOVERY_ROUTE_EXPIRATION
const uint64_t HUB_DISCOVERY_ROUTE_COST(1)
MulticastDiscovery(Face &face, nfd::Controller &controller)
const time::milliseconds HUB_DISCOVERY_INTEREST_LIFETIME
void provideHubFaceUri(const std::string &s)
parse HUB FaceUri from string and declare success
Definition: stage.cpp:45