|
|
|||
File indexing completed on 2026-09-29 09:35:20
0001 #ifndef __XRDNETUTILS_HH__ 0002 #define __XRDNETUTILS_HH__ 0003 /******************************************************************************/ 0004 /* */ 0005 /* X r d N e t U t i l s . h h */ 0006 /* */ 0007 /* (c) 2025 by the Board of Trustees of the Leland Stanford, Jr., University */ 0008 /* All Rights Reserved */ 0009 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 0010 /* DE-AC02-76-SFO0515 with the Department of Energy */ 0011 /* */ 0012 /* This file is part of the XRootD software suite. */ 0013 /* */ 0014 /* XRootD is free software: you can redistribute it and/or modify it under */ 0015 /* the terms of the GNU Lesser General Public License as published by the */ 0016 /* Free Software Foundation, either version 3 of the License, or (at your */ 0017 /* option) any later version. */ 0018 /* */ 0019 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ 0020 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ 0021 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ 0022 /* License for more details. */ 0023 /* */ 0024 /* You should have received a copy of the GNU Lesser General Public License */ 0025 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ 0026 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */ 0027 /* */ 0028 /* The copyright holder's institutional names and contributor's names may not */ 0029 /* be used to endorse or promote products derived from this software without */ 0030 /* specific prior written permission of the institution or contributor. */ 0031 /******************************************************************************/ 0032 0033 #include <string> 0034 #include <vector> 0035 #include <sstream> 0036 #include <cstdint> 0037 0038 #include "XrdOuc/XrdOucEnum.hh" 0039 0040 class XrdOucTList; 0041 class XrdNetAddr; 0042 union XrdNetSockAddr; 0043 0044 namespace XrdNetSpace {struct hpSpec;} 0045 0046 class XrdNetUtils 0047 { 0048 public: 0049 0050 //------------------------------------------------------------------------------ 0051 //! Compare two IP addresses and indicate differe\nces, if any. 0052 //! 0053 //! @param ip1 The first address. 0054 //! @param ip2 The second addres. 0055 //! @param psame If not zero set to true if ports are the same, o/w false. 0056 //! 0057 //! @return IPSame The addresses are the same. 0058 //! IPDFam The addresses differ in address family. 0059 //! IPDiff The addresses have different destination, same family. 0060 //! IPNSuf The address family of one or both addresses not supported. 0061 //------------------------------------------------------------------------------ 0062 0063 enum IPComp {IPSame = 0, IPDFam, IPDiff, IPNSup}; 0064 0065 static 0066 IPComp Compare(XrdNetSockAddr& ip1, XrdNetSockAddr& ip2, bool* psame=0); 0067 0068 //------------------------------------------------------------------------------ 0069 //! Decode an "encoded" ipv6/4 address and place it "sockaddr" type structure. 0070 //! 0071 //! @param sadr address of the union that will hold the results. 0072 //! @param buff address of buffer that holds the encoding. 0073 //! @param blen length of the string (it need not be null terminated). 0074 //! 0075 //! @return > 0 the port number in host byte order. 0076 //! = 0 the port number was not set. 0077 //! < 0 the encoding was not correct. 0078 //------------------------------------------------------------------------------ 0079 0080 static int Decode(XrdNetSockAddr *sadr, const char *buff, int blen); 0081 0082 //------------------------------------------------------------------------------ 0083 //! Encode the address and return it in a supplied buffer. 0084 //! 0085 //! @param sadr address of the union that holds the IPV4/6 address. 0086 //! @param buff address of buffer to hold the null terminated encoding. 0087 //! @param blen length of the buffer. It6 should be at least 40 bytes. 0088 //! @param port optional port value to use as opposed to the one present 0089 //! in sockaddr sadr. The port must be in host order. 0090 //! 0091 //! @return > 0 the length of the encoding less the null byte. 0092 //! = 0 current address format not supported for encoding. 0093 //! < 0 buffer is too small; abs(retval) bytes needed. 0094 //------------------------------------------------------------------------------ 0095 0096 static int Encode(const XrdNetSockAddr *sadr, char *buff, int blen, int port=-1); 0097 0098 0099 //------------------------------------------------------------------------------ 0100 //! Version 1: Return multiple addresses associated with a host or IP address. 0101 //! 0102 //! @param hSpec -> convert specification to addresses. Valid formats: 0103 //! IP.v4: nnn.nnn.nnn.nnn[:<port>] 0104 //! IP.v6: [ipv6_addr][:<port>] 0105 //! IP.xx: name[:port] xx is determined by getaddrinfo() 0106 //! @param aListP place where the pointer to the returned array of XrdNetAddr 0107 //! objects is to be placed. Set to zero if none returned. The 0108 //! caller must delete this array when no longer needed. 0109 //! @param aListN place where the number of elements in aListP are to be 0110 //! returned. 0111 //! @param opts Options on what to return. Choose one of: 0112 //! allIPMap - all IPv6 and mapped IPv4 addrs (default) 0113 //! allIPv64 - all IPv6 and unmapped IPv4 addrs 0114 //! allV4Map - all mapped IPV4 addrs. 0115 //! onlyIPv6 - only IPv6 addrs 0116 //! onlyIPv4 - only unmapped IPv4 addrs 0117 //! prefIPv6 - only IPv6 addrs; if none, mapped IPv4 addrs 0118 //! prefAuto - Returns addresses based on configured non-local 0119 //! interfaces. The returned addresses will be 0120 //! normally useable on this host and may be IPv4, 0121 //! IPv6, mapped IPv4, or a mixture. 0122 //! The above may be or'd with one or more of the following: 0123 //! onlyUDP - only addrs valid for UDP connections else TCP 0124 //! order46 - List IPv4 addresses (mapped or native) first. 0125 //! order64 - List IPv6 addresses first. 0126 //! @param pNum >= 0 uses the value as the port number regardless of what 0127 //! is in hSpec, should it be supplied. However, if is 0128 //! present, it must be a valid port number. 0129 //! < 0 uses the positive value as the port number if the 0130 //! port number has not been specified in hSpec. 0131 //! **** When set to PortInSpec(the default, see below) the 0132 //! port number/name must be specified in hSpec. If it is 0133 //! not, an error is returned. 0134 //! **** When set to NoPortRaw then hSpec does not contain a 0135 //! port number and is a host name, IPv4 address, or an 0136 //! IPv6 address *without* surrounding brackets. 0137 //! 0138 //! @return Success: 0 with aListN set to the number of elements in aListP. 0139 //! Failure: the error message text describing the error and aListP 0140 //! and aListN is set to zero. 0141 //------------------------------------------------------------------------------ 0142 0143 enum AddrOpts {allIPMap= 0, allIPv64= 1, allV4Map= 2, 0144 onlyIPv6= 3, onlyIPv4= 4, prefIPv6= 8, 0145 prefAuto= 16, order46 = 32, order64 = 64, 0146 onlyUDP =128 0147 }; 0148 0149 static const int PortInSpec = (int)0x80000000; 0150 static const int NoPortRaw = (int)0xC0000000; 0151 0152 static 0153 const char *GetAddrs(const char *hSpec, XrdNetAddr *aListP[], int &aListN, 0154 AddrOpts opts=allIPMap, int pNum=PortInSpec); 0155 0156 //------------------------------------------------------------------------------ 0157 //! Version 2: Return multiple addresses associated with a host or IP address. 0158 //! 0159 //! @param hSpec Reference to address specification (see version 1). 0160 //! @param aVec Reference to the vector to contain addresses. 0161 //! @param ordn Pointer to where the partition ordinal is to be stored. 0162 //! @param opts Options on what to return (see version 1). 0163 //! @param pNum Port number argument (see version 1). 0164 //! 0165 //! @return Success: 0 is returned. When ordn is not nil, the number of IPv4 0166 //! entries (for order46) or IPv6 (for order64) entries that 0167 //! appear in the front of the vector. If ordering is not 0168 //! specified, the value is set to the size of the vector. 0169 //! Failure: the error message text describing the error and aVec is 0170 //! cleared (i.e. has no elements). 0171 //------------------------------------------------------------------------------ 0172 0173 static 0174 const char *GetAddrs(const std::string &hSpec, std::vector<XrdNetAddr> &aVec, 0175 int *ordn=0, AddrOpts opts=allIPMap, int pNum=PortInSpec); 0176 0177 //------------------------------------------------------------------------------ 0178 //! Version 3: Return multiple addresses associated with a list of host or 0179 //! IP addresses. 0180 //! 0181 //! @param hSVec vector of address specification (see version 1). Note that 0182 //! this version requires hSVec entries to have a port number. 0183 //! @param aVec Reference to the vector to contain addresses. 0184 //! @param ordn Pointer to where the partition ordinal is to be stored. 0185 //! @param opts Options on what to return (see version 1). 0186 //! @param rotNum The rotation factor to order addresses in the result. 0187 //! @param force When true resolution errors are ignored. 0188 //! 0189 //! @return Success: 0 is returned. When ordn is not nil, the number of IPv4 0190 //! entries (for order46) or IPv6 (for order64) entries that 0191 //! appear in the front of the vector. If ordering is not 0192 //! specified, the value is set to the size of the vector. 0193 //! Failure: the error message text describing the error and aVec is 0194 //! cleared (i.e. has no elements). 0195 //------------------------------------------------------------------------------ 0196 0197 static 0198 const char *GetAddrs(std::vector<std::string> &hSVec, 0199 std::vector<XrdNetAddr> &aVec, 0200 int *ordn=0, AddrOpts opts=allIPMap, 0201 unsigned int rotNum=0, bool force=false); 0202 0203 //------------------------------------------------------------------------------ 0204 //! Obtain connection information from a socket. 0205 //! 0206 //! @param fd The file descriptor of the socket whose address is to be 0207 //! converted. The sign of the fd indicates which address: 0208 //! fd > 0 the peer address is used (i.e. getpeername) 0209 //! fd < 0 the local address is used (i.e. getsockname) 0210 //! @param theAddr pointer to a buffer of theAlen bytes where the text 0211 //! version of the IP address is to be returned. The text 0212 //! uses the actual native address format. If theAddr is 0213 //! nil or theAlen is not positive, only the port and 0214 //! address type are returned. 0215 //! @param theALen length of the theAddr buffer. 0216 //! @param theType either the character 4 (IPv4) or 6 (IPv6) is returned. 0217 //! corrresponding to the address family. Note that should 0218 //! be AF_INET6 but the address is mapped, '4' is returned. 0219 //! 0220 //! @return Success: >= 0 corresponding to the port number. 0221 //! @return Failure: < 0 corresponding to -errno. 0222 //------------------------------------------------------------------------------ 0223 0224 static 0225 int GetSokInfo(int fd, char *theAddr, int theALen, char &theType); 0226 0227 //------------------------------------------------------------------------------ 0228 //! Obtain an easily digestable list of hosts. This is the list of up to eight 0229 //! unique aliases (i.e. with different addresses) assigned to a base hostname. 0230 //! 0231 //! @param hSpec the host specification suitable for XrdNetAddr.Set(). 0232 //! @param hPort When >= 0 specified the port to use regardless of hSpec. 0233 //! When < 0 the port must be present in hSpec. 0234 //! @param hWant Maximum number of list entries wanted. If hWant is greater 0235 //! that eight it is set eigth. 0236 //! @param sPort If not nil, the *sPort will be set to hPort if and only if 0237 //! the IP address in one of the entries matches the host 0238 //! address. Otherwise, the value is unchanged. 0239 //! @param eText When not nil, is where to place error message text. 0240 //! 0241 //! @return Success: Pointer to a list of XrdOucTList objects where 0242 //! p->val is the port number 0243 //! p->text is the host name. 0244 //! The list of objects belongs to the caller. 0245 //! Failure: A nil pointer is returned. If eText is supplied, the error 0246 //! message, in persistent storage, is returned. 0247 //------------------------------------------------------------------------------ 0248 0249 static 0250 XrdOucTList *Hosts(const char *hSpec, int hPort=-1, int hWant=8, int *sPort=0, 0251 const char **eText=0); 0252 0253 //------------------------------------------------------------------------------ 0254 //! Convert an IP address/port (V4 or V6) into the standard V6 RFC ASCII 0255 //! representation: "[address]:port". 0256 //! 0257 //! @param sAddr Address to convert. This is either sockaddr_in or 0258 //! sockaddr_in6 cast to struct sockaddr. 0259 //! @param bP points to a buffer large enough to hold the result. 0260 //! A buffer 64 characters long will always be big enough. 0261 //! @param bL the actual size of the buffer. 0262 //! @param opts Formating options: 0263 //! noPort - does not suffix the port number with ":port". 0264 //! oldFmt - use the deprecated format for an IPV4 mapped 0265 //! address: [::d.d.d.d] vs [::ffff:d.d.d.d]. 0266 //! 0267 //! @return Success: The length of the formatted address is returned. 0268 //! @return Failure: Zero is returned and the buffer state is undefined. 0269 //! Failure occurs when the buffer is too small or the address family 0270 //! (sAddr->sa_family) is neither AF_INET nor AF_INET6. 0271 //------------------------------------------------------------------------------ 0272 0273 static const int noPort = 1; 0274 static const int oldFmt = 2; 0275 0276 static int IPFormat(const struct sockaddr *sAddr, char *bP, int bL, int opts=0); 0277 0278 //------------------------------------------------------------------------------ 0279 //! Convert an IP socket address/port (V4 or V6) into the standard V6 RFC ASCII 0280 //! representation: "[address]:port". 0281 //! 0282 //! @param fd The file descriptor of the socket whose address is to be 0283 //! converted. The sign of the fd indicates which address: 0284 //! fd > 0 the peer address is used (i.e. getpeername) 0285 //! fd < 0 the local address is used (i.e. getsockname) 0286 //! @param bP points to a buffer large enough to hold the result. 0287 //! A buffer 64 characters long will always be big enough. 0288 //! @param bL the actual size of the buffer. 0289 //! @param opts Formating options: 0290 //! noPort - does not suffix the port number with ":port". 0291 //! oldFmt - use the deprecated format for an IPV4 mapped 0292 //! address: [::d.d.d.d] vs [::ffff:d.d.d.d]. 0293 //! 0294 //! @return Success: The length of the formatted address is returned. 0295 //! @return Failure: Zero is returned and the buffer state is undefined. 0296 //! Failure occurs when the buffer is too small or the file 0297 //! descriptor does not refer to an open socket. 0298 //------------------------------------------------------------------------------ 0299 0300 static int IPFormat(int fd, char *bP, int bL, int opts=0); 0301 0302 //------------------------------------------------------------------------------ 0303 //! Determine if a hostname matches a pattern. 0304 //! 0305 //! @param hName the name of the host. 0306 //! @param pattern the pattern to match against. The pattern may contain one 0307 //! If the pattern contains a single asterisk, then the prefix 0308 //! of hName is compared with the characters before the '*' and 0309 //! the suffix of hName is compared with the character after. 0310 //! If the pattern ends with a plus, the all then pattern is 0311 //! taken as a hostname (less '+') and expanded to all possible 0312 //! hostnames and each one is compared with hName. If the 0313 //! pattern contains both, the asterisk rule is used first. 0314 //! If it contains neither then strict equality is used. 0315 //! 0316 //! @return Success: True, the pattern matches. 0317 //! Failure: False, no match found. 0318 //------------------------------------------------------------------------------ 0319 0320 static bool Match(const char *hName, const char *pattern); 0321 0322 //------------------------------------------------------------------------------ 0323 //! Get the fully qualified name of the current host. 0324 //! 0325 //! @param eName The name to be returned when the host name or its true 0326 //! address could not be returned. The pointer may be nil. 0327 //! @param eText When supplied will hold 0 if no errors occurred or error 0328 //! message text, in persistent storage, describing why the 0329 //! error-triggered alternate name was returned. 0330 //! If it contains neither then strict equality is used. 0331 //! 0332 //! @return An strdup() copy of the host name, address , or eName; unless eName 0333 //! is nil, in which case a nil pointer is returned. The caller is 0334 //! responsible for freeing any returned string using free(). 0335 //------------------------------------------------------------------------------ 0336 0337 static char *MyHostName(const char *eName="*unknown*", const char **eText=0); 0338 0339 //------------------------------------------------------------------------------ 0340 //! Get the supported network protocols. 0341 //! 0342 //! @param netqry An NetType enum specifying the protocol to inspect. 0343 //! @param eText When not nil, is where to place error message text. 0344 //! 0345 //! @return One the the NetProt enums (see below). When hasNone is returned 0346 //! and eText is not nill it will point to a static string that gives 0347 //! the reason. If the reason is a null string, the query was successful 0348 //! but returned no matching protocols. 0349 //------------------------------------------------------------------------------ 0350 0351 enum NetProt {hasNone = 0, //!< Unable to determine available protocols 0352 hasIPv4 = 1, //<! Has only IPv4 capability 0353 hasIPv6 = 2, //<! Has only IPv6 capability 0354 hasIP64 = 3, //<! Has IPv4 IPv6 capability (dual stack) 0355 hasPub4 = 4, //<! Has IPv4 public address (or'd with above) 0356 hasPub6 = 8 //<! Has IPv6 public address (or'd with above) 0357 }; 0358 0359 enum NetType {qryINET = 0,//!< Only consider internet protocols via DNS 0360 qryINIF = 1 //!< Only consider internet protocols via ifconfig 0361 }; 0362 0363 static NetProt NetConfig(NetType netquery=qryINET, const char **eText=0); 0364 0365 //------------------------------------------------------------------------------ 0366 //! Parse an IP or host name specification. 0367 //! 0368 //! @param hSpec the name or IP address of the host. As one of the following 0369 //! "[<ipv6>]:<port>", "<ipv4>:<port>", or "<name>:<port>". 0370 //! @param hName place where the starting address of the host is placed. 0371 //! @param hNend place where the ending address+1 is placed. This will 0372 //! point to either ']', ':', or a null byte. 0373 //! @param hPort place where the starting address of the port is placed. 0374 //! If no ":port" was found, this will contain *hNend. 0375 //! @param hPend place where the ending address+1 is placed. If no port 0376 //! If no ":port" was found, this will contain *hNend. 0377 //! 0378 //! @return Success: True. 0379 //! Failure: False, hSpec is not valid. Some output parameters may have 0380 //! been set but shlould be ignored. 0381 //------------------------------------------------------------------------------ 0382 0383 static bool Parse(const char *hSpec, const char **hName, const char **hNend, 0384 const char **hPort, const char **hPend); 0385 0386 //------------------------------------------------------------------------------ 0387 //! Obtain the numeric port associated with a file descriptor. 0388 //! 0389 //! @param fd the file descriptor number. 0390 //! @param eText when not null, the reason for a failure is returned. 0391 //! 0392 //! @return Success: The positive port number. 0393 //! Failure: 0 is returned and if eText is not null, the error message. 0394 //------------------------------------------------------------------------------ 0395 0396 static int Port(int fd, const char **eText=0); 0397 0398 //------------------------------------------------------------------------------ 0399 //! Obtain the protocol identifier. 0400 //! 0401 //! @param pName the name of the protocol (e.g. "tcp"). 0402 //! 0403 //! @return The protocol identifier. 0404 //------------------------------------------------------------------------------ 0405 0406 static int ProtoID(const char *pName); 0407 0408 //------------------------------------------------------------------------------ 0409 //! Obtain the numeric port corresponding to a symbolic name. 0410 //! 0411 //! @param sName the name of the service or a numeric port number. 0412 //! @param isUDP if true, returns the UDP service port o/w the TCP service 0413 //! @param eText when not null, the reason for a failure is returned. 0414 //! 0415 //! @return Success: The positive port number. 0416 //! Failure: 0 is returned and if eText is not null, the error message. 0417 //------------------------------------------------------------------------------ 0418 0419 static int ServPort(const char *sName, bool isUDP=false, const char **eText=0); 0420 0421 //------------------------------------------------------------------------------ 0422 //! Set the family and hints to be used in GetAddrs() with prefAuto. This is 0423 //! used within this class and by XrdNetAddr when the IP mode changes. It is 0424 //! meant for internal use only. 0425 //! 0426 //! @param aOpts Is one of the following from the AddrOpts enum: 0427 //! allIPMap - Use IPv6 and mapped IPv4 addrs (default) 0428 //! onlyIPv4 - Use only IPv4 addresses. 0429 //! prefAuto - Determine proper options based on configuration. 0430 //! 0431 //! @return The getaddrinfo() hints value that should be used. 0432 //------------------------------------------------------------------------------ 0433 0434 static int SetAuto(AddrOpts aOpts=allIPMap); 0435 0436 //------------------------------------------------------------------------------ 0437 //! Check if whether or not a host name represents more than one unique host. 0438 //! 0439 //! @param hSpec the host specification suitable for XrdNetAddr.Set(). 0440 //! @param eText When not nil, is where to place error message text. 0441 //! 0442 //! @return True is this is a simple single host. False if the name represensts 0443 //! more than one single host. 0444 //------------------------------------------------------------------------------ 0445 0446 static bool Singleton(const char *hSpec, const char **eText=0); 0447 0448 static bool ConnectWithTimeout(int sockfd, const struct sockaddr* clientAddr, size_t clientAddrLen,uint32_t timeout_sec, std::stringstream & errMsg); 0449 0450 //------------------------------------------------------------------------------ 0451 //! Constructor 0452 //------------------------------------------------------------------------------ 0453 0454 XrdNetUtils() {} 0455 0456 //------------------------------------------------------------------------------ 0457 //! Destructor 0458 //------------------------------------------------------------------------------ 0459 0460 ~XrdNetUtils() {} 0461 private: 0462 0463 static void FillAddr(XrdNetSpace::hpSpec &aBuff, XrdNetAddr *aVec, 0464 int *ordn=0, unsigned int rotNum=0); 0465 static 0466 const char *GetAInfo(XrdNetSpace::hpSpec &aBuff); 0467 static void GetHints(XrdNetSpace::hpSpec &aBuff, AddrOpts opts); 0468 static 0469 const char *GetHostPort(XrdNetSpace::hpSpec &aBuff, const char *hSpec, int pNum); 0470 static 0471 const char *getMyFQN(const char *&myDom); 0472 static int setET(const char **errtxt, int rc); 0473 static bool SetSockBlocking(int sockfd, bool blocking, std::stringstream & errMsg); 0474 static int autoFamily; 0475 static int autoHints; 0476 }; 0477 0478 XRDOUC_ENUM_OPERATORS(XrdNetUtils::AddrOpts) 0479 0480 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|