25c6ce41d5
refs #3760 Change-Id: I9a2e3012af2f72495ce3259fa4f51ebaa8ea7096
203 lines
6.0 KiB
C++
203 lines
6.0 KiB
C++
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
/**
|
|
* Copyright (c) 2014-2016, Regents of the University of California,
|
|
* Arizona Board of Regents,
|
|
* Colorado State University,
|
|
* University Pierre & Marie Curie, Sorbonne University,
|
|
* Washington University in St. Louis,
|
|
* Beijing Institute of Technology,
|
|
* The University of Memphis.
|
|
*
|
|
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
|
* See AUTHORS.md for complete list of NFD authors and contributors.
|
|
*
|
|
* NFD is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU General Public License as published by the Free Software Foundation,
|
|
* either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "face-id-fetcher.hpp"
|
|
|
|
#include <boost/lexical_cast.hpp>
|
|
#include <boost/regex.hpp>
|
|
|
|
#include <ndn-cxx/mgmt/nfd/face-query-filter.hpp>
|
|
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
|
|
#include <ndn-cxx/util/segment-fetcher.hpp>
|
|
|
|
namespace nfd {
|
|
namespace tools {
|
|
namespace nfdc {
|
|
|
|
FaceIdFetcher::FaceIdFetcher(ndn::Face& face,
|
|
ndn::nfd::Controller& controller,
|
|
bool allowCreate,
|
|
const SuccessCallback& onSucceed,
|
|
const FailureCallback& onFail)
|
|
: m_face(face)
|
|
, m_controller(controller)
|
|
, m_allowCreate(allowCreate)
|
|
, m_onSucceed(onSucceed)
|
|
, m_onFail(onFail)
|
|
{
|
|
}
|
|
|
|
void
|
|
FaceIdFetcher::start(ndn::Face& face,
|
|
ndn::nfd::Controller& controller,
|
|
const std::string& input,
|
|
bool allowCreate,
|
|
const SuccessCallback& onSucceed,
|
|
const FailureCallback& onFail)
|
|
{
|
|
// 1. Try parse input as FaceId, if input is FaceId, succeed with parsed FaceId
|
|
// 2. Try parse input as FaceUri, if input is not FaceUri, fail
|
|
// 3. Canonize faceUri
|
|
// 4. If canonization fails, fail
|
|
// 5. Query for face
|
|
// 6. If query succeeds and finds a face, succeed with found FaceId
|
|
// 7. Create face
|
|
// 8. If face creation succeeds, succeed with created FaceId
|
|
// 9. Fail
|
|
|
|
boost::regex e("^[a-z0-9]+\\:.*");
|
|
if (!boost::regex_match(input, e)) {
|
|
try {
|
|
uint32_t faceId = boost::lexical_cast<uint32_t>(input);
|
|
onSucceed(faceId);
|
|
return;
|
|
}
|
|
catch (const boost::bad_lexical_cast&) {
|
|
onFail("No valid faceId or faceUri is provided");
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
FaceUri faceUri;
|
|
if (!faceUri.parse(input)) {
|
|
onFail("FaceUri parse failed");
|
|
return;
|
|
}
|
|
|
|
auto fetcher = new FaceIdFetcher(std::ref(face), std::ref(controller),
|
|
allowCreate, onSucceed, onFail);
|
|
fetcher->startGetFaceId(faceUri);
|
|
}
|
|
}
|
|
|
|
void
|
|
FaceIdFetcher::startGetFaceId(const FaceUri& faceUri)
|
|
{
|
|
faceUri.canonize(bind(&FaceIdFetcher::onCanonizeSuccess, this, _1),
|
|
bind(&FaceIdFetcher::onCanonizeFailure, this, _1),
|
|
m_face.getIoService(), time::seconds(4));
|
|
}
|
|
|
|
void
|
|
FaceIdFetcher::onCanonizeSuccess(const FaceUri& canonicalUri)
|
|
{
|
|
ndn::Name queryName("/localhost/nfd/faces/query");
|
|
ndn::nfd::FaceQueryFilter queryFilter;
|
|
queryFilter.setRemoteUri(canonicalUri.toString());
|
|
queryName.append(queryFilter.wireEncode());
|
|
|
|
ndn::Interest interestPacket(queryName);
|
|
interestPacket.setMustBeFresh(true);
|
|
interestPacket.setInterestLifetime(time::milliseconds(4000));
|
|
auto interest = std::make_shared<ndn::Interest>(interestPacket);
|
|
|
|
ndn::util::SegmentFetcher::fetch(
|
|
m_face, *interest, m_validator,
|
|
bind(&FaceIdFetcher::onQuerySuccess, this, _1, canonicalUri),
|
|
bind(&FaceIdFetcher::onQueryFailure, this, _1, canonicalUri));
|
|
}
|
|
|
|
void
|
|
FaceIdFetcher::onCanonizeFailure(const std::string& reason)
|
|
{
|
|
fail("Canonize faceUri failed : " + reason);
|
|
}
|
|
|
|
void
|
|
FaceIdFetcher::onQuerySuccess(const ndn::ConstBufferPtr& data,
|
|
const FaceUri& canonicalUri)
|
|
{
|
|
size_t offset = 0;
|
|
bool isOk = false;
|
|
ndn::Block block;
|
|
std::tie(isOk, block) = ndn::Block::fromBuffer(data, offset);
|
|
|
|
if (!isOk) {
|
|
if (m_allowCreate) {
|
|
startFaceCreate(canonicalUri);
|
|
}
|
|
else {
|
|
fail("Fail to find faceId");
|
|
}
|
|
}
|
|
else {
|
|
try {
|
|
ndn::nfd::FaceStatus status(block);
|
|
succeed(status.getFaceId());
|
|
}
|
|
catch (const ndn::tlv::Error& e) {
|
|
std::string errorMessage(e.what());
|
|
fail("ERROR: " + errorMessage);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
FaceIdFetcher::onQueryFailure(uint32_t errorCode,
|
|
const FaceUri& canonicalUri)
|
|
{
|
|
std::stringstream ss;
|
|
ss << "Cannot fetch data (code " << errorCode << ")";
|
|
fail(ss.str());
|
|
}
|
|
|
|
void
|
|
FaceIdFetcher::onFaceCreateError(const ndn::nfd::ControlResponse& response,
|
|
const std::string& message)
|
|
{
|
|
std::stringstream ss;
|
|
ss << message << " : " << response.getText() << " (code " << response.getCode() << ")";
|
|
fail(ss.str());
|
|
}
|
|
|
|
void
|
|
FaceIdFetcher::startFaceCreate(const FaceUri& canonicalUri)
|
|
{
|
|
ndn::nfd::ControlParameters parameters;
|
|
parameters.setUri(canonicalUri.toString());
|
|
|
|
m_controller.start<ndn::nfd::FaceCreateCommand>(parameters,
|
|
[this] (const ndn::nfd::ControlParameters& result) { succeed(result.getFaceId()); },
|
|
bind(&FaceIdFetcher::onFaceCreateError, this, _1, "Face creation failed"));
|
|
}
|
|
|
|
void
|
|
FaceIdFetcher::succeed(uint32_t faceId)
|
|
{
|
|
m_onSucceed(faceId);
|
|
delete this;
|
|
}
|
|
|
|
void
|
|
FaceIdFetcher::fail(const std::string& reason)
|
|
{
|
|
m_onFail(reason);
|
|
delete this;
|
|
}
|
|
|
|
} // namespace nfdc
|
|
} // namespace tools
|
|
} // namespace nfd
|