* http.c (connect_server): Try and use getaddrinfo if it is available.
authorDavid Shaw <dshaw@jabberwocky.com>
Mon, 25 Aug 2003 02:18:45 +0000 (02:18 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Mon, 25 Aug 2003 02:18:45 +0000 (02:18 +0000)
Try for IPv6 via getaddrinfo() or a IPv6-ized gethostbyname().  Suggested
by Jun-ichiro itojun Hagino.

util/ChangeLog
util/http.c

index a6c4e7b..8b296a8 100644 (file)
@@ -1,3 +1,9 @@
+2003-08-24  David Shaw  <dshaw@jabberwocky.com>
+
+       * 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  <dshaw@jabberwocky.com> (from Werner on stable branch)
 
        * iobuf.c (check_special_filename): Replaced is isdigit by digitp
index a328fbd..fcad64b 100644 (file)
@@ -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;
 }