]> git.saurik.com Git - apt.git/commitdiff
Changed to using rfc2553 name resolution for http
authorArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:53:50 +0000 (16:53 +0000)
committerArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:53:50 +0000 (16:53 +0000)
Author: jgg
Date: 1999-05-25 05:56:24 GMT
Changed to using rfc2553 name resolution for http

methods/ftp.cc
methods/http.cc
methods/makefile
methods/rfc2553emu.cc [new file with mode: 0644]
methods/rfc2553emu.h [new file with mode: 0644]

index a93777488021201aa6b4d403b9b89099dabe4212..b567875e1780470cbd9406b467e104974821e3d4 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: ftp.cc,v 1.9 1999/05/23 23:30:09 jgg Exp $
+// $Id: ftp.cc,v 1.10 1999/05/25 05:56:24 jgg Exp $
 /* ######################################################################
 
    HTTP Aquire Method - This is the FTP aquire method for APT.
@@ -9,7 +9,9 @@
    at all. Commands are sent syncronously with the FTP server (as the
    rfc recommends, but it is not really necessary..) and no tricks are
    done to speed things along.
-                                                              
+                       
+   RFC 2428 describes the IPv6 FTP behavior
+   
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
index 4bd7975a47cd4b34a103514e6a6fd0738985d441..0c0acf60ff1e35c3f34c4d828bd9c2b0ffcf634d 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: http.cc,v 1.30 1999/04/04 02:02:04 jgg Exp $
+// $Id: http.cc,v 1.31 1999/05/25 05:56:24 jgg Exp $
 /* ######################################################################
 
    HTTP Aquire Method - This is the HTTP aquire method for APT.
 #include <errno.h>
 
 // Internet stuff
-#include <netinet/in.h>
+/*#include <netinet/in.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
-#include <netdb.h>
+#include <netdb.h>*/
 
+#include "rfc2553emu.h"
 #include "http.h"
+
                                                                        /*}}}*/
 
 string HttpMethod::FailFile;
@@ -258,7 +260,8 @@ ServerState::ServerState(URI Srv,HttpMethod *Owner) : Owner(Owner),
 // ---------------------------------------------------------------------
 /* This opens a connection to the server. */
 string LastHost;
-in_addr LastHostA;
+int LastPort = 0;
+struct addrinfo *LastHostAddr = 0;
 bool ServerState::Open()
 {
    // Use the already open connection if possible.
@@ -288,7 +291,7 @@ bool ServerState::Open()
       Proxy = getenv("http_proxy");
    
    // Determine what host and port to use based on the proxy settings
-   int Port = 80;
+   int Port = 0;
    string Host;   
    if (Proxy.empty() == true)
    {
@@ -306,33 +309,46 @@ bool ServerState::Open()
    /* We used a cached address record.. Yes this is against the spec but
       the way we have setup our rotating dns suggests that this is more
       sensible */
-   if (LastHost != Host)
+   if (LastHost != Host || LastPort != Port)
    {
       Owner->Status("Connecting to %s",Host.c_str());
 
       // Lookup the host
-      hostent *Addr = gethostbyname(Host.c_str());
-      if (Addr == 0 || Addr->h_addr_list[0] == 0)
+      char S[30] = "http";
+      if (Port != 0)
+        snprintf(S,sizeof(S),"%u",Port);
+
+      // Free the old address structure
+      if (LastHostAddr != 0)
+      {
+        freeaddrinfo(LastHostAddr);
+        LastHostAddr = 0;
+      }
+      
+      // We only understand SOCK_STREAM sockets.
+      struct addrinfo Hints;
+      memset(&Hints,0,sizeof(Hints));
+      Hints.ai_socktype = SOCK_STREAM;
+      
+      // Resolve both the host and service simultaneously
+      if (getaddrinfo(Host.c_str(),S,&Hints,&LastHostAddr) != 0 ||
+         LastHostAddr == 0)
         return _error->Error("Could not resolve '%s'",Host.c_str());
+
       LastHost = Host;
-      LastHostA = *(in_addr *)(Addr->h_addr_list[0]);
+      LastPort = Port;
    }
-   
-   Owner->Status("Connecting to %s (%s)",Host.c_str(),inet_ntoa(LastHostA));
-   
+      
+   // Connect to the server
    // Get a socket
-   if ((ServerFd = socket(AF_INET,SOCK_STREAM,0)) < 0)
+//   Owner->Status("Connecting to %s (%s)",Host.c_str(),inet_ntoa(LastHostA));
+   if ((ServerFd = socket(LastHostAddr->ai_family,LastHostAddr->ai_socktype,
+                         LastHostAddr->ai_protocol)) < 0)
       return _error->Errno("socket","Could not create a socket");
-   
-   // Connect to the server
-   struct sockaddr_in server;
-   server.sin_family = AF_INET;
-   server.sin_port = htons(Port);
-   server.sin_addr = LastHostA;
    SetNonBlock(ServerFd,true);
-   if (connect(ServerFd,(sockaddr *)&server,sizeof(server)) < 0 &&
+   if (connect(ServerFd,LastHostAddr->ai_addr,LastHostAddr->ai_addrlen) < 0 &&
        errno != EINPROGRESS)
-      return _error->Errno("socket","Could not create a socket");
+      return _error->Errno("connect","Connect initiate the connection");
 
    /* This implements a timeout for connect by opening the connection
       nonblocking */
index dc6b88780d51301cc208f7554c6b41732b425cf8..2cfc15cae53b5f1a3bb461ca9d629d9a97b6d9da 100644 (file)
@@ -38,7 +38,7 @@ include $(PROGRAM_H)
 PROGRAM=http
 SLIBS = -lapt-pkg 
 LIB_MAKES = apt-pkg/makefile
-SOURCE = http.cc
+SOURCE = http.cc rfc2553emu.cc
 include $(PROGRAM_H)
 
 # The ftp method
diff --git a/methods/rfc2553emu.cc b/methods/rfc2553emu.cc
new file mode 100644 (file)
index 0000000..66fe781
--- /dev/null
@@ -0,0 +1,139 @@
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: rfc2553emu.cc,v 1.1 1999/05/25 05:56:24 jgg Exp $
+/* ######################################################################
+
+   RFC 2553 Emulation - Provides emulation for RFC 2553 getaddrinfo,
+                        freeaddrinfo and getnameinfo
+   
+   Originally written by Jason Gunthorpe <jgg@debian.org> and placed into
+   the Public Domain, do with it what you will.
+   
+   ##################################################################### */
+                                                                       /*}}}*/
+#include "rfc2553emu.h"
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <iostream.h>
+
+#ifndef HAVE_GETADDRINFO
+int getaddrinfo(const char *nodename, const char *servname,
+               const struct addrinfo *hints,
+               struct addrinfo **res)
+{
+   struct addrinfo **Result;
+   hostent *Addr;
+   unsigned int Port;
+   int Proto;
+   const char *End;
+   char **CurAddr;
+   
+   Addr = gethostbyname(nodename);
+   if (Addr == 0)
+   {
+      if (h_errno == TRY_AGAIN)
+        return EAI_AGAIN;
+      if (h_errno == NO_RECOVERY)
+        return EAI_FAIL;
+      return EAI_NONAME;
+   }
+   
+   // No A records 
+   if (Addr->h_addr_list[0] == 0)
+      return EAI_NONAME;
+
+   // Try to convert the service as a number
+   Port = htons(strtol(servname,(char **)&End,0));
+   Proto = SOCK_STREAM;
+   
+   if (hints != 0 && hints->ai_socktype != 0)
+      Proto = hints->ai_socktype;
+   
+   // Not a number, must be a name.
+   if (End != servname + strlen(End))
+   {
+      struct servent *Srv = 0;
+      
+      // Do a lookup in the service database
+      if (hints == 0 || hints->ai_socktype == SOCK_STREAM)
+        Srv = getservbyname(servname,"tcp");
+      if (hints != 0 && hints->ai_socktype == SOCK_DGRAM)
+        Srv = getservbyname(servname,"udp");
+      if (Srv == 0)
+        return EAI_NONAME;  
+      
+      // Get the right protocol
+      Port = Srv->s_port;
+      if (strcmp(Srv->s_proto,"tcp") == 0)
+        Proto = SOCK_STREAM;
+      else
+      {
+        if (strcmp(Srv->s_proto,"udp") == 0)
+           Proto = SOCK_DGRAM;
+         else
+           return EAI_NONAME;
+      }      
+      
+      if (hints != 0 && hints->ai_socktype != Proto && 
+         hints->ai_socktype != 0)
+        return EAI_SERVICE;
+   }
+   
+   // Start constructing the linked list
+   *res = 0;
+   for (CurAddr = Addr->h_addr_list; *CurAddr != 0; CurAddr++)
+   {
+      // New result structure
+      *Result = (struct addrinfo *)calloc(sizeof(**Result),1);
+      if (*Result == 0)
+      {
+        freeaddrinfo(*res);
+        return EAI_MEMORY;
+      }
+      if (*res == 0)
+        *res = *Result;
+      
+      (*Result)->ai_family = AF_INET;
+      (*Result)->ai_socktype = Proto;
+
+      // If we have the IPPROTO defines we can set the protocol field
+      #ifdef IPPROTO_TCP
+      if (Proto == SOCK_STREAM)
+        (*Result)->ai_protocol = IPPROTO_TCP;
+      if (Proto == SOCK_DGRAM)
+        (*Result)->ai_protocol = IPPROTO_UDP;
+      #endif
+
+      // Allocate space for the address
+      (*Result)->ai_addrlen = sizeof(struct sockaddr_in);
+      (*Result)->ai_addr = (struct sockaddr *)calloc(sizeof(sockaddr_in),1);
+      if ((*Result)->ai_addr == 0)
+      {
+        freeaddrinfo(*res);
+        return EAI_MEMORY;
+      }
+      
+      // Set the address
+      ((struct sockaddr_in *)(*Result)->ai_addr)->sin_family = AF_INET;
+      ((struct sockaddr_in *)(*Result)->ai_addr)->sin_port = Port;
+      ((struct sockaddr_in *)(*Result)->ai_addr)->sin_addr = *(in_addr *)(*CurAddr);
+
+      Result = &(*Result)->ai_next;
+   }
+   
+   return 0;
+}
+
+void freeaddrinfo(struct addrinfo *ai)
+{
+   struct addrinfo *Tmp;
+   while (ai != 0)
+   {
+      free(ai->ai_addr);
+      Tmp = ai;
+      ai = ai->ai_next;
+      free(ai);
+   }
+}
+
+#endif // HAVE_GETADDRINFO
diff --git a/methods/rfc2553emu.h b/methods/rfc2553emu.h
new file mode 100644 (file)
index 0000000..e24e7a3
--- /dev/null
@@ -0,0 +1,85 @@
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: rfc2553emu.h,v 1.1 1999/05/25 05:56:24 jgg Exp $
+/* ######################################################################
+
+   RFC 2553 Emulation - Provides emulation for RFC 2553 getaddrinfo,
+                        freeaddrinfo and getnameinfo
+   
+   These functions are necessary to write portable protocol independent
+   networking. They transparently support IPv4, IPv6 and probably many 
+   other protocols too. This implementation is needed when the host does 
+   not support these standards. It implements a simple wrapper that 
+   basically supports only IPv4. 
+
+   Perfect emulation is not provided, but it is passable..
+   
+   Originally written by Jason Gunthorpe <jgg@debian.org> and placed into
+   the Public Domain, do with it what you will.
+  
+   ##################################################################### */
+                                                                       /*}}}*/
+#ifndef RFC2553EMU_H
+#define RFC2553EMU_H
+
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+// Autosense getaddrinfo
+#if defined(AI_PASSIVE) && defined(EAI_NONAME)
+#define HAVE_GETADDRINFO
+#endif
+
+// getaddrinfo support?
+#ifndef HAVE_GETADDRINFO
+  #error Boink
+
+  // Renamed to advoid type clashing.. (for debugging)
+  struct addrinfo_emu
+  {   
+     int     ai_flags;     /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
+     int     ai_family;    /* PF_xxx */
+     int     ai_socktype;  /* SOCK_xxx */
+     int     ai_protocol;  /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+     size_t  ai_addrlen;   /* length of ai_addr */
+     char   *ai_canonname; /* canonical name for nodename */
+     struct sockaddr  *ai_addr; /* binary address */
+     struct addrinfo  *ai_next; /* next structure in linked list */
+  };
+  #define addinfo addrinfo_emu
+
+  int getaddrinfo(const char *nodename, const char *servname,
+                  const struct addrinfo *hints,
+                  struct addrinfo **res);
+  void freeaddrinfo(struct addrinfo *ai);
+
+  #ifndef AI_PASSIVE
+  #define AI_PASSIVE (1<<1)
+  #endif
+  
+  #ifndef EAI_NONAME
+  #define EAI_NONAME     -1
+  #define EAI_AGAIN      -2
+  #define EAI_FAIL       -3
+  #define EAI_NODATA     -4
+  #define EAI_FAMILY     -5
+  #define EAI_SOCKTYPE   -6
+  #define EAI_SERVICE    -7
+  #define EAI_ADDRFAMILY -8
+  #define EAI_ADDRFAMILY -8
+  #define EAI_SYSTEM     -10
+  #endif
+
+#endif
+
+// getnameinfo support (glibc2.0 has getaddrinfo only)
+#ifndef HAVE_GETNAMEINFO
+
+  int getnameinfo(const struct sockaddr *sa, socklen_t salen,
+                 char *host, size_t hostlen,
+                 char *serv, size_t servlen,
+                 int flags);
+#endif
+
+#endif