]> git.saurik.com Git - apt.git/commitdiff
keep trying with next if connection to a SRV host failed
authorDavid Kalnischkies <david@kalnischkies.de>
Wed, 6 Jul 2016 12:49:39 +0000 (14:49 +0200)
committerJulian Andres Klode <jak@debian.org>
Wed, 31 Aug 2016 11:49:37 +0000 (13:49 +0200)
Instead of only trying the first host we get via SRV, we try them all as
we are supposed to and if that isn't working we try to connect to the
host itself as if we hadn't seen any SRV records. This was already the
intend of the old code, but it failed to hide earlier problems for the
next call, which would unconditionally fail then resulting in an all
around failure to connect. With proper stacking we can also keep the
error messages of each call around (and in the order tried) so if the
entire connection fails we can report all the things we have tried while
we discard the entire stack if something works out in the end.

(cherry picked from commit 3af3ac2f5ec007badeded46a94be2bd06b9917a2)

methods/connect.cc

index 07a730b887bdfa17f61b91537cd8a4774fb98590..f768169d1aceec08cb8d7a1458ccfcd80dc82ed2 100644 (file)
@@ -280,19 +280,35 @@ bool Connect(std::string Host,int Port,const char *Service,
       if (_config->FindB("Acquire::EnableSrvRecords", true) == true)
          GetSrvRecords(Host, DefPort, SrvRecords);
    }
-   // we have no SrvRecords for this host, connect right away
-   if(SrvRecords.size() == 0)
-      return ConnectToHostname(Host, Port, Service, DefPort, Fd, 
-                                    TimeOut, Owner);
 
+   size_t stackSize = 0;
    // try to connect in the priority order of the srv records
-   while(SrvRecords.size() > 0)
+   std::string initialHost{std::move(Host)};
+   while(SrvRecords.empty() == false)
    {
+      _error->PushToStack();
+      ++stackSize;
       // PopFromSrvRecs will also remove the server
       Host = PopFromSrvRecs(SrvRecords).target;
-      if(ConnectToHostname(Host, Port, Service, DefPort, Fd, TimeOut, Owner))
+      auto const ret = ConnectToHostname(Host, Port, Service, DefPort, Fd, TimeOut, Owner);
+      if (ret)
+      {
+        while(stackSize--)
+           _error->RevertToStack();
          return true;
+      }
    }
+   Host = std::move(initialHost);
 
-   return false;
+   // we have no (good) SrvRecords for this host, connect right away
+   _error->PushToStack();
+   ++stackSize;
+   auto const ret = ConnectToHostname(Host, Port, Service, DefPort, Fd,
+        TimeOut, Owner);
+   while(stackSize--)
+      if (ret)
+        _error->RevertToStack();
+      else
+        _error->MergeWithStack();
+   return ret;
 }