1 #include "artdaq/DAQdata/PortManager.hh"
2 #define TRACE_NAME "PortManager"
3 #include "artdaq/DAQdata/Globals.hh"
7 artdaq::PortManager::PortManager()
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")
37 void artdaq::PortManager::UpdateConfiguration(fhicl::ParameterSet
const& ps)
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;
268 int artdaq::PortManager::GetRoutingTokenPort(
int subsystemID)
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;
279 int artdaq::PortManager::GetRoutingAckPort(
int 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;
289 int artdaq::PortManager::GetXMLRPCPort(
int rank)
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_);
299 int artdaq::PortManager::GetTCPSocketTransferPort(
int rank)
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;
309 int artdaq::PortManager::GetRequestMessagePort()
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_;
320 std::string artdaq::PortManager::GetRequestMessageGroupAddress(
int subsystemID)
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);
331 int artdaq::PortManager::GetRoutingTablePort()
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_;
342 std::string artdaq::PortManager::GetRoutingTableGroupAddress(
int subsystemID)
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);
353 int artdaq::PortManager::GetMulticastTransferPort(
int rank)
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;
364 std::string artdaq::PortManager::GetMulticastTransferGroupAddress()
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_);
375 in_addr artdaq::PortManager::GetMulticastOutputAddress(std::string interface_name, std::string interface_address)
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 GetInterfaceForNetwork(char const *host_in, in_addr &addr)
Convert an IP address to the network address of the interface sharing the subnet mask.
int GetIPOfInterface(std::string interface_name, in_addr &addr)
Get the IP address associated with a given interface name.
int AutodetectPrivateInterface(in_addr &addr)
Pick a private IP address on this host.