.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
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
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;
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 */
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,
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;
}
multi stack. */
}
+
if(res) {
Curl_resolver_cleanup(data->state.resolver);
if(data->state.headerbuff)
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;
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 {