summaryrefslogtreecommitdiff
path: root/methods
diff options
context:
space:
mode:
authorFaidon Liambotis <paravoid@debian.org>2020-12-23 01:54:14 +0200
committerFaidon Liambotis <paravoid@debian.org>2020-12-23 01:54:14 +0200
commit1663774bf309fbd196fd2b9c5c2afdd7a25fd288 (patch)
tree60934613ba832c954ba1db2dd1a77cdd97198515 /methods
parent8d4b3a4fcead0ca534b5d1c5a99ae2a4c95eee21 (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.cc11
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)