tools: split nfdc into multiple files
refs #3749
Change-Id: I24a3fd287773d0577d438e9ca24dc1dfab335a4f
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);
+}