face: prevent creation of duplicate tcp/udp faces due to async calls

refs: #1680

Change-Id: I0e685d6bde1f6745902c86f782d41c9070aecb21
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index 99d01e3..684879a 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -180,11 +180,30 @@
 {
   udp::Endpoint remoteEndpoint = socket->remote_endpoint();
 
-  shared_ptr<UdpFace> face = make_shared<UdpFace>(socket, isOnDemand);
-  face->onFail += bind(&UdpChannel::afterFaceFailed, this, remoteEndpoint);
+  shared_ptr<UdpFace> face;
 
+  ChannelFaceMap::iterator faceMapPos = m_channelFaces.find(remoteEndpoint);
+  if (faceMapPos == m_channelFaces.end())
+    {
+      face = make_shared<UdpFace>(socket, isOnDemand);
+      face->onFail += bind(&UdpChannel::afterFaceFailed, this, remoteEndpoint);
+
+      m_channelFaces[remoteEndpoint] = face;
+    }
+  else
+    {
+      // we've already created a a face for this endpoint, just reuse it
+      face = faceMapPos->second;
+
+      boost::system::error_code error;
+      socket->shutdown(ip::udp::socket::shutdown_both, error);
+      socket->close(error);
+    }
+
+  // Need to invoke the callback regardless of whether or not we have already created
+  // the face so that control responses and such can be sent.
   onFaceCreated(face);
-  m_channelFaces[remoteEndpoint] = face;
+
   return face;
 }