]> 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                                                         /*{{{*/
 // -*- 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.
 /* ######################################################################
 
    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.
    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                                                       /*{{{*/
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
index 4bd7975a47cd4b34a103514e6a6fd0738985d441..0c0acf60ff1e35c3f34c4d828bd9c2b0ffcf634d 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // -*- 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.
 /* ######################################################################
 
    HTTP Aquire Method - This is the HTTP aquire method for APT.
 #include <errno.h>
 
 // Internet stuff
 #include <errno.h>
 
 // Internet stuff
-#include <netinet/in.h>
+/*#include <netinet/in.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
-#include <netdb.h>
+#include <netdb.h>*/
 
 
+#include "rfc2553emu.h"
 #include "http.h"
 #include "http.h"
+
                                                                        /*}}}*/
 
 string HttpMethod::FailFile;
                                                                        /*}}}*/
 
 string HttpMethod::FailFile;
@@ -258,7 +260,8 @@ ServerState::ServerState(URI Srv,HttpMethod *Owner) : Owner(Owner),
 // ---------------------------------------------------------------------
 /* This opens a connection to the server. */
 string LastHost;
 // ---------------------------------------------------------------------
 /* 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.
 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
       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)
    {
    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 */
    /* 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
    {
       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());
         return _error->Error("Could not resolve '%s'",Host.c_str());
+
       LastHost = Host;
       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
    // 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");
       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);
    SetNonBlock(ServerFd,true);
-   if (connect(ServerFd,(sockaddr *)&server,sizeof(server)) < 0 &&
+   if (connect(ServerFd,LastHostAddr->ai_addr,LastHostAddr->ai_addrlen) < 0 &&
        errno != EINPROGRESS)
        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 */
 
    /* 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
 PROGRAM=http
 SLIBS = -lapt-pkg 
 LIB_MAKES = apt-pkg/makefile
-SOURCE = http.cc
+SOURCE = http.cc rfc2553emu.cc
 include $(PROGRAM_H)
 
 # The ftp method
 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