face+mgmt: enable local fields through ProtocolFactory::createFace
refs #3731
Change-Id: I569dae59cda150ffcb1c0ff1d01a575d8850beca
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index 85f00f1..cfb4b79 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -58,6 +58,7 @@
void
EthernetFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
const FaceCreationFailedCallback& onFailure)
{
diff --git a/daemon/face/ethernet-factory.hpp b/daemon/face/ethernet-factory.hpp
index f29e09a..8e11024 100644
--- a/daemon/face/ethernet-factory.hpp
+++ b/daemon/face/ethernet-factory.hpp
@@ -79,6 +79,7 @@
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
const FaceCreationFailedCallback& onFailure) override;
diff --git a/daemon/face/protocol-factory.hpp b/daemon/face/protocol-factory.hpp
index 6af5bb8..ee19063 100644
--- a/daemon/face/protocol-factory.hpp
+++ b/daemon/face/protocol-factory.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -55,14 +55,20 @@
* This method should automatically choose channel, based on supplied FaceUri
* and create face.
*
- * \throw Error Factory does not support connect operation
- * \throw Error specified \p persistency is not supported
+ * \param uri remote URI of the new face
+ * \param persistency persistency of the new face
+ * \param wantLocalFieldsEnabled whether local fields should be enabled on the face
+ * \param onCreated callback if face creation succeeds
+ * If a face with the same remote URI already exists, its persistency and
+ * LocalFieldsEnabled setting will not be modified.
+ * \param onFailure callback if face creation fails
*/
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
- const FaceCreationFailedCallback& onConnectFailed) = 0;
+ const FaceCreationFailedCallback& onFailure) = 0;
virtual std::vector<shared_ptr<const Channel>>
getChannels() const = 0;
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index 163b0e9..656b671 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -66,6 +66,7 @@
void
TcpChannel::connect(const tcp::Endpoint& remoteEndpoint,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onConnectFailed,
const time::seconds& timeout/* = time::seconds(4)*/)
@@ -83,8 +84,8 @@
clientSocket->async_connect(remoteEndpoint,
bind(&TcpChannel::handleConnect, this,
- boost::asio::placeholders::error,
- clientSocket, connectTimeoutEvent,
+ boost::asio::placeholders::error, clientSocket,
+ wantLocalFieldsEnabled, connectTimeoutEvent,
onFaceCreated, onConnectFailed));
}
@@ -96,8 +97,9 @@
void
TcpChannel::createFace(ip::tcp::socket&& socket,
- const FaceCreatedCallback& onFaceCreated,
- bool isOnDemand)
+ bool isOnDemand,
+ bool wantLocalFieldsEnabled,
+ const FaceCreatedCallback& onFaceCreated)
{
shared_ptr<Face> face;
tcp::Endpoint remoteEndpoint = socket.remote_endpoint();
@@ -107,7 +109,12 @@
auto persistency = isOnDemand ? ndn::nfd::FACE_PERSISTENCY_ON_DEMAND
: ndn::nfd::FACE_PERSISTENCY_PERSISTENT;
auto linkService = make_unique<face::GenericLinkService>();
+ auto options = linkService->getOptions();
+ options.allowLocalFields = wantLocalFieldsEnabled;
+ linkService->setOptions(options);
+
auto transport = make_unique<face::TcpTransport>(std::move(socket), persistency);
+
face = make_shared<Face>(std::move(linkService), std::move(transport));
m_channelFaces[remoteEndpoint] = face;
@@ -157,7 +164,7 @@
NFD_LOG_DEBUG("[" << m_localEndpoint << "] Connection from " << m_acceptSocket.remote_endpoint());
- createFace(std::move(m_acceptSocket), onFaceCreated, true);
+ createFace(std::move(m_acceptSocket), true, false, onFaceCreated);
// prepare accepting the next connection
accept(onFaceCreated, onAcceptFailed);
@@ -166,6 +173,7 @@
void
TcpChannel::handleConnect(const boost::system::error_code& error,
const shared_ptr<ip::tcp::socket>& socket,
+ bool wantLocalFieldsEnabled,
const scheduler::EventId& connectTimeoutEvent,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onConnectFailed)
@@ -195,7 +203,7 @@
NFD_LOG_DEBUG("[" << m_localEndpoint << "] Connected to " << socket->remote_endpoint());
- createFace(std::move(*socket), onFaceCreated, false);
+ createFace(std::move(*socket), false, wantLocalFieldsEnabled, onFaceCreated);
}
void
diff --git a/daemon/face/tcp-channel.hpp b/daemon/face/tcp-channel.hpp
index c819014..1b2fd93 100644
--- a/daemon/face/tcp-channel.hpp
+++ b/daemon/face/tcp-channel.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -73,6 +73,7 @@
*/
void
connect(const tcp::Endpoint& remoteEndpoint,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onConnectFailed,
const time::seconds& timeout = time::seconds(4));
@@ -89,8 +90,9 @@
private:
void
createFace(boost::asio::ip::tcp::socket&& socket,
- const FaceCreatedCallback& onFaceCreated,
- bool isOnDemand);
+ bool isOnDemand,
+ bool wantLocalFieldsEnabled,
+ const FaceCreatedCallback& onFaceCreated);
void
accept(const FaceCreatedCallback& onFaceCreated,
@@ -104,6 +106,7 @@
void
handleConnect(const boost::system::error_code& error,
const shared_ptr<boost::asio::ip::tcp::socket>& socket,
+ bool wantLocalFieldsEnabled,
const scheduler::EventId& connectTimeoutEvent,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onConnectFailed);
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index 5c96492..8ae2337 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -99,14 +99,15 @@
void
TcpFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
- const FaceCreationFailedCallback& onConnectFailed)
+ const FaceCreationFailedCallback& onFailure)
{
BOOST_ASSERT(uri.isCanonical());
if (persistency != ndn::nfd::FACE_PERSISTENCY_PERSISTENT) {
NFD_LOG_TRACE("createFace only supports FACE_PERSISTENCY_PERSISTENT");
- onConnectFailed(406, "Outgoing TCP faces only support persistent persistency");
+ onFailure(406, "Outgoing TCP faces only support persistent persistency");
return;
}
@@ -115,14 +116,20 @@
if (endpoint.address().is_multicast()) {
NFD_LOG_TRACE("createFace cannot create multicast faces");
- onConnectFailed(406, "Cannot create multicast TCP faces");
+ onFailure(406, "Cannot create multicast TCP faces");
return;
}
if (m_prohibitedEndpoints.find(endpoint) != m_prohibitedEndpoints.end()) {
NFD_LOG_TRACE("Requested endpoint is prohibited "
"(reserved by NFD or disallowed by face management protocol)");
- onConnectFailed(406, "Requested endpoint is prohibited");
+ onFailure(406, "Requested endpoint is prohibited");
+ return;
+ }
+
+ if (wantLocalFieldsEnabled && !endpoint.address().is_loopback()) {
+ NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
+ onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
@@ -130,13 +137,13 @@
for (const auto& i : m_channels) {
if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
(i.first.address().is_v6() && endpoint.address().is_v6())) {
- i.second->connect(endpoint, onCreated, onConnectFailed);
+ i.second->connect(endpoint, wantLocalFieldsEnabled, onCreated, onFailure);
return;
}
}
NFD_LOG_TRACE("No channels available to connect to " + boost::lexical_cast<std::string>(endpoint));
- onConnectFailed(504, "No channels available to connect");
+ onFailure(504, "No channels available to connect");
}
std::vector<shared_ptr<const Channel>>
diff --git a/daemon/face/tcp-factory.hpp b/daemon/face/tcp-factory.hpp
index 126aef2..2ed6ad1 100644
--- a/daemon/face/tcp-factory.hpp
+++ b/daemon/face/tcp-factory.hpp
@@ -35,19 +35,6 @@
{
public:
/**
- * \brief Exception of TcpFactory
- */
- class Error : public ProtocolFactory::Error
- {
- public:
- explicit
- Error(const std::string& what)
- : ProtocolFactory::Error(what)
- {
- }
- };
-
- /**
* \brief Create TCP-based channel using tcp::Endpoint
*
* tcp::Endpoint is really an alias for boost::asio::ip::tcp::endpoint.
@@ -59,8 +46,6 @@
* \returns always a valid pointer to a TcpChannel object, an exception
* is thrown if it cannot be created.
*
- * \throws TcpFactory::Error
- *
* \see http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/ip__tcp/endpoint.html
* for details on ways to create tcp::Endpoint
*/
@@ -73,7 +58,7 @@
* This method is just a helper that converts a string representation of localIp and port to
* tcp::Endpoint and calls the other createChannel overload.
*
- * \throws TcpFactory::Error or std::runtime_error
+ * \throws std::runtime_error
*/
shared_ptr<TcpChannel>
createChannel(const std::string& localIp, const std::string& localPort);
@@ -82,8 +67,9 @@
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
- const FaceCreationFailedCallback& onConnectFailed) override;
+ const FaceCreationFailedCallback& onFailure) override;
virtual std::vector<shared_ptr<const Channel>>
getChannels() const override;
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index 9b66b0d..64907be 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -146,8 +146,10 @@
{
auto it = m_channelFaces.find(remoteEndpoint);
if (it != m_channelFaces.end()) {
- // we already have a face for this endpoint, just reuse it
+ // we already have a face for this endpoint, so reuse it
auto face = it->second;
+
+ // TODO #3232: Remove persistency transitions from faces/create
// only on-demand -> persistent -> permanent transition is allowed
bool isTransitionAllowed = persistency != face->getPersistency() &&
(face->getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND ||
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 499c72c..88ac221 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -233,14 +233,15 @@
void
UdpFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
- const FaceCreationFailedCallback& onConnectFailed)
+ const FaceCreationFailedCallback& onFailure)
{
BOOST_ASSERT(uri.isCanonical());
if (persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
- onConnectFailed(406, "Outgoing unicast UDP faces do not support on-demand persistency");
+ onFailure(406, "Outgoing unicast UDP faces do not support on-demand persistency");
return;
}
@@ -249,14 +250,21 @@
if (endpoint.address().is_multicast()) {
NFD_LOG_TRACE("createFace does not support multicast faces");
- onConnectFailed(406, "Cannot create multicast UDP faces");
+ onFailure(406, "Cannot create multicast UDP faces");
return;
}
if (m_prohibitedEndpoints.find(endpoint) != m_prohibitedEndpoints.end()) {
NFD_LOG_TRACE("Requested endpoint is prohibited "
"(reserved by this NFD or disallowed by face management protocol)");
- onConnectFailed(406, "Requested endpoint is prohibited");
+ onFailure(406, "Requested endpoint is prohibited");
+ return;
+ }
+
+ if (wantLocalFieldsEnabled) {
+ // UDP faces are never local
+ NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
+ onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
@@ -264,13 +272,13 @@
for (const auto& i : m_channels) {
if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
(i.first.address().is_v6() && endpoint.address().is_v6())) {
- i.second->connect(endpoint, persistency, onCreated, onConnectFailed);
+ i.second->connect(endpoint, persistency, onCreated, onFailure);
return;
}
}
NFD_LOG_TRACE("No channels available to connect to " + boost::lexical_cast<std::string>(endpoint));
- onConnectFailed(504, "No channels available to connect");
+ onFailure(504, "No channels available to connect");
}
std::vector<shared_ptr<const Channel>>
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
index bda8ac5..c788a3f 100644
--- a/daemon/face/udp-factory.hpp
+++ b/daemon/face/udp-factory.hpp
@@ -149,8 +149,9 @@
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
- const FaceCreationFailedCallback& onConnectFailed) override;
+ const FaceCreationFailedCallback& onFailure) override;
virtual std::vector<shared_ptr<const Channel>>
getChannels() const override;
diff --git a/daemon/face/unix-stream-factory.cpp b/daemon/face/unix-stream-factory.cpp
index b85953e..bfbab44 100644
--- a/daemon/face/unix-stream-factory.cpp
+++ b/daemon/face/unix-stream-factory.cpp
@@ -48,10 +48,11 @@
void
UnixStreamFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
- const FaceCreationFailedCallback& onConnectFailed)
+ const FaceCreationFailedCallback& onFailure)
{
- onConnectFailed(406, "Unsupported protocol");
+ onFailure(406, "Unsupported protocol");
}
std::vector<shared_ptr<const Channel>>
diff --git a/daemon/face/unix-stream-factory.hpp b/daemon/face/unix-stream-factory.hpp
index 2f899b6..07a8317 100644
--- a/daemon/face/unix-stream-factory.hpp
+++ b/daemon/face/unix-stream-factory.hpp
@@ -35,19 +35,6 @@
{
public:
/**
- * \brief Exception of UnixStreamFactory
- */
- class Error : public ProtocolFactory::Error
- {
- public:
- explicit
- Error(const std::string& what)
- : ProtocolFactory::Error(what)
- {
- }
- };
-
- /**
* \brief Create stream-oriented Unix channel using specified socket path
*
* If this method is called twice with the same path, only one channel
@@ -56,8 +43,6 @@
*
* \returns always a valid pointer to a UnixStreamChannel object,
* an exception will be thrown if the channel cannot be created.
- *
- * \throws UnixStreamFactory::Error
*/
shared_ptr<UnixStreamChannel>
createChannel(const std::string& unixSocketPath);
@@ -66,8 +51,9 @@
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
- const FaceCreationFailedCallback& onConnectFailed) override;
+ const FaceCreationFailedCallback& onFailure) override;
virtual std::vector<shared_ptr<const Channel>>
getChannels() const override;
diff --git a/daemon/face/websocket-factory.cpp b/daemon/face/websocket-factory.cpp
index cea0078..a92d93e 100644
--- a/daemon/face/websocket-factory.cpp
+++ b/daemon/face/websocket-factory.cpp
@@ -53,10 +53,11 @@
void
WebSocketFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
- const FaceCreationFailedCallback& onConnectFailed)
+ const FaceCreationFailedCallback& onFailure)
{
- onConnectFailed(406, "Unsupported protocol");
+ onFailure(406, "Unsupported protocol");
}
std::vector<shared_ptr<const Channel>>
diff --git a/daemon/face/websocket-factory.hpp b/daemon/face/websocket-factory.hpp
index 110c026..1f784b7 100644
--- a/daemon/face/websocket-factory.hpp
+++ b/daemon/face/websocket-factory.hpp
@@ -35,19 +35,6 @@
{
public:
/**
- * \brief Exception of WebSocketFactory
- */
- class Error : public ProtocolFactory::Error
- {
- public:
- explicit
- Error(const std::string& what)
- : ProtocolFactory::Error(what)
- {
- }
- };
-
- /**
* \brief Create WebSocket-based channel using websocket::Endpoint
*
* websocket::Endpoint is really an alias for boost::asio::ip::tcp::endpoint.
@@ -58,8 +45,6 @@
*
* \returns always a valid pointer to a WebSocketChannel object, an exception
* is thrown if it cannot be created.
- *
- * \throws WebSocketFactory::Error
*/
shared_ptr<WebSocketChannel>
createChannel(const websocket::Endpoint& localEndpoint);
@@ -69,8 +54,6 @@
*
* This method is just a helper that converts a string representation of localIp and port to
* websocket::Endpoint and calls the other createChannel overload.
- *
- * \throws WebSocketFactory::Error
*/
shared_ptr<WebSocketChannel>
createChannel(const std::string& localIp, const std::string& localPort);
@@ -79,8 +62,9 @@
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
+ bool wantLocalFieldsEnabled,
const FaceCreatedCallback& onCreated,
- const FaceCreationFailedCallback& onConnectFailed) override;
+ const FaceCreationFailedCallback& onFailure) override;
virtual std::vector<shared_ptr<const Channel>>
getChannels() const override;
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index 783d21a..9078bca 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -115,6 +115,8 @@
try {
factory->second->createFace(uri,
parameters.getFacePersistency(),
+ parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ?
+ parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) : false,
bind(&FaceManager::afterCreateFaceSuccess,
this, parameters, _1, done),
bind(&FaceManager::afterCreateFaceFailure,
@@ -140,20 +142,45 @@
*/
void
FaceManager::afterCreateFaceSuccess(const ControlParameters& parameters,
- const shared_ptr<Face>& newFace,
+ const shared_ptr<Face>& face,
const ndn::mgmt::CommandContinuation& done)
{
+ // TODO: Re-enable check in #3232
+ //if (face->getId() != face::INVALID_FACEID) {
+ //// Face already exists
+ //ControlParameters response;
+ //response.setFaceId(face->getId());
+ //response.setUri(face->getRemoteUri().toString());
+ //response.setFacePersistency(face->getPersistency());
+ //
+ //auto linkService = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
+ //BOOST_ASSERT(linkService != nullptr);
+ //auto options = linkService->getOptions();
+ //response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false);
+ //
+ // NFD_LOG_TRACE("Attempted to create duplicate face of " << face->getId());
+ // done(ControlResponse(409, "Face with remote URI already exists").setBody(response.wireEncode()));
+ //}
+ //else {
+ // If scope non-local and flags set to enable local fields, request shouldn't
+ // have made it this far
+ BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
+ !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
+ (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
+ !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
+
+ m_faceTable.add(face);
+
ControlParameters response;
-
- m_faceTable.add(newFace);
-
- // TODO: #3731: Verify and add Flags
-
- // Set ControlResponse parameters
- response.setFaceId(newFace->getId());
- response.setFacePersistency(newFace->getPersistency());
+ response.setFaceId(face->getId());
+ response.setFacePersistency(face->getPersistency());
+ response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
+ parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ?
+ parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) : false,
+ false);
done(ControlResponse(200, "OK").setBody(response.wireEncode()));
+ //}
}
void
@@ -222,9 +249,13 @@
setLinkServiceOptions(*face, parameters, response);
- // Set remaining ControlResponse fields
+ // Set ControlResponse fields
response.setFaceId(faceId);
response.setFacePersistency(face->getPersistency());
+ response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
+ parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ?
+ parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) : false,
+ false);
done(ControlResponse(200, "OK").setBody(response.wireEncode()));
}