diff options
author | David Shaw <[email protected]> | 2003-08-25 02:18:45 +0000 |
---|---|---|
committer | David Shaw <[email protected]> | 2003-08-25 02:18:45 +0000 |
commit | 68c898372bd9882f5fe76e06a2a1608a43a9c8ca (patch) | |
tree | 9b73fc43422edb2ad3e3df189b35c25d6447e874 | |
parent | * mainproc.c (check_sig_and_print): Get the uid validity before printing (diff) | |
download | gnupg-68c898372bd9882f5fe76e06a2a1608a43a9c8ca.tar.gz gnupg-68c898372bd9882f5fe76e06a2a1608a43a9c8ca.zip |
* http.c (connect_server): Try and use getaddrinfo if it is available.
Try for IPv6 via getaddrinfo() or a IPv6-ized gethostbyname(). Suggested
by Jun-ichiro itojun Hagino.
-rw-r--r-- | util/ChangeLog | 6 | ||||
-rw-r--r-- | util/http.c | 126 |
2 files changed, 81 insertions, 51 deletions
diff --git a/util/ChangeLog b/util/ChangeLog index a6c4e7bdb..8b296a8c9 100644 --- a/util/ChangeLog +++ b/util/ChangeLog @@ -1,3 +1,9 @@ +2003-08-24 David Shaw <[email protected]> + + * http.c (connect_server): Try and use getaddrinfo if it is + available. Try for IPv6 via getaddrinfo() or a IPv6-ized + gethostbyname(). Suggested by Jun-ichiro itojun Hagino. + 2003-07-10 David Shaw <[email protected]> (from Werner on stable branch) * iobuf.c (check_special_filename): Replaced is isdigit by digitp diff --git a/util/http.c b/util/http.c index a328fbd0d..fcad64bd3 100644 --- a/util/http.c +++ b/util/http.c @@ -1,5 +1,5 @@ /* http.c - HTTP protocol handler - * Copyright (C) 1999, 2001 Free Software Foundation, Inc. + * Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -710,37 +710,30 @@ start_server() static int connect_server( const char *server, ushort port, unsigned int flags ) { - int sock,srv,srvcount=0; - struct sockaddr_in addr; - struct hostent *host=NULL; + int sock=-1,srv,srvcount=0,connected=0; struct srventry *srvlist=NULL; - memset(&addr,0,sizeof(addr)); - - addr.sin_family = AF_INET; - #ifdef __MINGW32__ - init_sockets (); - - if((sock=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET) - { - log_error("error creating socket: ec=%d\n",(int)WSAGetLastError()); - return -1; - } -#else - if((sock=socket(AF_INET,SOCK_STREAM,0))==-1) - { - log_error("error creating socket\n"); - return -1; - } -#endif + in_addr_t inaddr; +#warning check the windoze type -#ifdef __MINGW32__ + init_sockets(); /* Win32 gethostbyname doesn't handle IP addresses internally, so we try inet_addr first on that platform only. */ - if((addr.sin_addr.s_addr=inet_addr(server))!=SOCKET_ERROR) + if((inaddr=inet_addr(server))!=SOCKET_ERROR) { - addr.sin_port = htons(port); + struct sockaddr_in addr; + + memset(&addr,0,sizeof(addr)); + + if((sock=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET) + { + log_error("error creating socket: ec=%d\n",(int)WSAGetLastError()); + return -1; + } + + addr.sin_family=AF_INET; + addr.sin_port=htons(port); if(connect(sock,(struct sockaddr *)&addr,sizeof(addr))==0) return sock; @@ -776,63 +769,94 @@ connect_server( const char *server, ushort port, unsigned int flags ) srvcount=1; } +#ifdef HAVE_GETADDRINFO + for(srv=0;srv<srvcount;srv++) { - int i=0; + struct addrinfo hints,*res,*ai; + char portstr[6]; - addr.sin_port = htons(srvlist[srv].port); - - if((host=gethostbyname(srvlist[srv].target))==NULL) + sprintf(portstr,"%u",srvlist[srv].port); + memset(&hints,0,sizeof(hints)); + hints.ai_socktype=SOCK_STREAM; + if(getaddrinfo(srvlist[srv].target,portstr,&hints,&res)!=0) continue; - if(host) + for(ai=res;ai;ai=ai->ai_next) { - if(host->h_addrtype != AF_INET) + if((sock=socket(ai->ai_family,ai->ai_socktype,ai->ai_protocol))==-1) { - log_error ("%s: unknown address family\n", srvlist[srv].target); - sock_close(sock); - m_free(srvlist); + log_error("error creating socket: %s\n",strerror(errno)); return -1; } - if(host->h_length != 4 ) + if(connect(sock,ai->ai_addr,ai->ai_addrlen)==0) { - log_error ("%s: illegal address length\n", srvlist[srv].target); - sock_close(sock); - m_free(srvlist); - return -1; + connected=1; + break; } + } - /* Try all A records until one responds. */ - while(host->h_addr_list[i]) - { - memcpy(&addr.sin_addr,host->h_addr_list[i],host->h_length); + if(ai) + break; + } - if(connect(sock,(struct sockaddr *)&addr,sizeof(addr))==0) - break; +#else /* !HAVE_GETADDRINFO */ - i++; + for(srv=0;srv<srvcount;srv++) + { + int i=0; + struct hostent *host=NULL; + struct sockaddr_in addr; + + memset(&addr,0,sizeof(addr)); + + if((host=gethostbyname(srvlist[srv].target))==NULL) + continue; + + if((sock=socket(host->h_addrtype,SOCK_STREAM,0))==-1) + { + log_error("error creating socket: %s\n",strerror(errno)); + return -1; + } + + addr.sin_family=host->h_addrtype; + addr.sin_port=htons(srvlist[srv].port); + + /* Try all A records until one responds. */ + while(host->h_addr_list[i]) + { + memcpy(&addr.sin_addr,host->h_addr_list[i],host->h_length); + + if(connect(sock,(struct sockaddr *)&addr,sizeof(addr))==0) + { + connected=1; + break; } - if(host->h_addr_list[i]) - break; + i++; } + + if(host->h_addr_list[i]) + break; } +#endif /* !HAVE_GETADDRINFO */ m_free(srvlist); - if(!host) + if(!connected) { #ifdef __MINGW32__ log_error("%s: host not found: ec=%d\n",server,(int)WSAGetLastError()); #else log_error("%s: host not found\n",server); #endif - sock_close(sock); + if(sock!=-1) + sock_close(sock); return -1; } - return sock; + return sock; } |