Back to home page

EIC code displayed by LXR

 
 

    


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