From 1384546a15d956a2fccc8ab3b77b67e80ae039e8 Mon Sep 17 00:00:00 2001
From: Reiner Hauser <Reiner.Hauser@cern.ch>
Date: Tue, 29 Oct 2013 14:10:04 +0000
Subject: [PATCH] new matching scheme for subnetworks; hack for selecting
 multicast interface

---
 src/NameService.cxx | 19 +++++++++++++------
 src/UDPSession.cxx  | 11 +++++++++--
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/src/NameService.cxx b/src/NameService.cxx
index 2930276..b11f784 100644
--- a/src/NameService.cxx
+++ b/src/NameService.cxx
@@ -74,11 +74,11 @@ namespace daq {
                     auto& mask = std::get<1>(network);
 
                     if(addr.is_v4() && intf->family() == AF_INET) {
-                        auto addr4(addr.to_v4());
-                        auto mask4(mask.to_v4());
+		        auto addr4(addr.to_v4());
+			auto mask4(mask.to_v4());
 
-                        if(htonl((addr4.to_ulong() & mask4.to_ulong())) == intf->network()) {
-                            info.Addresses.push_back(intf->address_string() + '/' + intf->netmask_string());
+                        if(htonl(addr4.to_ulong() & mask4.to_ulong()) == (intf->network() & htonl(mask4.to_ulong()))) {
+			    info.Addresses.push_back(intf->address_string() + '/' +  mask4.to_string());
                         }
 
                     } else if(addr.is_v6() && intf->family() == AF_INET6) {
@@ -124,7 +124,7 @@ namespace daq {
                 
                 // compare IPV4 address
                 if(addr.is_v4() && intf->family() == AF_INET) {
-                    if(htonl((addr.to_v4().to_ulong() & mask.to_v4().to_ulong())) == intf->network()) {
+		    if(htonl(addr.to_v4().to_ulong() & mask.to_v4().to_ulong()) == (intf->network() & htonl(mask.to_v4().to_ulong()))) {
                         // found one, first match will be used
                         return true;
                     }
@@ -280,6 +280,13 @@ namespace daq {
         {
             auto addr = boost::asio::ip::address::from_string(netmask).to_v4();
 
+	    // hack to pass additional mask for finding the multicast interface to use
+	    std::string mc_mask("255.255.255.255");
+	    if(getenv("TDAQ_ASYNCMSG_MULTICAST_MASK")) {
+		mc_mask = getenv("TDAQ_ASYNCMSG_MULTICAST_MASK");
+	    }
+	    auto mask = boost::asio::ip::address::from_string(mc_mask).to_v4();
+
             auto interfaces = daq::transport::Interface::interfaces();
             for(auto intf : interfaces) {
                 if(!intf->has_flag(IFF_UP) || intf->has_flag(IFF_LOOPBACK)) {
@@ -294,7 +301,7 @@ namespace daq {
                     continue;
                 }
 
-                if(intf->network() == htonl(addr.to_ulong())) {
+                if((intf->network() & htonl(mask.to_ulong())) == htonl(addr.to_ulong())) {
                     return boost::asio::ip::address::from_string(intf->address_string());
                 }
             }
diff --git a/src/UDPSession.cxx b/src/UDPSession.cxx
index 17f1582..d7736a4 100644
--- a/src/UDPSession.cxx
+++ b/src/UDPSession.cxx
@@ -210,8 +210,15 @@ void UDPSession::setOutgoingInterface(const boost::asio::ip::address& ip_address
     boost::asio::ip::multicast::outbound_interface option(ip_address.to_v4());
     m_socket.set_option(option);
 
-    // we never want to go beyond one hop (I hope)
-    boost::asio::ip::multicast::hops hops_option(1);
+    // TTL     Scope
+    // ----------------------------------------------------------------------
+    // 0    Restricted to the same host. Won't be output by any interface.
+    // 1    Restricted to the same subnet. Won't be forwarded by a router.
+    // <32         Restricted to the same site, organization or department.
+    // <64 Restricted to the same region.
+    // <128 Restricted to the same continent.
+    // <255 Unrestricted in scope. Global.
+    boost::asio::ip::multicast::hops hops_option(31);
     m_socket.set_option(hops_option);    
 }
 
-- 
GitLab