face: Fixing a bug in UdpChannel with missing async_receive
In cases when UdpChannel dispatches received UDP packet to a newly
created UdpFace, the Channel failed to resume reception of datagram on
the channel.
Change-Id: If876dacc237bd0a6a660d4d88581959782dc349b
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index cb4faa7..24c1833 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -162,6 +162,9 @@
std::size_t nBytesReceived)
{
NFD_LOG_DEBUG("UdpChannel::newPeer from " << m_newRemoteEndpoint);
+
+ shared_ptr<UdpFace> face;
+
ChannelFaceMap::iterator i = m_channelFaces.find(m_newRemoteEndpoint);
if (i != m_channelFaces.end()) {
//The face already exists.
@@ -172,25 +175,26 @@
//"at the same time", while the channel is creating the face the kernel
//could dispatch the other pkts to the channel because the face is not yet
//ready. In this case, the channel has to pass the pkt to the face
+
NFD_LOG_DEBUG("The creation of the face for the remote endpoint "
<< m_newRemoteEndpoint
<< " is in progress");
- //Passing the message to the correspondent face
- i->second->handleFirstReceive(m_inputBuffer, nBytesReceived, error);
- return;
+
+ face = i->second;
+ }
+ else {
+ shared_ptr<ip::udp::socket> clientSocket =
+ make_shared<ip::udp::socket>(boost::ref(getGlobalIoService()));
+ clientSocket->open(m_localEndpoint.protocol());
+ clientSocket->set_option(ip::udp::socket::reuse_address(true));
+ clientSocket->bind(m_localEndpoint);
+ clientSocket->connect(m_newRemoteEndpoint);
+
+ face = createFace(clientSocket, onFaceCreatedNewPeerCallback);
}
- shared_ptr<ip::udp::socket> clientSocket =
- make_shared<ip::udp::socket>(boost::ref(getGlobalIoService()));
- clientSocket->open(m_localEndpoint.protocol());
- clientSocket->set_option(ip::udp::socket::reuse_address(true));
- clientSocket->bind(m_localEndpoint);
- clientSocket->connect(m_newRemoteEndpoint);
-
- shared_ptr<UdpFace> newFace = createFace(clientSocket, onFaceCreatedNewPeerCallback);
-
//Passing the message to the correspondent face
- newFace->handleFirstReceive(m_inputBuffer, nBytesReceived, error);
+ face->handleFirstReceive(m_inputBuffer, nBytesReceived, error);
m_socket->async_receive_from(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE),
m_newRemoteEndpoint,
diff --git a/tests/face/udp.cpp b/tests/face/udp.cpp
index 3c86a6d..f6ed53b 100644
--- a/tests/face/udp.cpp
+++ b/tests/face/udp.cpp
@@ -366,9 +366,11 @@
m_face2->sendInterest(interest2);
m_face2->sendData (data2 );
+ m_face2->sendData (data2 );
+ m_face2->sendData (data2 );
- BOOST_CHECK_MESSAGE(m_limitedIo.run(3,//2 send + 1 listen return
- time::seconds(1)) == LimitedIo::EXCEED_OPS,
+ BOOST_CHECK_MESSAGE(m_limitedIo.run(5,//4 send + 1 listen return
+ time::seconds(4)) == LimitedIo::EXCEED_OPS,
"UdpChannel error: cannot send or receive Interest/Data packets");
BOOST_REQUIRE(static_cast<bool>(m_face1));
@@ -376,15 +378,17 @@
BOOST_CHECK_EQUAL(m_face1->isLocal(), false);
m_face1->sendInterest(interest1);
+ m_face1->sendInterest(interest1);
+ m_face1->sendInterest(interest1);
m_face1->sendData (data1 );
- BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+ BOOST_CHECK_MESSAGE(m_limitedIo.run(4, time::seconds(4)) == LimitedIo::EXCEED_OPS,
"UdpChannel error: cannot send or receive Interest/Data packets");
BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
- BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 1);
- BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
+ BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 3);
+ BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 3);
BOOST_REQUIRE_EQUAL(m_face2_receivedDatas .size(), 1);
BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
@@ -403,10 +407,10 @@
"UdpChannel error: cannot send or receive Interest/Data packets");
BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 2);
- BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 2);
+ BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 4);
BOOST_CHECK_EQUAL(m_face1_receivedInterests[1].getName(), interest3.getName());
- BOOST_CHECK_EQUAL(m_face1_receivedDatas [1].getName(), data3.getName());
+ BOOST_CHECK_EQUAL(m_face1_receivedDatas [3].getName(), data3.getName());
}
BOOST_FIXTURE_TEST_CASE(EndToEnd6, EndToEndFixture)