1 #include "artdaq/DAQdata/PortManager.hh"
2 #include "TRACE/tracemf.h"
3 #define TRACE_NAME "PortManager"
5 #include "artdaq/DAQdata/Globals.hh"
8 #include "fhiclcpp/ParameterSet.h"
15 : multicast_interface_address_()
16 , request_message_group_pattern_(
"227.128.PPP.SSS")
17 , routing_table_group_pattern_(
"227.129.PPP.SSS")
18 , multicast_transfer_group_pattern_(
"227.130.14.PPP")
24 if (ps.has_key(
"artdaq_base_port"))
26 auto newVal = ps.get<
int>(
"artdaq_base_port");
27 if (base_port_ != DEFAULT_BASE && base_port_ != newVal)
29 TLOG(TLVL_WARNING) <<
"Base port has changed! This may lead to misconfiguration and non-functional systems!";
33 if (ps.has_key(
"ports_per_partition"))
35 auto newVal = ps.get<
int>(
"ports_per_partition");
36 if (ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION && ports_per_partition_ != newVal)
38 TLOG(TLVL_WARNING) <<
"Ports per Partition has changed! This may lead to misconfiguration and non-functional systems!";
40 ports_per_partition_ = newVal;
43 auto bp = getenv(
"ARTDAQ_BASE_PORT");
48 auto bp_s = std::string(bp);
49 auto bp_tmp = std::stoi(bp_s,
nullptr, 0);
50 if (bp_tmp < 1024 || bp_tmp > 32000)
52 TLOG(TLVL_ERROR) <<
"Base port specified in ARTDAQ_BASE_PORT is invalid! Ignoring...";
59 catch (
const std::invalid_argument&)
61 catch (
const std::out_of_range&)
65 auto ppp = getenv(
"ARTDAQ_PORTS_PER_PARTITION");
70 auto ppp_s = std::string(ppp);
71 auto ppp_tmp = std::stoi(ppp_s,
nullptr, 0);
72 if (ppp_tmp < 0 || ppp_tmp > 32000)
74 TLOG(TLVL_ERROR) <<
"Ports per partition specified in ARTDAQ_PORTS_PER_PARTITION is invalid! Ignoring...";
78 ports_per_partition_ = ppp_tmp;
81 catch (
const std::invalid_argument&)
83 catch (
const std::out_of_range&)
87 if (!base_configured_ && (base_port_ != DEFAULT_BASE || ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION))
89 base_configured_ =
true;
90 auto max_partitions = (65535 - base_port_) / ports_per_partition_;
91 TLOG(TLVL_INFO) <<
"Based on configuration, there can be " << max_partitions <<
" partitions of " << ports_per_partition_ <<
" ports each, starting at port " << base_port_;
92 if (GetPartitionNumber() > max_partitions)
94 TLOG(TLVL_ERROR) <<
"Currently-configured partition number is greater than the allowed number! The system WILL NOT WORK!";
100 bool multicast_configured =
false;
101 if (ps.has_key(
"multicast_output_interface"))
103 multicast_configured =
GetIPOfInterface(ps.get<std::string>(
"multicast_output_interface"), tmp_addr) == 0;
105 else if (ps.has_key(
"multicast_output_network"))
107 multicast_configured =
GetInterfaceForNetwork(ps.get<std::string>(
"multicast_output_network").c_str(), tmp_addr) == 0;
109 if (multicast_configured && multicasts_configured_ && tmp_addr.s_addr != multicast_interface_address_.s_addr)
111 TLOG(TLVL_WARNING) <<
"Multicast output address has changed! This may lead to misconfiguration and non-functional systems!";
113 else if (multicast_configured)
115 multicasts_configured_ =
true;
116 multicast_interface_address_ = tmp_addr;
119 if (ps.has_key(
"multicast_group_offset"))
121 auto newVal = ps.get<
int>(
"multicast_group_offset");
122 if (multicast_group_offset_ != DEFAULT_MULTICAST_GROUP_OFFSET && multicast_group_offset_ != newVal)
124 TLOG(TLVL_WARNING) <<
"Multicast group offset (added to last part of group IP address) has changed! This may lead to misconfiguration and non-functional systems!";
126 multicast_group_offset_ = newVal;
129 if (ps.has_key(
"routing_token_port_offset"))
131 auto newVal = ps.get<
int>(
"routing_token_port_offset");
132 if (routing_tokens_configured_ && newVal != routing_token_offset_)
134 TLOG(TLVL_WARNING) <<
"Routing Token Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
137 routing_tokens_configured_ =
true;
138 routing_token_offset_ = newVal;
141 if (ps.has_key(
"routing_table_ack_port_offset"))
143 auto newVal = ps.get<
int>(
"routing_table_ack_port_offset");
144 if (routing_acks_configured_ && newVal != routing_ack_offset_)
146 TLOG(TLVL_WARNING) <<
"Routing Table Acknowledgement Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
149 routing_acks_configured_ =
true;
150 routing_ack_offset_ = newVal;
153 if (ps.has_key(
"xmlrpc_port_offset"))
155 auto newVal = ps.get<
int>(
"xmlrpc_port_offset");
156 if (xmlrpc_configured_ && newVal != xmlrpc_offset_)
158 TLOG(TLVL_WARNING) <<
"XMLRPC Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
161 xmlrpc_configured_ =
true;
162 xmlrpc_offset_ = newVal;
165 if (ps.has_key(
"tcp_socket_port_offset"))
167 auto newVal = ps.get<
int>(
"tcp_socket_port_offset");
168 if (tcpsocket_configured_ && newVal != tcp_socket_offset_)
170 TLOG(TLVL_WARNING) <<
"TCPSocketTransfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
173 tcpsocket_configured_ =
true;
174 tcp_socket_offset_ = newVal;
177 if (ps.has_key(
"request_port"))
179 auto newVal = ps.get<
int>(
"request_port");
180 if (request_port_configured_ && newVal != request_message_port_)
182 TLOG(TLVL_WARNING) <<
"Request Message Port has changed! This may lead to misconfiguration and non-functional systems!";
185 request_port_configured_ =
true;
186 request_message_port_ = newVal;
189 if (ps.has_key(
"request_pattern"))
191 auto newVal = ps.get<std::string>(
"request_pattern");
192 if (request_pattern_configured_ && newVal != request_message_group_pattern_)
194 TLOG(TLVL_WARNING) <<
"Request Message Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
197 request_pattern_configured_ =
true;
198 request_message_group_pattern_ = newVal;
201 if (ps.has_key(
"routing_table_port"))
203 auto newVal = ps.get<
int>(
"routing_table_port");
204 if (routing_table_port_configured_ && newVal != routing_table_port_)
206 TLOG(TLVL_WARNING) <<
"Routing Table Port has changed! This may lead to misconfiguration and non-functional systems!";
209 routing_table_port_configured_ =
true;
210 routing_table_port_ = newVal;
213 if (ps.has_key(
"routing_table_pattern"))
215 auto newVal = ps.get<std::string>(
"routing_table_pattern");
216 if (routing_table_pattern_configured_ && newVal != routing_table_group_pattern_)
218 TLOG(TLVL_WARNING) <<
"Routing Table Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
221 routing_table_pattern_configured_ =
true;
222 routing_table_group_pattern_ = newVal;
225 if (ps.has_key(
"multicast_transfer_port_offset"))
227 auto newVal = ps.get<
int>(
"multicast_transfer_port_offset");
228 if (multicast_transfer_port_configued_ && newVal != multicast_transfer_offset_)
230 TLOG(TLVL_WARNING) <<
"Multicast Transfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
233 multicast_transfer_port_configued_ =
true;
234 multicast_transfer_offset_ = newVal;
237 if (ps.has_key(
"multicast_transfer_pattern"))
239 auto newVal = ps.get<std::string>(
"multicast_transfer_pattern");
240 if (multicast_transfer_pattern_configured_ && newVal != multicast_transfer_group_pattern_)
242 TLOG(TLVL_WARNING) <<
"Multicast Transfer Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
245 multicast_transfer_pattern_configured_ =
true;
246 multicast_transfer_group_pattern_ = newVal;
252 if (!routing_tokens_configured_)
254 TLOG(TLVL_INFO) <<
"Using default port range for Routing Tokens";
255 routing_tokens_configured_ =
true;
258 return base_port_ + routing_token_offset_ + (GetPartitionNumber() * ports_per_partition_) + subsystemID;
263 if (!routing_acks_configured_)
265 TLOG(TLVL_INFO) <<
"Using default port range for Routing Table Acknowledgements";
266 routing_acks_configured_ =
true;
268 return base_port_ + routing_ack_offset_ + (GetPartitionNumber() * ports_per_partition_) + subsystemID;
273 if (!xmlrpc_configured_)
275 TLOG(TLVL_INFO) <<
"Using default port range for XMLRPC";
276 xmlrpc_configured_ =
true;
278 return base_port_ + xmlrpc_offset_ + rank + (GetPartitionNumber() * ports_per_partition_);
283 if (!tcpsocket_configured_)
285 TLOG(TLVL_INFO) <<
"Using default port range for TCPSocket Transfer";
286 tcpsocket_configured_ =
true;
288 return base_port_ + tcp_socket_offset_ + (GetPartitionNumber() * ports_per_partition_) + rank;
293 if (!request_port_configured_)
295 TLOG(TLVL_INFO) <<
"Using default port for Request Messages";
296 request_port_configured_ =
true;
298 return request_message_port_;
303 if (!request_pattern_configured_)
305 TLOG(TLVL_INFO) <<
"Using default address for Request Messages";
306 request_pattern_configured_ =
true;
309 return parse_pattern_(request_message_group_pattern_, subsystemID);
314 if (!routing_table_port_configured_)
316 TLOG(TLVL_INFO) <<
"Using default port for Routing Tables";
317 routing_table_port_configured_ =
true;
320 return routing_table_port_;
325 if (!routing_table_pattern_configured_)
327 TLOG(TLVL_INFO) <<
"Using default address for Routing Tables";
328 routing_table_pattern_configured_ =
true;
331 return parse_pattern_(routing_table_group_pattern_, subsystemID);
336 if (!multicast_transfer_port_configued_)
338 TLOG(TLVL_INFO) <<
"Using default port for Multicast Transfer";
339 multicast_transfer_port_configued_ =
true;
342 return multicast_transfer_offset_ + rank;
347 if (!multicast_transfer_pattern_configured_)
349 TLOG(TLVL_INFO) <<
"Using default address for Multicast Transfer";
350 multicast_transfer_pattern_configured_ =
true;
353 return parse_pattern_(multicast_transfer_group_pattern_);
358 if (!multicasts_configured_)
360 if (interface_name.empty() && interface_address.empty())
362 TLOG(TLVL_INFO) <<
"Using default multicast output address (autodetected private interface)";
364 if (!interface_name.empty())
368 else if (!interface_address.empty())
376 multicasts_configured_ =
true;
378 return multicast_interface_address_;
381 std::string artdaq::PortManager::parse_pattern_(
const std::string& pattern,
int subsystemID,
int rank)
383 std::istringstream f(pattern);
384 std::vector<int> address(4);
387 while (getline(f, s,
'.'))
391 address.push_back(GetPartitionNumber());
395 address.push_back(subsystemID);
399 address.push_back(rank);
403 address.push_back(stoi(s));
407 if (address.size() != 4)
409 TLOG(TLVL_ERROR) <<
"Invalid address pattern!";
410 while (address.size() < 4) { address.push_back(0); }
412 address[3] += multicast_group_offset_;
414 return std::to_string(address[0]) +
"." + std::to_string(address[1]) +
"." + std::to_string(address[2]) +
"." + std::to_string(address[3]);
int GetRequestMessagePort()
Get the port that should be used for multicast request messages.
int GetIPOfInterface(const std::string &interface_name, in_addr &addr)
Get the IP address associated with a given interface name.
int GetMulticastTransferPort(int rank)
Get the multicast transfer port for the given rank.
int GetRoutingAckPort(int subsystemID=0)
Get the port that should be used for Routing Acknowledgements.
std::string GetRequestMessageGroupAddress(int subsystemID=0)
Get the multicast address for request messages.
in_addr GetMulticastOutputAddress(const std::string &interface_name="", const std::string &interface_address="")
Determine the output interface address, using the hints provided.
int GetInterfaceForNetwork(char const *host_in, in_addr &addr)
Convert an IP address to the network address of the interface sharing the subnet mask.
PortManager()
PortManager Construator.
int GetRoutingTokenPort(int subsystemID=0)
Get the port that should be used for Routing Tokens.
std::string GetMulticastTransferGroupAddress()
Get the multicast address for multicast transfers.
int GetXMLRPCPort(int rank)
Get the XMLRPC port for the given rank.
int AutodetectPrivateInterface(in_addr &addr)
Pick a private IP address on this host.
void UpdateConfiguration(fhicl::ParameterSet const &ps)
Override the default configuration.
int GetRoutingTablePort()
Get the port that should be used for multicast Routing Tables.
int GetTCPSocketTransferPort(int rank)
Get the TCP Socket transfer port for the given rank.
std::string GetRoutingTableGroupAddress(int subsystemID=0)
Get the multicast address for Routing Tables.