1 #include "artdaq/DAQdata/PortManager.hh"
2 #define TRACE_NAME "PortManager"
4 #include "artdaq/DAQdata/Globals.hh"
8 : base_configured_(false)
9 , multicasts_configured_(false)
10 , routing_tokens_configured_(false)
11 , routing_acks_configured_(false)
12 , xmlrpc_configured_(false)
13 , tcpsocket_configured_(false)
14 , request_port_configured_(false)
15 , request_pattern_configured_(false)
16 , routing_table_port_configured_(false)
17 , routing_table_pattern_configured_(false)
18 , multicast_transfer_port_configued_(false)
19 , multicast_transfer_pattern_configured_(false)
20 , base_port_(DEFAULT_BASE)
21 , ports_per_partition_(DEFAULT_PORTS_PER_PARTITION)
22 , multicast_interface_address_()
23 , multicast_group_offset_(DEFAULT_MULTICAST_GROUP_OFFSET)
24 , routing_token_offset_(DEFAULT_ROUTING_TOKEN_OFFSET)
25 , routing_ack_offset_(DEFAULT_ROUTING_TABLE_ACK_OFFSET)
26 , xmlrpc_offset_(DEFAULT_XMLRPC_OFFSET)
27 , tcp_socket_offset_(DEFAULT_TCPSOCKET_OFFSET)
28 , request_message_port_(DEFAULT_REQUEST_PORT)
29 , routing_table_port_(DEFAULT_ROUTING_TABLE_PORT)
30 , multicast_transfer_offset_(1024)
31 , request_message_group_pattern_(
"227.128.PPP.SSS")
32 , routing_table_group_pattern_(
"227.129.PPP.SSS")
33 , multicast_transfer_group_pattern_(
"227.130.14.PPP")
39 if (ps.has_key(
"artdaq_base_port"))
41 auto newVal = ps.get<
int>(
"artdaq_base_port");
42 if (base_port_ != DEFAULT_BASE && base_port_ != newVal)
44 TLOG(TLVL_WARNING) <<
"Base port has changed! This may lead to misconfiguration and non-functional systems!";
48 if (ps.has_key(
"ports_per_partition"))
50 auto newVal = ps.get<
int>(
"ports_per_partition");
51 if (ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION && ports_per_partition_ != newVal)
53 TLOG(TLVL_WARNING) <<
"Ports per Partition has changed! This may lead to misconfiguration and non-functional systems!";
55 ports_per_partition_ = newVal;
58 auto bp = getenv(
"ARTDAQ_BASE_PORT");
63 auto bp_s = std::string(bp);
64 auto bp_tmp = std::stoi(bp_s, 0, 0);
65 if (bp_tmp < 1024 || bp_tmp > 32000)
67 TLOG(TLVL_ERROR) <<
"Base port specified in ARTDAQ_BASE_PORT is invalid! Ignoring...";
74 catch (
const std::invalid_argument&)
76 catch (
const std::out_of_range&)
80 auto ppp = getenv(
"ARTDAQ_PORTS_PER_PARTITION");
85 auto ppp_s = std::string(ppp);
86 auto ppp_tmp = std::stoi(ppp_s, 0, 0);
87 if (ppp_tmp < 0 || ppp_tmp > 32000)
89 TLOG(TLVL_ERROR) <<
"Ports per partition specified in ARTDAQ_PORTS_PER_PARTITION is invalid! Ignoring...";
93 ports_per_partition_ = ppp_tmp;
96 catch (
const std::invalid_argument&)
98 catch (
const std::out_of_range&)
102 if (!base_configured_ && (base_port_ != DEFAULT_BASE || ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION))
104 base_configured_ =
true;
105 auto max_partitions = (65535 - base_port_) / ports_per_partition_;
106 TLOG(TLVL_INFO) <<
"Based on configuration, there can be " << max_partitions <<
" partitions of " << ports_per_partition_ <<
" ports each, starting at port " << base_port_;
107 if (GetPartitionNumber() > max_partitions)
109 TLOG(TLVL_ERROR) <<
"Currently-configured partition number is greater than the allowed number! The system WILL NOT WORK!";
115 bool multicast_configured =
false;
116 if (ps.has_key(
"multicast_output_interface"))
118 multicast_configured =
GetIPOfInterface(ps.get<std::string>(
"multicast_output_interface"), tmp_addr) == 0;
120 else if (ps.has_key(
"multicast_output_network"))
122 multicast_configured =
GetInterfaceForNetwork(ps.get<std::string>(
"multicast_output_network").c_str(), tmp_addr) == 0;
124 if (multicast_configured && multicasts_configured_ && tmp_addr.s_addr != multicast_interface_address_.s_addr)
126 TLOG(TLVL_WARNING) <<
"Multicast output address has changed! This may lead to misconfiguration and non-functional systems!";
128 else if (multicast_configured)
130 multicasts_configured_ =
true;
131 multicast_interface_address_ = tmp_addr;
134 if (ps.has_key(
"multicast_group_offset"))
136 auto newVal = ps.get<
int>(
"multicast_group_offset");
137 if (multicast_group_offset_ != DEFAULT_MULTICAST_GROUP_OFFSET && multicast_group_offset_ != newVal)
139 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!";
141 multicast_group_offset_ = newVal;
144 if (ps.has_key(
"routing_token_port_offset"))
146 auto newVal = ps.get<
int>(
"routing_token_port_offset");
147 if (routing_tokens_configured_ && newVal != routing_token_offset_)
149 TLOG(TLVL_WARNING) <<
"Routing Token Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
152 routing_tokens_configured_ =
true;
153 routing_token_offset_ = newVal;
156 if (ps.has_key(
"routing_table_ack_port_offset"))
158 auto newVal = ps.get<
int>(
"routing_table_ack_port_offset");
159 if (routing_acks_configured_ && newVal != routing_ack_offset_)
161 TLOG(TLVL_WARNING) <<
"Routing Table Acknowledgement Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
164 routing_acks_configured_ =
true;
165 routing_ack_offset_ = newVal;
168 if (ps.has_key(
"xmlrpc_port_offset"))
170 auto newVal = ps.get<
int>(
"xmlrpc_port_offset");
171 if (xmlrpc_configured_ && newVal != xmlrpc_offset_)
173 TLOG(TLVL_WARNING) <<
"XMLRPC Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
176 xmlrpc_configured_ =
true;
177 xmlrpc_offset_ = newVal;
180 if (ps.has_key(
"tcp_socket_port_offset"))
182 auto newVal = ps.get<
int>(
"tcp_socket_port_offset");
183 if (tcpsocket_configured_ && newVal != tcp_socket_offset_)
185 TLOG(TLVL_WARNING) <<
"TCPSocketTransfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
188 tcpsocket_configured_ =
true;
189 tcp_socket_offset_ = newVal;
192 if (ps.has_key(
"request_port"))
194 auto newVal = ps.get<
int>(
"request_port");
195 if (request_port_configured_ && newVal != request_message_port_)
197 TLOG(TLVL_WARNING) <<
"Request Message Port has changed! This may lead to misconfiguration and non-functional systems!";
200 request_port_configured_ =
true;
201 request_message_port_ = newVal;
204 if (ps.has_key(
"request_pattern"))
206 auto newVal = ps.get<std::string>(
"request_pattern");
207 if (request_pattern_configured_ && newVal != request_message_group_pattern_)
209 TLOG(TLVL_WARNING) <<
"Request Message Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
212 request_pattern_configured_ =
true;
213 request_message_group_pattern_ = newVal;
216 if (ps.has_key(
"routing_table_port"))
218 auto newVal = ps.get<
int>(
"routing_table_port");
219 if (routing_table_port_configured_ && newVal != routing_table_port_)
221 TLOG(TLVL_WARNING) <<
"Routing Table Port has changed! This may lead to misconfiguration and non-functional systems!";
224 routing_table_port_configured_ =
true;
225 routing_table_port_ = newVal;
228 if (ps.has_key(
"routing_table_pattern"))
230 auto newVal = ps.get<std::string>(
"routing_table_pattern");
231 if (routing_table_pattern_configured_ && newVal != routing_table_group_pattern_)
233 TLOG(TLVL_WARNING) <<
"Routing Table Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
236 routing_table_pattern_configured_ =
true;
237 routing_table_group_pattern_ = newVal;
240 if (ps.has_key(
"multicast_transfer_port_offset"))
242 auto newVal = ps.get<
int>(
"multicast_transfer_port_offset");
243 if (multicast_transfer_port_configued_ && newVal != multicast_transfer_offset_)
245 TLOG(TLVL_WARNING) <<
"Multicast Transfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
248 multicast_transfer_port_configued_ =
true;
249 multicast_transfer_offset_ = newVal;
252 if (ps.has_key(
"multicast_transfer_pattern"))
254 auto newVal = ps.get<std::string>(
"multicast_transfer_pattern");
255 if (multicast_transfer_pattern_configured_ && newVal != multicast_transfer_group_pattern_)
257 TLOG(TLVL_WARNING) <<
"Multicast Transfer Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
260 multicast_transfer_pattern_configured_ =
true;
261 multicast_transfer_group_pattern_ = newVal;
267 if (!routing_tokens_configured_)
269 TLOG(TLVL_INFO) <<
"Using default port range for Routing Tokens";
270 routing_tokens_configured_ =
true;
273 return base_port_ + routing_token_offset_ + (GetPartitionNumber() * ports_per_partition_) + subsystemID;
278 if (!routing_acks_configured_)
280 TLOG(TLVL_INFO) <<
"Using default port range for Routing Table Acknowledgements";
281 routing_acks_configured_ =
true;
283 return base_port_ + routing_ack_offset_ + (GetPartitionNumber() * ports_per_partition_) + subsystemID;
288 if (!xmlrpc_configured_)
290 TLOG(TLVL_INFO) <<
"Using default port range for XMLRPC";
291 xmlrpc_configured_ =
true;
293 return base_port_ + xmlrpc_offset_ + rank + (GetPartitionNumber() * ports_per_partition_);
298 if (!tcpsocket_configured_)
300 TLOG(TLVL_INFO) <<
"Using default port range for TCPSocket Transfer";
301 tcpsocket_configured_ =
true;
303 return base_port_ + tcp_socket_offset_ + (GetPartitionNumber() * ports_per_partition_) + rank;
308 if (!request_port_configured_)
310 TLOG(TLVL_INFO) <<
"Using default port for Request Messages";
311 request_port_configured_ =
true;
313 return request_message_port_;
318 if (!request_pattern_configured_)
320 TLOG(TLVL_INFO) <<
"Using default address for Request Messages";
321 request_pattern_configured_ =
true;
324 return parse_pattern_(request_message_group_pattern_, subsystemID);
329 if (!routing_table_port_configured_)
331 TLOG(TLVL_INFO) <<
"Using default port for Routing Tables";
332 routing_table_port_configured_ =
true;
335 return routing_table_port_;
340 if (!routing_table_pattern_configured_)
342 TLOG(TLVL_INFO) <<
"Using default address for Routing Tables";
343 routing_table_pattern_configured_ =
true;
346 return parse_pattern_(routing_table_group_pattern_, subsystemID);
351 if (!multicast_transfer_port_configued_)
353 TLOG(TLVL_INFO) <<
"Using default port for Multicast Transfer";
354 multicast_transfer_port_configued_ =
true;
357 return multicast_transfer_offset_ + rank;
362 if (!multicast_transfer_pattern_configured_)
364 TLOG(TLVL_INFO) <<
"Using default address for Multicast Transfer";
365 multicast_transfer_pattern_configured_ =
true;
368 return parse_pattern_(multicast_transfer_group_pattern_);
373 if (!multicasts_configured_)
375 if (interface_name ==
"" && interface_address ==
"") TLOG(TLVL_INFO) <<
"Using default multicast output address (autodetected private interface)";
376 if (interface_name !=
"")
380 else if (interface_address !=
"")
388 multicasts_configured_ =
true;
390 return multicast_interface_address_;
393 std::string artdaq::PortManager::parse_pattern_(std::string pattern,
int subsystemID,
int rank)
395 std::istringstream f(pattern);
396 std::vector<int> address(4);
399 while (getline(f, s,
'.'))
403 address.push_back(GetPartitionNumber());
407 address.push_back(subsystemID);
411 address.push_back(rank);
415 address.push_back(stoi(s));
419 if (address.size() != 4)
421 TLOG(TLVL_ERROR) <<
"Invalid address pattern!";
422 while (address.size() < 4) { address.push_back(0); }
424 address[3] += multicast_group_offset_;
426 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 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.
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.
in_addr GetMulticastOutputAddress(std::string interface_name="", std::string interface_address="")
Determine the output interface address, using the hints provided.
int GetIPOfInterface(std::string interface_name, in_addr &addr)
Get the IP address associated with a given interface name.
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.