mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
add library support for tuning TCP_KEEPALIVE
This adds three new options to control the behavior of TCP keepalives: - CURLOPT_TCP_KEEPALIVE: enable/disable probes - CURLOPT_TCP_KEEPIDLE: idle time before sending first probe - CURLOPT_TCP_KEEPINTVL: delay between successive probes While not all operating systems support the TCP_KEEPIDLE and TCP_KEEPINTVL knobs, the library will still allow these options to be set by clients, silently ignoring the values.
This commit is contained in:
parent
ea055407fa
commit
705f0f7a5b
@ -915,6 +915,24 @@ overdone.
|
|||||||
.IP CURLOPT_ADDRESS_SCOPE
|
.IP CURLOPT_ADDRESS_SCOPE
|
||||||
Pass a long specifying the scope_id value to use when connecting to IPv6
|
Pass a long specifying the scope_id value to use when connecting to IPv6
|
||||||
link-local or site-local addresses. (Added in 7.19.0)
|
link-local or site-local addresses. (Added in 7.19.0)
|
||||||
|
|
||||||
|
.IP CURLOPT_TCP_KEEPALIVE
|
||||||
|
Pass a long. If set to 1, TCP keepalive probes will be sent. The delay and
|
||||||
|
frequency of these probes can be controlled by the \fICURLOPT_TCP_KEEPIDLE\fP
|
||||||
|
and \fICURLOPT_TCP_KEEPINTVL\fP options, provided the operating system supports
|
||||||
|
them. Set to 0 (default behavior) to disable keepalive probes (Added in
|
||||||
|
7.24.1).
|
||||||
|
|
||||||
|
.IP CURLOPT_TCP_KEEPIDLE
|
||||||
|
Pass a long. Sets the delay, in seconds, that the operating system will wait
|
||||||
|
while the connection is idle before sending keepalive probes. Not all operating
|
||||||
|
systems support this option. (Added in 7.24.1)
|
||||||
|
|
||||||
|
.IP CURLOPT_TCP_KEEPINTVL
|
||||||
|
Pass a long. Sets the interval, in seconds, that the operating system will wait
|
||||||
|
between sending keepalive probes. Not all operating systems support this
|
||||||
|
option. (Added in 7.24.1)
|
||||||
|
|
||||||
.SH NAMES and PASSWORDS OPTIONS (Authentication)
|
.SH NAMES and PASSWORDS OPTIONS (Authentication)
|
||||||
.IP CURLOPT_NETRC
|
.IP CURLOPT_NETRC
|
||||||
This parameter controls the preference of libcurl between using user names and
|
This parameter controls the preference of libcurl between using user names and
|
||||||
|
@ -486,6 +486,9 @@ CURLOPT_SSL_SESSIONID_CACHE 7.16.0
|
|||||||
CURLOPT_SSL_VERIFYHOST 7.8.1
|
CURLOPT_SSL_VERIFYHOST 7.8.1
|
||||||
CURLOPT_SSL_VERIFYPEER 7.4.2
|
CURLOPT_SSL_VERIFYPEER 7.4.2
|
||||||
CURLOPT_STDERR 7.1
|
CURLOPT_STDERR 7.1
|
||||||
|
CURLOPT_TCP_KEEPALIVE 7.24.1
|
||||||
|
CURLOPT_TCP_KEEPIDLE 7.24.1
|
||||||
|
CURLOPT_TCP_KEEPINTVL 7.24.1
|
||||||
CURLOPT_TCP_NODELAY 7.11.2
|
CURLOPT_TCP_NODELAY 7.11.2
|
||||||
CURLOPT_TELNETOPTIONS 7.7
|
CURLOPT_TELNETOPTIONS 7.7
|
||||||
CURLOPT_TFTP_BLKSIZE 7.19.4
|
CURLOPT_TFTP_BLKSIZE 7.19.4
|
||||||
|
@ -1499,6 +1499,13 @@ typedef enum {
|
|||||||
of miliseconds. */
|
of miliseconds. */
|
||||||
CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
|
CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
|
||||||
|
|
||||||
|
/* Set TCP keepalive */
|
||||||
|
CINIT(TCP_KEEPALIVE, LONG, 213),
|
||||||
|
|
||||||
|
/* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */
|
||||||
|
CINIT(TCP_KEEPIDLE, LONG, 214),
|
||||||
|
CINIT(TCP_KEEPINTVL, LONG, 215),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unused */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
|
@ -91,6 +91,35 @@
|
|||||||
|
|
||||||
static bool verifyconnect(curl_socket_t sockfd, int *error);
|
static bool verifyconnect(curl_socket_t sockfd, int *error);
|
||||||
|
|
||||||
|
static void
|
||||||
|
tcpkeepalive(struct SessionHandle *data,
|
||||||
|
int sockfd)
|
||||||
|
{
|
||||||
|
int optval = data->set.tcp_keepalive;
|
||||||
|
|
||||||
|
/* only set IDLE and INTVL if setting KEEPALIVE is successful */
|
||||||
|
if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
|
||||||
|
(void *)&optval, sizeof(optval)) < 0) {
|
||||||
|
infof(data, "Failed to set SO_KEEPALIVE on fd %d\n", sockfd);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef TCP_KEEPIDLE
|
||||||
|
optval = data->set.tcp_keepidle;
|
||||||
|
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
|
||||||
|
(void *)&optval, sizeof(optval)) < 0) {
|
||||||
|
infof(data, "Failed to set TCP_KEEPIDLE on fd %d\n", sockfd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef TCP_KEEPINTVL
|
||||||
|
optval = data->set.tcp_keepintvl;
|
||||||
|
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
|
||||||
|
(void *)&optval, sizeof(optval)) < 0) {
|
||||||
|
infof(data, "Failed to set TCP_KEEPINTVL on fd %d\n", sockfd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode
|
static CURLcode
|
||||||
singleipconnect(struct connectdata *conn,
|
singleipconnect(struct connectdata *conn,
|
||||||
const Curl_addrinfo *ai, /* start connecting to this */
|
const Curl_addrinfo *ai, /* start connecting to this */
|
||||||
@ -876,6 +905,9 @@ singleipconnect(struct connectdata *conn,
|
|||||||
|
|
||||||
Curl_sndbufset(sockfd);
|
Curl_sndbufset(sockfd);
|
||||||
|
|
||||||
|
if(data->set.tcp_keepalive)
|
||||||
|
tcpkeepalive(data, sockfd);
|
||||||
|
|
||||||
if(data->set.fsockopt) {
|
if(data->set.fsockopt) {
|
||||||
/* activate callback for setting socket options */
|
/* activate callback for setting socket options */
|
||||||
error = data->set.fsockopt(data->set.sockopt_client,
|
error = data->set.fsockopt(data->set.sockopt_client,
|
||||||
|
18
lib/url.c
18
lib/url.c
@ -748,6 +748,13 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
|
|||||||
set->chunk_bgn = ZERO_NULL;
|
set->chunk_bgn = ZERO_NULL;
|
||||||
set->chunk_end = ZERO_NULL;
|
set->chunk_end = ZERO_NULL;
|
||||||
|
|
||||||
|
/* tcp keepalives are disabled by default, but provide reasonable values for
|
||||||
|
* the interval and idle times.
|
||||||
|
*/
|
||||||
|
set->tcp_keepalive = 0;
|
||||||
|
set->tcp_keepintvl = 60;
|
||||||
|
set->tcp_keepidle = 60;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -811,6 +818,7 @@ CURLcode Curl_open(struct SessionHandle **curl)
|
|||||||
multi stack. */
|
multi stack. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(res) {
|
if(res) {
|
||||||
Curl_resolver_cleanup(data->state.resolver);
|
Curl_resolver_cleanup(data->state.resolver);
|
||||||
if(data->state.headerbuff)
|
if(data->state.headerbuff)
|
||||||
@ -2545,6 +2553,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
result = Curl_set_dns_servers(data, va_arg(param, char *));
|
result = Curl_set_dns_servers(data, va_arg(param, char *));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CURLOPT_TCP_KEEPALIVE:
|
||||||
|
data->set.tcp_keepalive = (0 != va_arg(param, long))?TRUE:FALSE;
|
||||||
|
break;
|
||||||
|
case CURLOPT_TCP_KEEPIDLE:
|
||||||
|
data->set.tcp_keepidle = va_arg(param, long);
|
||||||
|
break;
|
||||||
|
case CURLOPT_TCP_KEEPINTVL:
|
||||||
|
data->set.tcp_keepintvl = va_arg(param, long);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* unknown tag and its companion, just ignore: */
|
/* unknown tag and its companion, just ignore: */
|
||||||
result = CURLE_UNKNOWN_OPTION;
|
result = CURLE_UNKNOWN_OPTION;
|
||||||
|
@ -1539,6 +1539,10 @@ struct UserDefined {
|
|||||||
|
|
||||||
long gssapi_delegation; /* GSSAPI credential delegation, see the
|
long gssapi_delegation; /* GSSAPI credential delegation, see the
|
||||||
documentation of CURLOPT_GSSAPI_DELEGATION */
|
documentation of CURLOPT_GSSAPI_DELEGATION */
|
||||||
|
|
||||||
|
bool tcp_keepalive; /* use TCP keepalives */
|
||||||
|
long tcp_keepidle; /* seconds in idle before sending keepalive probe */
|
||||||
|
long tcp_keepintvl; /* seconds between TCP keepalive probes */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Names {
|
struct Names {
|
||||||
|
Loading…
Reference in New Issue
Block a user