face: Switching to 2 sockets in MulticastUdpFace for sending and receiving

To send over UDP multicast, we should not bind to multicast address.
This is true at least on OSX 10.9, which generates "Can't assign
requested address" error (error code: 49).  However, without binding to
the multicast address, the socket may receive unnecessary unrelated
packets.  To solve this problem, this commit splits sending and
receiving into two sockets, one for sending and one for receiving.

Change-Id: Ibce05c7071fd683a26b3c88cd2a168546c5dc605
Refs: #1668
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index fc156ea..1a4ca01 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -207,21 +207,31 @@
                 "the multicast group given as input is not a multicast address");
   }
 
-  shared_ptr<ip::udp::socket> clientSocket =
+  shared_ptr<ip::udp::socket> receiveSocket =
     make_shared<ip::udp::socket>(ref(getGlobalIoService()));
 
-  clientSocket->open(multicastEndpoint.protocol());
+  shared_ptr<ip::udp::socket> sendSocket =
+    make_shared<ip::udp::socket>(ref(getGlobalIoService()));
 
-  clientSocket->set_option(ip::udp::socket::reuse_address(true));
+  receiveSocket->open(multicastEndpoint.protocol());
+  receiveSocket->set_option(ip::udp::socket::reuse_address(true));
+
+  sendSocket->open(multicastEndpoint.protocol());
+  sendSocket->set_option(ip::udp::socket::reuse_address(true));
+  sendSocket->set_option(ip::multicast::enable_loopback(false));
 
   try {
-    clientSocket->bind(multicastEndpoint);
+    sendSocket->bind(udp::Endpoint(ip::address_v4::any(), multicastEndpoint.port()));
+    receiveSocket->bind(multicastEndpoint);
 
     if (localEndpoint.address() != ip::address::from_string("0.0.0.0")) {
-      clientSocket->set_option(ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
+      sendSocket->set_option(ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
     }
-    clientSocket->set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
-                                                       localEndpoint.address().to_v4()));
+    sendSocket->set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
+                                                     localEndpoint.address().to_v4()));
+
+    receiveSocket->set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
+                                                        localEndpoint.address().to_v4()));
   }
   catch (boost::system::system_error& e) {
     std::stringstream msg;
@@ -238,7 +248,7 @@
   //This applies only on linux, for OS X the ip::multicast::join_group is enough to get
   //the desired behaviour
   if (!networkInterfaceName.empty()) {
-    if (::setsockopt(clientSocket->native_handle(), SOL_SOCKET, SO_BINDTODEVICE,
+    if (::setsockopt(receiveSocket->native_handle(), SOL_SOCKET, SO_BINDTODEVICE,
                      networkInterfaceName.c_str(), networkInterfaceName.size()+1) == -1){
       throw Error("Cannot bind multicast face to " + networkInterfaceName
                   + " make sure you have CAP_NET_RAW capability" );
@@ -247,9 +257,8 @@
 
 #endif
 
-  clientSocket->set_option(ip::multicast::enable_loopback(false));
-
-  multicastFace = make_shared<MulticastUdpFace>(clientSocket, localEndpoint);
+  multicastFace = make_shared<MulticastUdpFace>(receiveSocket, sendSocket,
+                                                localEndpoint, multicastEndpoint);
   multicastFace->onFail += bind(&UdpFactory::afterFaceFailed, this, localEndpoint);
 
   m_multicastFaces[localEndpoint] = multicastFace;