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