]> granicus.if.org Git - curl/commitdiff
conncache: make "bundles" per host name when doing proxy tunnels
authorDaniel Stenberg <daniel@haxx.se>
Tue, 28 May 2019 10:14:51 +0000 (12:14 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 28 May 2019 14:23:59 +0000 (16:23 +0200)
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
Closes #3955

lib/conncache.c
lib/conncache.h
lib/url.c

index 535091996501630aee9008816ff568ea7fb614d0..2cdfd34d9a04680a37ce12fecc1c7acee22cc5db 100644 (file)
@@ -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) {
index 35be9e0aa1c0f22f7f87cf81c273cfaa3508d725..58f90240931588b17f195f616372af81e905e6dc 100644 (file)
@@ -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);
index 6a6715403d2cc0b9e9f0e953bc7e6a1d0fcca221..88d72bfeac91c9684cbcd8cbf09415f21817bf2a 100644 (file)
--- 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;
         }
       }