face: minimal UDP permanent face
Change-Id: I44f652b95c911667107fd30829c7ce6e5acab706
Refs: #2989
diff --git a/daemon/face/datagram-face.hpp b/daemon/face/datagram-face.hpp
index 82d0347..a55fb8c 100644
--- a/daemon/face/datagram-face.hpp
+++ b/daemon/face/datagram-face.hpp
@@ -168,7 +168,11 @@
if (error == boost::asio::error::operation_aborted) // when cancel() is called
return;
- // this should be unnecessary, but just in case
+ if (getPersistency() == ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERMANENT) {
+ NFD_LOG_FACE_DEBUG("Permanent face ignores error: " << error.message());
+ return;
+ }
+
if (!m_socket.is_open()) {
this->fail("Tunnel closed");
return;
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index 81cf401..c9920c4 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -67,12 +67,13 @@
void
UdpChannel::connect(const udp::Endpoint& remoteEndpoint,
+ ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onConnectFailed)
{
shared_ptr<UdpFace> face;
try {
- face = createFace(remoteEndpoint, false).second;
+ face = createFace(remoteEndpoint, persistency).second;
}
catch (const boost::system::system_error& e) {
NFD_LOG_WARN("[" << m_localEndpoint << "] Connect failed: " << e.what());
@@ -93,16 +94,20 @@
}
std::pair<bool, shared_ptr<UdpFace>>
-UdpChannel::createFace(const udp::Endpoint& remoteEndpoint, bool isOnDemand)
+UdpChannel::createFace(const udp::Endpoint& remoteEndpoint, ndn::nfd::FacePersistency persistency)
{
auto it = m_channelFaces.find(remoteEndpoint);
if (it != m_channelFaces.end()) {
// we already have a face for this endpoint, just reuse it
- if (!isOnDemand) {
- // only on-demand -> persistent transition is allowed
- it->second->setPersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+ auto face = it->second;
+ // only on-demand -> persistent -> permanent transition is allowed
+ bool isTransitionAllowed = persistency != face->getPersistency() &&
+ (face->getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND ||
+ persistency == ndn::nfd::FACE_PERSISTENCY_PERMANENT);
+ if (isTransitionAllowed) {
+ face->setPersistency(persistency);
}
- return {false, it->second};
+ return {false, face};
}
// else, create a new face
@@ -112,7 +117,7 @@
socket.connect(remoteEndpoint);
auto face = make_shared<UdpFace>(FaceUri(remoteEndpoint), FaceUri(m_localEndpoint),
- std::move(socket), isOnDemand, m_idleFaceTimeout);
+ std::move(socket), persistency, m_idleFaceTimeout);
face->onFail.connectSingleShot([this, remoteEndpoint] (const std::string&) {
NFD_LOG_TRACE("Erasing " << remoteEndpoint << " from channel face map");
@@ -144,7 +149,7 @@
bool created;
shared_ptr<UdpFace> face;
try {
- std::tie(created, face) = createFace(m_remoteEndpoint, true);
+ std::tie(created, face) = createFace(m_remoteEndpoint, ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
}
catch (const boost::system::system_error& e) {
NFD_LOG_WARN("[" << m_localEndpoint << "] Failed to create face for peer "
diff --git a/daemon/face/udp-channel.hpp b/daemon/face/udp-channel.hpp
index 17410dc..3f92ada 100644
--- a/daemon/face/udp-channel.hpp
+++ b/daemon/face/udp-channel.hpp
@@ -78,6 +78,7 @@
*/
void
connect(const udp::Endpoint& remoteEndpoint,
+ ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onConnectFailed);
@@ -92,7 +93,7 @@
private:
std::pair<bool, shared_ptr<UdpFace>>
- createFace(const udp::Endpoint& remoteEndpoint, bool isOnDemand);
+ createFace(const udp::Endpoint& remoteEndpoint, ndn::nfd::FacePersistency persistency);
/**
* \brief The channel has received a new packet from a remote
diff --git a/daemon/face/udp-face.cpp b/daemon/face/udp-face.cpp
index 20b57cf..6985784 100644
--- a/daemon/face/udp-face.cpp
+++ b/daemon/face/udp-face.cpp
@@ -38,13 +38,13 @@
NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(DatagramFace, UdpFace::protocol, "UdpFace");
UdpFace::UdpFace(const FaceUri& remoteUri, const FaceUri& localUri,
- protocol::socket socket, bool isOnDemand,
+ protocol::socket socket, ndn::nfd::FacePersistency persistency,
const time::seconds& idleTimeout)
: DatagramFace(remoteUri, localUri, std::move(socket))
, m_idleTimeout(idleTimeout)
, m_lastIdleCheck(time::steady_clock::now())
{
- this->setPersistency(isOnDemand ? ndn::nfd::FACE_PERSISTENCY_ON_DEMAND : ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+ this->setPersistency(persistency);
#ifdef __linux__
//
diff --git a/daemon/face/udp-face.hpp b/daemon/face/udp-face.hpp
index 333bae2..a7541a5 100644
--- a/daemon/face/udp-face.hpp
+++ b/daemon/face/udp-face.hpp
@@ -39,7 +39,7 @@
{
public:
UdpFace(const FaceUri& remoteUri, const FaceUri& localUri,
- protocol::socket socket, bool isOnDemand,
+ protocol::socket socket, ndn::nfd::FacePersistency persistency,
const time::seconds& idleTimeout);
ndn::nfd::FaceStatus
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 07b0367..8d24bbe 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -255,8 +255,8 @@
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
- if (persistency != ndn::nfd::FACE_PERSISTENCY_PERSISTENT) {
- BOOST_THROW_EXCEPTION(Error("UdpFactory only supports persistent face"));
+ if (persistency == ndn::nfd::FacePersistency::FACE_PERSISTENCY_ON_DEMAND) {
+ BOOST_THROW_EXCEPTION(Error("UdpFactory::createFace does not support creating on-demand face"));
}
BOOST_ASSERT(uri.isCanonical());
@@ -283,7 +283,7 @@
if ((channel->first.address().is_v4() && endpoint.address().is_v4()) ||
(channel->first.address().is_v6() && endpoint.address().is_v6()))
{
- channel->second->connect(endpoint, onCreated, onConnectFailed);
+ channel->second->connect(endpoint, persistency, onCreated, onConnectFailed);
return;
}
}
diff --git a/tests/daemon/face/udp.t.cpp b/tests/daemon/face/udp.t.cpp
index ff0c710..c00f54f 100644
--- a/tests/daemon/face/udp.t.cpp
+++ b/tests/daemon/face/udp.t.cpp
@@ -228,22 +228,25 @@
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind([]{}),
bind(&FaceCreateFixture::failIfError, this, _1));
+ //test the upgrade
+ factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
+ ndn::nfd::FACE_PERSISTENCY_PERMANENT,
+ bind([]{}),
+ bind(&FaceCreateFixture::failIfError, this, _1));
+
+ factory.createFace(FaceUri("udp4://127.0.0.1:20072"),
+ ndn::nfd::FACE_PERSISTENCY_PERMANENT,
+ bind([]{}),
+ bind(&FaceCreateFixture::failIfError, this, _1));
}
-BOOST_FIXTURE_TEST_CASE(UnsupportedFaceCreate, FaceCreateFixture)
+BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
{
UdpFactory factory;
factory.createChannel("127.0.0.1", "20070");
- factory.createChannel("127.0.0.1", "20071");
BOOST_CHECK_THROW(factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
- ndn::nfd::FACE_PERSISTENCY_PERMANENT,
- bind([]{}),
- bind([]{})),
- ProtocolFactory::Error);
-
- BOOST_CHECK_THROW(factory.createFace(FaceUri("udp4://127.0.0.1:20071"),
ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
bind([]{}),
bind([]{})),
@@ -480,6 +483,7 @@
boost::asio::ip::address ipAddress2 = boost::asio::ip::address::from_string(A::getLocalIp());
udp::Endpoint endpoint2(ipAddress2, boost::lexical_cast<uint16_t>(A::getPort1()));
channel2->connect(endpoint2,
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
[&] (shared_ptr<Face> newFace) {
face2 = newFace;
limitedIo.afterOp();
@@ -497,6 +501,7 @@
boost::asio::ip::address ipAddress3 = boost::asio::ip::address::from_string(A::getLocalIp());
udp::Endpoint endpoint3(ipAddress3, boost::lexical_cast<uint16_t>(A::getPort1()));
channel3->connect(endpoint3,
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
[&] (shared_ptr<Face> newFace) {
face3 = newFace;
limitedIo.afterOp();
@@ -579,6 +584,7 @@
boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(A::getLocalIp());
udp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(A::getPort1()));
channel2->connect(endpoint,
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
[&] (shared_ptr<Face> newFace) {
face2 = newFace;
history2.reset(new FaceHistory(*face2, limitedIo));