1
0
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:
Dave Reisner 2012-01-24 01:28:06 +00:00 committed by Daniel Stenberg
parent ea055407fa
commit 705f0f7a5b
6 changed files with 82 additions and 0 deletions

View File

@ -915,6 +915,24 @@ overdone.
.IP CURLOPT_ADDRESS_SCOPE
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)
.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)
.IP CURLOPT_NETRC
This parameter controls the preference of libcurl between using user names and

View File

@ -486,6 +486,9 @@ CURLOPT_SSL_SESSIONID_CACHE 7.16.0
CURLOPT_SSL_VERIFYHOST 7.8.1
CURLOPT_SSL_VERIFYPEER 7.4.2
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_TELNETOPTIONS 7.7
CURLOPT_TFTP_BLKSIZE 7.19.4

View File

@ -1499,6 +1499,13 @@ typedef enum {
of miliseconds. */
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 */
} CURLoption;

View File

@ -91,6 +91,35 @@
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
singleipconnect(struct connectdata *conn,
const Curl_addrinfo *ai, /* start connecting to this */
@ -876,6 +905,9 @@ singleipconnect(struct connectdata *conn,
Curl_sndbufset(sockfd);
if(data->set.tcp_keepalive)
tcpkeepalive(data, sockfd);
if(data->set.fsockopt) {
/* activate callback for setting socket options */
error = data->set.fsockopt(data->set.sockopt_client,

View File

@ -748,6 +748,13 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
set->chunk_bgn = 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;
}
@ -811,6 +818,7 @@ CURLcode Curl_open(struct SessionHandle **curl)
multi stack. */
}
if(res) {
Curl_resolver_cleanup(data->state.resolver);
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 *));
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:
/* unknown tag and its companion, just ignore: */
result = CURLE_UNKNOWN_OPTION;

View File

@ -1539,6 +1539,10 @@ struct UserDefined {
long gssapi_delegation; /* GSSAPI credential delegation, see the
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 {