00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "setup.h"
00025
00026 #include <string.h>
00027
00028 #ifdef NEED_MALLOC_H
00029 #include <malloc.h>
00030 #endif
00031 #ifdef HAVE_SYS_SOCKET_H
00032 #include <sys/socket.h>
00033 #endif
00034 #ifdef HAVE_NETINET_IN_H
00035 #include <netinet/in.h>
00036 #endif
00037 #ifdef HAVE_NETDB_H
00038 #include <netdb.h>
00039 #endif
00040 #ifdef HAVE_ARPA_INET_H
00041 #include <arpa/inet.h>
00042 #endif
00043 #ifdef HAVE_STDLIB_H
00044 #include <stdlib.h>
00045 #endif
00046 #ifdef HAVE_UNISTD_H
00047 #include <unistd.h>
00048 #endif
00049 #ifdef VMS
00050 #include <in.h>
00051 #include <inet.h>
00052 #include <stdlib.h>
00053 #endif
00054
00055 #ifdef HAVE_SETJMP_H
00056 #include <setjmp.h>
00057 #endif
00058
00059 #ifdef HAVE_PROCESS_H
00060 #include <process.h>
00061 #endif
00062
00063 #include "urldata.h"
00064 #include "sendf.h"
00065 #include "hostip.h"
00066 #include "hash.h"
00067 #include "share.h"
00068 #include "strerror.h"
00069 #include "url.h"
00070 #include "inet_pton.h"
00071 #include "connect.h"
00072
00073 #define _MPRINTF_REPLACE
00074 #include <curl/mprintf.h>
00075
00076 #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
00077 #include "inet_ntoa_r.h"
00078 #endif
00079
00080 #include "memory.h"
00081
00082 #include "memdebug.h"
00083
00084
00085
00086
00087 #ifdef CURLRES_IPV6
00088 #ifndef CURLRES_ARES
00089
00090
00091
00092
00093
00094 void Curl_freeaddrinfo(Curl_addrinfo *p)
00095 {
00096 freeaddrinfo(p);
00097 }
00098
00099 #ifdef CURLRES_ASYNCH
00100
00101
00102
00103
00104
00105 Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port)
00106 {
00107 (void) port;
00108 return (Curl_addrinfo*)orig;
00109 }
00110 #endif
00111 #endif
00112
00113 #ifdef CURLDEBUG
00114
00115
00116
00117
00118 int curl_dogetaddrinfo(const char *hostname, const char *service,
00119 struct addrinfo *hints,
00120 struct addrinfo **result,
00121 int line, const char *source)
00122 {
00123 int res=(getaddrinfo)(hostname, service, hints, result);
00124 if(0 == res) {
00125
00126 if(logfile)
00127 fprintf(logfile, "ADDR %s:%d getaddrinfo() = %p\n",
00128 source, line, (void *)*result);
00129 }
00130 else {
00131 if(logfile)
00132 fprintf(logfile, "ADDR %s:%d getaddrinfo() failed\n",
00133 source, line);
00134 }
00135 return res;
00136 }
00137
00138
00139
00140
00141
00142 #ifdef HAVE_GETNAMEINFO
00143 int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
00144 GETNAMEINFO_TYPE_ARG2 salen,
00145 char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
00146 char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
00147 GETNAMEINFO_TYPE_ARG7 flags,
00148 int line, const char *source)
00149 {
00150 int res = (getnameinfo)(sa, salen,
00151 host, hostlen,
00152 serv, servlen,
00153 flags);
00154 if(0 == res) {
00155
00156 if(logfile)
00157 fprintf(logfile, "GETNAME %s:%d getnameinfo()\n",
00158 source, line);
00159 }
00160 else {
00161 if(logfile)
00162 fprintf(logfile, "GETNAME %s:%d getnameinfo() failed = %d\n",
00163 source, line, res);
00164 }
00165 return res;
00166 }
00167 #endif
00168
00169 void curl_dofreeaddrinfo(struct addrinfo *freethis,
00170 int line, const char *source)
00171 {
00172 (freeaddrinfo)(freethis);
00173 if(logfile)
00174 fprintf(logfile, "ADDR %s:%d freeaddrinfo(%p)\n",
00175 source, line, (void *)freethis);
00176 }
00177 #endif
00178
00179
00180
00181
00182
00183 bool Curl_ipvalid(struct SessionHandle *data)
00184 {
00185 if(data->set.ip_version == CURL_IPRESOLVE_V6) {
00186
00187 curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
00188 if (s == CURL_SOCKET_BAD)
00189
00190 return FALSE;
00191 sclose(s);
00192 }
00193 return TRUE;
00194 }
00195
00196 #if !defined(USE_THREADING_GETADDRINFO) && !defined(CURLRES_ARES)
00197
00198 #ifdef DEBUG_ADDRINFO
00199 static void dump_addrinfo(struct connectdata *conn, const struct addrinfo *ai)
00200 {
00201 printf("dump_addrinfo:\n");
00202 for ( ; ai; ai = ai->ai_next) {
00203 char buf[INET6_ADDRSTRLEN];
00204
00205 printf(" fam %2d, CNAME %s, ",
00206 ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
00207 if (Curl_printable_address(ai, buf, sizeof(buf)))
00208 printf("%s\n", buf);
00209 else
00210 printf("failed; %s\n", Curl_strerror(conn, SOCKERRNO));
00211 }
00212 }
00213 #else
00214 #define dump_addrinfo(x,y)
00215 #endif
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
00227 const char *hostname,
00228 int port,
00229 int *waitp)
00230 {
00231 struct addrinfo hints, *res;
00232 int error;
00233 char sbuf[NI_MAXSERV];
00234 char *sbufptr = NULL;
00235 char addrbuf[128];
00236 curl_socket_t s;
00237 int pf;
00238 struct SessionHandle *data = conn->data;
00239
00240 *waitp=0;
00241
00242
00243 s = socket(PF_INET6, SOCK_DGRAM, 0);
00244 if (s == CURL_SOCKET_BAD) {
00245
00246
00247
00248
00249 pf = PF_INET;
00250 }
00251 else {
00252
00253
00254
00255 sclose(s);
00256
00257
00258
00259
00260 switch(data->set.ip_version) {
00261 case CURL_IPRESOLVE_V4:
00262 pf = PF_INET;
00263 break;
00264 case CURL_IPRESOLVE_V6:
00265 pf = PF_INET6;
00266 break;
00267 default:
00268 pf = PF_UNSPEC;
00269 break;
00270 }
00271 }
00272
00273 memset(&hints, 0, sizeof(hints));
00274 hints.ai_family = pf;
00275 hints.ai_socktype = conn->socktype;
00276
00277 if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
00278 (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
00279
00280 hints.ai_flags = AI_NUMERICHOST;
00281 }
00282 #ifdef HAVE_GSSAPI
00283 if(conn->data->set.krb)
00284
00285 hints.ai_flags |= AI_CANONNAME;
00286 #endif
00287
00288 if(port) {
00289 snprintf(sbuf, sizeof(sbuf), "%d", port);
00290 sbufptr=sbuf;
00291 }
00292 error = getaddrinfo(hostname, sbufptr, &hints, &res);
00293 if (error) {
00294 infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
00295 return NULL;
00296 }
00297
00298 dump_addrinfo(conn, res);
00299
00300 return res;
00301 }
00302 #endif
00303 #endif
00304