Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:27:54

0001 #ifndef __XRDNETADDRINFO_HH__
0002 #define __XRDNETADDRINFO_HH__
0003 /******************************************************************************/
0004 /*                                                                            */
0005 /*                     X r d N e t A d d r I n f o . 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 <cinttypes>
0034 #include <cstdlib>
0035 #include <cstring>
0036 #include <netinet/in.h>
0037 #include <sys/socket.h>
0038 #include <sys/un.h>
0039 
0040 #include "XrdNet/XrdNetSockAddr.hh"
0041 #include "XrdSys/XrdSysPlatform.hh"
0042   
0043 //------------------------------------------------------------------------------
0044 //! The XrdNetAddrInfo class is meant to provide read/only access to members
0045 //! that only class XrdNetAddr can manipulate. This allows the generic use of
0046 //! the XrdNetAddr class but provides a means of exporting that information to
0047 //! other objects without allowing those objects to modify the information.
0048 //------------------------------------------------------------------------------
0049 
0050 struct addrinfo;
0051 class  XrdNetCache;
0052 
0053 class XrdNetAddrInfo
0054 {
0055 public:
0056 
0057 //------------------------------------------------------------------------------
0058 //! Provide the protocol languag being spoken (e.g. xroot, http, etc).
0059 //!
0060 //! @return Pointer to the protocol language being used. If unknown, nil ia
0061 //!         returned. Use the isUsingTLS() method to see if a secure version of
0062 //!         the protocol is being used.
0063 //------------------------------------------------------------------------------
0064 
0065 const char *Dialect() {return protName;}
0066 
0067 //------------------------------------------------------------------------------
0068 //! Provide our address family.
0069 //!
0070 //! @return Success: Returns AF_INET, AF_INET6, or AF_UNIX.
0071 //!         Failure: Returns 0, address is not valid.
0072 //------------------------------------------------------------------------------
0073 
0074 int         Family() const {return static_cast<int>(IP.Addr.sa_family);}
0075 
0076 //------------------------------------------------------------------------------
0077 //! Format our address into a supplied buffer with one of the following layouts
0078 //! (the ':<port>' or ':/path' can be omitted if desired, see fmtOpts param):
0079 //! IP.xx:   host_name:<port>
0080 //! IP.v4:   a.b.c.d:<port>
0081 //! IP.4to6: [::ffff:a.b.c.d]:<port>  | [::a.b.c.d]:<port>
0082 //! IP.v6:   [a:b:c:d:e:f:g:h]:<port>
0083 //! IP.Unix: localhost:/<path>
0084 //!
0085 //! @param  bAddr    address of buffer for result
0086 //! @param  bLen     length  of buffer
0087 //! @param  fmtType  specifies the type of format desired via fmtUse enum.
0088 //! @param  fmtOpts  additional formatting options (can be or'd):
0089 //!                  noPort    - do not append the port number to the address.
0090 //!                  noPortRaw - no port and no brackets for IPv6.
0091 //!                  old6Map4  - use deprecated IPV6 mapped format '[::x.x.x.x]'
0092 //!
0093 //! @return Success: The number of characters (less null) in Buff.
0094 //! @return Failure: 0 (buffer is too small or not a valid address). However,
0095 //!                  if bLen > 0 the buffer will contain a null terminated
0096 //!                  string of up to 8 question marks.
0097 //------------------------------------------------------------------------------
0098 
0099 enum fmtUse {fmtAuto=0, //!< Hostname if already resolved o/w use fmtAddr
0100              fmtName,   //!< Hostname if it is resolvable o/w use fmtAddr
0101              fmtAddr,   //!< Address using suitable ipv4 or ipv6 format
0102              fmtAdv6};  //!< Address only in ipv6 format
0103 
0104 static const int noPort    = 0x0000001; //!< Do not add port number
0105 static const int noPortRaw = 0x0000002; //!< Use raw address format (no port)
0106 static const int old6Map4  = 0x0000004; //!< Use deprecated IPV6 mapped format
0107 static const int prefipv4  = 0x0000008; //!< Use if mapped  IPV4 actual format
0108 
0109 int         Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0);
0110 
0111 //------------------------------------------------------------------------------
0112 //! Indicate whether or not our address is the loopback address. Use this
0113 //! method to gaurd against UDP packet spoofing.
0114 //!
0115 //! @return True:    This is     the loopback address.
0116 //! @return False:   This is not the loopback address.
0117 //------------------------------------------------------------------------------
0118 
0119 bool        isLoopback();
0120 
0121 //------------------------------------------------------------------------------
0122 //! Indicate whether or not a string is a possible hostname and not IP address.
0123 //! The return value does not aimply any kind of validity. For instance, a
0124 //! false return indicates this is not a valid hostname does not mean it is
0125 //! a valid IP address.
0126 //!
0127 //! @param name      The string to check.
0128 //!
0129 //! @return True:    This is     a possible hostname (i.e. not IP address).
0130 //! @return False:   This is not a possible hostname.
0131 //------------------------------------------------------------------------------
0132 
0133 static bool isHostName(const char *name);
0134 
0135 //------------------------------------------------------------------------------
0136 //! Indicate whether or not our address is if the desired type.
0137 //!
0138 //! @param ipType    The IP address version to test (see enum below).
0139 //!
0140 //! @return True:    This is     the address version of ipType.
0141 //! @return False:   This is not the address version of ipType.
0142 //------------------------------------------------------------------------------
0143 
0144 enum IPType {IPv4 = AF_INET, IPv6 = AF_INET6, IPuX = AF_UNIX};
0145 
0146 bool        isIPType(IPType ipType) const {return IP.Addr.sa_family == ipType;}
0147 
0148 //------------------------------------------------------------------------------
0149 //! Indicate whether or not our address is an IPv4 mapped to IPv6 address.
0150 //!
0151 //! @return True:  The address is     a mapped IPv4 address.
0152 //!         False: The address is not a mapped IPv4 address.
0153 //------------------------------------------------------------------------------
0154 
0155 bool        isMapped() const {return IP.Addr.sa_family == AF_INET6
0156                                   && IN6_IS_ADDR_V4MAPPED(&IP.v6.sin6_addr);
0157                              }
0158 
0159 //------------------------------------------------------------------------------
0160 //! Indicate whether or not our address is private.
0161 //!
0162 //! @return True:    This address is     private.
0163 //!         False:   This address is not private.
0164 //------------------------------------------------------------------------------
0165 
0166 bool        isPrivate();
0167 
0168 //------------------------------------------------------------------------------
0169 //! Indicate whether or not our address is registered in the DNS.
0170 //!
0171 //! @return True:    This address is     registered.
0172 //!         False:   This address is not registered.
0173 //------------------------------------------------------------------------------
0174 
0175 bool        isRegistered();
0176 
0177 //------------------------------------------------------------------------------
0178 //! Indicate whether or not the endpoint is using TLS for communications.
0179 //!
0180 //! @return True:    This address is     using TLS.
0181 //!         False:   This address is not using TLS.
0182 //------------------------------------------------------------------------------
0183 
0184 bool        isUsingTLS();
0185 
0186 //------------------------------------------------------------------------------
0187 //! Obtain the location of this address.
0188 //!
0189 //! @return !0       pointer to the unverified location information. Not all
0190 //!                  fields may be set.
0191 //! @return =0       location information is not available.
0192 //------------------------------------------------------------------------------
0193 
0194 struct LocInfo
0195       {unsigned char  Country[2]; //!< Two letter TLD country code
0196        unsigned char  Region;     //!< Region (may combine adjacent countries)
0197        unsigned char  Locale;     //!< Locale (may combine adjacent regions)
0198                 char  TimeZone;   //!< +/- hours from GMT (-128 if not set)
0199                 char  Flags;      //!< Flags
0200                 short Speed;      //!< I/F speed (Gb*1024/100)(not supported)
0201                 int   Latitude;   //!< Degrees +/- xx.xxxxxx  (not supported)
0202                 int   Longtitude; //!< Degrees +/- xx.xxxxxx  (not supported)
0203 
0204                 LocInfo() : Region(0), Locale(0), TimeZone(-128), Flags(0),
0205                             Speed(0), Latitude(0), Longtitude(0) {*Country = 0;}
0206 
0207        };
0208 
0209 const struct
0210 LocInfo    *Location() {return (addrLoc.Country[0] ? &addrLoc : 0);}
0211 
0212 //------------------------------------------------------------------------------
0213 //! Convert our IP address to the corresponding [host] name.
0214 //!
0215 //! @param  eName    value to return when the name cannot be determined.
0216 //! @param  eText    when not null, the reason for a failure is returned.
0217 //!
0218 //! @return Success: Pointer to the name or ip address with eText, if supplied,
0219 //!                  set to zero. The memory is owned by the object and is
0220 //!                  deleted when the object is deleted or Set() is called.
0221 //!         Failure: eName param and if eText is not zero, returns a pointer
0222 //!                  to a message describing the reason for the failure. The
0223 //!                  message is in persistent storage and cannot be modified.
0224 //------------------------------------------------------------------------------
0225 
0226 const char *Name(const char *eName=0, const char **eText=0);
0227 
0228 //------------------------------------------------------------------------------
0229 //! Provide a pointer to our socket address suitable for use in calls to methods
0230 //! that require our internal format of sock addr. A value is only returned for
0231 //! IPV6/4 addresses and is nill otherwise. The pointer refers to memory
0232 //! allocated by this object and becomes invalid should the object be deleted.
0233 //! Use SockSize() to get its logical length.
0234 //------------------------------------------------------------------------------
0235 
0236 const
0237 XrdNetSockAddr  *NetAddr() {return (sockAddr == (void *)&IP ? &IP : 0);}
0238 
0239 //------------------------------------------------------------------------------
0240 //! Return the port number for our address.
0241 //!
0242 //! @return Success: The port number, which may be 0 if not set.
0243 //!         Failure: -1 address is not an internet address or port is invalid.
0244 //------------------------------------------------------------------------------
0245 
0246 int         Port();
0247 
0248 //------------------------------------------------------------------------------
0249 //! Provide our protocol family.
0250 //!
0251 //! @return Success: Returns PF_INET, PF_INET6, or PF_UNIX.
0252 //!         Failure: Returns 0, address is not valid.
0253 //------------------------------------------------------------------------------
0254 
0255 int         Protocol() {return static_cast<int>(protType);}
0256 
0257 //------------------------------------------------------------------------------
0258 //! Check if the IP address in this object is the same as the one passed.
0259 //!
0260 //! @param ipAddr    points to the network address object to compare.
0261 //! @param plusPort  when true, port values must also match. In any case, both
0262 //!                  addresses must be of the same address family.
0263 //!
0264 //! @return Success: True  (addresses are     the same).
0265 //!         Failure: False (addresses are not the same).
0266 //!
0267 //! Note: implemented in terms of const version
0268 //------------------------------------------------------------------------------
0269 
0270 int         Same(const XrdNetAddrInfo *ipAddr, bool plusPort=false);
0271 
0272 //------------------------------------------------------------------------------
0273 //! Provide a pointer to our socket address suitable for use in calls to
0274 //! functions that require one (e.g. bind() etc). The pointer refers to memory
0275 //! allocated by this object and becomes invalid should the object be deleted
0276 //! or when Set() is called. Use SockSize() to get its length.
0277 //------------------------------------------------------------------------------
0278 
0279 const
0280 sockaddr   *SockAddr() {return sockAddr;}
0281 
0282 //------------------------------------------------------------------------------
0283 //! Provide the length of our socket adress. Useful for system calls needing it.
0284 //!
0285 //! @return Success: Returns the length of the address returned by SockAddr().
0286 //!         Failure: Returns 0, address is not valid.
0287 //------------------------------------------------------------------------------
0288 
0289 SOCKLEN_t   SockSize() {return static_cast<SOCKLEN_t>(addrSize);}
0290 
0291 //------------------------------------------------------------------------------
0292 //! Get the associated file descriptor.
0293 //!
0294 //! @return The associated file descriptor. If negative, no association exists.
0295 //------------------------------------------------------------------------------
0296 
0297 int         SockFD() {return (sockNum ? sockNum : -1);}
0298 
0299 //------------------------------------------------------------------------------
0300 //! Assignment operator
0301 //------------------------------------------------------------------------------
0302 
0303 XrdNetAddrInfo &operator=(XrdNetAddrInfo const &rhs)
0304                {if (&rhs != this)
0305                    {memmove(&IP, &rhs.IP, sizeof(IP));
0306                     addrSize = rhs.addrSize; sockNum = rhs.sockNum;
0307                     protType = rhs.protType;
0308                     protFlgs = rhs.protFlgs;
0309                     protName = rhs.protName;
0310                     if (hostName) free(hostName);
0311                     hostName = (rhs.hostName ? strdup(rhs.hostName):0);
0312                     addrLoc = rhs.addrLoc;
0313                     if (rhs.sockAddr != &rhs.IP.Addr)
0314                        {if (!unixPipe || sockAddr == &IP.Addr)
0315                            unixPipe = new sockaddr_un;
0316                         memcpy(unixPipe, rhs.unixPipe, sizeof(sockaddr_un));
0317                        } else sockAddr = &IP.Addr;
0318                    }
0319                 return *this;
0320                }
0321 
0322 //------------------------------------------------------------------------------
0323 //! Copy constructor
0324 //------------------------------------------------------------------------------
0325 
0326                XrdNetAddrInfo(XrdNetAddrInfo const &oP)
0327                              {hostName = 0;
0328                               unixPipe = 0;
0329                               *this = oP;
0330                              }
0331 
0332 //------------------------------------------------------------------------------
0333 //! Constructor
0334 //------------------------------------------------------------------------------
0335 
0336             XrdNetAddrInfo() : hostName(0), addrSize(0), protType(0),
0337                                protFlgs(0), sockNum(0), protName(0)
0338                            {IP.Addr.sa_family = 0;
0339                             sockAddr = &IP.Addr;
0340                            }
0341 
0342             XrdNetAddrInfo(const XrdNetAddrInfo *addr) : hostName(0) {*this = *addr;}
0343 
0344 //------------------------------------------------------------------------------
0345 //! Destructor
0346 //------------------------------------------------------------------------------
0347 
0348            ~XrdNetAddrInfo() {if (hostName) free(hostName);
0349                           if (sockAddr != &IP.Addr) delete unixPipe;
0350                          }
0351 
0352 protected:
0353        char               *LowCase(char *str);
0354        int                 QFill(char *bAddr, int bLen);
0355        int                 Resolve();
0356 
0357 static XrdNetCache        *dnsCache;
0358 
0359 XrdNetSockAddr             IP;
0360 union {struct sockaddr    *sockAddr;
0361        struct sockaddr_un *unixPipe;
0362       };
0363 char                      *hostName;
0364 LocInfo                    addrLoc;
0365 unsigned short             addrSize;
0366 unsigned char              protType;
0367 unsigned char              protFlgs;
0368 int                        sockNum;
0369 const char                *protName;
0370 
0371 // Flag settings in protFlgs
0372 //
0373 static const char          isTLS = 0x01; //!< Location using TLS
0374 };
0375 #endif