diff options
author | Faidon Liambotis <paravoid@debian.org> | 2020-12-23 01:54:14 +0200 |
---|---|---|
committer | Faidon Liambotis <paravoid@debian.org> | 2020-12-23 01:54:14 +0200 |
commit | 1663774bf309fbd196fd2b9c5c2afdd7a25fd288 (patch) | |
tree | 60934613ba832c954ba1db2dd1a77cdd97198515 /methods | |
parent | 8d4b3a4fcead0ca534b5d1c5a99ae2a4c95eee21 (diff) |
connect: use ServiceNameOrPort, not Port, as the cache key
The "last connection" cache is currently being stored and looked up on
the combination of (LastHost, LastPort). However, these are not what the
arguments to getaddrinfo() were on the first try: the call is to
getaddrinfo(Host, ServiceNameOrPort, ...), i.e. with the port *or if 0,
the service name* (e.g. http).
Effectively this means that the connection cache lookup for:
https://example.org/... i.e. Host = example.org, Port = 0, Service = http
would end up matching the "last" connection of (if existed):
https://example.org/... i.e. Host = example.org, Port = 0, Service = https
...and thus performing a TLS request over an (unrelated) port 80
connection. Therefore, an HTTP request, followed up by an (unrelated)
HTTPS request to the same server, would always fail.
Address this by using as the cache key the ServiceNameOrPort, rather
than Port.
Diffstat (limited to 'methods')
-rw-r--r-- | methods/connect.cc | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/methods/connect.cc b/methods/connect.cc index bb7fba85d..d513a4540 100644 --- a/methods/connect.cc +++ b/methods/connect.cc @@ -45,7 +45,7 @@ /*}}}*/ static std::string LastHost; -static int LastPort = 0; +static std::string LastService; static struct addrinfo *LastHostAddr = 0; static struct addrinfo *LastUsed = 0; @@ -356,7 +356,7 @@ static ResultState ConnectToHostname(std::string const &Host, int const Port, /* 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 || LastPort != Port) + if (LastHost != Host || LastService != ServiceNameOrPort) { Owner->Status(_("Connecting to %s"),Host.c_str()); @@ -438,7 +438,7 @@ static ResultState ConnectToHostname(std::string const &Host, int const Port, } LastHost = Host; - LastPort = Port; + LastService = ServiceNameOrPort; } // When we have an IP rotation stay with the last IP. @@ -483,7 +483,10 @@ ResultState Connect(std::string Host, int Port, const char *Service, if (ConnectionAllowed(Service, Host) == false) return ResultState::FATAL_ERROR; - if(LastHost != Host || LastPort != Port) + // Used by getaddrinfo(); prefer port if given, else fallback to service + std::string ServiceNameOrPort = Port != 0 ? std::to_string(Port) : Service; + + if(LastHost != Host || LastService != ServiceNameOrPort) { SrvRecords.clear(); if (_config->FindB("Acquire::EnableSrvRecords", true) == true) |