summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJeffrey Tolar <tolar@yahooinc.com>2021-09-18 11:29:44 -0500
committerDaniel Stenberg <daniel@haxx.se>2021-10-06 14:38:59 +0200
commit5f563495f1f9cf7ef4f23f997e4c2707dd3e74a8 (patch)
treee6d017874795f4c0bfe61105b1a245f44699ae2c /lib
parent013cb2ff7d3a37cab6910cc2e4d255377d341b6e (diff)
downloadcurl-5f563495f1f9cf7ef4f23f997e4c2707dd3e74a8.tar.gz
CURLOPT_MAXLIFETIME_CONN: maximum allowed lifetime for conn reuse
... and close connections that are too old instead of reusing them. By default, this behavior is disabled. Bug: https://curl.se/mail/lib-2021-09/0058.html Closes #7751
Diffstat (limited to 'lib')
-rw-r--r--lib/easyoptions.c3
-rw-r--r--lib/setopt.c6
-rw-r--r--lib/url.c24
-rw-r--r--lib/urldata.h2
4 files changed, 30 insertions, 5 deletions
diff --git a/lib/easyoptions.c b/lib/easyoptions.c
index bc149e7be..b6131d432 100644
--- a/lib/easyoptions.c
+++ b/lib/easyoptions.c
@@ -165,6 +165,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"MAXCONNECTS", CURLOPT_MAXCONNECTS, CURLOT_LONG, 0},
{"MAXFILESIZE", CURLOPT_MAXFILESIZE, CURLOT_LONG, 0},
{"MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE, CURLOT_OFF_T, 0},
+ {"MAXLIFETIME_CONN", CURLOPT_MAXLIFETIME_CONN, CURLOT_LONG, 0},
{"MAXREDIRS", CURLOPT_MAXREDIRS, CURLOT_LONG, 0},
{"MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE, CURLOT_OFF_T, 0},
{"MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE, CURLOT_OFF_T, 0},
@@ -358,6 +359,6 @@ struct curl_easyoption Curl_easyopts[] = {
*/
int Curl_easyopts_check(void)
{
- return ((CURLOPT_LASTENTRY%10000) != (313 + 1));
+ return ((CURLOPT_LASTENTRY%10000) != (314 + 1));
}
#endif
diff --git a/lib/setopt.c b/lib/setopt.c
index 8e19389ae..65fe252f4 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -2938,6 +2938,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.maxage_conn = arg;
break;
+ case CURLOPT_MAXLIFETIME_CONN:
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.maxlifetime_conn = arg;
+ break;
case CURLOPT_TRAILERFUNCTION:
#ifndef CURL_DISABLE_HTTP
data->set.trailer_callback = va_arg(param, curl_trailer_callback);
diff --git a/lib/url.c b/lib/url.c
index 5c31cadd6..1603b3072 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -622,6 +622,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT;
set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
set->maxage_conn = 118;
+ set->maxlifetime_conn = 0;
set->http09_allowed = FALSE;
set->httpwant =
#ifdef USE_NGHTTP2
@@ -962,21 +963,36 @@ socks_proxy_info_matches(const struct proxy_info *data,
#define socks_proxy_info_matches(x,y) FALSE
#endif
-/* A connection has to have been idle for a shorter time than 'maxage_conn' to
- be subject for reuse. The success rate is just too low after this. */
+/* A connection has to have been idle for a shorter time than 'maxage_conn'
+ (the success rate is just too low after this), or created less than
+ 'maxlifetime_conn' ago, to be subject for reuse. */
static bool conn_maxage(struct Curl_easy *data,
struct connectdata *conn,
struct curltime now)
{
- timediff_t idletime = Curl_timediff(now, conn->lastused);
+ timediff_t idletime, lifetime;
+
+ idletime = Curl_timediff(now, conn->lastused);
idletime /= 1000; /* integer seconds is fine */
if(idletime > data->set.maxage_conn) {
- infof(data, "Too old connection (%ld seconds), disconnect it",
+ infof(data, "Too old connection (%ld seconds idle), disconnect it",
idletime);
return TRUE;
}
+
+ lifetime = Curl_timediff(now, conn->created);
+ lifetime /= 1000; /* integer seconds is fine */
+
+ if(data->set.maxlifetime_conn && lifetime > data->set.maxlifetime_conn) {
+ infof(data,
+ "Too old connection (%ld seconds since creation), disconnect it",
+ lifetime);
+ return TRUE;
+ }
+
+
return FALSE;
}
diff --git a/lib/urldata.h b/lib/urldata.h
index 47cb9e282..92df52467 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1678,6 +1678,8 @@ struct UserDefined {
long server_response_timeout; /* in milliseconds, 0 means no timeout */
long maxage_conn; /* in seconds, max idle time to allow a connection that
is to be reused */
+ long maxlifetime_conn; /* in seconds, max time since creation to allow a
+ connection that is to be reused */
long tftp_blksize; /* in bytes, 0 means use default */
curl_off_t filesize; /* size of file to upload, -1 means unknown */
long low_speed_limit; /* bytes/second */