X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/e8d72d2faa67283a2c7e691c1a7a440c4cdd179f..c4d749b78a46e69887ec9662851f180e587f2d34:/methods/connect.cc diff --git a/methods/connect.cc b/methods/connect.cc index c5d57a99f..e2cbf4f5c 100644 --- a/methods/connect.cc +++ b/methods/connect.cc @@ -11,15 +11,19 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#include "connect.h" +#include + #include #include +#include +#include +#include #include #include #include #include - +#include #include #include @@ -29,17 +33,18 @@ #include #include +#include "connect.h" #include "rfc2553emu.h" #include /*}}}*/ -static string LastHost; +static std::string LastHost; static int LastPort = 0; static struct addrinfo *LastHostAddr = 0; static struct addrinfo *LastUsed = 0; // Set of IP/hostnames that we timed out before or couldn't resolve -static std::set bad_addr; +static std::set bad_addr; // RotateDNS - Select a new server from a DNS rotation /*{{{*/ // --------------------------------------------------------------------- @@ -56,7 +61,7 @@ void RotateDNS() // DoConnect - Attempt a connect operation /*{{{*/ // --------------------------------------------------------------------- /* This helper function attempts a connection to a single address. */ -static bool DoConnect(struct addrinfo *Addr,string Host, +static bool DoConnect(struct addrinfo *Addr,std::string Host, unsigned long TimeOut,int &Fd,pkgAcqMethod *Owner) { // Show a status indicator @@ -71,7 +76,7 @@ static bool DoConnect(struct addrinfo *Addr,string Host, Owner->Status(_("Connecting to %s (%s)"),Host.c_str(),Name); // if that addr did timeout before, we do not try it again - if(bad_addr.find(string(Name)) != bad_addr.end()) + if(bad_addr.find(std::string(Name)) != bad_addr.end()) return false; /* If this is an IP rotation store the IP we are using.. If something goes @@ -98,7 +103,7 @@ static bool DoConnect(struct addrinfo *Addr,string Host, /* This implements a timeout for connect by opening the connection nonblocking */ if (WaitFd(Fd,true,TimeOut) == false) { - bad_addr.insert(bad_addr.begin(), string(Name)); + bad_addr.insert(bad_addr.begin(), std::string(Name)); Owner->SetFailReason("Timeout"); return _error->Error(_("Could not connect to %s:%s (%s), " "connection timed out"),Host.c_str(),Service,Name); @@ -115,6 +120,9 @@ static bool DoConnect(struct addrinfo *Addr,string Host, errno = Err; if(errno == ECONNREFUSED) Owner->SetFailReason("ConnectionRefused"); + else if (errno == ETIMEDOUT) + Owner->SetFailReason("ConnectionTimedOut"); + bad_addr.insert(bad_addr.begin(), std::string(Name)); return _error->Errno("connect",_("Could not connect to %s:%s (%s)."),Host.c_str(), Service,Name); } @@ -125,7 +133,7 @@ static bool DoConnect(struct addrinfo *Addr,string Host, // Connect - Connect to a server /*{{{*/ // --------------------------------------------------------------------- /* Performs a connection to the server */ -bool Connect(string Host,int Port,const char *Service,int DefPort,int &Fd, +bool Connect(std::string Host,int Port,const char *Service,int DefPort,int &Fd, unsigned long TimeOut,pkgAcqMethod *Owner) { if (_error->PendingError() == true) @@ -134,9 +142,9 @@ bool Connect(string Host,int Port,const char *Service,int DefPort,int &Fd, // Convert the port name/number char ServStr[300]; if (Port != 0) - snprintf(ServStr,sizeof(ServStr),"%u",Port); + snprintf(ServStr,sizeof(ServStr),"%i", Port); else - snprintf(ServStr,sizeof(ServStr),"%s",Service); + snprintf(ServStr,sizeof(ServStr),"%s", Service); /* 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 @@ -157,8 +165,16 @@ bool Connect(string Host,int Port,const char *Service,int DefPort,int &Fd, struct addrinfo Hints; memset(&Hints,0,sizeof(Hints)); Hints.ai_socktype = SOCK_STREAM; + Hints.ai_flags = AI_ADDRCONFIG; Hints.ai_protocol = 0; + if(_config->FindB("Acquire::ForceIPv4", false) == true) + Hints.ai_family = AF_INET; + else if(_config->FindB("Acquire::ForceIPv6", false) == true) + Hints.ai_family = AF_INET6; + else + Hints.ai_family = AF_UNSPEC; + // if we couldn't resolve the host before, we don't try now if(bad_addr.find(Host) != bad_addr.end()) return _error->Error(_("Could not resolve '%s'"),Host.c_str()); @@ -174,7 +190,7 @@ bool Connect(string Host,int Port,const char *Service,int DefPort,int &Fd, { if (DefPort != 0) { - snprintf(ServStr,sizeof(ServStr),"%u",DefPort); + snprintf(ServStr, sizeof(ServStr), "%i", DefPort); DefPort = 0; continue; } @@ -189,8 +205,11 @@ bool Connect(string Host,int Port,const char *Service,int DefPort,int &Fd, return _error->Error(_("Temporary failure resolving '%s'"), Host.c_str()); } - return _error->Error(_("Something wicked happened resolving '%s:%s' (%i)"), - Host.c_str(),ServStr,Res); + if (Res == EAI_SYSTEM) + return _error->Errno("getaddrinfo", _("System error resolving '%s:%s'"), + Host.c_str(),ServStr); + return _error->Error(_("Something wicked happened resolving '%s:%s' (%i - %s)"), + Host.c_str(),ServStr,Res,gai_strerror(Res)); } break; } @@ -236,6 +255,6 @@ bool Connect(string Host,int Port,const char *Service,int DefPort,int &Fd, if (_error->PendingError() == true) return false; - return _error->Error(_("Unable to connect to %s %s:"),Host.c_str(),ServStr); + return _error->Error(_("Unable to connect to %s:%s:"),Host.c_str(),ServStr); } /*}}}*/