00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "curl_setup.h"
00024
00025 #ifdef HAVE_NETINET_IN_H
00026 #include <netinet/in.h>
00027 #endif
00028 #ifdef HAVE_NETDB_H
00029 #include <netdb.h>
00030 #endif
00031 #ifdef HAVE_ARPA_INET_H
00032 #include <arpa/inet.h>
00033 #endif
00034 #ifdef __VMS
00035 #include <in.h>
00036 #include <inet.h>
00037 #endif
00038
00039 #ifdef HAVE_PROCESS_H
00040 #include <process.h>
00041 #endif
00042
00043 #include "urldata.h"
00044 #include "sendf.h"
00045 #include "hostip.h"
00046 #include "hash.h"
00047 #include "share.h"
00048 #include "strerror.h"
00049 #include "url.h"
00050 #include "inet_pton.h"
00051 #include "connect.h"
00052
00053 #include "curl_printf.h"
00054 #include "curl_memory.h"
00055 #include "memdebug.h"
00056
00057
00058
00059
00060 #ifdef CURLRES_IPV6
00061
00062 #if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
00074 GETNAMEINFO_TYPE_ARG2 salen,
00075 char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
00076 char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
00077 GETNAMEINFO_TYPE_ARG7 flags,
00078 int line, const char *source)
00079 {
00080 int res = (getnameinfo)(sa, salen,
00081 host, hostlen,
00082 serv, servlen,
00083 flags);
00084 if(0 == res)
00085
00086 curl_memlog("GETNAME %s:%d getnameinfo()\n",
00087 source, line);
00088 else
00089 curl_memlog("GETNAME %s:%d getnameinfo() failed = %d\n",
00090 source, line, res);
00091 return res;
00092 }
00093 #endif
00094
00095
00096
00097
00098 bool Curl_ipv6works(void)
00099 {
00100
00101
00102
00103 static int ipv6_works = -1;
00104 if(-1 == ipv6_works) {
00105
00106 curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
00107 if(s == CURL_SOCKET_BAD)
00108
00109 ipv6_works = 0;
00110 else {
00111 ipv6_works = 1;
00112 Curl_closesocket(NULL, s);
00113 }
00114 }
00115 return (ipv6_works>0)?TRUE:FALSE;
00116 }
00117
00118
00119
00120
00121
00122 bool Curl_ipvalid(struct connectdata *conn)
00123 {
00124 if(conn->ip_version == CURL_IPRESOLVE_V6)
00125 return Curl_ipv6works();
00126
00127 return TRUE;
00128 }
00129
00130 #if defined(CURLRES_SYNCH)
00131
00132 #ifdef DEBUG_ADDRINFO
00133 static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
00134 {
00135 printf("dump_addrinfo:\n");
00136 for(; ai; ai = ai->ai_next) {
00137 char buf[INET6_ADDRSTRLEN];
00138
00139 printf(" fam %2d, CNAME %s, ",
00140 ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
00141 if(Curl_printable_address(ai, buf, sizeof(buf)))
00142 printf("%s\n", buf);
00143 else
00144 printf("failed; %s\n", Curl_strerror(conn, SOCKERRNO));
00145 }
00146 }
00147 #else
00148 #define dump_addrinfo(x,y) Curl_nop_stmt
00149 #endif
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
00161 const char *hostname,
00162 int port,
00163 int *waitp)
00164 {
00165 struct addrinfo hints;
00166 Curl_addrinfo *res;
00167 int error;
00168 char sbuf[12];
00169 char *sbufptr = NULL;
00170 #ifndef USE_RESOLVE_ON_IPS
00171 char addrbuf[128];
00172 #endif
00173 int pf;
00174 #if !defined(CURL_DISABLE_VERBOSE_STRINGS)
00175 struct Curl_easy *data = conn->data;
00176 #endif
00177
00178 *waitp = 0;
00179
00180
00181 switch(conn->ip_version) {
00182 case CURL_IPRESOLVE_V4:
00183 pf = PF_INET;
00184 break;
00185 case CURL_IPRESOLVE_V6:
00186 pf = PF_INET6;
00187 break;
00188 default:
00189 pf = PF_UNSPEC;
00190 break;
00191 }
00192
00193 if((pf != PF_INET) && !Curl_ipv6works())
00194
00195 pf = PF_INET;
00196
00197 memset(&hints, 0, sizeof(hints));
00198 hints.ai_family = pf;
00199 hints.ai_socktype = conn->socktype;
00200
00201 #ifndef USE_RESOLVE_ON_IPS
00202
00203
00204
00205
00206 if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
00207 (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
00208
00209 hints.ai_flags = AI_NUMERICHOST;
00210 }
00211 #endif
00212
00213 if(port) {
00214 snprintf(sbuf, sizeof(sbuf), "%d", port);
00215 sbufptr=sbuf;
00216 }
00217
00218 error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res);
00219 if(error) {
00220 infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
00221 return NULL;
00222 }
00223
00224 if(port) {
00225 Curl_addrinfo_set_port(res, port);
00226 }
00227
00228 dump_addrinfo(conn, res);
00229
00230 return res;
00231 }
00232 #endif
00233
00234 #endif