Skip to content
Snippets Groups Projects
Commit 008cf1bb authored by Reiner Hauser's avatar Reiner Hauser
Browse files

Update to latest boost::asio, better IPv6 support.

Make use of newer boost::asio methods, avoid deprecated ones.
Switch to <address>/<prefix> notation instead of <address>/<netmask>.
parent 9d36eb93
No related branches found
No related tags found
No related merge requests found
...@@ -2,15 +2,16 @@ ...@@ -2,15 +2,16 @@
#ifndef ASYNCMSG_NAMESERVICE_H_ #ifndef ASYNCMSG_NAMESERVICE_H_
#define ASYNCMSG_NAMESERVICE_H_ #define ASYNCMSG_NAMESERVICE_H_
#include "ipc/partition.h"
#include "ers/Issue.h"
#include "boost/asio.hpp"
#include <vector> #include <vector>
#include <string> #include <string>
#include <map> #include <map>
#include <tuple>
#include <cstdint> #include <cstdint>
#include "boost/asio.hpp" #include <variant>
#include "ipc/partition.h"
#include "ers/Issue.h"
namespace daq { namespace daq {
...@@ -144,10 +145,10 @@ namespace daq { ...@@ -144,10 +145,10 @@ namespace daq {
*/ */
std::string lookup_multicast_address(const std::string& addr) const; std::string lookup_multicast_address(const std::string& addr) const;
/** typedef for readability, a 2-tuple of IP addresses representing network/netmask. */ /** typedef for readability, either a ipv4 or ipv6 network */
typedef std::tuple<boost::asio::ip::address,boost::asio::ip::address> Network; using Network = std::variant<boost::asio::ip::network_v4, boost::asio::ip::network_v6>;
/** \brief A helper method to parse a string of the form network/netmask. /** \brief A helper method to parse a string of the form network/prefix.
*/ */
static Network parse_address_network(const std::string& network); static Network parse_address_network(const std::string& network);
...@@ -157,7 +158,7 @@ namespace daq { ...@@ -157,7 +158,7 @@ namespace daq {
private: private:
bool matches(const boost::asio::ip::address& addr, const boost::asio::ip::address& mask) const; bool matches(const Network& addr_mask) const;
IPCPartition m_partition; IPCPartition m_partition;
std::string m_is_server; std::string m_is_server;
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <algorithm> #include <algorithm>
#include <map> // for map, map<>::mapped_type #include <map> // for map, map<>::mapped_type
#include <string> // for string, allocator, operator+ #include <string> // for string, allocator, operator+
#include <tuple> // for tie, get, tuple, make_tuple
#include <vector> // for vector #include <vector> // for vector
...@@ -99,33 +98,20 @@ namespace daq { ...@@ -99,33 +98,20 @@ namespace daq {
for(const auto& network : m_data_networks) { for(const auto& network : m_data_networks) {
auto& addr = std::get<0>(network); if((network.index() == 0) && (intf->family() == AF_INET)) {
auto& mask = std::get<1>(network);
if(addr.is_v4() && intf->family() == AF_INET) { auto addr(std::get<0>(network).network());
auto addr4(addr.to_v4());
auto mask4(mask.to_v4());
if(htonl(addr4.to_ulong() & mask4.to_ulong()) == (intf->address() & htonl(mask4.to_ulong()))) { if(htonl(addr.to_ulong()) == intf->network()) {
info.Addresses.push_back(intf->address_string() + '/' + mask4.to_string()); info.Addresses.push_back(intf->address_string() + '/' + std::to_string(std::get<0>(network).prefix_length()));
} }
} else if(addr.is_v6() && intf->family() == AF_INET6) { } else if((network.index() == 1) && (intf->family() == AF_INET6)) {
auto addr6(addr.to_v6().to_bytes()); auto addr(std::get<1>(network).network().to_bytes());
auto mask6(mask.to_v6().to_bytes());
auto local_network = intf->network_v6(); auto local_network = intf->network_v6();
if(memcmp(&addr[0], &local_network.s6_addr[0], addr.size()) == 0) {
bool matches = true; info.Addresses.push_back(intf->address_string() + '/' + std::to_string(std::get<1>(network).prefix_length()));
for(size_t i = 0; i < addr6.size(); i++) {
if((addr6[i] & mask6[i]) != local_network.s6_addr[i]) {
matches = false;
break;
}
}
if(matches) {
info.Addresses.push_back(intf->address_string() + '/' + intf->netmask_string());
} }
} }
} }
...@@ -171,39 +157,32 @@ namespace daq { ...@@ -171,39 +157,32 @@ namespace daq {
throw InvalidISServer(ERS_HERE, servers.name(), reason); throw InvalidISServer(ERS_HERE, servers.name(), reason);
} }
} }
} }
bool NameService::matches(const boost::asio::ip::address& addr, const boost::asio::ip::address& mask) const bool NameService::matches(const Network& addr_mask) const
{ {
for(const auto intf : daq::asyncmsg::Interface::interfaces()) { for(const auto intf : daq::asyncmsg::Interface::interfaces()) {
// ignore these // ignore these
if(!intf->has_flag(IFF_UP) || intf->has_flag(IFF_LOOPBACK) || intf->address() == 0) { if(!intf->has_flag(IFF_UP) || intf->has_flag(IFF_LOOPBACK)) {
continue; continue;
} }
// compare IPV4 address // compare IPV4 address
if(addr.is_v4() && intf->family() == AF_INET) { if(addr_mask.index() == 0 && intf->family() == AF_INET && intf->address() != 0) {
if(htonl(addr.to_v4().to_ulong() & mask.to_v4().to_ulong()) == (intf->network() & htonl(mask.to_v4().to_ulong()))) { auto addr(std::get<0>(addr_mask).network().to_bytes());
// found one, first match will be used auto local_network = intf->network();
if(memcmp(&addr[0], &local_network, addr.size()) == 0) {
return true; return true;
} }
} else if (addr.is_v6() && intf->family() == AF_INET6) { } else if (addr_mask.index() == 1 && intf->family() == AF_INET6) {
auto addr6(addr.to_v6().to_bytes()); auto addr(std::get<1>(addr_mask).network().to_bytes());
auto mask6(mask.to_v6().to_bytes());
auto local_network = intf->network_v6(); auto local_network = intf->network_v6();
bool matches = true; if(memcmp(&addr[0], &local_network.s6_addr[0], addr.size()) == 0) {
for(size_t i = 0; i < addr6.size(); i++) { return true;
if((addr6[i] & mask6[i]) != local_network.s6_addr[i]) {
matches = false;
break;
}
} }
return matches;
} }
} }
...@@ -229,10 +208,14 @@ namespace daq { ...@@ -229,10 +208,14 @@ namespace daq {
// match my local interfaces against the list // match my local interfaces against the list
for(auto& addr_netmask : info.Addresses) { for(auto& addr_netmask : info.Addresses) {
boost::asio::ip::address addr, mask; boost::asio::ip::address addr, mask;
std::tie(addr, mask) = parse_address_network(addr_netmask); Network addr_mask = parse_address_network(addr_netmask);
if(matches(addr_mask)) {
if(matches(addr, mask)) { // retrieve address part only
results.push_back(boost::asio::ip::tcp::endpoint(addr, info.Port)); if(addr_mask.index() == 0) {
results.push_back(boost::asio::ip::tcp::endpoint(std::get<0>(addr_mask).address(), info.Port));
} else {
results.push_back(boost::asio::ip::tcp::endpoint(std::get<1>(addr_mask).address(), info.Port));
}
break; break;
} }
} }
...@@ -259,10 +242,14 @@ namespace daq { ...@@ -259,10 +242,14 @@ namespace daq {
// match my local interfaces against the list // match my local interfaces against the list
for(auto& addr_netmask : info.Addresses) { for(auto& addr_netmask : info.Addresses) {
boost::asio::ip::address addr, mask; boost::asio::ip::address addr, mask;
std::tie(addr, mask) = parse_address_network(addr_netmask); Network addr_mask = parse_address_network(addr_netmask);
if(matches(addr, mask)) { if(matches(addr_mask)) {
results[name.substr(m_is_server.size() + 5)] = boost::asio::ip::tcp::endpoint(addr, info.Port); if(addr_mask.index() == 0) {
results[name.substr(m_is_server.size() + 5)] = boost::asio::ip::tcp::endpoint(std::get<0>(addr_mask).address(), info.Port);
} else {
results[name.substr(m_is_server.size() + 5)] = boost::asio::ip::tcp::endpoint(std::get<1>(addr_mask).address(), info.Port);
}
break; break;
} }
} }
...@@ -288,11 +275,14 @@ namespace daq { ...@@ -288,11 +275,14 @@ namespace daq {
// match my local interfaces against the list // match my local interfaces against the list
for(auto& addr_netmask : info.Addresses) { for(auto& addr_netmask : info.Addresses) {
boost::asio::ip::address addr, mask; Network addr_mask = parse_address_network(addr_netmask);
std::tie(addr, mask) = parse_address_network(addr_netmask);
if(matches(addr, mask)) { if(matches(addr_mask)) {
results[name.substr(m_is_server.size() + 5)].push_back(boost::asio::ip::tcp::endpoint(addr, info.Port)); if(addr_mask.index() == 0) {
results[name.substr(m_is_server.size() + 5)].push_back(boost::asio::ip::tcp::endpoint(std::get<0>(addr_mask).address(), info.Port));
} else {
results[name.substr(m_is_server.size() + 5)].push_back(boost::asio::ip::tcp::endpoint(std::get<1>(addr_mask).address(), info.Port));
}
} }
} }
} }
...@@ -311,11 +301,14 @@ namespace daq { ...@@ -311,11 +301,14 @@ namespace daq {
d.getValue(m_is_server + ".MSG_" + name, info); d.getValue(m_is_server + ".MSG_" + name, info);
for(auto& addr_netmask : info.Addresses) { for(auto& addr_netmask : info.Addresses) {
boost::asio::ip::address addr, mask; Network addr_mask = parse_address_network(addr_netmask);
std::tie(addr, mask) = parse_address_network(addr_netmask);
if(matches(addr_mask)) {
if(matches(addr, mask)) { if(addr_mask.index() == 0) {
return boost::asio::ip::tcp::endpoint(addr, info.Port); return boost::asio::ip::tcp::endpoint(std::get<0>(addr_mask).address(), info.Port);
} else {
return boost::asio::ip::tcp::endpoint(std::get<1>(addr_mask).address(), info.Port);
}
} }
} }
...@@ -326,15 +319,14 @@ namespace daq { ...@@ -326,15 +319,14 @@ namespace daq {
NameService::Network NameService::Network
NameService::parse_address_network(const std::string& network) NameService::parse_address_network(const std::string& network)
{ {
size_t slash = network.find('/'); boost::system::error_code ec;
std::string address = network.substr(0, slash);
std::string netmask = "255.255.255.255";
if(slash != std::string::npos) {
netmask = network.substr(slash+1);
}
return std::make_tuple(boost::asio::ip::address::from_string(address), // Try v4 first
boost::asio::ip::address::from_string(netmask)); Network result{boost::asio::ip::make_network_v4(network, ec)};
if(!ec.failed()) {
return result;
}
return Network{boost::asio::ip::make_network_v6(network)};
} }
boost::asio::ip::address NameService::find_interface(const std::string& netmask) boost::asio::ip::address NameService::find_interface(const std::string& netmask)
......
...@@ -37,12 +37,8 @@ int main(int argc, char *argv[]) ...@@ -37,12 +37,8 @@ int main(int argc, char *argv[])
// DFParameters.DefaultDataNetworks // DFParameters.DefaultDataNetworks
// //
// CERN GPN // CERN GPN
// Testbed B.4 pub, internal
// //
std::vector<std::string> data_networks{"137.138.0.0/255.255.0.0", std::vector<std::string> data_networks{"137.138.0.0/16"};
"188.184.2.64/255.255.255.192",
"10.193.128.0/255.255.254.0",
"10.193.64.0/255.255.254.0"};
argv += 3; argv += 3;
argc -= 3; argc -= 3;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment