face: close idle Datagram faces
refs #1281
Change-Id: Ifc766964f653d3991b55d76361c8b9bbe5d630cf
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index 24c1833..cedb033 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -18,6 +18,7 @@
const time::Duration& timeout)
: m_localEndpoint(localEndpoint)
, m_isListening(false)
+ , m_idleFaceTimeout(timeout)
{
/// \todo the reuse_address works as we want in Linux, but in other system could be different.
/// We need to check this
@@ -38,10 +39,15 @@
}
this->setUri(FaceUri(localEndpoint));
+
+ //setting the timeout to close the idle faces
+ m_closeIdleFaceEvent = scheduler::schedule(m_idleFaceTimeout,
+ bind(&UdpChannel::closeIdleFaces, this));
}
UdpChannel::~UdpChannel()
{
+ scheduler::cancel(m_closeIdleFaceEvent);
}
void
@@ -70,6 +76,7 @@
{
ChannelFaceMap::iterator i = m_channelFaces.find(remoteEndpoint);
if (i != m_channelFaces.end()) {
+ i->second->setPermanent(true);
onFaceCreated(i->second);
return;
}
@@ -93,7 +100,7 @@
throw Error("Failed to properly configure the socket. Check the address ("
+ std::string(e.what()) + ")");
}
- createFace(clientSocket, onFaceCreated);
+ createFace(clientSocket, onFaceCreated, true);
}
void
@@ -145,11 +152,12 @@
shared_ptr<UdpFace>
UdpChannel::createFace(const shared_ptr<ip::udp::socket>& socket,
- const FaceCreatedCallback& onFaceCreated)
+ const FaceCreatedCallback& onFaceCreated,
+ bool isPermanent)
{
udp::Endpoint remoteEndpoint = socket->remote_endpoint();
- shared_ptr<UdpFace> face = make_shared<UdpFace>(boost::cref(socket));
+ shared_ptr<UdpFace> face = make_shared<UdpFace>(boost::cref(socket), isPermanent);
face->onFail += bind(&UdpChannel::afterFaceFailed, this, remoteEndpoint);
onFaceCreated(face);
@@ -190,7 +198,9 @@
clientSocket->bind(m_localEndpoint);
clientSocket->connect(m_newRemoteEndpoint);
- face = createFace(clientSocket, onFaceCreatedNewPeerCallback);
+ face = createFace(clientSocket,
+ onFaceCreatedNewPeerCallback,
+ false);
}
//Passing the message to the correspondent face
@@ -204,10 +214,33 @@
}
-void UdpChannel::afterFaceFailed(udp::Endpoint &endpoint)
+void
+UdpChannel::afterFaceFailed(udp::Endpoint &endpoint)
{
NFD_LOG_DEBUG("afterFaceFailed: " << endpoint);
m_channelFaces.erase(endpoint);
}
+void
+UdpChannel::closeIdleFaces()
+{
+ ChannelFaceMap::iterator next = m_channelFaces.begin();
+
+ while (next != m_channelFaces.end()) {
+ ChannelFaceMap::iterator it = next;
+ next++;
+ if (!it->second->isPermanent() &&
+ !it->second->hasBeenUsedRecently()) {
+ //face has been idle since the last time closeIdleFaces
+ //has been called. Going to close it
+ NFD_LOG_DEBUG("Found idle face id: " << it->second->getId());
+ it->second->close();
+ } else {
+ it->second->resetRecentUsage();
+ }
+ }
+ m_closeIdleFaceEvent = scheduler::schedule(m_idleFaceTimeout,
+ bind(&UdpChannel::closeIdleFaces, this));
+}
+
} // namespace nfd