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)