diff --git a/daemon/fw/face-table.cpp b/daemon/fw/face-table.cpp index 18842032..a8a8053e 100644 --- a/daemon/fw/face-table.cpp +++ b/daemon/fw/face-table.cpp @@ -25,6 +25,7 @@ #include "face-table.hpp" #include "forwarder.hpp" +#include "core/global-io.hpp" #include "core/logger.hpp" namespace nfd { @@ -111,6 +112,9 @@ FaceTable::remove(shared_ptr face, const std::string& reason) " (" << reason << ")"); m_forwarder.getFib().removeNextHopFromAllEntries(face); + + // defer Face deallocation, so that Transport isn't deallocated during afterStateChange signal + getGlobalIoService().post([face] {}); } FaceTable::ForwardRange diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp index b49b7529..29cac396 100644 --- a/daemon/mgmt/face-manager.cpp +++ b/daemon/mgmt/face-manager.cpp @@ -26,6 +26,7 @@ #include "face-manager.hpp" #include "core/network-interface.hpp" +#include "face/generic-link-service.hpp" #include "face/lp-face-wrapper.hpp" #include "face/tcp-factory.hpp" #include "face/udp-factory.hpp" @@ -132,43 +133,6 @@ FaceManager::createFace(const Name& topPrefix, const Interest& interest, } } -void -FaceManager::destroyFace(const Name& topPrefix, const Interest& interest, - const ControlParameters& parameters, - const ndn::mgmt::CommandContinuation& done) -{ - shared_ptr target = m_faceTable.get(parameters.getFaceId()); - if (target) { - target->close(); - } - - done(ControlResponse(200, "OK").setBody(parameters.wireEncode())); -} - -void -FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest, - const ControlParameters& parameters, - const ndn::mgmt::CommandContinuation& done) -{ - auto result = extractLocalControlParameters(interest, parameters, done); - if (result.isValid) { - result.face->setLocalControlHeaderFeature(result.feature, true); - return done(ControlResponse(200, "OK").setBody(parameters.wireEncode())); - } -} - -void -FaceManager::disableLocalControl(const Name& topPrefix, const Interest& interest, - const ControlParameters& parameters, - const ndn::mgmt::CommandContinuation& done) -{ - auto result = extractLocalControlParameters(interest, parameters, done); - if (result.isValid) { - result.face->setLocalControlHeaderFeature(result.feature, false); - return done(ControlResponse(200, "OK").setBody(parameters.wireEncode())); - } -} - void FaceManager::afterCreateFaceSuccess(ControlParameters& parameters, const shared_ptr& newFace, @@ -182,6 +146,19 @@ FaceManager::afterCreateFaceSuccess(ControlParameters& parameters, done(ControlResponse(200, "OK").setBody(parameters.wireEncode())); } +void +FaceManager::destroyFace(const Name& topPrefix, const Interest& interest, + const ControlParameters& parameters, + const ndn::mgmt::CommandContinuation& done) +{ + shared_ptr target = m_faceTable.get(parameters.getFaceId()); + if (target) { + target->close(); + } + + done(ControlResponse(200, "OK").setBody(parameters.wireEncode())); +} + void FaceManager::afterCreateFaceFailure(const std::string& reason, const ndn::mgmt::CommandContinuation& done) @@ -191,6 +168,68 @@ FaceManager::afterCreateFaceFailure(const std::string& reason, done(ControlResponse(408, "Failed to create face: " + reason)); } +void +FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest, + const ControlParameters& parameters, + const ndn::mgmt::CommandContinuation& done) +{ + auto result = extractLocalControlParameters(interest, parameters, done); + if (!result.isValid) { + return; + } + + if (result.face) { + result.face->setLocalControlHeaderFeature(result.feature, true); + return done(ControlResponse(200, "OK").setBody(parameters.wireEncode())); + } + + // TODO#3226 redesign enable-local-control + // For now, enable-local-control will enable all local fields in GenericLinkService. + BOOST_ASSERT(result.lpFace != nullptr); + auto service = dynamic_cast(result.lpFace->getLinkService()); + if (service == nullptr) { + return done(ControlResponse(503, "LinkService type not supported")); + } + + face::GenericLinkService::Options options = service->getOptions(); + options.allowLocalFields = true; + service->setOptions(options); + + return done(ControlResponse(200, "OK: enable all local fields on GenericLinkService") + .setBody(parameters.wireEncode())); +} + +void +FaceManager::disableLocalControl(const Name& topPrefix, const Interest& interest, + const ControlParameters& parameters, + const ndn::mgmt::CommandContinuation& done) +{ + auto result = extractLocalControlParameters(interest, parameters, done); + if (!result.isValid) { + return; + } + + if (result.face) { + result.face->setLocalControlHeaderFeature(result.feature, false); + return done(ControlResponse(200, "OK").setBody(parameters.wireEncode())); + } + + // TODO#3226 redesign disable-local-control + // For now, disable-local-control will disable all local fields in GenericLinkService. + BOOST_ASSERT(result.lpFace != nullptr); + auto service = dynamic_cast(result.lpFace->getLinkService()); + if (service == nullptr) { + return done(ControlResponse(503, "LinkService type not supported")); + } + + face::GenericLinkService::Options options = service->getOptions(); + options.allowLocalFields = false; + service->setOptions(options); + + return done(ControlResponse(200, "OK: disable all local fields on GenericLinkService") + .setBody(parameters.wireEncode())); +} + FaceManager::ExtractLocalControlParametersResult FaceManager::extractLocalControlParameters(const Interest& request, const ControlParameters& parameters, @@ -198,6 +237,7 @@ FaceManager::extractLocalControlParameters(const Interest& request, { ExtractLocalControlParametersResult result; result.isValid = false; + result.lpFace = nullptr; auto face = m_faceTable.get(request.getIncomingFaceId()); if (!static_cast(face)) { @@ -215,6 +255,11 @@ FaceManager::extractLocalControlParameters(const Interest& request, result.isValid = true; result.face = dynamic_pointer_cast(face); + if (result.face == nullptr) { + auto lpFaceW = dynamic_pointer_cast(face); + BOOST_ASSERT(lpFaceW != nullptr); + result.lpFace = lpFaceW->getLpFace(); + } result.feature = static_cast(parameters.getLocalControlFeature()); return result; diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp index f5283d6d..e3c955ff 100644 --- a/daemon/mgmt/face-manager.hpp +++ b/daemon/mgmt/face-manager.hpp @@ -36,6 +36,10 @@ class FaceTable; class NetworkInterfaceInfo; class ProtocolFactory; +namespace face { +class LpFace; +} // namespace face + /** * @brief implement the Face Management of NFD Management Protocol. * @sa http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt @@ -88,6 +92,7 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE: // helpers for ControlCommand { bool isValid; shared_ptr face; + face::LpFace* lpFace; LocalControlFeature feature; };