mirror of
https://github.com/curl/curl.git
synced 2026-08-24 13:33:33 +03:00
multi: add CURLMOPT_NETWORK_CHANGED to signal network changed
New multi option CURLMOPT_NETWORK_CHANGED with a long bitmask value: - CURLM_NWCOPT_CLEAR_CONNS: do not reuse existing connections, close all idle connections. - CURLM_NWCOPT_CLEAR_DNS: clear the multi's DNS cache. All other bits reserved for future extensions. Fixes #17225 Reported-by: ウさん Closes #17613
This commit is contained in:
parent
7b8594176d
commit
55c045c863
19 changed files with 354 additions and 4 deletions
|
|
@ -709,7 +709,8 @@ static int cpool_reap_dead_cb(struct Curl_easy *data,
|
|||
struct connectdata *conn, void *param)
|
||||
{
|
||||
struct cpool_reaper_ctx *rctx = param;
|
||||
if(Curl_conn_seems_dead(conn, data, &rctx->now)) {
|
||||
if((!CONN_INUSE(conn) && conn->bits.no_reuse) ||
|
||||
Curl_conn_seems_dead(conn, data, &rctx->now)) {
|
||||
/* stop the iteration here, pass back the connection that was pruned */
|
||||
Curl_conn_terminate(data, conn, FALSE);
|
||||
return 1;
|
||||
|
|
@ -849,6 +850,40 @@ void Curl_cpool_do_locked(struct Curl_easy *data,
|
|||
cb(conn, data, cbdata);
|
||||
}
|
||||
|
||||
static int cpool_mark_stale(struct Curl_easy *data,
|
||||
struct connectdata *conn, void *param)
|
||||
{
|
||||
(void)data;
|
||||
(void)param;
|
||||
conn->bits.no_reuse = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpool_reap_no_reuse(struct Curl_easy *data,
|
||||
struct connectdata *conn, void *param)
|
||||
{
|
||||
(void)data;
|
||||
(void)param;
|
||||
if(!CONN_INUSE(conn) && conn->bits.no_reuse) {
|
||||
Curl_conn_terminate(data, conn, FALSE);
|
||||
return 1;
|
||||
}
|
||||
return 0; /* continue iteration */
|
||||
}
|
||||
|
||||
void Curl_cpool_nw_changed(struct Curl_easy *data)
|
||||
{
|
||||
struct cpool *cpool = cpool_get_instance(data);
|
||||
|
||||
if(cpool) {
|
||||
CPOOL_LOCK(cpool, data);
|
||||
cpool_foreach(data, cpool, NULL, cpool_mark_stale);
|
||||
while(cpool_foreach(data, cpool, NULL, cpool_reap_no_reuse))
|
||||
;
|
||||
CPOOL_UNLOCK(cpool, data);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Useful for debugging the connection pool */
|
||||
void Curl_cpool_print(struct cpool *cpool)
|
||||
|
|
|
|||
|
|
@ -163,4 +163,8 @@ void Curl_cpool_do_locked(struct Curl_easy *data,
|
|||
struct connectdata *conn,
|
||||
Curl_cpool_conn_do_cb *cb, void *cbdata);
|
||||
|
||||
/* Close all unused connections, prevent reuse of existing ones. */
|
||||
void Curl_cpool_nw_changed(struct Curl_easy *data);
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_CONNCACHE_H */
|
||||
|
|
|
|||
|
|
@ -1102,6 +1102,7 @@ void curl_easy_reset(CURL *d)
|
|||
data->progress.hide = TRUE;
|
||||
data->state.current_speed = -1; /* init to negative == impossible */
|
||||
data->state.retrycount = 0; /* reset the retry counter */
|
||||
data->state.recent_conn_id = -1; /* clear remembered connection id */
|
||||
|
||||
/* zero out authentication data: */
|
||||
memset(&data->state.authhost, 0, sizeof(struct auth));
|
||||
|
|
|
|||
10
lib/hostip.c
10
lib/hostip.c
|
|
@ -290,6 +290,16 @@ void Curl_dnscache_prune(struct Curl_easy *data)
|
|||
dnscache_unlock(data, dnscache);
|
||||
}
|
||||
|
||||
void Curl_dnscache_clear(struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_dnscache *dnscache = dnscache_get(data);
|
||||
if(dnscache) {
|
||||
dnscache_lock(data, dnscache);
|
||||
Curl_hash_clean(&dnscache->entries);
|
||||
dnscache_unlock(data, dnscache);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_ALARM_TIMEOUT
|
||||
/* Beware this is a global and unique instance. This is used to store the
|
||||
return address that we can jump back to from inside a signal handler. This
|
||||
|
|
|
|||
|
|
@ -130,6 +130,9 @@ void Curl_dnscache_destroy(struct Curl_dnscache *dns);
|
|||
/* prune old entries from the DNS cache */
|
||||
void Curl_dnscache_prune(struct Curl_easy *data);
|
||||
|
||||
/* clear the DNS cache */
|
||||
void Curl_dnscache_clear(struct Curl_easy *data);
|
||||
|
||||
/* IPv4 threadsafe resolve function used for synch and asynch builds */
|
||||
struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
|
||||
|
||||
|
|
|
|||
10
lib/multi.c
10
lib/multi.c
|
|
@ -3235,6 +3235,16 @@ CURLMcode curl_multi_setopt(CURLM *m,
|
|||
multi->max_concurrent_streams = (unsigned int)streams;
|
||||
}
|
||||
break;
|
||||
case CURLMOPT_NETWORK_CHANGED: {
|
||||
long val = va_arg(param, long);
|
||||
if(val & CURLM_NWCOPT_CLEAR_DNS) {
|
||||
Curl_dnscache_clear(multi->admin);
|
||||
}
|
||||
if(val & CURLM_NWCOPT_CLEAR_CONNS) {
|
||||
Curl_cpool_nw_changed(multi->admin);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = CURLM_UNKNOWN_OPTION;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -843,7 +843,7 @@ static bool url_match_connect_config(struct connectdata *conn,
|
|||
struct url_conn_match *m)
|
||||
{
|
||||
/* connect-only or to-be-closed connections will not be reused */
|
||||
if(conn->connect_only || conn->bits.close)
|
||||
if(conn->connect_only || conn->bits.close || conn->bits.no_reuse)
|
||||
return FALSE;
|
||||
|
||||
/* ip_version must match */
|
||||
|
|
|
|||
|
|
@ -423,6 +423,7 @@ struct ConnectBits {
|
|||
BIT(parallel_connect); /* set TRUE when a parallel connect attempt has
|
||||
started (happy eyeballs) */
|
||||
BIT(aborted); /* connection was aborted, e.g. in unclean state */
|
||||
BIT(no_reuse); /* connection should not be reused */
|
||||
BIT(shutdown_handler); /* connection shutdown: handler shut down */
|
||||
BIT(shutdown_filters); /* connection shutdown: filters shut down */
|
||||
BIT(in_cpool); /* connection is kept in a connection pool */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue