summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2019-05-28 12:14:51 +0200
committerDaniel Stenberg <daniel@haxx.se>2019-05-28 12:14:51 +0200
commitfc4b007b96987bd009143132dc9882af3df68304 (patch)
tree475f0dd9579bceac98c318b760d4c3cab6bf1f93
parent28526e9c80f7c923fac0aef503c7a63d84994282 (diff)
downloadcurl-bagder/bundle-per-hostname.tar.gz
conncache: make "bundles" per host name when doing proxy tunnelsbagder/bundle-per-hostname
Only HTTP proxy use where multiple host names can be used over the same connection should use the proxy host name for bundles. Reported-by: Tom van der Woerdt Fixes #3951
-rw-r--r--lib/conncache.c20
-rw-r--r--lib/conncache.h3
-rw-r--r--lib/url.c17
3 files changed, 23 insertions, 17 deletions
diff --git a/lib/conncache.c b/lib/conncache.c
index 535091996..2cdfd34d9 100644
--- a/lib/conncache.c
+++ b/lib/conncache.c
@@ -159,19 +159,22 @@ void Curl_conncache_destroy(struct conncache *connc)
/* creates a key to find a bundle for this connection */
static void hashkey(struct connectdata *conn, char *buf,
- size_t len) /* something like 128 is fine */
+ size_t len, /* something like 128 is fine */
+ const char **hostp)
{
const char *hostname;
- if(conn->bits.socksproxy)
- hostname = conn->socks_proxy.host.name;
- else if(conn->bits.httpproxy)
+ if(conn->bits.httpproxy && !conn->bits.tunnel_proxy)
hostname = conn->http_proxy.host.name;
else if(conn->bits.conn_to_host)
hostname = conn->conn_to_host.name;
else
hostname = conn->host.name;
+ if(hostp)
+ /* report back which name we used */
+ *hostp = hostname;
+
DEBUGASSERT(len > 32);
/* put the number first so that the hostname gets cut off if too long */
@@ -212,13 +215,14 @@ size_t Curl_conncache_bundle_size(struct connectdata *conn)
**NOTE**: When it returns, it holds the connection cache lock! */
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
- struct conncache *connc)
+ struct conncache *connc,
+ const char **hostp)
{
struct connectbundle *bundle = NULL;
CONN_LOCK(conn->data);
if(connc) {
char key[128];
- hashkey(conn, key, sizeof(key));
+ hashkey(conn, key, sizeof(key), hostp);
bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
}
@@ -267,7 +271,7 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
struct Curl_easy *data = conn->data;
/* *find_bundle() locks the connection cache */
- bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
+ bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache, NULL);
if(!bundle) {
int rc;
char key[128];
@@ -277,7 +281,7 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
goto unlock;
}
- hashkey(conn, key, sizeof(key));
+ hashkey(conn, key, sizeof(key), NULL);
rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
if(!rc) {
diff --git a/lib/conncache.h b/lib/conncache.h
index 35be9e0aa..58f902409 100644
--- a/lib/conncache.h
+++ b/lib/conncache.h
@@ -54,7 +54,8 @@ void Curl_conncache_destroy(struct conncache *connc);
/* return the correct bundle, to a host or a proxy */
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
- struct conncache *connc);
+ struct conncache *connc,
+ const char **hostp);
void Curl_conncache_unlock(struct Curl_easy *data);
/* returns number of connections currently held in the connection cache */
size_t Curl_conncache_size(struct Curl_easy *data);
diff --git a/lib/url.c b/lib/url.c
index 6a6715403..88d72bfea 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1006,6 +1006,7 @@ ConnectionExists(struct Curl_easy *data,
bool canmultiplex = IsMultiplexingPossible(data, needle);
struct connectbundle *bundle;
struct curltime now = Curl_now();
+ const char *hostbundle;
#ifdef USE_NTLM
bool wantNTLMhttp = ((data->state.authhost.want &
@@ -1022,16 +1023,15 @@ ConnectionExists(struct Curl_easy *data,
/* Look up the bundle with all the connections to this particular host.
Locks the connection cache, beware of early returns! */
- bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
+ bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache,
+ &hostbundle);
if(bundle) {
/* Max pipe length is zero (unlimited) for multiplexed connections */
struct curl_llist_element *curr;
infof(data, "Found bundle for host %s: %p [%s]\n",
- (needle->bits.conn_to_host ? needle->conn_to_host.name :
- needle->host.name), (void *)bundle,
- (bundle->multiuse == BUNDLE_MULTIPLEX ?
- "can multiplex" : "serially"));
+ hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ?
+ "can multiplex" : "serially"));
/* We can't multiplex if we don't know anything about the server */
if(canmultiplex) {
@@ -3762,8 +3762,9 @@ static CURLcode create_conn(struct Curl_easy *data,
connections_available = FALSE;
else {
/* this gets a lock on the conncache */
+ const char *bundlehost;
struct connectbundle *bundle =
- Curl_conncache_find_bundle(conn, data->state.conn_cache);
+ Curl_conncache_find_bundle(conn, data->state.conn_cache, &bundlehost);
if(max_host_connections > 0 && bundle &&
(bundle->num_connections >= max_host_connections)) {
@@ -3777,8 +3778,8 @@ static CURLcode create_conn(struct Curl_easy *data,
(void)Curl_disconnect(data, conn_candidate,
/* dead_connection */ FALSE);
else {
- infof(data, "No more connections allowed to host: %zu\n",
- max_host_connections);
+ infof(data, "No more connections allowed to host %s: %zu\n",
+ bundlehost, max_host_connections);
connections_available = FALSE;
}
}