$treeview $search $mathjax $extrastylesheet
artdaq
v3_04_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "artdaq/DAQdata/PortManager.hh" 00002 #define TRACE_NAME "PortManager" 00003 #include "artdaq/DAQdata/Globals.hh" 00004 #include "artdaq/DAQdata/TCPConnect.hh" 00005 #include <sstream> 00006 00007 artdaq::PortManager::PortManager() 00008 : base_configured_(false) 00009 , multicasts_configured_(false) 00010 , routing_tokens_configured_(false) 00011 , routing_acks_configured_(false) 00012 , xmlrpc_configured_(false) 00013 , tcpsocket_configured_(false) 00014 , request_port_configured_(false) 00015 , request_pattern_configured_(false) 00016 , routing_table_port_configured_(false) 00017 , routing_table_pattern_configured_(false) 00018 , multicast_transfer_port_configued_(false) 00019 , multicast_transfer_pattern_configured_(false) 00020 , base_port_(DEFAULT_BASE) 00021 , ports_per_partition_(DEFAULT_PORTS_PER_PARTITION) 00022 , multicast_interface_address_() 00023 , multicast_group_offset_(DEFAULT_MULTICAST_GROUP_OFFSET) 00024 , routing_token_offset_(DEFAULT_ROUTING_TOKEN_OFFSET) 00025 , routing_ack_offset_(DEFAULT_ROUTING_TABLE_ACK_OFFSET) 00026 , xmlrpc_offset_(DEFAULT_XMLRPC_OFFSET) 00027 , tcp_socket_offset_(DEFAULT_TCPSOCKET_OFFSET) 00028 , request_message_port_(DEFAULT_REQUEST_PORT) 00029 , routing_table_port_(DEFAULT_ROUTING_TABLE_PORT) 00030 , multicast_transfer_offset_(1024) 00031 , request_message_group_pattern_("227.128.PPP.SSS") 00032 , routing_table_group_pattern_("227.129.PPP.SSS") 00033 , multicast_transfer_group_pattern_("227.130.14.PPP") 00034 { 00035 } 00036 00037 void artdaq::PortManager::UpdateConfiguration(fhicl::ParameterSet const& ps) 00038 { 00039 if (ps.has_key("artdaq_base_port")) 00040 { 00041 auto newVal = ps.get<int>("artdaq_base_port"); 00042 if (base_port_ != DEFAULT_BASE && base_port_ != newVal) 00043 { 00044 TLOG(TLVL_WARNING) << "Base port has changed! This may lead to misconfiguration and non-functional systems!"; 00045 } 00046 base_port_ = newVal; 00047 } 00048 if (ps.has_key("ports_per_partition")) 00049 { 00050 auto newVal = ps.get<int>("ports_per_partition"); 00051 if (ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION && ports_per_partition_ != newVal) 00052 { 00053 TLOG(TLVL_WARNING) << "Ports per Partition has changed! This may lead to misconfiguration and non-functional systems!"; 00054 } 00055 ports_per_partition_ = newVal; 00056 } 00057 00058 auto bp = getenv("ARTDAQ_BASE_PORT"); //Environment overrides configuration 00059 if (bp != nullptr) 00060 { 00061 try 00062 { 00063 auto bp_s = std::string(bp); 00064 auto bp_tmp = std::stoi(bp_s, 0, 0); 00065 if (bp_tmp < 1024 || bp_tmp > 32000) 00066 { 00067 TLOG(TLVL_ERROR) << "Base port specified in ARTDAQ_BASE_PORT is invalid! Ignoring..."; 00068 } 00069 else 00070 { 00071 base_port_ = bp_tmp; 00072 } 00073 } 00074 catch (std::invalid_argument) {} 00075 catch (std::out_of_range) {} 00076 } 00077 00078 auto ppp = getenv("ARTDAQ_PORTS_PER_PARTITION"); //Environment overrides configuration 00079 if (ppp != nullptr) 00080 { 00081 try 00082 { 00083 auto ppp_s = std::string(ppp); 00084 auto ppp_tmp = std::stoi(ppp_s, 0, 0); 00085 if (ppp_tmp < 0 || ppp_tmp > 32000) 00086 { 00087 TLOG(TLVL_ERROR) << "Ports per partition specified in ARTDAQ_PORTS_PER_PARTITION is invalid! Ignoring..."; 00088 } 00089 else 00090 { 00091 ports_per_partition_ = ppp_tmp; 00092 } 00093 } 00094 catch (std::invalid_argument) {} 00095 catch (std::out_of_range) {} 00096 } 00097 00098 if (!base_configured_ && (base_port_ != DEFAULT_BASE || ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION)) 00099 { 00100 base_configured_ = true; 00101 auto max_partitions = (65535 - base_port_) / ports_per_partition_; 00102 TLOG(TLVL_INFO) << "Based on configuration, there can be " << max_partitions << " partitions of " << ports_per_partition_ << " ports each, starting at port " << base_port_; 00103 if (GetPartitionNumber() > max_partitions) 00104 { 00105 TLOG(TLVL_ERROR) << "Currently-configured partition number is greater than the allowed number! The system WILL NOT WORK!"; 00106 exit(22); 00107 } 00108 } 00109 00110 in_addr tmp_addr; 00111 bool multicast_configured = false; 00112 if (ps.has_key("multicast_output_interface")) 00113 { 00114 multicast_configured = GetIPOfInterface(ps.get<std::string>("multicast_output_interface"), tmp_addr) == 0; 00115 } 00116 else if (ps.has_key("multicast_output_network")) 00117 { 00118 multicast_configured = GetInterfaceForNetwork(ps.get<std::string>("multicast_output_network").c_str(), tmp_addr) == 0; 00119 } 00120 if (multicast_configured && multicasts_configured_ && tmp_addr.s_addr != multicast_interface_address_.s_addr) 00121 { 00122 TLOG(TLVL_WARNING) << "Multicast output address has changed! This may lead to misconfiguration and non-functional systems!"; 00123 } 00124 else if (multicast_configured) 00125 { 00126 multicasts_configured_ = true; 00127 multicast_interface_address_ = tmp_addr; 00128 } 00129 00130 if (ps.has_key("multicast_group_offset")) 00131 { 00132 auto newVal = ps.get<int>("multicast_group_offset"); 00133 if (multicast_group_offset_ != DEFAULT_MULTICAST_GROUP_OFFSET && multicast_group_offset_ != newVal) 00134 { 00135 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!"; 00136 } 00137 multicast_group_offset_ = newVal; 00138 } 00139 00140 if (ps.has_key("routing_token_port_offset")) 00141 { 00142 auto newVal = ps.get<int>("routing_token_port_offset"); 00143 if (routing_tokens_configured_ && newVal != routing_token_offset_) 00144 { 00145 TLOG(TLVL_WARNING) << "Routing Token Port Offset has changed! This may lead to misconfiguration and non-functional systems!"; 00146 } 00147 00148 routing_tokens_configured_ = true; 00149 routing_token_offset_ = newVal; 00150 } 00151 00152 if (ps.has_key("routing_table_ack_port_offset")) 00153 { 00154 auto newVal = ps.get<int>("routing_table_ack_port_offset"); 00155 if (routing_acks_configured_ && newVal != routing_ack_offset_) 00156 { 00157 TLOG(TLVL_WARNING) << "Routing Table Acknowledgement Port Offset has changed! This may lead to misconfiguration and non-functional systems!"; 00158 } 00159 00160 routing_acks_configured_ = true; 00161 routing_ack_offset_ = newVal; 00162 } 00163 00164 if (ps.has_key("xmlrpc_port_offset")) 00165 { 00166 00167 auto newVal = ps.get<int>("xmlrpc_port_offset"); 00168 if (xmlrpc_configured_ && newVal != xmlrpc_offset_) 00169 { 00170 TLOG(TLVL_WARNING) << "XMLRPC Port Offset has changed! This may lead to misconfiguration and non-functional systems!"; 00171 } 00172 00173 xmlrpc_configured_ = true; 00174 xmlrpc_offset_ = newVal; 00175 } 00176 00177 if (ps.has_key("tcp_socket_port_offset")) 00178 { 00179 auto newVal = ps.get<int>("tcp_socket_port_offset"); 00180 if (tcpsocket_configured_ && newVal != tcp_socket_offset_) 00181 { 00182 TLOG(TLVL_WARNING) << "TCPSocketTransfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!"; 00183 } 00184 00185 tcpsocket_configured_ = true; 00186 tcp_socket_offset_ = newVal; 00187 } 00188 00189 if (ps.has_key("request_port")) 00190 { 00191 auto newVal = ps.get<int>("request_port"); 00192 if (request_port_configured_ && newVal != request_message_port_) 00193 { 00194 TLOG(TLVL_WARNING) << "Request Message Port has changed! This may lead to misconfiguration and non-functional systems!"; 00195 } 00196 00197 request_port_configured_ = true; 00198 request_message_port_ = newVal; 00199 00200 } 00201 00202 if (ps.has_key("request_pattern")) 00203 { 00204 auto newVal = ps.get<std::string>("request_pattern"); 00205 if (request_pattern_configured_ && newVal != request_message_group_pattern_) 00206 { 00207 TLOG(TLVL_WARNING) << "Request Message Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!"; 00208 } 00209 00210 request_pattern_configured_ = true; 00211 request_message_group_pattern_ = newVal; 00212 00213 } 00214 00215 if (ps.has_key("routing_table_port")) 00216 { 00217 auto newVal = ps.get<int>("routing_table_port"); 00218 if (routing_table_port_configured_ && newVal != routing_table_port_) 00219 { 00220 TLOG(TLVL_WARNING) << "Routing Table Port has changed! This may lead to misconfiguration and non-functional systems!"; 00221 } 00222 00223 routing_table_port_configured_ = true; 00224 routing_table_port_ = newVal; 00225 00226 } 00227 00228 if (ps.has_key("routing_table_pattern")) 00229 { 00230 auto newVal = ps.get<std::string>("routing_table_pattern"); 00231 if (routing_table_pattern_configured_ && newVal != routing_table_group_pattern_) 00232 { 00233 TLOG(TLVL_WARNING) << "Routing Table Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!"; 00234 } 00235 00236 routing_table_pattern_configured_ = true; 00237 routing_table_group_pattern_ = newVal; 00238 00239 } 00240 00241 if (ps.has_key("multicast_transfer_port_offset")) 00242 { 00243 auto newVal = ps.get<int>("multicast_transfer_port_offset"); 00244 if (multicast_transfer_port_configued_ && newVal != multicast_transfer_offset_) 00245 { 00246 TLOG(TLVL_WARNING) << "Multicast Transfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!"; 00247 } 00248 00249 multicast_transfer_port_configued_ = true; 00250 multicast_transfer_offset_ = newVal; 00251 00252 } 00253 00254 if (ps.has_key("multicast_transfer_pattern")) 00255 { 00256 auto newVal = ps.get<std::string>("multicast_transfer_pattern"); 00257 if (multicast_transfer_pattern_configured_ && newVal != multicast_transfer_group_pattern_) 00258 { 00259 TLOG(TLVL_WARNING) << "Multicast Transfer Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!"; 00260 } 00261 00262 multicast_transfer_pattern_configured_ = true; 00263 multicast_transfer_group_pattern_ = newVal; 00264 00265 } 00266 } 00267 00268 int artdaq::PortManager::GetRoutingTokenPort(int subsystemID) 00269 { 00270 if (!routing_tokens_configured_) 00271 { 00272 TLOG(TLVL_INFO) << "Using default port range for Routing Tokens"; 00273 routing_tokens_configured_ = true; 00274 } 00275 00276 return base_port_ + routing_token_offset_ + (GetPartitionNumber() * ports_per_partition_) + subsystemID; 00277 } 00278 00279 int artdaq::PortManager::GetRoutingAckPort(int subsystemID) 00280 { 00281 if (!routing_acks_configured_) 00282 { 00283 TLOG(TLVL_INFO) << "Using default port range for Routing Table Acknowledgements"; 00284 routing_acks_configured_ = true; 00285 } 00286 return base_port_ + routing_ack_offset_ + (GetPartitionNumber() * ports_per_partition_) + subsystemID; 00287 } 00288 00289 int artdaq::PortManager::GetXMLRPCPort(int rank) 00290 { 00291 if (!xmlrpc_configured_) 00292 { 00293 TLOG(TLVL_INFO) << "Using default port range for XMLRPC"; 00294 xmlrpc_configured_ = true; 00295 } 00296 return base_port_ + xmlrpc_offset_ + rank + (GetPartitionNumber() * ports_per_partition_); 00297 } 00298 00299 int artdaq::PortManager::GetTCPSocketTransferPort(int rank) 00300 { 00301 if (!tcpsocket_configured_) 00302 { 00303 TLOG(TLVL_INFO) << "Using default port range for TCPSocket Transfer"; 00304 tcpsocket_configured_ = true; 00305 } 00306 return base_port_ + tcp_socket_offset_ + (GetPartitionNumber() * ports_per_partition_) + rank; 00307 } 00308 00309 int artdaq::PortManager::GetRequestMessagePort() 00310 { 00311 if (!request_port_configured_) 00312 { 00313 TLOG(TLVL_INFO) << "Using default port for Request Messages"; 00314 request_port_configured_ = true; 00315 } 00316 return request_message_port_; 00317 00318 } 00319 00320 std::string artdaq::PortManager::GetRequestMessageGroupAddress(int subsystemID) 00321 { 00322 if (!request_pattern_configured_) 00323 { 00324 TLOG(TLVL_INFO) << "Using default address for Request Messages"; 00325 request_pattern_configured_ = true; 00326 } 00327 00328 return parse_pattern_(request_message_group_pattern_, subsystemID); 00329 } 00330 00331 int artdaq::PortManager::GetRoutingTablePort() 00332 { 00333 if (!routing_table_port_configured_) 00334 { 00335 TLOG(TLVL_INFO) << "Using default port for Routing Tables"; 00336 routing_table_port_configured_ = true; 00337 } 00338 00339 return routing_table_port_; 00340 } 00341 00342 std::string artdaq::PortManager::GetRoutingTableGroupAddress(int subsystemID) 00343 { 00344 if (!routing_table_pattern_configured_) 00345 { 00346 TLOG(TLVL_INFO) << "Using default address for Routing Tables"; 00347 routing_table_pattern_configured_ = true; 00348 } 00349 00350 return parse_pattern_(routing_table_group_pattern_, subsystemID); 00351 } 00352 00353 int artdaq::PortManager::GetMulticastTransferPort(int rank) 00354 { 00355 if (!multicast_transfer_port_configued_) 00356 { 00357 TLOG(TLVL_INFO) << "Using default port for Multicast Transfer"; 00358 multicast_transfer_port_configued_ = true; 00359 } 00360 00361 return multicast_transfer_offset_ + rank; 00362 } 00363 00364 std::string artdaq::PortManager::GetMulticastTransferGroupAddress() 00365 { 00366 if (!multicast_transfer_pattern_configured_) 00367 { 00368 TLOG(TLVL_INFO) << "Using default address for Multicast Transfer"; 00369 multicast_transfer_pattern_configured_ = true; 00370 } 00371 00372 return parse_pattern_(multicast_transfer_group_pattern_); 00373 } 00374 00375 in_addr artdaq::PortManager::GetMulticastOutputAddress(std::string interface_name, std::string interface_address) 00376 { 00377 if (!multicasts_configured_) 00378 { 00379 if (interface_name == "" && interface_address == "") TLOG(TLVL_INFO) << "Using default multicast output address (autodetected private interface)"; 00380 if (interface_name != "") 00381 { 00382 GetIPOfInterface(interface_name, multicast_interface_address_); 00383 } 00384 else if (interface_address != "") 00385 { 00386 GetInterfaceForNetwork(interface_address.c_str(), multicast_interface_address_); 00387 } 00388 else 00389 { 00390 AutodetectPrivateInterface(multicast_interface_address_); 00391 } 00392 multicasts_configured_ = true; 00393 } 00394 return multicast_interface_address_; 00395 } 00396 00397 std::string artdaq::PortManager::parse_pattern_(std::string pattern, int subsystemID, int rank) 00398 { 00399 std::istringstream f(pattern); 00400 std::vector<int> address(4); 00401 std::string s; 00402 00403 while (getline(f, s, '.')) 00404 { 00405 if (s == "PPP") { 00406 address.push_back(GetPartitionNumber()); 00407 } 00408 else if (s == "SSS") { 00409 address.push_back(subsystemID); 00410 } 00411 else if (s == "RRR") { 00412 address.push_back(rank); 00413 } 00414 else 00415 { 00416 address.push_back(stoi(s)); 00417 } 00418 } 00419 00420 if (address.size() != 4) 00421 { 00422 TLOG(TLVL_ERROR) << "Invalid address pattern!"; 00423 while (address.size() < 4) { address.push_back(0); } 00424 } 00425 address[3] += multicast_group_offset_; 00426 00427 return std::to_string(address[0]) + "." + std::to_string(address[1]) + "." + std::to_string(address[2]) + "." + std::to_string(address[3]); 00428 }