1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* 3 * Copyright (C) 2001,2002,2003,2004 by the Massachusetts Institute of Technology, 4 * Cambridge, MA, USA. All Rights Reserved. 5 * 6 * This software is being provided to you, the LICENSEE, by the 7 * Massachusetts Institute of Technology (M.I.T.) under the following 8 * license. By obtaining, using and/or copying this software, you agree 9 * that you have read, understood, and will comply with these terms and 10 * conditions: 11 * 12 * Export of this software from the United States of America may 13 * require a specific license from the United States Government. 14 * It is the responsibility of any person or organization contemplating 15 * export to obtain such a license before exporting. 16 * 17 * WITHIN THAT CONSTRAINT, permission to use, copy, modify and distribute 18 * this software and its documentation for any purpose and without fee or 19 * royalty is hereby granted, provided that you agree to comply with the 20 * following copyright notice and statements, including the disclaimer, and 21 * that the same appear on ALL copies of the software and documentation, 22 * including modifications that you make for internal use or for 23 * distribution: 24 * 25 * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS 26 * OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not 27 * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF 28 * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF 29 * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY 30 * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. 31 * 32 * The name of the Massachusetts Institute of Technology or M.I.T. may NOT 33 * be used in advertising or publicity pertaining to distribution of the 34 * software. Title to copyright in this software and any associated 35 * documentation shall at all times remain with M.I.T., and USER agrees to 36 * preserve same. 37 * 38 * Furthermore if you modify this software you must label 39 * your software as modified software and not distribute it in such a 40 * fashion that it might be confused with the original M.I.T. software. 41 */ 42 43 /* Approach overview: 44 45 If a system version is available but buggy, save handles to it (via 46 inline functions in a support library), redefine the names to refer 47 to library functions, and in those functions, call the system 48 versions and fix up the returned data. Use the native data 49 structures and flag values. 50 51 If no system version exists, use gethostby* and fake it. Define 52 the data structures and flag values locally. 53 54 55 On macOS, getaddrinfo results aren't cached (though 56 gethostbyname results are), so we need to build a cache here. Now 57 things are getting really messy. Because the cache is in use, we 58 use getservbyname, and throw away thread safety. (Not that the 59 cache is thread safe, but when we get locking support, that'll be 60 dealt with.) This code needs tearing down and rebuilding, soon. 61 62 63 Note that recent Windows developers' code has an interesting hack: 64 When you include the right header files, with the right set of 65 macros indicating system versions, you'll get an inline function 66 that looks for getaddrinfo (or whatever) in the system library, and 67 calls it if it's there. If it's not there, it fakes it with 68 gethostby* calls. 69 70 We're taking a simpler approach: A system provides these routines or 71 it does not. 72 73 Someday, we may want to take into account different versions (say, 74 different revs of GNU libc) where some are broken in one way, and 75 some work or are broken in another way. Cross that bridge when we 76 come to it. */ 77 78 /* To do, maybe: 79 80 + For AIX 4.3.3, using the RFC 2133 definition: Implement 81 AI_NUMERICHOST. It's not defined in the header file. 82 83 For certain (old?) versions of GNU libc, AI_NUMERICHOST is 84 defined but not implemented. 85 86 + Use gethostbyname2, inet_aton and other IPv6 or thread-safe 87 functions if available. But, see 88 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=135182 for one 89 gethostbyname2 problem on Linux. And besides, if a platform is 90 supporting IPv6 at all, they really should be doing getaddrinfo 91 by now. 92 93 + inet_ntop, inet_pton 94 95 + Conditionally export/import the function definitions, so a 96 library can have a single copy instead of multiple. 97 98 + Upgrade host requirements to include working implementations of 99 these functions, and throw all this away. Pleeease? :-) */ 100 101 #ifndef FAI_DEFINED 102 #define FAI_DEFINED 103 #include "port-sockets.h" 104 #include "socket-utils.h" 105 106 #if !defined (HAVE_GETADDRINFO) 107 108 #undef addrinfo 109 #define addrinfo my_fake_addrinfo 110 111 struct addrinfo { 112 int ai_family; /* PF_foo */ 113 int ai_socktype; /* SOCK_foo */ 114 int ai_protocol; /* 0, IPPROTO_foo */ 115 int ai_flags; /* AI_PASSIVE etc */ 116 size_t ai_addrlen; /* real length of socket address */ 117 char *ai_canonname; /* canonical name of host */ 118 struct sockaddr *ai_addr; /* pointer to variable-size address */ 119 struct addrinfo *ai_next; /* next in linked list */ 120 }; 121 122 #undef AI_PASSIVE 123 #define AI_PASSIVE 0x01 124 #undef AI_CANONNAME 125 #define AI_CANONNAME 0x02 126 #undef AI_NUMERICHOST 127 #define AI_NUMERICHOST 0x04 128 /* RFC 2553 says these are part of the interface for getipnodebyname, 129 not for getaddrinfo. RFC 3493 says they're part of the interface 130 for getaddrinfo, and getipnodeby* are deprecated. Our fake 131 getaddrinfo implementation here does IPv4 only anyways. */ 132 #undef AI_V4MAPPED 133 #define AI_V4MAPPED 0 134 #undef AI_ADDRCONFIG 135 #define AI_ADDRCONFIG 0 136 #undef AI_ALL 137 #define AI_ALL 0 138 #undef AI_DEFAULT 139 #define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG) 140 141 #ifndef NI_MAXHOST 142 #define NI_MAXHOST 1025 143 #endif 144 #ifndef NI_MAXSERV 145 #define NI_MAXSERV 32 146 #endif 147 148 #undef NI_NUMERICHOST 149 #define NI_NUMERICHOST 0x01 150 #undef NI_NUMERICSERV 151 #define NI_NUMERICSERV 0x02 152 #undef NI_NAMEREQD 153 #define NI_NAMEREQD 0x04 154 #undef NI_DGRAM 155 #define NI_DGRAM 0x08 156 #undef NI_NOFQDN 157 #define NI_NOFQDN 0x10 158 159 160 #undef EAI_ADDRFAMILY 161 #define EAI_ADDRFAMILY 1 162 #undef EAI_AGAIN 163 #define EAI_AGAIN 2 164 #undef EAI_BADFLAGS 165 #define EAI_BADFLAGS 3 166 #undef EAI_FAIL 167 #define EAI_FAIL 4 168 #undef EAI_FAMILY 169 #define EAI_FAMILY 5 170 #undef EAI_MEMORY 171 #define EAI_MEMORY 6 172 #undef EAI_NODATA 173 #define EAI_NODATA 7 174 #undef EAI_NONAME 175 #define EAI_NONAME 8 176 #undef EAI_SERVICE 177 #define EAI_SERVICE 9 178 #undef EAI_SOCKTYPE 179 #define EAI_SOCKTYPE 10 180 #undef EAI_SYSTEM 181 #define EAI_SYSTEM 11 182 183 #endif /* ! HAVE_GETADDRINFO */ 184 185 /* Fudge things on older gai implementations. */ 186 /* AIX 4.3.3 is based on RFC 2133; no AI_NUMERICHOST. */ 187 #ifndef AI_NUMERICHOST 188 # define AI_NUMERICHOST 0 189 #endif 190 /* Partial RFC 2553 implementations may not have AI_ADDRCONFIG and 191 friends, which RFC 3493 says are now part of the getaddrinfo 192 interface, and we'll want to use. */ 193 #ifndef AI_ADDRCONFIG 194 # define AI_ADDRCONFIG 0 195 #endif 196 #ifndef AI_V4MAPPED 197 # define AI_V4MAPPED 0 198 #endif 199 #ifndef AI_ALL 200 # define AI_ALL 0 201 #endif 202 #ifndef AI_DEFAULT 203 # define AI_DEFAULT (AI_ADDRCONFIG|AI_V4MAPPED) 204 #endif 205 206 #if defined(NEED_INSIXADDR_ANY) 207 /* If compiling with IPv6 support and C library does not define in6addr_any */ 208 extern const struct in6_addr krb5int_in6addr_any; 209 #undef in6addr_any 210 #define in6addr_any krb5int_in6addr_any 211 #endif 212 213 /* Call out to stuff defined in libkrb5support. */ 214 extern int krb5int_getaddrinfo (const char *node, const char *service, 215 const struct addrinfo *hints, 216 struct addrinfo **aip); 217 extern void krb5int_freeaddrinfo (struct addrinfo *ai); 218 extern const char *krb5int_gai_strerror(int err); 219 extern int krb5int_getnameinfo (const struct sockaddr *sa, socklen_t salen, 220 char *hbuf, size_t hbuflen, 221 char *sbuf, size_t sbuflen, 222 int flags); 223 #ifndef IMPLEMENT_FAKE_GETADDRINFO 224 #undef getaddrinfo 225 #define getaddrinfo krb5int_getaddrinfo 226 #undef freeaddrinfo 227 #define freeaddrinfo krb5int_freeaddrinfo 228 #undef gai_strerror 229 #define gai_strerror krb5int_gai_strerror 230 #undef getnameinfo 231 #define getnameinfo krb5int_getnameinfo 232 #endif 233 234 #endif /* FAI_DEFINED */ 235