face: Implementing nfd::Controller
This commit also adds an option for Node constructor to use
nfd::Controller instead of default ndnd::Controller to set interest
filter (register prefix).
Change-Id: If395756c1b98abe909cec0967c07d347affe5928
diff --git a/src/management/controller.hpp b/src/management/controller.hpp
new file mode 100644
index 0000000..f919489
--- /dev/null
+++ b/src/management/controller.hpp
@@ -0,0 +1,43 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_MANAGEMENT_CONTROLLER_HPP
+#define NDN_MANAGEMENT_CONTROLLER_HPP
+
+#include "../common.hpp"
+#include "../name.hpp"
+#include "../interest.hpp"
+#include "../data.hpp"
+
+namespace ndn {
+
+class Node;
+
+class Controller
+{
+public:
+ typedef function<void()> SuccessCallback;
+ typedef function<void(const std::string&)> FailCallback;
+
+ virtual
+ ~Controller()
+ {
+ }
+
+ virtual void
+ selfRegisterPrefix(const Name& prefixToRegister,
+ const SuccessCallback& onSuccess,
+ const FailCallback& onFail) = 0;
+
+ virtual void
+ selfDeregisterPrefix(const Name& prefixToRegister,
+ const SuccessCallback& onSuccess,
+ const FailCallback& onFail) = 0;
+};
+
+} // namespace ndn
+
+#endif // NDN_MANAGEMENT_CONTROLLER_HPP
diff --git a/src/management/ndnd-control.cpp b/src/management/ndnd-controller.cpp
similarity index 66%
rename from src/management/ndnd-control.cpp
rename to src/management/ndnd-controller.cpp
index 6f48231..e95d85e 100644
--- a/src/management/ndnd-control.cpp
+++ b/src/management/ndnd-controller.cpp
@@ -5,6 +5,8 @@
*/
#include "common.hpp"
+#include "ndnd-controller.hpp"
+
#include "../node.hpp"
#include "../security/signature-sha256-with-rsa.hpp"
#include "../util/random.hpp"
@@ -16,43 +18,43 @@
namespace ndn {
namespace ndnd {
-Control::Control(Node& face)
+Controller::Controller(Node& face)
: m_face(face)
, m_faceId(-1)
{
}
void
-Control::selfRegisterPrefix(const Name& prefixToRegister,
- const SuccessCallback& onSuccess,
- const FailCallback& onFail)
+Controller::selfRegisterPrefix(const Name& prefixToRegister,
+ const SuccessCallback& onSuccess,
+ const FailCallback& onFail)
{
if (!m_ndndId.hasValue())
{
if (m_filterRequests.empty())
{
m_face.expressInterest(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"),
- bind(&Control::onNdnidFetched, this, _1, _2),
- bind(onFail));
+ bind(&Controller::onNdnidFetched, this, _1, _2),
+ bind(onFail, "NDNDID fetching timed out"));
}
m_filterRequests.push_back(FilterRequest(prefixToRegister, onSuccess, onFail));
}
else
startPrefixAction(ForwardingEntry("selfreg", prefixToRegister),
- bind(&Control::recordSelfRegisteredFaceId, this, _1, onSuccess),
+ bind(&Controller::recordSelfRegisteredFaceId, this, _1, onSuccess),
onFail);
}
void
-Control::selfDeregisterPrefix(const Name& prefixToRegister,
- const SuccessCallback& onSuccess,
- const FailCallback& onFail)
+Controller::selfDeregisterPrefix(const Name& prefixToRegister,
+ const SuccessCallback& onSuccess,
+ const FailCallback& onFail)
{
if (!m_ndndId.hasValue() || m_faceId == -1)
{
if (static_cast<bool>(onFail))
- onFail();
+ onFail("NDNID is not available (must have been present after a successful registration operation)");
return;
}
@@ -62,8 +64,8 @@
void
-Control::onNdnidFetched(const shared_ptr<const Interest>& interest,
- const shared_ptr<Data>& data)
+Controller::onNdnidFetched(const shared_ptr<const Interest>& interest,
+ const shared_ptr<Data>& data)
{
if (data->getName().size() > interest->getName().size())
{
@@ -74,7 +76,7 @@
++i)
{
startPrefixAction(ForwardingEntry("selfreg", i->m_prefixToRegister),
- bind(&Control::recordSelfRegisteredFaceId, this, _1, i->m_onSuccess),
+ bind(&Controller::recordSelfRegisteredFaceId, this, _1, i->m_onSuccess),
i->m_onFailure);
}
}
@@ -85,15 +87,15 @@
++i)
{
if (static_cast<bool>(i->m_onFailure))
- i->m_onFailure();
+ i->m_onFailure("NDNID cannot be fetched");
}
}
m_filterRequests.clear();
}
void
-Control::recordSelfRegisteredFaceId(const ForwardingEntry& entry,
- const SuccessCallback& onSuccess)
+Controller::recordSelfRegisteredFaceId(const ForwardingEntry& entry,
+ const SuccessCallback& onSuccess)
{
m_faceId = entry.getFaceId();
if (static_cast<bool>(onSuccess))
@@ -101,9 +103,9 @@
}
void
-Control::startFaceAction(const FaceInstance& entry,
- const FaceOperationSucceedCallback& onSuccess,
- const FailCallback& onFailure)
+Controller::startFaceAction(const FaceInstance& entry,
+ const FaceOperationSucceedCallback& onSuccess,
+ const FailCallback& onFail)
{
// Set the ForwardingEntry as the content of a Data packet and sign.
Data data;
@@ -129,14 +131,14 @@
interest.setMustBeFresh(true);
m_face.expressInterest(interest,
- bind(&Control::processFaceActionResponse, this, _2, onSuccess, onFailure),
- bind(onFailure));
+ bind(&Controller::processFaceActionResponse, this, _2, onSuccess, onFail),
+ bind(onFail, "Command Interest failed"));
}
void
-Control::startPrefixAction(const ForwardingEntry& entry,
- const PrefixOperationSucceedCallback& onSuccess,
- const FailCallback& onFailure)
+Controller::startPrefixAction(const ForwardingEntry& entry,
+ const PrefixOperationSucceedCallback& onSuccess,
+ const FailCallback& onFail)
{
// Set the ForwardingEntry as the content of a Data packet and sign.
Data data;
@@ -162,14 +164,14 @@
interest.setMustBeFresh(true);
m_face.expressInterest(interest,
- bind(&Control::processPrefixActionResponse, this, _2, onSuccess, onFailure),
- bind(onFailure));
+ bind(&Controller::processPrefixActionResponse, this, _2, onSuccess, onFail),
+ bind(onFail, "Command Interest timed out"));
}
void
-Control::processFaceActionResponse(const shared_ptr<Data>& data,
- const FaceOperationSucceedCallback& onSuccess,
- const FailCallback& onFail)
+Controller::processFaceActionResponse(const shared_ptr<Data>& data,
+ const FaceOperationSucceedCallback& onSuccess,
+ const FailCallback& onFail)
{
Block content = data->getContent();
content.parse();
@@ -177,7 +179,7 @@
if (content.getAll().empty())
{
if (static_cast<bool>(onFail))
- onFail();
+ onFail("Empty response");
return;
}
@@ -200,22 +202,22 @@
resp.wireDecode(*val);
if (static_cast<bool>(onFail))
- onFail();
+ onFail(resp.getInfo());
return;
}
default:
{
if (static_cast<bool>(onFail))
- onFail();
+ onFail("Invalid response");
return;
}
}
}
void
-Control::processPrefixActionResponse(const shared_ptr<Data>& data,
- const PrefixOperationSucceedCallback& onSuccess,
- const FailCallback& onFail)
+Controller::processPrefixActionResponse(const shared_ptr<Data>& data,
+ const PrefixOperationSucceedCallback& onSuccess,
+ const FailCallback& onFail)
{
Block content = data->getContent();
content.parse();
@@ -223,7 +225,7 @@
if (content.getAll().empty())
{
if (static_cast<bool>(onFail))
- onFail();
+ onFail("Empty response");
return;
}
@@ -248,13 +250,13 @@
// std::cerr << "StatusReponse: " << resp << std::endl;
if (static_cast<bool>(onFail))
- onFail();
+ onFail(resp.getInfo());
return;
}
default:
{
if (static_cast<bool>(onFail))
- onFail();
+ onFail("Invalid response");
return;
}
}
diff --git a/src/management/ndnd-control.hpp b/src/management/ndnd-controller.hpp
similarity index 88%
rename from src/management/ndnd-control.hpp
rename to src/management/ndnd-controller.hpp
index fd22f15..319f995 100644
--- a/src/management/ndnd-control.hpp
+++ b/src/management/ndnd-controller.hpp
@@ -4,10 +4,15 @@
* See COPYING for copyright and distribution information.
*/
-#ifndef NDN_MANAGEMENT_NDND_CONTROL_HPP
-#define NDN_MANAGEMENT_NDND_CONTROL_HPP
+#ifndef NDN_MANAGEMENT_NDND_CONTROLLER_HPP
+#define NDN_MANAGEMENT_NDND_CONTROLLER_HPP
#include "../common.hpp"
+#include "controller.hpp"
+
+#include "../name.hpp"
+#include "../interest.hpp"
+#include "../data.hpp"
namespace ndn {
@@ -23,26 +28,23 @@
*
* ndnd::Control should be used when connecting to ndnd-tlv daemon
*/
-class Control
+class Controller : public ndn::Controller
{
public:
- typedef function<void()> SuccessCallback;
- typedef function<void()> FailCallback;
-
typedef function<void(const ForwardingEntry&)> PrefixOperationSucceedCallback;
typedef function<void(const FaceInstance&)> FaceOperationSucceedCallback;
/**
* @brief Construct ndnd::Control object
*/
- Control(Node& face);
+ Controller(Node& face);
- void
+ virtual void
selfRegisterPrefix(const Name& prefixToRegister,
const SuccessCallback& onSuccess,
const FailCallback& onFail);
- void
+ virtual void
selfDeregisterPrefix(const Name& prefixToRegister,
const SuccessCallback& onSuccess,
const FailCallback& onFail);
@@ -106,4 +108,4 @@
} // namespace ndnd
} // namespace ndn
-#endif // NDN_MANAGEMENT_NDND_CONTROL_HPP
+#endif // NDN_MANAGEMENT_NDND_CONTROLLER_HPP
diff --git a/src/management/control-response.hpp b/src/management/nfd-control-response.hpp
similarity index 92%
rename from src/management/control-response.hpp
rename to src/management/nfd-control-response.hpp
index f493f5a..238d1c5 100644
--- a/src/management/control-response.hpp
+++ b/src/management/nfd-control-response.hpp
@@ -11,6 +11,7 @@
#include "../encoding/tlv-nfd-control.hpp"
namespace ndn {
+namespace nfd {
/**
* @brief Class defining abstraction of ControlResponse for NFD Control Protocol
@@ -31,6 +32,11 @@
, m_text(text)
{
}
+
+ ControlResponse(const Block& block)
+ {
+ wireDecode(block);
+ }
inline uint32_t
getCode() const;
@@ -133,6 +139,9 @@
m_wire = wire;
m_wire.parse();
+ if (m_wire.type() != tlv::nfd_control::ControlResponse)
+ throw Error("Requested decoding of ControlResponse, but Block is of different type");
+
Block::element_iterator val = m_wire.getAll().begin();
if (val == m_wire.getAll().end() ||
val->type() != tlv::nfd_control::StatusCode)
@@ -164,6 +173,7 @@
return os;
}
+} // namespace nfd
} // namespace ndn
#endif // NDN_MANAGEMENT_CONTROL_RESPONSE_HPP
diff --git a/src/management/nfd-control.hpp b/src/management/nfd-control.hpp
deleted file mode 100644
index 642afd8..0000000
--- a/src/management/nfd-control.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2013 Regents of the University of California.
- * See COPYING for copyright and distribution information.
- */
-
-#ifndef NDN_MANAGEMENT_NFD_CONTROL_HPP
-#define NDN_MANAGEMENT_NFD_CONTROL_HPP
-
-namespace ndn {
-
-} // namespace ndn
-
-#endif // NDN_MANAGEMENT_NFD_CONTROL_HPP
diff --git a/src/management/nfd-controller.cpp b/src/management/nfd-controller.cpp
new file mode 100644
index 0000000..c72c5d3
--- /dev/null
+++ b/src/management/nfd-controller.cpp
@@ -0,0 +1,122 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "common.hpp"
+#include "../node.hpp"
+
+#include "nfd-controller.hpp"
+#include "nfd-fib-management-options.hpp"
+#include "nfd-control-response.hpp"
+
+namespace ndn {
+namespace nfd {
+
+Controller::Controller(Node& face)
+ : m_face(face)
+ , m_faceId(0)
+{
+}
+
+void
+Controller::selfRegisterPrefix(const Name& prefixToRegister,
+ const SuccessCallback& onSuccess,
+ const FailCallback& onFail)
+{
+ startFibCommand("add-nexthop",
+ FibManagementOptions()
+ .setName(prefixToRegister)
+ .setFaceId(0) // self-registration
+ .setCost(0),
+ bind(&Controller::recordSelfRegisteredFaceId, this, _1, onSuccess),
+ onFail);
+}
+
+void
+Controller::selfDeregisterPrefix(const Name& prefixToRegister,
+ const SuccessCallback& onSuccess,
+ const FailCallback& onFail)
+{
+ if (m_faceId == 0)
+ {
+ if (static_cast<bool>(onFail))
+ onFail("Face ID is not set, should have been set after a successful prefix registration command");
+ return;
+ }
+
+ startFibCommand("remove-nexthop",
+ FibManagementOptions()
+ .setName(prefixToRegister)
+ .setFaceId(m_faceId),
+ bind(onSuccess), onFail);
+}
+
+void
+Controller::startFibCommand(const std::string& command,
+ const FibManagementOptions& options,
+ const FibCommandSucceedCallback& onSuccess,
+ const FailCallback& onFail)
+{
+ Name fibCommandInterestName("/localhost/nfd/fib");
+ fibCommandInterestName
+ .append(command)
+ .append(options.wireEncode());
+
+ Interest fibCommandInterest(fibCommandInterestName);
+ m_keyChain.sign(fibCommandInterest);
+
+ m_face.expressInterest(fibCommandInterest,
+ bind(&Controller::processFibCommandResponse, this, _2,
+ onSuccess, onFail),
+ bind(onFail, "Command Interest timed out"));
+}
+
+void
+Controller::recordSelfRegisteredFaceId(const FibManagementOptions& entry,
+ const SuccessCallback& onSuccess)
+{
+ m_faceId = entry.getFaceId();
+ onSuccess();
+}
+
+// void
+// processFaceActionResponse(const shared_ptr<Data>& data,
+// const FaceOperationSucceedCallback& onSuccess,
+// const FailCallback& onFail);
+
+void
+Controller::processFibCommandResponse(const shared_ptr<Data>& data,
+ const FibCommandSucceedCallback& onSuccess,
+ const FailCallback& onFail)
+{
+ try
+ {
+ ControlResponse response(data->getContent().blockFromValue());
+
+ if (response.getCode() != 200)
+ return onFail(response.getText());
+
+ FibManagementOptions options(response.getBody());
+ return onSuccess(options);
+ }
+ catch(ndn::Tlv::Error& e)
+ {
+ if (static_cast<bool>(onFail))
+ return onFail(e.what());
+ }
+ catch(ControlResponse::Error& e)
+ {
+ if (static_cast<bool>(onFail))
+ return onFail(e.what());
+ }
+ catch(FibManagementOptions::Error& e)
+ {
+ if (static_cast<bool>(onFail))
+ return onFail(e.what());
+ }
+}
+
+} // namespace nfd
+} // namespace ndn
diff --git a/src/management/nfd-controller.hpp b/src/management/nfd-controller.hpp
new file mode 100644
index 0000000..d5400c6
--- /dev/null
+++ b/src/management/nfd-controller.hpp
@@ -0,0 +1,75 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_MANAGEMENT_NFD_CONTROL_HPP
+#define NDN_MANAGEMENT_NFD_CONTROL_HPP
+
+#include "../common.hpp"
+#include "controller.hpp"
+
+#include "../name.hpp"
+#include "../interest.hpp"
+#include "../data.hpp"
+#include "../security/key-chain.hpp"
+
+namespace ndn {
+
+class Name;
+
+namespace nfd {
+
+class FibManagementOptions;
+
+class Controller : public ndn::Controller
+{
+public:
+ typedef function<void(const FibManagementOptions&)> FibCommandSucceedCallback;
+
+ /**
+ * @brief Construct ndnd::Control object
+ */
+ Controller(Node& face);
+
+ virtual void
+ selfRegisterPrefix(const Name& prefixToRegister,
+ const SuccessCallback& onSuccess,
+ const FailCallback& onFail);
+
+ virtual void
+ selfDeregisterPrefix(const Name& prefixToRegister,
+ const SuccessCallback& onSuccess,
+ const FailCallback& onFail);
+
+ void
+ startFibCommand(const std::string& command,
+ const FibManagementOptions& options,
+ const FibCommandSucceedCallback& onSuccess,
+ const FailCallback& onFailure);
+private:
+ void
+ recordSelfRegisteredFaceId(const FibManagementOptions& entry,
+ const SuccessCallback& onSuccess);
+
+ // void
+ // processFaceActionResponse(const shared_ptr<Data>& data,
+ // const FaceOperationSucceedCallback& onSuccess,
+ // const FailCallback& onFail);
+
+ void
+ processFibCommandResponse(const shared_ptr<Data>& data,
+ const FibCommandSucceedCallback& onSuccess,
+ const FailCallback& onFail);
+
+private:
+ Node& m_face;
+ KeyChain m_keyChain;
+ uint64_t m_faceId; // internal face ID (needed for prefix de-registration)
+};
+
+} // namespace nfd
+} // namespace ndn
+
+#endif // NDN_MANAGEMENT_NFD_CONTROL_HPP
diff --git a/src/management/fib-management-options.hpp b/src/management/nfd-fib-management-options.hpp
similarity index 63%
rename from src/management/fib-management-options.hpp
rename to src/management/nfd-fib-management-options.hpp
index 58048b5..67e344c 100644
--- a/src/management/fib-management-options.hpp
+++ b/src/management/nfd-fib-management-options.hpp
@@ -7,8 +7,8 @@
* See COPYING for copyright and distribution information.
*/
-#ifndef NDN_FIB_MANAGEMENT_HPP
-#define NDN_FIB_MANAGEMENT_HPP
+#ifndef NDN_MANAGEMENT_NFD_FIB_MANAGEMENT_OPTIONS_HPP
+#define NDN_MANAGEMENT_NFD_FIB_MANAGEMENT_OPTIONS_HPP
#include "../encoding/block.hpp"
#include "../encoding/encoding-buffer.hpp"
@@ -16,40 +16,73 @@
#include "../name.hpp"
namespace ndn {
+namespace nfd {
class FibManagementOptions {
public:
+ struct Error : public Tlv::Error { Error(const std::string &what) : Tlv::Error(what) {} };
+
FibManagementOptions ()
: faceId_ (-1)
, cost_ (-1)
{
}
+
+ FibManagementOptions(const Block& block)
+ {
+ wireDecode(block);
+ }
const Name&
- getName () const { return name_; }
+ getName () const
+ {
+ return name_;
+ }
- void
- setName (const Name &name) { name_ = name; wire_.reset (); }
+ FibManagementOptions&
+ setName (const Name &name)
+ {
+ name_ = name;
+ wire_.reset ();
+ return *this;
+ }
int
- getFaceId () const { return faceId_; }
+ getFaceId () const
+ {
+ return faceId_;
+ }
- void
- setFaceId (int faceId) { faceId_ = faceId; wire_.reset (); }
+ FibManagementOptions&
+ setFaceId (int faceId)
+ {
+ faceId_ = faceId;
+ wire_.reset ();
+ return *this;
+ }
int
- getCost () const { return cost_; }
+ getCost () const
+ {
+ return cost_;
+ }
- void
- setCost (int cost) { cost_ = cost; wire_.reset (); }
+ FibManagementOptions&
+ setCost (int cost)
+ {
+ cost_ = cost;
+ wire_.reset ();
+ return *this;
+ }
- inline size_t
- wireEncode (EncodingBuffer& blk);
+ template<bool T>
+ size_t
+ wireEncode(EncodingImpl<T> &block) const;
- inline const Block&
+ const Block&
wireEncode () const;
- inline void
+ void
wireDecode (const Block &wire);
private:
@@ -62,8 +95,9 @@
mutable Block wire_;
};
+template<bool T>
inline size_t
-FibManagementOptions::wireEncode (EncodingBuffer& blk)
+FibManagementOptions::wireEncode(EncodingImpl<T>& blk) const
{
size_t total_len = 0;
if (cost_ != -1)
@@ -89,28 +123,27 @@
return total_len;
}
+template
+size_t
+FibManagementOptions::wireEncode<true>(EncodingBuffer& block) const;
+
+template
+size_t
+FibManagementOptions::wireEncode<false>(EncodingEstimator& block) const;
+
inline const Block&
FibManagementOptions::wireEncode () const
{
if (wire_.hasWire ())
return wire_;
-
- wire_ = Block (tlv::nfd_control::FibManagementOptions);
- // Name
- wire_.push_back (name_.wireEncode ());
+ EncodingEstimator estimator;
+ size_t estimatedSize = wireEncode(estimator);
- // FaceId
- if (faceId_ != -1)
- wire_.push_back (nonNegativeIntegerBlock (tlv::nfd_control::FaceId, faceId_));
+ EncodingBuffer buffer(estimatedSize, 0);
+ wireEncode(buffer);
- // Cost
- if (cost_ != -1)
- wire_.push_back (nonNegativeIntegerBlock (tlv::nfd_control::Cost, cost_));
-
- //TODO: Strategy
-
- wire_.encode ();
+ wire_ = buffer.block();
return wire_;
}
@@ -122,6 +155,10 @@
cost_ = -1;
wire_ = wire;
+
+ if (wire_.type() != tlv::nfd_control::FibManagementOptions)
+ throw Error("Requested decoding of FibManagementOptions, but Block is of different type");
+
wire_.parse ();
// Name
@@ -166,6 +203,7 @@
return os;
}
-}
+} // namespace nfd
+} // namespace ndn
-#endif
+#endif // NDN_MANAGEMENT_NFD_FIB_MANAGEMENT_OPTIONS_HPP