From 1663774bf309fbd196fd2b9c5c2afdd7a25fd288 Mon Sep 17 00:00:00 2001 From: Faidon Liambotis Date: Wed, 23 Dec 2020 01:54:14 +0200 Subject: 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. --- methods/connect.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'methods') 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) -- cgit v1.2.3