mirror of
https://github.com/moparisthebest/curl
synced 2025-01-11 05:58:01 -05:00
conncache: make "bundles" per host name when doing proxy tunnels
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
This commit is contained in:
parent
8581e1928e
commit
2f11fbf208
@ -159,19 +159,22 @@ void Curl_conncache_destroy(struct conncache *connc)
|
|||||||
|
|
||||||
/* creates a key to find a bundle for this connection */
|
/* creates a key to find a bundle for this connection */
|
||||||
static void hashkey(struct connectdata *conn, char *buf,
|
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;
|
const char *hostname;
|
||||||
|
|
||||||
if(conn->bits.socksproxy)
|
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy)
|
||||||
hostname = conn->socks_proxy.host.name;
|
|
||||||
else if(conn->bits.httpproxy)
|
|
||||||
hostname = conn->http_proxy.host.name;
|
hostname = conn->http_proxy.host.name;
|
||||||
else if(conn->bits.conn_to_host)
|
else if(conn->bits.conn_to_host)
|
||||||
hostname = conn->conn_to_host.name;
|
hostname = conn->conn_to_host.name;
|
||||||
else
|
else
|
||||||
hostname = conn->host.name;
|
hostname = conn->host.name;
|
||||||
|
|
||||||
|
if(hostp)
|
||||||
|
/* report back which name we used */
|
||||||
|
*hostp = hostname;
|
||||||
|
|
||||||
DEBUGASSERT(len > 32);
|
DEBUGASSERT(len > 32);
|
||||||
|
|
||||||
/* put the number first so that the hostname gets cut off if too long */
|
/* 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! */
|
**NOTE**: When it returns, it holds the connection cache lock! */
|
||||||
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
||||||
struct conncache *connc)
|
struct conncache *connc,
|
||||||
|
const char **hostp)
|
||||||
{
|
{
|
||||||
struct connectbundle *bundle = NULL;
|
struct connectbundle *bundle = NULL;
|
||||||
CONN_LOCK(conn->data);
|
CONN_LOCK(conn->data);
|
||||||
if(connc) {
|
if(connc) {
|
||||||
char key[128];
|
char key[128];
|
||||||
hashkey(conn, key, sizeof(key));
|
hashkey(conn, key, sizeof(key), hostp);
|
||||||
bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
|
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;
|
struct Curl_easy *data = conn->data;
|
||||||
|
|
||||||
/* *find_bundle() locks the connection cache */
|
/* *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) {
|
if(!bundle) {
|
||||||
int rc;
|
int rc;
|
||||||
char key[128];
|
char key[128];
|
||||||
@ -277,7 +281,7 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashkey(conn, key, sizeof(key));
|
hashkey(conn, key, sizeof(key), NULL);
|
||||||
rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
|
rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
|
||||||
|
|
||||||
if(!rc) {
|
if(!rc) {
|
||||||
|
@ -54,7 +54,8 @@ void Curl_conncache_destroy(struct conncache *connc);
|
|||||||
|
|
||||||
/* return the correct bundle, to a host or a proxy */
|
/* return the correct bundle, to a host or a proxy */
|
||||||
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
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);
|
void Curl_conncache_unlock(struct Curl_easy *data);
|
||||||
/* returns number of connections currently held in the connection cache */
|
/* returns number of connections currently held in the connection cache */
|
||||||
size_t Curl_conncache_size(struct Curl_easy *data);
|
size_t Curl_conncache_size(struct Curl_easy *data);
|
||||||
|
17
lib/url.c
17
lib/url.c
@ -1006,6 +1006,7 @@ ConnectionExists(struct Curl_easy *data,
|
|||||||
bool canmultiplex = IsMultiplexingPossible(data, needle);
|
bool canmultiplex = IsMultiplexingPossible(data, needle);
|
||||||
struct connectbundle *bundle;
|
struct connectbundle *bundle;
|
||||||
struct curltime now = Curl_now();
|
struct curltime now = Curl_now();
|
||||||
|
const char *hostbundle;
|
||||||
|
|
||||||
#ifdef USE_NTLM
|
#ifdef USE_NTLM
|
||||||
bool wantNTLMhttp = ((data->state.authhost.want &
|
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.
|
/* Look up the bundle with all the connections to this particular host.
|
||||||
Locks the connection cache, beware of early returns! */
|
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) {
|
if(bundle) {
|
||||||
/* Max pipe length is zero (unlimited) for multiplexed connections */
|
/* Max pipe length is zero (unlimited) for multiplexed connections */
|
||||||
struct curl_llist_element *curr;
|
struct curl_llist_element *curr;
|
||||||
|
|
||||||
infof(data, "Found bundle for host %s: %p [%s]\n",
|
infof(data, "Found bundle for host %s: %p [%s]\n",
|
||||||
(needle->bits.conn_to_host ? needle->conn_to_host.name :
|
hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ?
|
||||||
needle->host.name), (void *)bundle,
|
"can multiplex" : "serially"));
|
||||||
(bundle->multiuse == BUNDLE_MULTIPLEX ?
|
|
||||||
"can multiplex" : "serially"));
|
|
||||||
|
|
||||||
/* We can't multiplex if we don't know anything about the server */
|
/* We can't multiplex if we don't know anything about the server */
|
||||||
if(canmultiplex) {
|
if(canmultiplex) {
|
||||||
@ -3762,8 +3762,9 @@ static CURLcode create_conn(struct Curl_easy *data,
|
|||||||
connections_available = FALSE;
|
connections_available = FALSE;
|
||||||
else {
|
else {
|
||||||
/* this gets a lock on the conncache */
|
/* this gets a lock on the conncache */
|
||||||
|
const char *bundlehost;
|
||||||
struct connectbundle *bundle =
|
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 &&
|
if(max_host_connections > 0 && bundle &&
|
||||||
(bundle->num_connections >= max_host_connections)) {
|
(bundle->num_connections >= max_host_connections)) {
|
||||||
@ -3777,8 +3778,8 @@ static CURLcode create_conn(struct Curl_easy *data,
|
|||||||
(void)Curl_disconnect(data, conn_candidate,
|
(void)Curl_disconnect(data, conn_candidate,
|
||||||
/* dead_connection */ FALSE);
|
/* dead_connection */ FALSE);
|
||||||
else {
|
else {
|
||||||
infof(data, "No more connections allowed to host: %zu\n",
|
infof(data, "No more connections allowed to host %s: %zu\n",
|
||||||
max_host_connections);
|
bundlehost, max_host_connections);
|
||||||
connections_available = FALSE;
|
connections_available = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user