1 #include "artdaq/DAQdata/PortManager.hh"
2 #define TRACE_NAME "PortManager"
3 #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 (std::invalid_argument) {}
75 catch (std::out_of_range) {}
78 auto ppp = getenv(
"ARTDAQ_PORTS_PER_PARTITION");
83 auto ppp_s = std::string(ppp);
84 auto ppp_tmp = std::stoi(ppp_s, 0, 0);
85 if (ppp_tmp < 0 || ppp_tmp > 32000)
87 TLOG(TLVL_ERROR) <<
"Ports per partition specified in ARTDAQ_PORTS_PER_PARTITION is invalid! Ignoring...";
91 ports_per_partition_ = ppp_tmp;
94 catch (std::invalid_argument) {}
95 catch (std::out_of_range) {}
98 if (!base_configured_ && (base_port_ != DEFAULT_BASE || ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION))
100 base_configured_ =
true;
101 auto max_partitions = (65535 - base_port_) / ports_per_partition_;
102 TLOG(TLVL_INFO) <<
"Based on configuration, there can be " << max_partitions <<
" partitions of " << ports_per_partition_ <<
" ports each, starting at port " << base_port_;
103 if (GetPartitionNumber() > max_partitions)
105 TLOG(TLVL_ERROR) <<
"Currently-configured partition number is greater than the allowed number! The system WILL NOT WORK!";
111 bool multicast_configured =
false;
112 if (ps.has_key(
"multicast_output_interface"))
114 multicast_configured =
GetIPOfInterface(ps.get<std::string>(
"multicast_output_interface"), tmp_addr) == 0;
116 else if (ps.has_key(
"multicast_output_network"))
118 multicast_configured =
GetInterfaceForNetwork(ps.get<std::string>(
"multicast_output_network").c_str(), tmp_addr) == 0;
120 if (multicast_configured && multicasts_configured_ && tmp_addr.s_addr != multicast_interface_address_.s_addr)
122 TLOG(TLVL_WARNING) <<
"Multicast output address has changed! This may lead to misconfiguration and non-functional systems!";
124 else if (multicast_configured)
126 multicasts_configured_ =
true;
127 multicast_interface_address_ = tmp_addr;
130 if (ps.has_key(
"multicast_group_offset"))
132 auto newVal = ps.get<
int>(
"multicast_group_offset");
133 if (multicast_group_offset_ != DEFAULT_MULTICAST_GROUP_OFFSET && multicast_group_offset_ != newVal)
135 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!";
137 multicast_group_offset_ = newVal;
140 if (ps.has_key(
"routing_token_port_offset"))
142 auto newVal = ps.get<
int>(
"routing_token_port_offset");
143 if (routing_tokens_configured_ && newVal != routing_token_offset_)
145 TLOG(TLVL_WARNING) <<
"Routing Token Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
148 routing_tokens_configured_ =
true;
149 routing_token_offset_ = newVal;
152 if (ps.has_key(
"routing_table_ack_port_offset"))
154 auto newVal = ps.get<
int>(
"routing_table_ack_port_offset");
155 if (routing_acks_configured_ && newVal != routing_ack_offset_)
157 TLOG(TLVL_WARNING) <<
"Routing Table Acknowledgement Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
160 routing_acks_configured_ =
true;
161 routing_ack_offset_ = newVal;
164 if (ps.has_key(
"xmlrpc_port_offset"))
167 auto newVal = ps.get<
int>(
"xmlrpc_port_offset");
168 if (xmlrpc_configured_ && newVal != xmlrpc_offset_)
170 TLOG(TLVL_WARNING) <<
"XMLRPC Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
173 xmlrpc_configured_ =
true;
174 xmlrpc_offset_ = newVal;
177 if (ps.has_key(
"tcp_socket_port_offset"))
179 auto newVal = ps.get<
int>(
"tcp_socket_port_offset");
180 if (tcpsocket_configured_ && newVal != tcp_socket_offset_)
182 TLOG(TLVL_WARNING) <<
"TCPSocketTransfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
185 tcpsocket_configured_ =
true;
186 tcp_socket_offset_ = newVal;
189 if (ps.has_key(
"request_port"))
191 auto newVal = ps.get<
int>(
"request_port");
192 if (request_port_configured_ && newVal != request_message_port_)
194 TLOG(TLVL_WARNING) <<
"Request Message Port has changed! This may lead to misconfiguration and non-functional systems!";
197 request_port_configured_ =
true;
198 request_message_port_ = newVal;
202 if (ps.has_key(
"request_pattern"))
204 auto newVal = ps.get<std::string>(
"request_pattern");
205 if (request_pattern_configured_ && newVal != request_message_group_pattern_)
207 TLOG(TLVL_WARNING) <<
"Request Message Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
210 request_pattern_configured_ =
true;
211 request_message_group_pattern_ = newVal;
215 if (ps.has_key(
"routing_table_port"))
217 auto newVal = ps.get<
int>(
"routing_table_port");
218 if (routing_table_port_configured_ && newVal != routing_table_port_)
220 TLOG(TLVL_WARNING) <<
"Routing Table Port has changed! This may lead to misconfiguration and non-functional systems!";
223 routing_table_port_configured_ =
true;
224 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;
241 if (ps.has_key(
"multicast_transfer_port_offset"))
243 auto newVal = ps.get<
int>(
"multicast_transfer_port_offset");
244 if (multicast_transfer_port_configued_ && newVal != multicast_transfer_offset_)
246 TLOG(TLVL_WARNING) <<
"Multicast Transfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
249 multicast_transfer_port_configued_ =
true;
250 multicast_transfer_offset_ = newVal;
254 if (ps.has_key(
"multicast_transfer_pattern"))
256 auto newVal = ps.get<std::string>(
"multicast_transfer_pattern");
257 if (multicast_transfer_pattern_configured_ && newVal != multicast_transfer_group_pattern_)
259 TLOG(TLVL_WARNING) <<
"Multicast Transfer Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
262 multicast_transfer_pattern_configured_ =
true;
263 multicast_transfer_group_pattern_ = newVal;
270 if (!routing_tokens_configured_)
272 TLOG(TLVL_INFO) <<
"Using default port range for Routing Tokens";
273 routing_tokens_configured_ =
true;
276 return base_port_ + routing_token_offset_ + (GetPartitionNumber() * ports_per_partition_) + subsystemID;
281 if (!routing_acks_configured_)
283 TLOG(TLVL_INFO) <<
"Using default port range for Routing Table Acknowledgements";
284 routing_acks_configured_ =
true;
286 return base_port_ + routing_ack_offset_ + (GetPartitionNumber() * ports_per_partition_) + subsystemID;
291 if (!xmlrpc_configured_)
293 TLOG(TLVL_INFO) <<
"Using default port range for XMLRPC";
294 xmlrpc_configured_ =
true;
296 return base_port_ + xmlrpc_offset_ + rank + (GetPartitionNumber() * ports_per_partition_);
301 if (!tcpsocket_configured_)
303 TLOG(TLVL_INFO) <<
"Using default port range for TCPSocket Transfer";
304 tcpsocket_configured_ =
true;
306 return base_port_ + tcp_socket_offset_ + (GetPartitionNumber() * ports_per_partition_) + rank;
311 if (!request_port_configured_)
313 TLOG(TLVL_INFO) <<
"Using default port for Request Messages";
314 request_port_configured_ =
true;
316 return request_message_port_;
322 if (!request_pattern_configured_)
324 TLOG(TLVL_INFO) <<
"Using default address for Request Messages";
325 request_pattern_configured_ =
true;
328 return parse_pattern_(request_message_group_pattern_, subsystemID);
333 if (!routing_table_port_configured_)
335 TLOG(TLVL_INFO) <<
"Using default port for Routing Tables";
336 routing_table_port_configured_ =
true;
339 return routing_table_port_;
344 if (!routing_table_pattern_configured_)
346 TLOG(TLVL_INFO) <<
"Using default address for Routing Tables";
347 routing_table_pattern_configured_ =
true;
350 return parse_pattern_(routing_table_group_pattern_, subsystemID);
355 if (!multicast_transfer_port_configued_)
357 TLOG(TLVL_INFO) <<
"Using default port for Multicast Transfer";
358 multicast_transfer_port_configued_ =
true;
361 return multicast_transfer_offset_ + rank;
366 if (!multicast_transfer_pattern_configured_)
368 TLOG(TLVL_INFO) <<
"Using default address for Multicast Transfer";
369 multicast_transfer_pattern_configured_ =
true;
372 return parse_pattern_(multicast_transfer_group_pattern_);
377 if (!multicasts_configured_)
379 if (interface_name ==
"" && interface_address ==
"") TLOG(TLVL_INFO) <<
"Using default multicast output address (autodetected private interface)";
380 if (interface_name !=
"")
384 else if (interface_address !=
"")
392 multicasts_configured_ =
true;
394 return multicast_interface_address_;
397 std::string artdaq::PortManager::parse_pattern_(std::string pattern,
int subsystemID,
int rank)
399 std::istringstream f(pattern);
400 std::vector<int> address(4);
403 while (getline(f, s,
'.'))
406 address.push_back(GetPartitionNumber());
408 else if (s ==
"SSS") {
409 address.push_back(subsystemID);
411 else if (s ==
"RRR") {
412 address.push_back(rank);
416 address.push_back(stoi(s));
420 if (address.size() != 4)
422 TLOG(TLVL_ERROR) <<
"Invalid address pattern!";
423 while (address.size() < 4) { address.push_back(0); }
425 address[3] += multicast_group_offset_;
427 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.