face: Implementation of encode/decode of LocalControlHeader
LocalControlHeader can only be used on faces that are derived from
LocalFace. UnixStreamFace is directly inherited from LocalFace,
TCP face has two specializations: generic TcpFace (strictly not local),
and LocalTcpFace.
refs #1213
Change-Id: I8a158c3bc4bb929eedd15757cfddecc0d1049f9f
diff --git a/daemon/common.hpp b/daemon/common.hpp
index 76bbab5..af4a9fd 100644
--- a/daemon/common.hpp
+++ b/daemon/common.hpp
@@ -49,6 +49,7 @@
using boost::enable_shared_from_this;
using boost::make_shared;
using boost::static_pointer_cast;
+using boost::dynamic_pointer_cast;
using boost::function;
using boost::bind;
diff --git a/daemon/core/logger.hpp b/daemon/core/logger.hpp
index 6732384..f8c6e8e 100644
--- a/daemon/core/logger.hpp
+++ b/daemon/core/logger.hpp
@@ -68,6 +68,10 @@
template<> \
nfd::Logger cls<specialization>::g_logger = nfd::Logger(name);
+#define NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(cls, s1, s2, name) \
+ template<> \
+ nfd::Logger cls<s1, s2>::g_logger = nfd::Logger(name);
+
#define NFD_LOG_TRACE(expression) \
if(g_logger.isEnabled(nfd::LOG_TRACE)) \
std::cerr<<"TRACE: "<<"["<<g_logger<<"] " << expression << "\n"
diff --git a/daemon/face/face.cpp b/daemon/face/face.cpp
index 5ca8f29..cc4fba8 100644
--- a/daemon/face/face.cpp
+++ b/daemon/face/face.cpp
@@ -13,7 +13,6 @@
Face::Face()
: m_id(INVALID_FACEID)
- , m_localControlHeaderFeatures(LOCAL_CONTROL_HEADER_FEATURE_MAX)
{
}
@@ -35,6 +34,20 @@
}
bool
+Face::isLocal() const
+{
+ return m_isLocal;
+}
+
+// this method is protected and can be used only in derived class
+// to set localhost scope
+void
+Face::setLocal(bool isLocal)
+{
+ m_isLocal = isLocal;
+}
+
+bool
Face::isUp() const
{
return true;
@@ -58,21 +71,27 @@
return false;
}
-void
-Face::setLocalControlHeaderFeature(LocalControlHeaderFeature feature, bool enabled)
+bool
+Face::decodeAndDispatchInput(const Block& element)
{
- BOOST_ASSERT(feature > LOCAL_CONTROL_HEADER_FEATURE_ANY &&
- feature < m_localControlHeaderFeatures.size());
- m_localControlHeaderFeatures[feature] = enabled;
- NFD_LOG_DEBUG("face" << this->getId() << " setLocalControlHeaderFeature " <<
- (enabled ? "enable" : "disable") << " feature " << feature);
-
- BOOST_STATIC_ASSERT(LOCAL_CONTROL_HEADER_FEATURE_ANY == 0);
- m_localControlHeaderFeatures[LOCAL_CONTROL_HEADER_FEATURE_ANY] =
- std::find(m_localControlHeaderFeatures.begin() + 1,
- m_localControlHeaderFeatures.end(), true) <
- m_localControlHeaderFeatures.end();
- // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
+ /// \todo Ensure lazy field decoding process
+
+ if (element.type() == tlv::Interest)
+ {
+ shared_ptr<Interest> i = make_shared<Interest>();
+ i->wireDecode(element);
+ this->onReceiveInterest(*i);
+ }
+ else if (element.type() == tlv::Data)
+ {
+ shared_ptr<Data> d = make_shared<Data>();
+ d->wireDecode(element);
+ this->onReceiveData(*d);
+ }
+ else
+ return false;
+
+ return true;
}
} //namespace nfd
diff --git a/daemon/face/face.hpp b/daemon/face/face.hpp
index 924b4fa..f3c5d40 100644
--- a/daemon/face/face.hpp
+++ b/daemon/face/face.hpp
@@ -22,21 +22,6 @@
const std::size_t MAX_NDN_PACKET_SIZE = 8800;
-/* \brief indicates a feature in LocalControlHeader
- */
-enum LocalControlHeaderFeature
-{
- /// any feature
- LOCAL_CONTROL_HEADER_FEATURE_ANY,
- /// in-faceid
- LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID,
- /// out-faceid
- LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID,
- /// upper bound of enum
- LOCAL_CONTROL_HEADER_FEATURE_MAX
-};
-
-
/** \brief represents a face
*/
class Face : noncopyable, public enable_shared_from_this<Face>
@@ -75,22 +60,14 @@
virtual void
sendData(const Data& data) = 0;
- /**
- * \brief Close the face
+ /** \brief Close the face
*
- * This terminates all communication on the face and cause
- * onFail() method event to be invoked
+ * This terminates all communication on the face and cause
+ * onFail() method event to be invoked
*/
virtual void
close() = 0;
- /** \brief Get whether face is connected to a local app
- *
- * In this base class this property is always false.
- */
- virtual bool
- isLocal() const = 0;
-
/** \brief Get whether underlying communication is up
*
* In this base class this property is always true.
@@ -98,6 +75,14 @@
virtual bool
isUp() const;
+ /** \brief Get whether face is connected to a local app
+ *
+ * False by default and can become true if a derived class, implementing
+ * one of the local face types, explicitly calls Face::setLocal(true)
+ */
+ bool
+ isLocal() const;
+
/** \brief Set the description
*
* This is typically invoked by mgmt on set description command
@@ -116,22 +101,13 @@
virtual bool
isMultiAccess() const;
- /** \brief get whether a LocalControlHeader feature is enabled
- *
- * \param feature The feature. Cannot be LOCAL_CONTROL_HEADER_FEATURE_MAX
- * LOCAL_CONTROL_HEADER_FEATURE_ANY returns true if any feature is enabled.
- */
- bool
- isLocalControlHeaderEnabled(LocalControlHeaderFeature feature =
- LOCAL_CONTROL_HEADER_FEATURE_ANY) const;
-
- /** \brief enable or disable a LocalControlHeader feature
- *
- * \param feature The feature. Cannot be LOCAL_CONTROL_HEADER_FEATURE_ANY
- * or LOCAL_CONTROL_HEADER_FEATURE_MAX
- */
+protected:
void
- setLocalControlHeaderFeature(LocalControlHeaderFeature feature, bool enabled);
+ setLocal(bool isLocal);
+
+ // this is a non-virtual method
+ bool
+ decodeAndDispatchInput(const Block& element);
private:
void
@@ -140,19 +116,12 @@
private:
FaceId m_id;
std::string m_description;
- std::vector<bool> m_localControlHeaderFeatures;
-
+ bool m_isLocal; // for scoping purposes
+
// allow setting FaceId
friend class Forwarder;
};
-inline bool
-Face::isLocalControlHeaderEnabled(LocalControlHeaderFeature feature) const
-{
- BOOST_ASSERT(feature < m_localControlHeaderFeatures.size());
- return m_localControlHeaderFeatures[feature];
-}
-
} // namespace nfd
#endif // NFD_FACE_FACE_HPP
diff --git a/daemon/face/local-face.hpp b/daemon/face/local-face.hpp
new file mode 100644
index 0000000..6175b5d
--- /dev/null
+++ b/daemon/face/local-face.hpp
@@ -0,0 +1,179 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_LOCAL_FACE_HPP
+#define NFD_FACE_LOCAL_FACE_HPP
+
+#include "face.hpp"
+
+namespace nfd {
+
+/* \brief indicates a feature in LocalControlHeader
+ */
+enum LocalControlHeaderFeature
+{
+ /// any feature
+ LOCAL_CONTROL_HEADER_FEATURE_ANY,
+ /// in-faceid
+ LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID,
+ /// out-faceid
+ LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID,
+ /// upper bound of enum
+ LOCAL_CONTROL_HEADER_FEATURE_MAX
+};
+
+
+/** \brief represents a face
+ */
+class LocalFace : public Face
+{
+public:
+ LocalFace();
+
+ /** \brief get whether a LocalControlHeader feature is enabled
+ *
+ * \param feature The feature. Cannot be LOCAL_CONTROL_HEADER_FEATURE_MAX
+ * LOCAL_CONTROL_HEADER_FEATURE_ANY returns true if any feature is enabled.
+ */
+ bool
+ isLocalControlHeaderEnabled(LocalControlHeaderFeature feature =
+ LOCAL_CONTROL_HEADER_FEATURE_ANY) const;
+
+ /** \brief enable or disable a LocalControlHeader feature
+ *
+ * \param feature The feature. Cannot be LOCAL_CONTROL_HEADER_FEATURE_ANY
+ * or LOCAL_CONTROL_HEADER_FEATURE_MAX
+ */
+ void
+ setLocalControlHeaderFeature(LocalControlHeaderFeature feature, bool enabled = true);
+
+protected:
+ // statically overridden from Face
+
+ /** \brief Decode block into Interest/Data, considering potential LocalControlHeader
+ *
+ * If LocalControlHeader is present, the encoded data is filtered out, based
+ * on enabled features on the face.
+ */
+ bool
+ decodeAndDispatchInput(const Block& element);
+
+ // LocalFace-specific methods
+
+ /** \brief Check if LocalControlHeader needs to be included, taking into account
+ * both set parameters in supplied LocalControlHeader and features
+ * enabled on the local face.
+ */
+ bool
+ isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
+
+ /** \brief Create LocalControlHeader, considering enabled features
+ */
+ template<class Packet>
+ Block
+ filterAndEncodeLocalControlHeader(const Packet& packet);
+
+private:
+ std::vector<bool> m_localControlHeaderFeatures;
+};
+
+inline
+LocalFace::LocalFace()
+ : m_localControlHeaderFeatures(LOCAL_CONTROL_HEADER_FEATURE_MAX)
+{
+ setLocal(true);
+}
+
+inline bool
+LocalFace::isLocalControlHeaderEnabled(LocalControlHeaderFeature feature) const
+{
+ BOOST_ASSERT(feature < m_localControlHeaderFeatures.size());
+ return m_localControlHeaderFeatures[feature];
+}
+
+inline void
+LocalFace::setLocalControlHeaderFeature(LocalControlHeaderFeature feature, bool enabled/* = true*/)
+{
+ BOOST_ASSERT(feature > LOCAL_CONTROL_HEADER_FEATURE_ANY &&
+ feature < m_localControlHeaderFeatures.size());
+ m_localControlHeaderFeatures[feature] = enabled;
+
+ BOOST_STATIC_ASSERT(LOCAL_CONTROL_HEADER_FEATURE_ANY == 0);
+ m_localControlHeaderFeatures[LOCAL_CONTROL_HEADER_FEATURE_ANY] =
+ std::find(m_localControlHeaderFeatures.begin() + 1,
+ m_localControlHeaderFeatures.end(), true) <
+ m_localControlHeaderFeatures.end();
+ // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
+}
+
+inline bool
+LocalFace::decodeAndDispatchInput(const Block& element)
+{
+ const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
+
+ // If received LocalControlHeader, but it is not enabled on the face
+ if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
+ return false;
+
+ if (payload.type() == tlv::Interest)
+ {
+ shared_ptr<Interest> i = make_shared<Interest>();
+ i->wireDecode(payload);
+ if (&payload != &element)
+ {
+ i->getLocalControlHeader().wireDecode(element,
+ false,
+ this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID));
+ }
+
+ this->onReceiveInterest(*i);
+ }
+ else if (payload.type() == tlv::Data)
+ {
+ shared_ptr<Data> d = make_shared<Data>();
+ d->wireDecode(payload);
+
+ /// \todo Uncomment and correct the following when we have more
+ /// options in LocalControlHeader that apply for incoming
+ /// Data packets (if ever)
+ // if (&payload != &element)
+ // {
+ //
+ // d->getLocalControlHeader().wireDecode(element,
+ // false,
+ // false);
+ // }
+
+ this->onReceiveData(*d);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+inline bool
+LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
+{
+ if (!this->isLocalControlHeaderEnabled())
+ return true;
+
+ return header.empty(this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID),
+ false);
+}
+
+template<class Packet>
+inline Block
+LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
+{
+ return packet.getLocalControlHeader().wireEncode(packet,
+ this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID),
+ false);
+}
+
+} // namespace nfd
+
+#endif // NFD_FACE_LOCAL_FACE_HPP
diff --git a/daemon/face/stream-face.hpp b/daemon/face/stream-face.hpp
index ac08421..9baef1d 100644
--- a/daemon/face/stream-face.hpp
+++ b/daemon/face/stream-face.hpp
@@ -8,14 +8,18 @@
#define NFD_FACE_STREAM_FACE_HPP
#include "face.hpp"
+#include "local-face.hpp"
namespace nfd {
-template <class T>
-class StreamFace : public Face
+// forward declaration
+template<class T, class U, class V> struct StreamFaceSenderImpl;
+
+template<class Protocol, class FaceBase = Face>
+class StreamFace : public FaceBase
{
public:
- typedef T protocol;
+ typedef Protocol protocol;
/**
* \brief Create instance of StreamFace
@@ -37,6 +41,12 @@
protected:
void
+ processErrorCode(const boost::system::error_code& error);
+
+ void
+ handleSend(const boost::system::error_code& error,
+ const Block& header, const Block& payload);
+ void
handleSend(const boost::system::error_code& error,
const Block& wire);
@@ -56,159 +66,201 @@
private:
uint8_t m_inputBuffer[MAX_NDN_PACKET_SIZE];
std::size_t m_inputBufferSize;
-
+
+ friend struct StreamFaceSenderImpl<Protocol, FaceBase, Interest>;
+ friend struct StreamFaceSenderImpl<Protocol, FaceBase, Data>;
+
NFD_LOG_INCLASS_DECLARE();
};
// All inherited classes must use
// NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(StreamFace, <specialization-parameter>, "Name");
-template <class T>
+
+/** \brief Class allowing validation of the StreamFace use
+ *
+ * For example, partial specialization based on boost::asio::ip::tcp should check
+ * that local endpoint is loopback
+ *
+ * @throws Face::Error if validation failed
+ */
+template<class Protocol, class U>
+struct StreamFaceValidator
+{
+ static void
+ validateSocket(typename Protocol::socket& socket)
+ {
+ }
+};
+
+
+template<class T, class U>
inline
-StreamFace<T>::StreamFace(const shared_ptr<typename StreamFace::protocol::socket>& socket)
+StreamFace<T, U>::StreamFace(const shared_ptr<typename StreamFace::protocol::socket>& socket)
: m_socket(socket)
, m_inputBufferSize(0)
{
+ StreamFaceValidator<T, U>::validateSocket(*socket);
m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
- bind(&StreamFace<T>::handleReceive, this, _1, _2));
+ bind(&StreamFace<T, U>::handleReceive, this, _1, _2));
}
-template <class T>
+template<class T, class U>
inline
-StreamFace<T>::~StreamFace()
+StreamFace<T, U>::~StreamFace()
{
}
-
-template <class T>
-inline void
-StreamFace<T>::sendInterest(const Interest& interest)
+template<class Protocol, class FaceBase, class Packet>
+struct StreamFaceSenderImpl
{
- m_socket->async_send(boost::asio::buffer(interest.wireEncode().wire(),
- interest.wireEncode().size()),
- bind(&StreamFace<T>::handleSend, this, _1, interest.wireEncode()));
-
- // anything else should be done here?
+ static void
+ send(StreamFace<Protocol, FaceBase>& face, const Packet& packet)
+ {
+ face.m_socket->async_send(boost::asio::buffer(packet.wireEncode().wire(),
+ packet.wireEncode().size()),
+ bind(&StreamFace<Protocol, FaceBase>::handleSend,
+ &face, _1, packet.wireEncode()));
+ }
+};
+
+// partial specialization (only classes can be partially specialized)
+template<class Protocol, class Packet>
+struct StreamFaceSenderImpl<Protocol, LocalFace, Packet>
+{
+ static void
+ send(StreamFace<Protocol, LocalFace>& face, const Packet& packet)
+ {
+ using namespace boost::asio;
+
+ if (face.isEmptyFilteredLocalControlHeader(packet.getLocalControlHeader()))
+ {
+ const Block& payload = packet.wireEncode();
+ face.m_socket->async_send(buffer(payload.wire(), payload.size()),
+ bind(&StreamFace<Protocol, LocalFace>::handleSend,
+ &face, _1, packet.wireEncode()));
+ }
+ else
+ {
+ Block header = face.filterAndEncodeLocalControlHeader(packet);
+ const Block& payload = packet.wireEncode();
+
+ std::vector<const_buffer> buffers;
+ buffers.reserve(2);
+ buffers.push_back(buffer(header.wire(), header.size()));
+ buffers.push_back(buffer(payload.wire(), payload.size()));
+
+ face.m_socket->async_send(buffers,
+ bind(&StreamFace<Protocol, LocalFace>::handleSend,
+ &face, _1, header, payload));
+ }
+ }
+};
+
+
+template<class T, class U>
+inline void
+StreamFace<T, U>::sendInterest(const Interest& interest)
+{
+ StreamFaceSenderImpl<T, U, Interest>::send(*this, interest);
}
-template <class T>
+template<class T, class U>
inline void
-StreamFace<T>::sendData(const Data& data)
+StreamFace<T, U>::sendData(const Data& data)
{
- m_socket->async_send(boost::asio::buffer(data.wireEncode().wire(),
- data.wireEncode().size()),
- bind(&StreamFace<T>::handleSend, this, _1, data.wireEncode()));
-
- // anything else should be done here?
+ StreamFaceSenderImpl<T, U, Data>::send(*this, data);
}
-template <class T>
+template<class T, class U>
inline void
-StreamFace<T>::close()
+StreamFace<T, U>::close()
{
if (!m_socket->is_open())
return;
-
+
NFD_LOG_INFO("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
<< "] Close connection");
closeSocket();
- onFail("Close connection");
+ this->onFail("Close connection");
}
-template <class T>
+template<class T, class U>
inline void
-StreamFace<T>::handleSend(const boost::system::error_code& error,
- const Block& wire)
+StreamFace<T, U>::processErrorCode(const boost::system::error_code& error)
{
- if (error) {
- if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
- return;
-
- if (!m_socket->is_open())
- {
- onFail("Connection closed");
- return;
- }
-
- if (error == boost::asio::error::eof)
- {
- NFD_LOG_INFO("[id:" << this->getId()
- << ",endpoint:" << m_socket->local_endpoint()
- << "] Connection closed");
- }
- else
- {
- NFD_LOG_WARN("[id:" << this->getId()
- << ",endpoint:" << m_socket->local_endpoint()
- << "] Send operation failed, closing socket: "
- << error.category().message(error.value()));
- }
-
- closeSocket();
-
- if (error == boost::asio::error::eof)
- {
- onFail("Connection closed");
- }
- else
- {
- onFail("Send operation failed, closing socket: " +
- error.category().message(error.value()));
- }
+ if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
return;
- }
+
+ if (!m_socket->is_open())
+ {
+ this->onFail("Connection closed");
+ return;
+ }
+
+ if (error == boost::asio::error::eof)
+ {
+ NFD_LOG_INFO("[id:" << this->getId()
+ << ",endpoint:" << m_socket->local_endpoint()
+ << "] Connection closed");
+ }
+ else
+ {
+ NFD_LOG_WARN("[id:" << this->getId()
+ << ",endpoint:" << m_socket->local_endpoint()
+ << "] Send or receive operation failed, closing socket: "
+ << error.category().message(error.value()));
+ }
+
+ closeSocket();
+
+ if (error == boost::asio::error::eof)
+ {
+ this->onFail("Connection closed");
+ }
+ else
+ {
+ this->onFail("Send or receive operation failed, closing socket: " +
+ error.category().message(error.value()));
+ }
+}
+
+
+template<class T, class U>
+inline void
+StreamFace<T, U>::handleSend(const boost::system::error_code& error,
+ const Block& wire)
+{
+ if (error)
+ return processErrorCode(error);
NFD_LOG_TRACE("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
<< "] Successfully sent: " << wire.size() << " bytes");
- // do nothing (needed to retain validity of wire memory block
}
-template <class T>
+template<class T, class U>
inline void
-StreamFace<T>::handleReceive(const boost::system::error_code& error,
+StreamFace<T, U>::handleSend(const boost::system::error_code& error,
+ const Block& header, const Block& payload)
+{
+ if (error)
+ return processErrorCode(error);
+
+ NFD_LOG_TRACE("[id:" << this->getId()
+ << ",endpoint:" << m_socket->local_endpoint()
+ << "] Successfully sent: " << (header.size()+payload.size()) << " bytes");
+}
+
+template<class T, class U>
+inline void
+StreamFace<T, U>::handleReceive(const boost::system::error_code& error,
std::size_t bytes_recvd)
{
- if (error || bytes_recvd == 0) {
- if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
- return;
-
- // this should be unnecessary, but just in case
- if (!m_socket->is_open())
- {
- onFail("Connection closed");
- return;
- }
-
- if (error == boost::asio::error::eof)
- {
- NFD_LOG_INFO("[id:" << this->getId()
- << ",endpoint:" << m_socket->local_endpoint()
- << "] Connection closed");
- }
- else
- {
- NFD_LOG_WARN("[id:" << this->getId()
- << ",endpoint:" << m_socket->local_endpoint()
- << "] Receive operation failed: "
- << error.category().message(error.value()));
- }
-
- closeSocket();
-
- if (error == boost::asio::error::eof)
- {
- onFail("Connection closed");
- }
- else
- {
- onFail("Receive operation failed, closing socket: " +
- error.category().message(error.value()));
- }
- return;
- }
+ if (error)
+ return processErrorCode(error);
NFD_LOG_TRACE("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
@@ -226,27 +278,8 @@
offset += element.size();
BOOST_ASSERT(offset <= m_inputBufferSize);
-
- /// @todo Ensure lazy field decoding process
- if (element.type() == tlv::Interest)
- {
- shared_ptr<Interest> i = make_shared<Interest>();
- i->wireDecode(element);
- onReceiveInterest(*i);
- }
- else if (element.type() == tlv::Data)
- {
- shared_ptr<Data> d = make_shared<Data>();
- d->wireDecode(element);
- onReceiveData(*d);
- }
- // @todo Add local header support
- // else if (element.type() == tlv::LocalHeader)
- // {
- // shared_ptr<Interest> i = make_shared<Interest>();
- // i->wireDecode(element);
- // }
- else
+
+ if (!this->decodeAndDispatchInput(element))
{
NFD_LOG_WARN("[id:" << this->getId()
<< ",endpoint:" << m_socket->local_endpoint()
@@ -265,7 +298,7 @@
<< "closing down the face");
closeSocket();
- onFail("Received input is invalid or too large to process, closing down the face");
+ this->onFail("Received input is invalid or too large to process, closing down the face");
return;
}
}
@@ -286,18 +319,18 @@
m_socket->async_receive(boost::asio::buffer(m_inputBuffer + m_inputBufferSize,
MAX_NDN_PACKET_SIZE - m_inputBufferSize), 0,
- bind(&StreamFace<T>::handleReceive, this, _1, _2));
+ bind(&StreamFace<T, U>::handleReceive, this, _1, _2));
}
-template <class T>
+template<class T, class U>
inline void
-StreamFace<T>::keepFaceAliveUntilAllHandlersExecuted(const shared_ptr<Face>& face)
+StreamFace<T, U>::keepFaceAliveUntilAllHandlersExecuted(const shared_ptr<Face>& face)
{
}
-template <class T>
+template<class T, class U>
inline void
-StreamFace<T>::closeSocket()
+StreamFace<T, U>::closeSocket()
{
boost::asio::io_service& io = m_socket->get_io_service();
@@ -309,7 +342,7 @@
// ensure that the Face object is alive at least until all pending
// handlers are dispatched
- io.post(bind(&StreamFace<T>::keepFaceAliveUntilAllHandlersExecuted,
+ io.post(bind(&StreamFace<T, U>::keepFaceAliveUntilAllHandlersExecuted,
this, this->shared_from_this()));
}
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index 087a24c..34b734a 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -123,7 +123,12 @@
{
tcp::Endpoint remoteEndpoint = socket->remote_endpoint();
- shared_ptr<TcpFace> face = make_shared<TcpFace>(boost::cref(socket));
+ shared_ptr<Face> face;
+ if (socket->local_endpoint().address().is_loopback())
+ face = make_shared<TcpLocalFace>(boost::cref(socket));
+ else
+ face = make_shared<TcpFace>(boost::cref(socket));
+
face->onFail += bind(&TcpChannel::afterFaceFailed, this, remoteEndpoint);
onFaceCreated(face);
diff --git a/daemon/face/tcp-channel.hpp b/daemon/face/tcp-channel.hpp
index 4cca5c5..db6521f 100644
--- a/daemon/face/tcp-channel.hpp
+++ b/daemon/face/tcp-channel.hpp
@@ -32,7 +32,7 @@
* (as a response to incoming connection or after connection
* is established)
*/
- typedef function<void(const shared_ptr<TcpFace>& newFace)> FaceCreatedCallback;
+ typedef function<void(const shared_ptr<Face>& newFace)> FaceCreatedCallback;
/**
* \brief Prototype for the callback that is called when face is failed to
@@ -135,7 +135,7 @@
boost::asio::io_service& m_ioService;
tcp::Endpoint m_localEndpoint;
- typedef std::map< tcp::Endpoint, shared_ptr<TcpFace> > ChannelFaceMap;
+ typedef std::map< tcp::Endpoint, shared_ptr<Face> > ChannelFaceMap;
ChannelFaceMap m_channelFaces;
bool isListening;
diff --git a/daemon/face/tcp-face.cpp b/daemon/face/tcp-face.cpp
index 874de98..4f8cbab 100644
--- a/daemon/face/tcp-face.cpp
+++ b/daemon/face/tcp-face.cpp
@@ -13,15 +13,19 @@
NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(StreamFace, TcpFace::protocol, "TcpFace");
+NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(StreamFace,
+ TcpLocalFace::protocol, LocalFace, "TcpLocalFace");
+
TcpFace::TcpFace(const shared_ptr<TcpFace::protocol::socket>& socket)
: StreamFace<protocol>(socket)
{
}
-bool
-TcpFace::isLocal() const
+//
+
+TcpLocalFace::TcpLocalFace(const shared_ptr<TcpLocalFace::protocol::socket>& socket)
+ : StreamFace<protocol, LocalFace>(socket)
{
- return false;
}
diff --git a/daemon/face/tcp-face.hpp b/daemon/face/tcp-face.hpp
index c41f601..dfd6028 100644
--- a/daemon/face/tcp-face.hpp
+++ b/daemon/face/tcp-face.hpp
@@ -23,11 +23,45 @@
explicit
TcpFace(const shared_ptr<protocol::socket>& socket);
-
- virtual bool
- isLocal() const;
};
+//
+
+/** \brief Class validating use of TcpLocalFace
+ */
+template<>
+struct StreamFaceValidator<boost::asio::ip::tcp, LocalFace>
+{
+ /** Check that local endpoint is loopback
+ *
+ * @throws Face::Error if validation failed
+ */
+ static void
+ validateSocket(boost::asio::ip::tcp::socket& socket)
+ {
+ if (!socket.local_endpoint().address().is_loopback() ||
+ !socket.remote_endpoint().address().is_loopback())
+ {
+ throw Face::Error("TcpLocalFace can be created only on loopback interface");
+ }
+ }
+};
+
+/**
+ * \brief Implementation of Face abstraction that uses TCP
+ * as underlying transport mechanism and is used for
+ * local communication (can enable LocalControlHeader)
+ */
+class TcpLocalFace : public StreamFace<boost::asio::ip::tcp, LocalFace>
+{
+public:
+ typedef boost::asio::ip::tcp protocol;
+
+ explicit
+ TcpLocalFace(const shared_ptr<protocol::socket>& socket);
+};
+
+
} // namespace nfd
#endif // NFD_FACE_TCP_FACE_HPP
diff --git a/daemon/face/unix-stream-face.cpp b/daemon/face/unix-stream-face.cpp
index de7c4f9..27ba693 100644
--- a/daemon/face/unix-stream-face.cpp
+++ b/daemon/face/unix-stream-face.cpp
@@ -11,17 +11,13 @@
// The whole purpose of this file is to specialize the logger,
// otherwise, everything could be put into the header file.
-NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(StreamFace, UnixStreamFace::protocol, "UnixStreamFace");
+NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(StreamFace,
+ UnixStreamFace::protocol, LocalFace,
+ "UnixStreamFace");
UnixStreamFace::UnixStreamFace(const shared_ptr<UnixStreamFace::protocol::socket>& socket)
- : StreamFace<protocol>(socket)
+ : StreamFace<protocol, LocalFace>(socket)
{
}
-bool
-UnixStreamFace::isLocal() const
-{
- return true;
-}
-
} // namespace nfd
diff --git a/daemon/face/unix-stream-face.hpp b/daemon/face/unix-stream-face.hpp
index cc97c21..8492f54 100644
--- a/daemon/face/unix-stream-face.hpp
+++ b/daemon/face/unix-stream-face.hpp
@@ -20,20 +20,13 @@
* \brief Implementation of Face abstraction that uses stream-oriented
* Unix domain sockets as underlying transport mechanism
*/
-class UnixStreamFace : public StreamFace<boost::asio::local::stream_protocol>
+class UnixStreamFace : public StreamFace<boost::asio::local::stream_protocol, LocalFace>
{
public:
typedef boost::asio::local::stream_protocol protocol;
explicit
UnixStreamFace(const shared_ptr<protocol::socket>& socket);
-
- /** \brief Get whether face is connected to a local app
- *
- * Always true for a UnixStreamFace.
- */
- virtual bool
- isLocal() const;
};
} // namespace nfd
diff --git a/daemon/mgmt/internal-face.cpp b/daemon/mgmt/internal-face.cpp
index 1f1a6cb..707ee30 100644
--- a/daemon/mgmt/internal-face.cpp
+++ b/daemon/mgmt/internal-face.cpp
@@ -12,7 +12,7 @@
InternalFace::InternalFace()
{
-
+ setLocal(true);
}
void
@@ -98,12 +98,6 @@
throw Error("Internal face cannot be closed");
}
-bool
-InternalFace::isLocal() const
-{
- return true;
-}
-
void
InternalFace::setInterestFilter(const Name& filter,
OnInterest onInterest)
diff --git a/daemon/mgmt/internal-face.hpp b/daemon/mgmt/internal-face.hpp
index 0e17b3b..8d5805c 100644
--- a/daemon/mgmt/internal-face.hpp
+++ b/daemon/mgmt/internal-face.hpp
@@ -36,13 +36,6 @@
virtual void
close();
- /** \brief Get whether face is connected to a local app
- *
- * Always true for a InternalFace.
- */
- virtual bool
- isLocal() const;
-
// Methods implementing AppFace interface. Do not invoke from forwarder.
virtual void
diff --git a/daemon/mgmt/local-control-header-manager.cpp b/daemon/mgmt/local-control-header-manager.cpp
index 6a0f056..5717f54 100644
--- a/daemon/mgmt/local-control-header-manager.cpp
+++ b/daemon/mgmt/local-control-header-manager.cpp
@@ -5,6 +5,7 @@
*/
#include "local-control-header-manager.hpp"
+#include "face/local-face.hpp"
namespace nfd {
@@ -58,7 +59,15 @@
return;
}
- shared_ptr<Face> face = m_getFace(request.getIncomingFaceId());
+ shared_ptr<LocalFace> face =
+ dynamic_pointer_cast<LocalFace>(m_getFace(request.getIncomingFaceId()));
+
+ if (!static_cast<bool>(face))
+ {
+ NFD_LOG_INFO("command result: request to enable control header on non-local face");
+ sendResponse(command, 400, "Command not supported on the requested face");
+ return;
+ }
const Name::Component& module = command.get(COMMAND_PREFIX.size());
const Name::Component& verb = command.get(COMMAND_PREFIX.size() + 1);
diff --git a/daemon/mgmt/local-control-header-manager.hpp b/daemon/mgmt/local-control-header-manager.hpp
index ab3c08a..8c03e4e 100644
--- a/daemon/mgmt/local-control-header-manager.hpp
+++ b/daemon/mgmt/local-control-header-manager.hpp
@@ -23,7 +23,6 @@
void
onLocalControlHeaderRequest(const Interest& request);
-
private:
function<shared_ptr<Face>(FaceId)> m_getFace;
diff --git a/tests/face/dummy-face.hpp b/tests/face/dummy-face.hpp
index 7de128d..92100b6 100644
--- a/tests/face/dummy-face.hpp
+++ b/tests/face/dummy-face.hpp
@@ -8,6 +8,7 @@
#define NFD_TEST_FACE_DUMMY_FACE_HPP
#include "face/face.hpp"
+#include "face/local-face.hpp"
namespace nfd {
@@ -15,15 +16,10 @@
* \brief provides a Face that cannot communicate
* for unit testing only
*/
-class DummyFace : public Face
+template<class FaceBase>
+class DummyFaceImpl : public FaceBase
{
public:
- explicit
- DummyFace(bool isLocal = false)
- : m_isLocal(isLocal)
- {
- }
-
virtual void
sendInterest(const Interest& interest)
{
@@ -39,16 +35,12 @@
{
}
- virtual bool
- isLocal() const
- {
- return m_isLocal;
- }
-
private:
- bool m_isLocal;
};
+typedef DummyFaceImpl<Face> DummyFace;
+typedef DummyFaceImpl<LocalFace> DummyLocalFace;
+
} // namespace nfd
#endif // TEST_FACE_DUMMY_FACE_HPP
diff --git a/tests/face/face.cpp b/tests/face/face.cpp
index 07e3fb4..3fb4ea4 100644
--- a/tests/face/face.cpp
+++ b/tests/face/face.cpp
@@ -5,6 +5,7 @@
*/
#include "face/face.hpp"
+#include "face/local-face.hpp"
#include "dummy-face.hpp"
#include <boost/test/unit_test.hpp>
@@ -22,7 +23,7 @@
BOOST_AUTO_TEST_CASE(LocalControlHeaderEnabled)
{
- DummyFace face;
+ DummyLocalFace face;
BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(), false);
diff --git a/tests/face/tcp.cpp b/tests/face/tcp.cpp
index d64d1ce..8014f52 100644
--- a/tests/face/tcp.cpp
+++ b/tests/face/tcp.cpp
@@ -32,7 +32,7 @@
{
public:
void
- channel1_onFaceCreated(const shared_ptr<TcpFace>& newFace)
+ channel1_onFaceCreated(const shared_ptr<Face>& newFace)
{
BOOST_CHECK(!static_cast<bool>(m_face1));
m_face1 = newFace;
@@ -78,7 +78,7 @@
}
void
- channel2_onFaceCreated(const shared_ptr<TcpFace>& newFace)
+ channel2_onFaceCreated(const shared_ptr<Face>& newFace)
{
BOOST_CHECK(!static_cast<bool>(m_face2));
m_face2 = newFace;
@@ -124,7 +124,7 @@
}
void
- channel_onFaceCreated(const shared_ptr<TcpFace>& newFace)
+ channel_onFaceCreated(const shared_ptr<Face>& newFace)
{
m_faces.push_back(newFace);
this->afterIo();
@@ -163,14 +163,14 @@
int m_ioRemaining;
- shared_ptr<TcpFace> m_face1;
+ shared_ptr<Face> m_face1;
std::vector<Interest> m_face1_receivedInterests;
std::vector<Data> m_face1_receivedDatas;
- shared_ptr<TcpFace> m_face2;
+ shared_ptr<Face> m_face2;
std::vector<Interest> m_face2_receivedInterests;
std::vector<Data> m_face2_receivedDatas;
- std::list< shared_ptr<TcpFace> > m_faces;
+ std::list< shared_ptr<Face> > m_faces;
};
@@ -202,7 +202,15 @@
BOOST_REQUIRE(static_cast<bool>(m_face1));
BOOST_REQUIRE(static_cast<bool>(m_face2));
-
+
+ BOOST_CHECK_EQUAL(m_face1->isLocal(), true);
+ BOOST_CHECK_EQUAL(m_face2->isLocal(), true);
+
+ BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(m_face1)), true);
+ BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(m_face2)), true);
+
+ // integrated tests needs to check that TcpFace for non-loopback fails these tests...
+
abortEvent =
scheduler.scheduleEvent(time::seconds(1),
bind(&EndToEndFixture::abortTestCase, this,
diff --git a/tests/face/unix-stream.cpp b/tests/face/unix-stream.cpp
index fee5827..9d6a6cf 100644
--- a/tests/face/unix-stream.cpp
+++ b/tests/face/unix-stream.cpp
@@ -61,7 +61,7 @@
this->afterIo();
}
-
+
void
face1_onReceiveInterest(const Interest& interest)
{
@@ -69,7 +69,7 @@
this->afterIo();
}
-
+
void
face1_onReceiveData(const Data& data)
{
@@ -85,7 +85,7 @@
this->afterIo();
}
-
+
void
face2_onReceiveData(const Data& data)
{
@@ -310,6 +310,138 @@
BOOST_CHECK_EQUAL(m_face2_receivedDatas [0].getName(), data1.getName());
}
+static inline void
+noOp()
+{
+}
+
+BOOST_FIXTURE_TEST_CASE(UnixStreamFaceLocalControlHeader, EndToEndFixture)
+{
+ UnixStreamChannelFactory factory(m_ioService);
+ Scheduler scheduler(m_ioService); // to limit the amount of time the test may take
+
+ EventId abortEvent =
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&EndToEndFixture::abortTestCase, this,
+ "UnixStreamChannel error: cannot connect or cannot accept connection"));
+
+ shared_ptr<UnixStreamChannel> channel1 = factory.create("foo");
+ channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
+ bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+ shared_ptr<stream_protocol::socket> client =
+ make_shared<stream_protocol::socket>(boost::ref(m_ioService));
+ client->async_connect(stream_protocol::endpoint("foo"),
+ bind(&EndToEndFixture::client_onConnect, this, _1));
+
+ m_ioRemaining = 2;
+ m_ioService.run();
+ m_ioService.reset();
+ scheduler.cancelEvent(abortEvent);
+
+ BOOST_REQUIRE(static_cast<bool>(m_face1));
+
+ abortEvent =
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&EndToEndFixture::abortTestCase, this,
+ "UnixStreamChannel error: cannot send or receive Interest/Data packets"));
+
+ m_face2 = make_shared<UnixStreamFace>(client);
+ m_face2->onReceiveInterest +=
+ bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
+ m_face2->onReceiveData +=
+ bind(&EndToEndFixture::face2_onReceiveData, this, _1);
+
+ Interest interest1("ndn:/TpnzGvW9R");
+ Data data1 ("ndn:/KfczhUqVix");
+ data1.setContent(0, 0);
+ Interest interest2("ndn:/QWiIMfj5sL");
+ Data data2 ("ndn:/XNBV796f");
+ data2.setContent(0, 0);
+
+ ndn::SignatureSha256WithRsa fakeSignature;
+ fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+ // set fake signature on data1 and data2
+ data1.setSignature(fakeSignature);
+ data2.setSignature(fakeSignature);
+
+ m_face1->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID);
+ m_face1->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID);
+
+ BOOST_CHECK(m_face1->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID));
+ BOOST_CHECK(m_face1->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID));
+
+ m_face2->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID);
+ m_face2->setLocalControlHeaderFeature(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID);
+
+ BOOST_CHECK(m_face2->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID));
+ BOOST_CHECK(m_face2->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID));
+
+ ////////////////////////////////////////////////////////
+
+ interest1.setIncomingFaceId(11);
+ interest1.setNextHopFaceId(111);
+
+ m_face1->sendInterest(interest1);
+
+ data1.setIncomingFaceId(22);
+ data1.getLocalControlHeader().setNextHopFaceId(222);
+
+ m_face1->sendData (data1);
+
+ //
+
+ m_ioRemaining = 2;
+ m_ioService.run();
+ m_ioService.reset();
+
+ BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
+ BOOST_REQUIRE_EQUAL(m_face2_receivedDatas .size(), 1);
+
+ // sending allows only IncomingFaceId, receiving allows only NextHopFaceId
+ BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getLocalControlHeader().hasIncomingFaceId(), false);
+ BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getLocalControlHeader().hasNextHopFaceId(), false);
+
+ BOOST_CHECK_EQUAL(m_face2_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
+ BOOST_CHECK_EQUAL(m_face2_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
+
+ ////////////////////////////////////////////////////////
+
+ using namespace boost::asio;
+
+ std::vector<const_buffer> interestWithHeader;
+ Block iHeader = interest1.getLocalControlHeader().wireEncode(interest1, true, true);
+ Block iPayload = interest1.wireEncode();
+ interestWithHeader.push_back(buffer(iHeader.wire(), iHeader.size()));
+ interestWithHeader.push_back(buffer(iPayload.wire(), iPayload.size()));
+
+ std::vector<const_buffer> dataWithHeader;
+ Block dHeader = data1.getLocalControlHeader().wireEncode(data1, true, true);
+ Block dPayload = data1.wireEncode();
+ dataWithHeader.push_back(buffer(dHeader.wire(), dHeader.size()));
+ dataWithHeader.push_back(buffer(dPayload.wire(), dPayload.size()));
+
+ //
+
+ client->async_send(interestWithHeader, bind(&noOp));
+ client->async_send(dataWithHeader, bind(&noOp));
+
+ m_ioRemaining = 2;
+ m_ioService.run();
+ m_ioService.reset();
+
+ BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
+ BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 1);
+
+ BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getLocalControlHeader().hasIncomingFaceId(), false);
+ BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getLocalControlHeader().hasNextHopFaceId(), true);
+ BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getNextHopFaceId(), 111);
+
+ BOOST_CHECK_EQUAL(m_face1_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
+ BOOST_CHECK_EQUAL(m_face1_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
+}
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace nfd
diff --git a/tests/fw/forwarder.cpp b/tests/fw/forwarder.cpp
index ed8f6a7..e066f52 100644
--- a/tests/fw/forwarder.cpp
+++ b/tests/fw/forwarder.cpp
@@ -38,12 +38,6 @@
{
}
- virtual bool
- isLocal() const
- {
- return false;
- }
-
void
receiveInterest(const Interest& interest)
{
@@ -129,25 +123,6 @@
BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), face2->getId());
}
-
-class ForwarderTestLocalFace : public DummyFace {
-public:
- explicit
- ForwarderTestLocalFace(bool isLocal)
- : m_isLocal(isLocal)
- {
- }
-
- virtual bool
- isLocal() const
- {
- return m_isLocal;
- }
-
-private:
- bool m_isLocal;
-};
-
class ScopeLocalhostTestForwarder : public Forwarder
{
public:
@@ -182,8 +157,8 @@
{
boost::asio::io_service io;
ScopeLocalhostTestForwarder forwarder(io);
- shared_ptr<ForwarderTestLocalFace> face1 = make_shared<ForwarderTestLocalFace>(true);
- shared_ptr<ForwarderTestLocalFace> face2 = make_shared<ForwarderTestLocalFace>(false);
+ shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
+ shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
forwarder.addFace(face1);
forwarder.addFace(face2);
diff --git a/tests/mgmt/local-control-header-manager.cpp b/tests/mgmt/local-control-header-manager.cpp
index b9c1d32..b7fdf58 100644
--- a/tests/mgmt/local-control-header-manager.cpp
+++ b/tests/mgmt/local-control-header-manager.cpp
@@ -6,6 +6,7 @@
#include "mgmt/local-control-header-manager.hpp"
#include "face/face.hpp"
+#include "face/local-face.hpp"
#include "mgmt/internal-face.hpp"
#include "../face/dummy-face.hpp"
@@ -94,7 +95,7 @@
BOOST_FIXTURE_TEST_CASE(InFaceId, LocalControlHeaderManagerFixture)
{
- shared_ptr<Face> dummy = make_shared<DummyFace>();
+ shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
addFace(dummy);
shared_ptr<InternalFace> face(make_shared<InternalFace>());
@@ -136,7 +137,7 @@
BOOST_FIXTURE_TEST_CASE(NextHopFaceId, LocalControlHeaderManagerFixture)
{
- shared_ptr<Face> dummy = make_shared<DummyFace>();
+ shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
addFace(dummy);
shared_ptr<InternalFace> face(make_shared<InternalFace>());
@@ -179,7 +180,7 @@
BOOST_FIXTURE_TEST_CASE(ShortCommand, LocalControlHeaderManagerFixture)
{
- shared_ptr<Face> dummy = make_shared<DummyFace>();
+ shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
addFace(dummy);
shared_ptr<InternalFace> face(make_shared<InternalFace>());
@@ -204,7 +205,7 @@
BOOST_FIXTURE_TEST_CASE(ShortCommandModule, LocalControlHeaderManagerFixture)
{
- shared_ptr<Face> dummy = make_shared<DummyFace>();
+ shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
addFace(dummy);
shared_ptr<InternalFace> face(make_shared<InternalFace>());
@@ -229,7 +230,7 @@
BOOST_FIXTURE_TEST_CASE(UnsupportedModule, LocalControlHeaderManagerFixture)
{
- shared_ptr<Face> dummy = make_shared<DummyFace>();
+ shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
addFace(dummy);
shared_ptr<InternalFace> face(make_shared<InternalFace>());
@@ -254,7 +255,7 @@
BOOST_FIXTURE_TEST_CASE(InFaceIdUnsupportedVerb, LocalControlHeaderManagerFixture)
{
- shared_ptr<Face> dummy = make_shared<DummyFace>();
+ shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
addFace(dummy);
shared_ptr<InternalFace> face(make_shared<InternalFace>());
@@ -279,7 +280,7 @@
BOOST_FIXTURE_TEST_CASE(NextHopFaceIdUnsupportedVerb, LocalControlHeaderManagerFixture)
{
- shared_ptr<Face> dummy = make_shared<DummyFace>();
+ shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
addFace(dummy);
shared_ptr<InternalFace> face(make_shared<InternalFace>());