tools: split nfdc into multiple files
refs #3749
Change-Id: I24a3fd287773d0577d438e9ca24dc1dfab335a4f
diff --git a/tools/nfdc.cpp b/tools/nfdc.cpp
deleted file mode 100644
index 31ce4f3..0000000
--- a/tools/nfdc.cpp
+++ /dev/null
@@ -1,627 +0,0 @@
-/* -*- 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 "nfdc.hpp"
-#include "core/version.hpp"
-
-#include <boost/lexical_cast.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/algorithm/string/regex_find_format.hpp>
-#include <boost/regex.hpp>
-
-#include <ndn-cxx/management/nfd-face-query-filter.hpp>
-#include <ndn-cxx/management/nfd-face-status.hpp>
-#include <ndn-cxx/util/segment-fetcher.hpp>
-
-void
-usage(const char* programName)
-{
- std::cout << "Usage:\n" << programName << " [-h] [-V] COMMAND [<Command Options>]\n"
- " -h print usage and exit\n"
- " -V print version and exit\n"
- "\n"
- " COMMAND can be one of the following:\n"
- " register [-I] [-C] [-c cost] [-e expiration time] [-o origin] name <faceId | faceUri>\n"
- " register name to the given faceId or faceUri\n"
- " -I: unset CHILD_INHERIT flag\n"
- " -C: set CAPTURE flag\n"
- " -c: specify cost (default 0)\n"
- " -e: specify expiration time in ms\n"
- " (by default the entry remains in FIB for the lifetime of the associated face)\n"
- " -o: specify origin\n"
- " 0 for Local producer applications, 128 for NLSR, 255(default) for static routes\n"
- " unregister [-o origin] name <faceId | faceUri>\n"
- " unregister name from the given faceId\n"
- " create [-P] <faceUri> \n"
- " Create a face in one of the following formats:\n"
- " UDP unicast: udp[4|6]://<remote-IP-or-host>[:<remote-port>]\n"
- " TCP: tcp[4|6]://<remote-IP-or-host>[:<remote-port>] \n"
- " -P: create permanent (instead of persistent) face\n"
- " destroy <faceId | faceUri> \n"
- " Destroy a face\n"
- " set-strategy <name> <strategy> \n"
- " Set the strategy for a namespace \n"
- " unset-strategy <name> \n"
- " Unset the strategy for a namespace \n"
- " add-nexthop [-c <cost>] <name> <faceId | faceUri>\n"
- " Add a nexthop to a FIB entry\n"
- " -c: specify cost (default 0)\n"
- " remove-nexthop <name> <faceId | faceUri> \n"
- " Remove a nexthop from a FIB entry\n"
- << std::endl;
-}
-
-namespace nfdc {
-
-using std::bind;
-
-const ndn::time::milliseconds Nfdc::DEFAULT_EXPIRATION_PERIOD = ndn::time::milliseconds::max();
-const uint64_t Nfdc::DEFAULT_COST = 0;
-
-Nfdc::FaceIdFetcher::FaceIdFetcher(ndn::Face& face,
- 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
-Nfdc::FaceIdFetcher::start(ndn::Face& face,
- 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
- {
- u_int32_t faceId = boost::lexical_cast<uint32_t>(input);
- onSucceed(faceId);
- return;
- }
- catch (boost::bad_lexical_cast&)
- {
- onFail("No valid faceId or faceUri is provided");
- return;
- }
- }
- else {
- ndn::util::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
-Nfdc::FaceIdFetcher::startGetFaceId(const ndn::util::FaceUri& faceUri)
-{
- faceUri.canonize(bind(&FaceIdFetcher::onCanonizeSuccess, this, _1),
- bind(&FaceIdFetcher::onCanonizeFailure, this, _1),
- m_face.getIoService(), ndn::time::seconds(4));
-}
-
-void
-Nfdc::FaceIdFetcher::onCanonizeSuccess(const ndn::util::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(ndn::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
-Nfdc::FaceIdFetcher::onCanonizeFailure(const std::string& reason)
-{
- fail("Canonize faceUri failed : " + reason);
-}
-
-void
-Nfdc::FaceIdFetcher::onQuerySuccess(const ndn::ConstBufferPtr& data,
- const ndn::util::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 {
- FaceStatus status(block);
- succeed(status.getFaceId());
- }
- catch (const ndn::tlv::Error& e) {
- std::string errorMessage(e.what());
- fail("ERROR: " + errorMessage);
- }
- }
-}
-
-void
-Nfdc::FaceIdFetcher::onQueryFailure(uint32_t errorCode,
- const ndn::util::FaceUri& canonicalUri)
-{
- std::stringstream ss;
- ss << "Cannot fetch data (code " << errorCode << ")";
- fail(ss.str());
-}
-
-void
-Nfdc::FaceIdFetcher::onFaceCreateError(uint32_t code,
- const std::string& error,
- const std::string& message)
-{
- std::stringstream ss;
- ss << message << " : " << error << " (code " << code << ")";
- fail(ss.str());
-}
-
-void
-Nfdc::FaceIdFetcher::startFaceCreate(const ndn::util::FaceUri& canonicalUri)
-{
- ControlParameters parameters;
- parameters.setUri(canonicalUri.toString());
-
- m_controller.start<FaceCreateCommand>(parameters,
- [this] (const ControlParameters& result) {
- succeed(result.getFaceId());
- },
- bind(&FaceIdFetcher::onFaceCreateError, this, _1, _2,
- "Face creation failed"));
-}
-
-void
-Nfdc::FaceIdFetcher::succeed(uint32_t faceId)
-{
- m_onSucceed(faceId);
- delete this;
-}
-
-void
-Nfdc::FaceIdFetcher::fail(const std::string& reason)
-{
- m_onFail(reason);
- delete this;
-}
-
-Nfdc::Nfdc(ndn::Face& face)
- : m_flags(ROUTE_FLAG_CHILD_INHERIT)
- , m_cost(DEFAULT_COST)
- , m_origin(ROUTE_ORIGIN_STATIC)
- , m_expires(DEFAULT_EXPIRATION_PERIOD)
- , m_facePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT)
- , m_face(face)
- , m_controller(face, m_keyChain)
- , m_ioService(face.getIoService())
-{
-}
-
-Nfdc::~Nfdc()
-{
-}
-
-bool
-Nfdc::dispatch(const std::string& command)
-{
- if (command == "add-nexthop") {
- if (m_nOptions != 2)
- return false;
- fibAddNextHop();
- }
- else if (command == "remove-nexthop") {
- if (m_nOptions != 2)
- return false;
- fibRemoveNextHop();
- }
- else if (command == "register") {
- if (m_nOptions != 2)
- return false;
- ribRegisterPrefix();
- }
- else if (command == "unregister") {
- if (m_nOptions != 2)
- return false;
- ribUnregisterPrefix();
- }
- else if (command == "create") {
- if (m_nOptions != 1)
- return false;
- faceCreate();
- }
- else if (command == "destroy") {
- if (m_nOptions != 1)
- return false;
- faceDestroy();
- }
- else if (command == "set-strategy") {
- if (m_nOptions != 2)
- return false;
- strategyChoiceSet();
- }
- else if (command == "unset-strategy") {
- if (m_nOptions != 1)
- return false;
- strategyChoiceUnset();
- }
- else
- return false;
-
- return true;
-}
-
-void
-Nfdc::fibAddNextHop()
-{
- m_name = m_commandLineArguments[0];
- const std::string& faceName = m_commandLineArguments[1];
-
- FaceIdFetcher::start(m_face, m_controller, faceName, true,
- [this] (const uint32_t faceId) {
- ControlParameters parameters;
- parameters
- .setName(m_name)
- .setCost(m_cost)
- .setFaceId(faceId);
-
- m_controller
- .start<FibAddNextHopCommand>(parameters,
- bind(&Nfdc::onSuccess, this, _1,
- "Nexthop insertion succeeded"),
- bind(&Nfdc::onError, this, _1, _2,
- "Nexthop insertion failed"));
- },
- bind(&Nfdc::onObtainFaceIdFailure, this, _1));
-}
-
-void
-Nfdc::fibRemoveNextHop()
-{
- m_name = m_commandLineArguments[0];
- const std::string& faceName = m_commandLineArguments[1];
-
- FaceIdFetcher::start(m_face, m_controller, faceName, false,
- [this] (const uint32_t faceId) {
- ControlParameters parameters;
- parameters
- .setName(m_name)
- .setFaceId(faceId);
-
- m_controller
- .start<FibRemoveNextHopCommand>(parameters,
- bind(&Nfdc::onSuccess, this, _1,
- "Nexthop removal succeeded"),
- bind(&Nfdc::onError, this, _1, _2,
- "Nexthop removal failed"));
- },
- bind(&Nfdc::onObtainFaceIdFailure, this, _1));
-}
-
-void
-Nfdc::ribRegisterPrefix()
-{
- m_name = m_commandLineArguments[0];
- const std::string& faceName = m_commandLineArguments[1];
-
- FaceIdFetcher::start(m_face, m_controller, faceName, true,
- [this] (const uint32_t faceId) {
- ControlParameters parameters;
- parameters
- .setName(m_name)
- .setCost(m_cost)
- .setFlags(m_flags)
- .setOrigin(m_origin)
- .setFaceId(faceId);
-
- if (m_expires != DEFAULT_EXPIRATION_PERIOD)
- parameters.setExpirationPeriod(m_expires);
-
- m_controller
- .start<RibRegisterCommand>(parameters,
- bind(&Nfdc::onSuccess, this, _1,
- "Successful in name registration"),
- bind(&Nfdc::onError, this, _1, _2,
- "Failed in name registration"));
- },
- bind(&Nfdc::onObtainFaceIdFailure, this, _1));
-}
-
-void
-Nfdc::ribUnregisterPrefix()
-{
- m_name = m_commandLineArguments[0];
- const std::string& faceName = m_commandLineArguments[1];
-
- FaceIdFetcher::start(m_face, m_controller, faceName, false,
- [this] (const uint32_t faceId) {
- ControlParameters parameters;
- parameters
- .setName(m_name)
- .setFaceId(faceId)
- .setOrigin(m_origin);
-
- m_controller
- .start<RibUnregisterCommand>(parameters,
- bind(&Nfdc::onSuccess, this, _1,
- "Successful in unregistering name"),
- bind(&Nfdc::onError, this, _1, _2,
- "Failed in unregistering name"));
- },
- bind(&Nfdc::onObtainFaceIdFailure, this, _1));
-}
-
-void
-Nfdc::onCanonizeFailure(const std::string& reason)
-{
- BOOST_THROW_EXCEPTION(Error(reason));
-}
-
-void
-Nfdc::onObtainFaceIdFailure(const std::string& message)
-{
- BOOST_THROW_EXCEPTION(Error(message));
-}
-
-void
-Nfdc::faceCreate()
-{
- boost::regex e("^[a-z0-9]+\\:.*");
- if (!boost::regex_match(m_commandLineArguments[0], e))
- BOOST_THROW_EXCEPTION(Error("invalid uri format"));
-
- ndn::util::FaceUri faceUri;
- faceUri.parse(m_commandLineArguments[0]);
-
- faceUri.canonize(bind(&Nfdc::startFaceCreate, this, _1),
- bind(&Nfdc::onCanonizeFailure, this, _1),
- m_ioService, ndn::time::seconds(4));
-}
-
-void
-Nfdc::startFaceCreate(const ndn::util::FaceUri& canonicalUri)
-{
- ControlParameters parameters;
- parameters.setUri(canonicalUri.toString());
- parameters.setFacePersistency(m_facePersistency);
-
- m_controller.start<FaceCreateCommand>(parameters,
- bind(&Nfdc::onSuccess, this, _1,
- "Face creation succeeded"),
- bind(&Nfdc::onError, this, _1, _2,
- "Face creation failed"));
-}
-
-void
-Nfdc::faceDestroy()
-{
- ControlParameters parameters;
- const std::string& faceName = m_commandLineArguments[0];
-
- FaceIdFetcher::start(m_face, m_controller, faceName, false,
- [this] (const uint32_t faceId) {
- ControlParameters faceParameters;
- faceParameters.setFaceId(faceId);
-
- m_controller.start<FaceDestroyCommand>(faceParameters,
- bind(&Nfdc::onSuccess, this, _1,
- "Face destroy succeeded"),
- bind(&Nfdc::onError, this, _1, _2,
- "Face destroy failed"));
- },
- bind(&Nfdc::onObtainFaceIdFailure, this, _1));
-}
-
-void
-Nfdc::strategyChoiceSet()
-{
- const std::string& name = m_commandLineArguments[0];
- const std::string& strategy = m_commandLineArguments[1];
-
- ControlParameters parameters;
- parameters
- .setName(name)
- .setStrategy(strategy);
-
- m_controller.start<StrategyChoiceSetCommand>(parameters,
- bind(&Nfdc::onSuccess, this, _1,
- "Successfully set strategy choice"),
- bind(&Nfdc::onError, this, _1, _2,
- "Failed to set strategy choice"));
-}
-
-void
-Nfdc::strategyChoiceUnset()
-{
- const std::string& name = m_commandLineArguments[0];
-
- ControlParameters parameters;
- parameters.setName(name);
-
- m_controller.start<StrategyChoiceUnsetCommand>(parameters,
- bind(&Nfdc::onSuccess, this, _1,
- "Successfully unset strategy choice"),
- bind(&Nfdc::onError, this, _1, _2,
- "Failed to unset strategy choice"));
-}
-
-void
-Nfdc::onSuccess(const ControlParameters& commandSuccessResult, const std::string& message)
-{
- std::cout << message << ": " << commandSuccessResult << std::endl;
-}
-
-void
-Nfdc::onError(uint32_t code, const std::string& error, const std::string& message)
-{
- std::ostringstream os;
- os << message << ": " << error << " (code: " << code << ")";
- BOOST_THROW_EXCEPTION(Error(os.str()));
-}
-
-} // namespace nfdc
-
-int
-main(int argc, char** argv)
-{
- ndn::Face face;
- nfdc::Nfdc p(face);
-
- p.m_programName = argv[0];
-
- if (argc < 2) {
- usage(p.m_programName);
- return 0;
- }
-
- if (!strcmp(argv[1], "-h")) {
- usage(p.m_programName);
- return 0;
- }
-
- if (!strcmp(argv[1], "-V")) {
- std::cout << NFD_VERSION_BUILD_STRING << std::endl;
- return 0;
- }
-
- ::optind = 2; //start reading options from 2nd argument i.e. Command
- int opt;
- while ((opt = ::getopt(argc, argv, "ICc:e:o:P")) != -1) {
- switch (opt) {
- case 'I':
- p.m_flags = p.m_flags & ~(nfdc::ROUTE_FLAG_CHILD_INHERIT);
- break;
-
- case 'C':
- p.m_flags = p.m_flags | nfdc::ROUTE_FLAG_CAPTURE;
- break;
-
- case 'c':
- try {
- p.m_cost = boost::lexical_cast<uint64_t>(::optarg);
- }
- catch (boost::bad_lexical_cast&) {
- std::cerr << "Error: cost must be in unsigned integer format" << std::endl;
- return 1;
- }
- break;
-
- case 'e':
- uint64_t expires;
- try {
- expires = boost::lexical_cast<uint64_t>(::optarg);
- }
- catch (boost::bad_lexical_cast&) {
- std::cerr << "Error: expiration time must be in unsigned integer format" << std::endl;
- return 1;
- }
- p.m_expires = ndn::time::milliseconds(expires);
- break;
-
- case 'o':
- try {
- p.m_origin = boost::lexical_cast<uint64_t>(::optarg);
- }
- catch (boost::bad_lexical_cast&) {
- std::cerr << "Error: origin must be in unsigned integer format" << std::endl;
- return 1;
- }
- break;
-
- case 'P':
- p.m_facePersistency = ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERMANENT;
- break;
-
- default:
- usage(p.m_programName);
- return 1;
- }
- }
-
- if (argc == ::optind) {
- usage(p.m_programName);
- return 1;
- }
-
- try {
- p.m_commandLineArguments = argv + ::optind;
- p.m_nOptions = argc - ::optind;
-
- //argv[1] points to the command, so pass it to the dispatch
- bool isOk = p.dispatch(argv[1]);
- if (!isOk) {
- usage(p.m_programName);
- return 1;
- }
- face.processEvents();
- }
- catch (const std::exception& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
- return 2;
- }
- return 0;
-}
diff --git a/tools/nfdc.hpp b/tools/nfdc.hpp
deleted file mode 100644
index 3928ae5..0000000
--- a/tools/nfdc.hpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014, 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/>.
- */
-
-#ifndef NFD_TOOLS_NFDC_HPP
-#define NFD_TOOLS_NFDC_HPP
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/util/time.hpp>
-#include <ndn-cxx/management/nfd-controller.hpp>
-#include <ndn-cxx/util/face-uri.hpp>
-#include <ndn-cxx/security/validator-null.hpp>
-#include <memory>
-
-namespace nfdc {
-
-using namespace ndn::nfd;
-
-class Nfdc : boost::noncopyable
-{
-public:
-
- static const ndn::time::milliseconds DEFAULT_EXPIRATION_PERIOD;
- static const uint64_t DEFAULT_COST;
-
- class Error : public std::runtime_error
- {
- public:
- explicit
- Error(const std::string& what)
- : std::runtime_error(what)
- {
- }
- };
-
- class FaceIdFetcher
- {
- public:
- typedef std::function<void(uint32_t)> SuccessCallback;
- typedef std::function<void(const std::string&)> FailureCallback;
-
- /** \brief obtain FaceId from input
- * \param face Reference to the Face that should be used to fetch data
- * \param controller Reference to the controller that should be used to sign the Interest
- * \param input User input, either FaceId or FaceUri
- * \param allowCreate Whether creating face is allowed
- * \param onSucceed Callback to be fired when faceId is obtained
- * \param onFail Callback to be fired when an error occurs
- */
- static void
- start(ndn::Face& face,
- Controller& controller,
- const std::string& input,
- bool allowCreate,
- const SuccessCallback& onSucceed,
- const FailureCallback& onFail);
-
- private:
- FaceIdFetcher(ndn::Face& face,
- Controller& controller,
- bool allowCreate,
- const SuccessCallback& onSucceed,
- const FailureCallback& onFail);
-
- void
- onQuerySuccess(const ndn::ConstBufferPtr& data,
- const ndn::util::FaceUri& canonicalUri);
-
- void
- onQueryFailure(uint32_t errorCode,
- const ndn::util::FaceUri& canonicalUri);
-
- void
- onCanonizeSuccess(const ndn::util::FaceUri& canonicalUri);
-
- void
- onCanonizeFailure(const std::string& reason);
-
- void
- startGetFaceId(const ndn::util::FaceUri& faceUri);
-
- void
- startFaceCreate(const ndn::util::FaceUri& canonicalUri);
-
- void
- onFaceCreateError(uint32_t code,
- const std::string& error,
- const std::string& message);
-
- void
- succeed(uint32_t faceId);
-
- void
- fail(const std::string& reason);
-
- private:
- ndn::Face& m_face;
- Controller& m_controller;
- bool m_allowCreate;
- SuccessCallback m_onSucceed;
- FailureCallback m_onFail;
- ndn::ValidatorNull m_validator;
- };
-
- explicit
- Nfdc(ndn::Face& face);
-
- ~Nfdc();
-
- bool
- dispatch(const std::string& cmd);
-
- /**
- * \brief Adds a nexthop to a FIB entry
- *
- * If the FIB entry does not exist, it is inserted automatically
- *
- * cmd format:
- * [-c cost] name faceId|faceUri
- *
- */
- void
- fibAddNextHop();
-
- /**
- * \brief Removes a nexthop from an existing FIB entry
- *
- * If the last nexthop record in a FIB entry is removed, the FIB entry is also deleted
- *
- * cmd format:
- * name faceId
- *
- */
- void
- fibRemoveNextHop();
-
- /**
- * \brief Registers name to the given faceId or faceUri
- *
- * cmd format:
- * [-I] [-C] [-c cost] name faceId|faceUri
- */
- void
- ribRegisterPrefix();
-
- /**
- * \brief Unregisters name from the given faceId/faceUri
- *
- * cmd format:
- * name faceId/faceUri
- */
- void
- ribUnregisterPrefix();
-
- /**
- * \brief Creates new face
- *
- * This command allows creation of UDP unicast and TCP faces only
- *
- * cmd format:
- * uri
- *
- */
- void
- faceCreate();
-
- /**
- * \brief Destroys face
- *
- * cmd format:
- * faceId|faceUri
- *
- */
- void
- faceDestroy();
-
- /**
- * \brief Sets the strategy for a namespace
- *
- * cmd format:
- * name strategy
- *
- */
- void
- strategyChoiceSet();
-
- /**
- * \brief Unset the strategy for a namespace
- *
- * cmd format:
- * name strategy
- *
- */
- void
- strategyChoiceUnset();
-
-private:
-
- void
- onSuccess(const ControlParameters& commandSuccessResult,
- const std::string& message);
-
- void
- onError(uint32_t code, const std::string& error, const std::string& message);
-
- void
- onCanonizeFailure(const std::string& reason);
-
- void
- startFaceCreate(const ndn::util::FaceUri& canonicalUri);
-
- void
- onObtainFaceIdFailure(const std::string& message);
-
-public:
- const char* m_programName;
-
- // command parameters without leading 'cmd' component
- const char* const* m_commandLineArguments;
- int m_nOptions;
- uint64_t m_flags;
- uint64_t m_cost;
- uint64_t m_faceId;
- uint64_t m_origin;
- ndn::time::milliseconds m_expires;
- std::string m_name;
- FacePersistency m_facePersistency;
-
-private:
- ndn::KeyChain m_keyChain;
- ndn::Face& m_face;
- Controller m_controller;
- boost::asio::io_service& m_ioService;
-};
-
-} // namespace nfdc
-
-#endif // NFD_TOOLS_NFDC_HPP
diff --git a/tools/nfdc/face-id-fetcher.cpp b/tools/nfdc/face-id-fetcher.cpp
new file mode 100644
index 0000000..da09c11
--- /dev/null
+++ b/tools/nfdc/face-id-fetcher.cpp
@@ -0,0 +1,203 @@
+/* -*- 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/management/nfd-face-query-filter.hpp>
+#include <ndn-cxx/management/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(uint32_t code,
+ const std::string& error,
+ const std::string& message)
+{
+ std::stringstream ss;
+ ss << message << " : " << error << " (code " << code << ")";
+ 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, _2, "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
diff --git a/tools/nfdc/face-id-fetcher.hpp b/tools/nfdc/face-id-fetcher.hpp
new file mode 100644
index 0000000..50e0083
--- /dev/null
+++ b/tools/nfdc/face-id-fetcher.hpp
@@ -0,0 +1,114 @@
+/* -*- 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/>.
+ */
+
+#ifndef NFD_TOOLS_NFDC_FACE_ID_FETCHER_HPP
+#define NFD_TOOLS_NFDC_FACE_ID_FETCHER_HPP
+
+#include "core/common.hpp"
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/management/nfd-controller.hpp>
+#include <ndn-cxx/util/face-uri.hpp>
+#include <ndn-cxx/security/validator-null.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfdc {
+
+using ndn::util::FaceUri;
+
+class FaceIdFetcher
+{
+public:
+ typedef std::function<void(uint32_t)> SuccessCallback;
+ typedef std::function<void(const std::string&)> FailureCallback;
+
+ /** \brief obtain FaceId from input
+ * \param face Reference to the Face that should be used to fetch data
+ * \param controller Reference to the controller that should be used to sign the Interest
+ * \param input User input, either FaceId or FaceUri
+ * \param allowCreate Whether creating face is allowed
+ * \param onSucceed Callback to be fired when faceId is obtained
+ * \param onFail Callback to be fired when an error occurs
+ */
+ static void
+ start(ndn::Face& face,
+ ndn::nfd::Controller& controller,
+ const std::string& input,
+ bool allowCreate,
+ const SuccessCallback& onSucceed,
+ const FailureCallback& onFail);
+
+private:
+ FaceIdFetcher(ndn::Face& face,
+ ndn::nfd::Controller& controller,
+ bool allowCreate,
+ const SuccessCallback& onSucceed,
+ const FailureCallback& onFail);
+
+ void
+ onQuerySuccess(const ndn::ConstBufferPtr& data,
+ const FaceUri& canonicalUri);
+
+ void
+ onQueryFailure(uint32_t errorCode,
+ const FaceUri& canonicalUri);
+
+ void
+ onCanonizeSuccess(const FaceUri& canonicalUri);
+
+ void
+ onCanonizeFailure(const std::string& reason);
+
+ void
+ startGetFaceId(const FaceUri& faceUri);
+
+ void
+ startFaceCreate(const FaceUri& canonicalUri);
+
+ void
+ onFaceCreateError(uint32_t code,
+ const std::string& error,
+ const std::string& message);
+
+ void
+ succeed(uint32_t faceId);
+
+ void
+ fail(const std::string& reason);
+
+private:
+ ndn::Face& m_face;
+ ndn::nfd::Controller& m_controller;
+ bool m_allowCreate;
+ SuccessCallback m_onSucceed;
+ FailureCallback m_onFail;
+ ndn::ValidatorNull m_validator;
+};
+
+} // namespace nfdc
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFDC_FACE_ID_FETCHER_HPP
diff --git a/tools/nfdc/legacy-nfdc.cpp b/tools/nfdc/legacy-nfdc.cpp
new file mode 100644
index 0000000..83a3db8
--- /dev/null
+++ b/tools/nfdc/legacy-nfdc.cpp
@@ -0,0 +1,290 @@
+/* -*- 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 "legacy-nfdc.hpp"
+#include "face-id-fetcher.hpp"
+
+#include <boost/regex.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfdc {
+
+using ndn::nfd::ControlParameters;
+
+const time::milliseconds LegacyNfdc::DEFAULT_EXPIRATION_PERIOD = time::milliseconds::max();
+const uint64_t LegacyNfdc::DEFAULT_COST = 0;
+
+LegacyNfdc::LegacyNfdc(ndn::Face& face)
+ : m_flags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
+ , m_cost(DEFAULT_COST)
+ , m_origin(ndn::nfd::ROUTE_ORIGIN_STATIC)
+ , m_expires(DEFAULT_EXPIRATION_PERIOD)
+ , m_facePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
+ , m_face(face)
+ , m_controller(face, m_keyChain)
+{
+}
+
+bool
+LegacyNfdc::dispatch(const std::string& command)
+{
+ if (command == "add-nexthop") {
+ if (m_nOptions != 2)
+ return false;
+ fibAddNextHop();
+ }
+ else if (command == "remove-nexthop") {
+ if (m_nOptions != 2)
+ return false;
+ fibRemoveNextHop();
+ }
+ else if (command == "register") {
+ if (m_nOptions != 2)
+ return false;
+ ribRegisterPrefix();
+ }
+ else if (command == "unregister") {
+ if (m_nOptions != 2)
+ return false;
+ ribUnregisterPrefix();
+ }
+ else if (command == "create") {
+ if (m_nOptions != 1)
+ return false;
+ faceCreate();
+ }
+ else if (command == "destroy") {
+ if (m_nOptions != 1)
+ return false;
+ faceDestroy();
+ }
+ else if (command == "set-strategy") {
+ if (m_nOptions != 2)
+ return false;
+ strategyChoiceSet();
+ }
+ else if (command == "unset-strategy") {
+ if (m_nOptions != 1)
+ return false;
+ strategyChoiceUnset();
+ }
+ else
+ return false;
+
+ return true;
+}
+
+void
+LegacyNfdc::fibAddNextHop()
+{
+ m_name = m_commandLineArguments[0];
+ const std::string& faceName = m_commandLineArguments[1];
+
+ FaceIdFetcher::start(m_face, m_controller, faceName, true,
+ [this] (const uint32_t faceId) {
+ ControlParameters parameters;
+ parameters
+ .setName(m_name)
+ .setCost(m_cost)
+ .setFaceId(faceId);
+
+ m_controller.start<ndn::nfd::FibAddNextHopCommand>(parameters,
+ bind(&LegacyNfdc::onSuccess, this, _1, "Nexthop insertion succeeded"),
+ bind(&LegacyNfdc::onError, this, _1, _2, "Nexthop insertion failed"));
+ },
+ bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
+}
+
+void
+LegacyNfdc::fibRemoveNextHop()
+{
+ m_name = m_commandLineArguments[0];
+ const std::string& faceName = m_commandLineArguments[1];
+
+ FaceIdFetcher::start(m_face, m_controller, faceName, false,
+ [this] (const uint32_t faceId) {
+ ControlParameters parameters;
+ parameters
+ .setName(m_name)
+ .setFaceId(faceId);
+
+ m_controller.start<ndn::nfd::FibRemoveNextHopCommand>(parameters,
+ bind(&LegacyNfdc::onSuccess, this, _1, "Nexthop removal succeeded"),
+ bind(&LegacyNfdc::onError, this, _1, _2, "Nexthop removal failed"));
+ },
+ bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
+}
+
+void
+LegacyNfdc::ribRegisterPrefix()
+{
+ m_name = m_commandLineArguments[0];
+ const std::string& faceName = m_commandLineArguments[1];
+
+ FaceIdFetcher::start(m_face, m_controller, faceName, true,
+ [this] (const uint32_t faceId) {
+ ControlParameters parameters;
+ parameters
+ .setName(m_name)
+ .setCost(m_cost)
+ .setFlags(m_flags)
+ .setOrigin(m_origin)
+ .setFaceId(faceId);
+
+ if (m_expires != DEFAULT_EXPIRATION_PERIOD)
+ parameters.setExpirationPeriod(m_expires);
+
+ m_controller.start<ndn::nfd::RibRegisterCommand>(parameters,
+ bind(&LegacyNfdc::onSuccess, this, _1, "Successful in name registration"),
+ bind(&LegacyNfdc::onError, this, _1, _2, "Failed in name registration"));
+ },
+ bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
+}
+
+void
+LegacyNfdc::ribUnregisterPrefix()
+{
+ m_name = m_commandLineArguments[0];
+ const std::string& faceName = m_commandLineArguments[1];
+
+ FaceIdFetcher::start(m_face, m_controller, faceName, false,
+ [this] (const uint32_t faceId) {
+ ControlParameters parameters;
+ parameters
+ .setName(m_name)
+ .setFaceId(faceId)
+ .setOrigin(m_origin);
+
+ m_controller.start<ndn::nfd::RibUnregisterCommand>(parameters,
+ bind(&LegacyNfdc::onSuccess, this, _1, "Successful in unregistering name"),
+ bind(&LegacyNfdc::onError, this, _1, _2, "Failed in unregistering name"));
+ },
+ bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
+}
+
+void
+LegacyNfdc::onCanonizeFailure(const std::string& reason)
+{
+ BOOST_THROW_EXCEPTION(Error(reason));
+}
+
+void
+LegacyNfdc::onObtainFaceIdFailure(const std::string& message)
+{
+ BOOST_THROW_EXCEPTION(Error(message));
+}
+
+void
+LegacyNfdc::faceCreate()
+{
+ boost::regex e("^[a-z0-9]+\\:.*");
+ if (!boost::regex_match(m_commandLineArguments[0], e))
+ BOOST_THROW_EXCEPTION(Error("invalid uri format"));
+
+ FaceUri faceUri;
+ faceUri.parse(m_commandLineArguments[0]);
+
+ faceUri.canonize(bind(&LegacyNfdc::startFaceCreate, this, _1),
+ bind(&LegacyNfdc::onCanonizeFailure, this, _1),
+ m_face.getIoService(), time::seconds(4));
+}
+
+void
+LegacyNfdc::startFaceCreate(const FaceUri& canonicalUri)
+{
+ ControlParameters parameters;
+ parameters.setUri(canonicalUri.toString());
+ parameters.setFacePersistency(m_facePersistency);
+
+ m_controller.start<ndn::nfd::FaceCreateCommand>(parameters,
+ bind(&LegacyNfdc::onSuccess, this, _1, "Face creation succeeded"),
+ bind(&LegacyNfdc::onError, this, _1, _2, "Face creation failed"));
+}
+
+void
+LegacyNfdc::faceDestroy()
+{
+ ControlParameters parameters;
+ const std::string& faceName = m_commandLineArguments[0];
+
+ FaceIdFetcher::start(m_face, m_controller, faceName, false,
+ [this] (const uint32_t faceId) {
+ ControlParameters faceParameters;
+ faceParameters.setFaceId(faceId);
+
+ m_controller.start<ndn::nfd::FaceDestroyCommand>(faceParameters,
+ bind(&LegacyNfdc::onSuccess, this, _1, "Face destroy succeeded"),
+ bind(&LegacyNfdc::onError, this, _1, _2, "Face destroy failed"));
+ },
+ bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
+}
+
+void
+LegacyNfdc::strategyChoiceSet()
+{
+ const std::string& name = m_commandLineArguments[0];
+ const std::string& strategy = m_commandLineArguments[1];
+
+ ControlParameters parameters;
+ parameters
+ .setName(name)
+ .setStrategy(strategy);
+
+ m_controller.start<ndn::nfd::StrategyChoiceSetCommand>(parameters,
+ bind(&LegacyNfdc::onSuccess, this, _1, "Successfully set strategy choice"),
+ bind(&LegacyNfdc::onError, this, _1, _2, "Failed to set strategy choice"));
+}
+
+void
+LegacyNfdc::strategyChoiceUnset()
+{
+ const std::string& name = m_commandLineArguments[0];
+
+ ControlParameters parameters;
+ parameters.setName(name);
+
+ m_controller.start<ndn::nfd::StrategyChoiceUnsetCommand>(parameters,
+ bind(&LegacyNfdc::onSuccess, this, _1, "Successfully unset strategy choice"),
+ bind(&LegacyNfdc::onError, this, _1, _2, "Failed to unset strategy choice"));
+}
+
+void
+LegacyNfdc::onSuccess(const ControlParameters& commandSuccessResult, const std::string& message)
+{
+ std::cout << message << ": " << commandSuccessResult << std::endl;
+}
+
+void
+LegacyNfdc::onError(uint32_t code, const std::string& error, const std::string& message)
+{
+ std::ostringstream os;
+ os << message << ": " << error << " (code: " << code << ")";
+ BOOST_THROW_EXCEPTION(Error(os.str()));
+}
+
+} // namespace nfdc
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfdc/legacy-nfdc.hpp b/tools/nfdc/legacy-nfdc.hpp
new file mode 100644
index 0000000..01ed7b9
--- /dev/null
+++ b/tools/nfdc/legacy-nfdc.hpp
@@ -0,0 +1,186 @@
+/* -*- 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/>.
+ */
+
+#ifndef NFD_TOOLS_NFDC_LEGACY_NFDC_HPP
+#define NFD_TOOLS_NFDC_LEGACY_NFDC_HPP
+
+#include "core/common.hpp"
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/management/nfd-controller.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfdc {
+
+class LegacyNfdc : noncopyable
+{
+public:
+ static const time::milliseconds DEFAULT_EXPIRATION_PERIOD;
+ static const uint64_t DEFAULT_COST;
+
+ class Error : public std::runtime_error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : std::runtime_error(what)
+ {
+ }
+ };
+
+ explicit
+ LegacyNfdc(ndn::Face& face);
+
+ bool
+ dispatch(const std::string& cmd);
+
+ /**
+ * \brief Adds a nexthop to a FIB entry
+ *
+ * If the FIB entry does not exist, it is inserted automatically
+ *
+ * cmd format:
+ * [-c cost] name faceId|faceUri
+ *
+ */
+ void
+ fibAddNextHop();
+
+ /**
+ * \brief Removes a nexthop from an existing FIB entry
+ *
+ * If the last nexthop record in a FIB entry is removed, the FIB entry is also deleted
+ *
+ * cmd format:
+ * name faceId
+ *
+ */
+ void
+ fibRemoveNextHop();
+
+ /**
+ * \brief Registers name to the given faceId or faceUri
+ *
+ * cmd format:
+ * [-I] [-C] [-c cost] name faceId|faceUri
+ */
+ void
+ ribRegisterPrefix();
+
+ /**
+ * \brief Unregisters name from the given faceId/faceUri
+ *
+ * cmd format:
+ * name faceId/faceUri
+ */
+ void
+ ribUnregisterPrefix();
+
+ /**
+ * \brief Creates new face
+ *
+ * This command allows creation of UDP unicast and TCP faces only
+ *
+ * cmd format:
+ * uri
+ *
+ */
+ void
+ faceCreate();
+
+ /**
+ * \brief Destroys face
+ *
+ * cmd format:
+ * faceId|faceUri
+ *
+ */
+ void
+ faceDestroy();
+
+ /**
+ * \brief Sets the strategy for a namespace
+ *
+ * cmd format:
+ * name strategy
+ *
+ */
+ void
+ strategyChoiceSet();
+
+ /**
+ * \brief Unset the strategy for a namespace
+ *
+ * cmd format:
+ * name strategy
+ *
+ */
+ void
+ strategyChoiceUnset();
+
+private:
+
+ void
+ onSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
+ const std::string& message);
+
+ void
+ onError(uint32_t code, const std::string& error, const std::string& message);
+
+ void
+ onCanonizeFailure(const std::string& reason);
+
+ void
+ startFaceCreate(const ndn::util::FaceUri& canonicalUri);
+
+ void
+ onObtainFaceIdFailure(const std::string& message);
+
+public:
+ const char* m_programName;
+
+ // command parameters without leading 'cmd' component
+ const char* const* m_commandLineArguments;
+ int m_nOptions;
+ uint64_t m_flags;
+ uint64_t m_cost;
+ uint64_t m_faceId;
+ uint64_t m_origin;
+ time::milliseconds m_expires;
+ std::string m_name;
+ ndn::nfd::FacePersistency m_facePersistency;
+
+private:
+ ndn::KeyChain m_keyChain;
+ ndn::Face& m_face;
+ ndn::nfd::Controller m_controller;
+};
+
+} // namespace nfdc
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFDC_LEGACY_NFDC_HPP
diff --git a/tools/nfdc/main.cpp b/tools/nfdc/main.cpp
new file mode 100644
index 0000000..7d9f763
--- /dev/null
+++ b/tools/nfdc/main.cpp
@@ -0,0 +1,182 @@
+/* -*- 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 "legacy-nfdc.hpp"
+#include "core/version.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfdc {
+
+static void
+usage(const char* programName)
+{
+ std::cout << "Usage:\n" << programName << " [-h] [-V] COMMAND [<Command Options>]\n"
+ " -h print usage and exit\n"
+ " -V print version and exit\n"
+ "\n"
+ " COMMAND can be one of the following:\n"
+ " register [-I] [-C] [-c cost] [-e expiration time] [-o origin] name <faceId | faceUri>\n"
+ " register name to the given faceId or faceUri\n"
+ " -I: unset CHILD_INHERIT flag\n"
+ " -C: set CAPTURE flag\n"
+ " -c: specify cost (default 0)\n"
+ " -e: specify expiration time in ms\n"
+ " (by default the entry remains in FIB for the lifetime of the associated face)\n"
+ " -o: specify origin\n"
+ " 0 for Local producer applications, 128 for NLSR, 255(default) for static routes\n"
+ " unregister [-o origin] name <faceId | faceUri>\n"
+ " unregister name from the given faceId\n"
+ " create [-P] <faceUri> \n"
+ " Create a face in one of the following formats:\n"
+ " UDP unicast: udp[4|6]://<remote-IP-or-host>[:<remote-port>]\n"
+ " TCP: tcp[4|6]://<remote-IP-or-host>[:<remote-port>] \n"
+ " -P: create permanent (instead of persistent) face\n"
+ " destroy <faceId | faceUri> \n"
+ " Destroy a face\n"
+ " set-strategy <name> <strategy> \n"
+ " Set the strategy for a namespace \n"
+ " unset-strategy <name> \n"
+ " Unset the strategy for a namespace \n"
+ " add-nexthop [-c <cost>] <name> <faceId | faceUri>\n"
+ " Add a nexthop to a FIB entry\n"
+ " -c: specify cost (default 0)\n"
+ " remove-nexthop <name> <faceId | faceUri> \n"
+ " Remove a nexthop from a FIB entry\n"
+ << std::endl;
+}
+
+static int
+main(int argc, char** argv)
+{
+ ndn::Face face;
+ LegacyNfdc p(face);
+
+ p.m_programName = argv[0];
+
+ if (argc < 2) {
+ usage(p.m_programName);
+ return 0;
+ }
+
+ if (!strcmp(argv[1], "-h")) {
+ usage(p.m_programName);
+ return 0;
+ }
+
+ if (!strcmp(argv[1], "-V")) {
+ std::cout << NFD_VERSION_BUILD_STRING << std::endl;
+ return 0;
+ }
+
+ ::optind = 2; //start reading options from 2nd argument i.e. Command
+ int opt;
+ while ((opt = ::getopt(argc, argv, "ICc:e:o:P")) != -1) {
+ switch (opt) {
+ case 'I':
+ p.m_flags = p.m_flags & ~(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
+ break;
+
+ case 'C':
+ p.m_flags = p.m_flags | ndn::nfd::ROUTE_FLAG_CAPTURE;
+ break;
+
+ case 'c':
+ try {
+ p.m_cost = boost::lexical_cast<uint64_t>(::optarg);
+ }
+ catch (const boost::bad_lexical_cast&) {
+ std::cerr << "Error: cost must be in unsigned integer format" << std::endl;
+ return 1;
+ }
+ break;
+
+ case 'e':
+ uint64_t expires;
+ try {
+ expires = boost::lexical_cast<uint64_t>(::optarg);
+ }
+ catch (const boost::bad_lexical_cast&) {
+ std::cerr << "Error: expiration time must be in unsigned integer format" << std::endl;
+ return 1;
+ }
+ p.m_expires = ndn::time::milliseconds(expires);
+ break;
+
+ case 'o':
+ try {
+ p.m_origin = boost::lexical_cast<uint64_t>(::optarg);
+ }
+ catch (const boost::bad_lexical_cast&) {
+ std::cerr << "Error: origin must be in unsigned integer format" << std::endl;
+ return 1;
+ }
+ break;
+
+ case 'P':
+ p.m_facePersistency = ndn::nfd::FACE_PERSISTENCY_PERMANENT;
+ break;
+
+ default:
+ usage(p.m_programName);
+ return 1;
+ }
+ }
+
+ if (argc == ::optind) {
+ usage(p.m_programName);
+ return 1;
+ }
+
+ try {
+ p.m_commandLineArguments = argv + ::optind;
+ p.m_nOptions = argc - ::optind;
+
+ //argv[1] points to the command, so pass it to the dispatch
+ bool isOk = p.dispatch(argv[1]);
+ if (!isOk) {
+ usage(p.m_programName);
+ return 1;
+ }
+ face.processEvents();
+ }
+ catch (const std::exception& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl;
+ return 2;
+ }
+ return 0;
+}
+
+} // namespace nfdc
+} // namespace tools
+} // namespace nfd
+
+int
+main(int argc, char** argv)
+{
+ return nfd::tools::nfdc::main(argc, argv);
+}