aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--util/ChangeLog6
-rw-r--r--util/http.c126
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;
}