diff options
author | David Kalnischkies <david@kalnischkies.de> | 2016-07-06 14:49:39 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2016-07-06 15:53:59 +0200 |
commit | 3af3ac2f5ec007badeded46a94be2bd06b9917a2 (patch) | |
tree | 38513401fbf38cbb9d3836ddb0c0cb4b873e35cc /methods | |
parent | b50dfa6b2dd2d459e0c2746ac9367982b96ffac0 (diff) | |
download | apt-3af3ac2f5ec007badeded46a94be2bd06b9917a2.tar.gz |
keep trying with next if connection to a SRV host failed
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.
Diffstat (limited to 'methods')
-rw-r--r-- | methods/connect.cc | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/methods/connect.cc b/methods/connect.cc index 07a730b88..f768169d1 100644 --- a/methods/connect.cc +++ b/methods/connect.cc @@ -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; } |