1 #include "artdaq/DAQdata/PortManager.hh"
2 #define TRACE_NAME "PortManager"
4 #include "artdaq/DAQdata/Globals.hh"
8 : multicast_interface_address_()
9 , request_message_group_pattern_(
"227.128.PPP.SSS")
10 , routing_table_group_pattern_(
"227.129.PPP.SSS")
11 , multicast_transfer_group_pattern_(
"227.130.14.PPP")
17 if (ps.has_key(
"artdaq_base_port"))
19 auto newVal = ps.get<
int>(
"artdaq_base_port");
20 if (base_port_ != DEFAULT_BASE && base_port_ != newVal)
22 TLOG(TLVL_WARNING) <<
"Base port has changed! This may lead to misconfiguration and non-functional systems!";
26 if (ps.has_key(
"ports_per_partition"))
28 auto newVal = ps.get<
int>(
"ports_per_partition");
29 if (ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION && ports_per_partition_ != newVal)
31 TLOG(TLVL_WARNING) <<
"Ports per Partition has changed! This may lead to misconfiguration and non-functional systems!";
33 ports_per_partition_ = newVal;
36 auto bp = getenv(
"ARTDAQ_BASE_PORT");
41 auto bp_s = std::string(bp);
42 auto bp_tmp = std::stoi(bp_s,
nullptr, 0);
43 if (bp_tmp < 1024 || bp_tmp > 32000)
45 TLOG(TLVL_ERROR) <<
"Base port specified in ARTDAQ_BASE_PORT is invalid! Ignoring...";
52 catch (
const std::invalid_argument&)
54 catch (
const std::out_of_range&)
58 auto ppp = getenv(
"ARTDAQ_PORTS_PER_PARTITION");
63 auto ppp_s = std::string(ppp);
64 auto ppp_tmp = std::stoi(ppp_s,
nullptr, 0);
65 if (ppp_tmp < 0 || ppp_tmp > 32000)
67 TLOG(TLVL_ERROR) <<
"Ports per partition specified in ARTDAQ_PORTS_PER_PARTITION is invalid! Ignoring...";
71 ports_per_partition_ = ppp_tmp;
74 catch (
const std::invalid_argument&)
76 catch (
const std::out_of_range&)
80 if (!base_configured_ && (base_port_ != DEFAULT_BASE || ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION))
82 base_configured_ =
true;
83 auto max_partitions = (65535 - base_port_) / ports_per_partition_;
84 TLOG(TLVL_INFO) <<
"Based on configuration, there can be " << max_partitions <<
" partitions of " << ports_per_partition_ <<
" ports each, starting at port " << base_port_;
85 if (GetPartitionNumber() > max_partitions)
87 TLOG(TLVL_ERROR) <<
"Currently-configured partition number is greater than the allowed number! The system WILL NOT WORK!";
93 bool multicast_configured =
false;
94 if (ps.has_key(
"multicast_output_interface"))
96 multicast_configured =
GetIPOfInterface(ps.get<std::string>(
"multicast_output_interface"), tmp_addr) == 0;
98 else if (ps.has_key(
"multicast_output_network"))
100 multicast_configured =
GetInterfaceForNetwork(ps.get<std::string>(
"multicast_output_network").c_str(), tmp_addr) == 0;
102 if (multicast_configured && multicasts_configured_ && tmp_addr.s_addr != multicast_interface_address_.s_addr)
104 TLOG(TLVL_WARNING) <<
"Multicast output address has changed! This may lead to misconfiguration and non-functional systems!";
106 else if (multicast_configured)
108 multicasts_configured_ =
true;
109 multicast_interface_address_ = tmp_addr;
112 if (ps.has_key(
"multicast_group_offset"))
114 auto newVal = ps.get<
int>(
"multicast_group_offset");
115 if (multicast_group_offset_ != DEFAULT_MULTICAST_GROUP_OFFSET && multicast_group_offset_ != newVal)
117 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!";
119 multicast_group_offset_ = newVal;
122 if (ps.has_key(
"routing_token_port_offset"))
124 auto newVal = ps.get<
int>(
"routing_token_port_offset");
125 if (routing_tokens_configured_ && newVal != routing_token_offset_)
127 TLOG(TLVL_WARNING) <<
"Routing Token Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
130 routing_tokens_configured_ =
true;
131 routing_token_offset_ = newVal;
134 if (ps.has_key(
"routing_table_ack_port_offset"))
136 auto newVal = ps.get<
int>(
"routing_table_ack_port_offset");
137 if (routing_acks_configured_ && newVal != routing_ack_offset_)
139 TLOG(TLVL_WARNING) <<
"Routing Table Acknowledgement Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
142 routing_acks_configured_ =
true;
143 routing_ack_offset_ = newVal;
146 if (ps.has_key(
"xmlrpc_port_offset"))
148 auto newVal = ps.get<
int>(
"xmlrpc_port_offset");
149 if (xmlrpc_configured_ && newVal != xmlrpc_offset_)
151 TLOG(TLVL_WARNING) <<
"XMLRPC Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
154 xmlrpc_configured_ =
true;
155 xmlrpc_offset_ = newVal;
158 if (ps.has_key(
"tcp_socket_port_offset"))
160 auto newVal = ps.get<
int>(
"tcp_socket_port_offset");
161 if (tcpsocket_configured_ && newVal != tcp_socket_offset_)
163 TLOG(TLVL_WARNING) <<
"TCPSocketTransfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
166 tcpsocket_configured_ =
true;
167 tcp_socket_offset_ = newVal;
170 if (ps.has_key(
"request_port"))
172 auto newVal = ps.get<
int>(
"request_port");
173 if (request_port_configured_ && newVal != request_message_port_)
175 TLOG(TLVL_WARNING) <<
"Request Message Port has changed! This may lead to misconfiguration and non-functional systems!";
178 request_port_configured_ =
true;
179 request_message_port_ = newVal;
182 if (ps.has_key(
"request_pattern"))
184 auto newVal = ps.get<std::string>(
"request_pattern");
185 if (request_pattern_configured_ && newVal != request_message_group_pattern_)
187 TLOG(TLVL_WARNING) <<
"Request Message Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
190 request_pattern_configured_ =
true;
191 request_message_group_pattern_ = newVal;
194 if (ps.has_key(
"routing_table_port"))
196 auto newVal = ps.get<
int>(
"routing_table_port");
197 if (routing_table_port_configured_ && newVal != routing_table_port_)
199 TLOG(TLVL_WARNING) <<
"Routing Table Port has changed! This may lead to misconfiguration and non-functional systems!";
202 routing_table_port_configured_ =
true;
203 routing_table_port_ = newVal;
206 if (ps.has_key(
"routing_table_pattern"))
208 auto newVal = ps.get<std::string>(
"routing_table_pattern");
209 if (routing_table_pattern_configured_ && newVal != routing_table_group_pattern_)
211 TLOG(TLVL_WARNING) <<
"Routing Table Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
214 routing_table_pattern_configured_ =
true;
215 routing_table_group_pattern_ = newVal;
218 if (ps.has_key(
"multicast_transfer_port_offset"))
220 auto newVal = ps.get<
int>(
"multicast_transfer_port_offset");
221 if (multicast_transfer_port_configued_ && newVal != multicast_transfer_offset_)
223 TLOG(TLVL_WARNING) <<
"Multicast Transfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
226 multicast_transfer_port_configued_ =
true;
227 multicast_transfer_offset_ = newVal;
230 if (ps.has_key(
"multicast_transfer_pattern"))
232 auto newVal = ps.get<std::string>(
"multicast_transfer_pattern");
233 if (multicast_transfer_pattern_configured_ && newVal != multicast_transfer_group_pattern_)
235 TLOG(TLVL_WARNING) <<
"Multicast Transfer Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
238 multicast_transfer_pattern_configured_ =
true;
239 multicast_transfer_group_pattern_ = newVal;
245 if (!routing_tokens_configured_)
247 TLOG(TLVL_INFO) <<
"Using default port range for Routing Tokens";
248 routing_tokens_configured_ =
true;
251 return base_port_ + routing_token_offset_ + (GetPartitionNumber() * ports_per_partition_) + subsystemID;
256 if (!routing_acks_configured_)
258 TLOG(TLVL_INFO) <<
"Using default port range for Routing Table Acknowledgements";
259 routing_acks_configured_ =
true;
261 return base_port_ + routing_ack_offset_ + (GetPartitionNumber() * ports_per_partition_) + subsystemID;
266 if (!xmlrpc_configured_)
268 TLOG(TLVL_INFO) <<
"Using default port range for XMLRPC";
269 xmlrpc_configured_ =
true;
271 return base_port_ + xmlrpc_offset_ + rank + (GetPartitionNumber() * ports_per_partition_);
276 if (!tcpsocket_configured_)
278 TLOG(TLVL_INFO) <<
"Using default port range for TCPSocket Transfer";
279 tcpsocket_configured_ =
true;
281 return base_port_ + tcp_socket_offset_ + (GetPartitionNumber() * ports_per_partition_) + rank;
286 if (!request_port_configured_)
288 TLOG(TLVL_INFO) <<
"Using default port for Request Messages";
289 request_port_configured_ =
true;
291 return request_message_port_;
296 if (!request_pattern_configured_)
298 TLOG(TLVL_INFO) <<
"Using default address for Request Messages";
299 request_pattern_configured_ =
true;
302 return parse_pattern_(request_message_group_pattern_, subsystemID);
307 if (!routing_table_port_configured_)
309 TLOG(TLVL_INFO) <<
"Using default port for Routing Tables";
310 routing_table_port_configured_ =
true;
313 return routing_table_port_;
318 if (!routing_table_pattern_configured_)
320 TLOG(TLVL_INFO) <<
"Using default address for Routing Tables";
321 routing_table_pattern_configured_ =
true;
324 return parse_pattern_(routing_table_group_pattern_, subsystemID);
329 if (!multicast_transfer_port_configued_)
331 TLOG(TLVL_INFO) <<
"Using default port for Multicast Transfer";
332 multicast_transfer_port_configued_ =
true;
335 return multicast_transfer_offset_ + rank;
340 if (!multicast_transfer_pattern_configured_)
342 TLOG(TLVL_INFO) <<
"Using default address for Multicast Transfer";
343 multicast_transfer_pattern_configured_ =
true;
346 return parse_pattern_(multicast_transfer_group_pattern_);
351 if (!multicasts_configured_)
353 if (interface_name.empty() && interface_address.empty())
355 TLOG(TLVL_INFO) <<
"Using default multicast output address (autodetected private interface)";
357 if (!interface_name.empty())
361 else if (!interface_address.empty())
369 multicasts_configured_ =
true;
371 return multicast_interface_address_;
374 std::string artdaq::PortManager::parse_pattern_(
const std::string& pattern,
int subsystemID,
int rank)
376 std::istringstream f(pattern);
377 std::vector<int> address(4);
380 while (getline(f, s,
'.'))
384 address.push_back(GetPartitionNumber());
388 address.push_back(subsystemID);
392 address.push_back(rank);
396 address.push_back(stoi(s));
400 if (address.size() != 4)
402 TLOG(TLVL_ERROR) <<
"Invalid address pattern!";
403 while (address.size() < 4) { address.push_back(0); }
405 address[3] += multicast_group_offset_;
407 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.