ipv6.md \
json.md \
junk-session-cookies.md \
+ keepalive-cnt.md \
keepalive-time.md \
key-type.md \
key.md \
--- /dev/null
+---
+c: Copyright (C) Daniel Stenberg, <daniel.se>, et al.
+SPDX-License-Identifier: curl
+Long: keepalive-cnt
+Arg: <integer>
+Help: Maximum number of keepalive probes
+Added: 8.9.0
+Category: connection
+Multi: single
+See-also:
+ - keepalive-time
+ - no-keepalive
+Example:
+ - --keepalive-cnt 3 $URL
+---
+
+# `--keepalive-cnt`
+
+Set the maximum number of keepalive probes TCP should send but get no response
+before dropping the connection. This option is usually used in conjunction
+with --keepalive-time.
+
+This option is supported on Linux, *BSD/macOS, Windows \>=10.0.16299, Solaris
+11.4, and recent AIX, HP-UX and more. This option has no effect if
+--no-keepalive is used.
+
+If unspecified, the option defaults to 9.
Multi: single
See-also:
- no-keepalive
+ - keepalive-cnt
- max-time
Example:
- --keepalive-time 20 $URL
options (meaning Linux, *BSD/macOS, Windows, Solaris, and recent AIX, HP-UX and more).
Keepalive is used by the TCP stack to detect broken networks on idle connections.
The number of missed keepalive probes before declaring the connection down is OS
-dependent and is commonly 8 (*BSD/macOS/AIX), 9 (Linux/AIX) or 5/10 (Windows).
-This option has no effect if --no-keepalive is used.
+dependent and is commonly 8 (*BSD/macOS/AIX), 9 (Linux/AIX) or 5/10 (Windows), and
+this number can be changed by specifying the curl option `keepalive-cnt`.
+Note that this option has no effect if --no-keepalive is used.
If unspecified, the option defaults to 60 seconds.
Multi: boolean
See-also:
- keepalive-time
+ - keepalive-cnt
Example:
- --no-keepalive $URL
---
/* interval time between keep-alive probes: 60 seconds */
curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L);
+ /* maximum number of keep-alive probes: 3 */
+ curl_easy_setopt(curl, CURLOPT_TCP_KEEPCNT, 3L);
+
curl_easy_setopt(curl, CURLOPT_URL, "https://curl.se/");
res = curl_easy_perform(curl);
Interval between keep-alive probes. See CURLOPT_TCP_KEEPINTVL(3)
+## CURLOPT_TCP_KEEPCNT
+
+Maximum number of keep-alive probes. See CURLOPT_TCP_KEEPCNT(3)
+
## CURLOPT_UNIX_SOCKET_PATH
Path to a Unix domain socket. See CURLOPT_UNIX_SOCKET_PATH(3)
- CURLOPT_MAX_RECV_SPEED_LARGE (3)
- CURLOPT_TCP_KEEPIDLE (3)
- CURLOPT_TCP_KEEPINTVL (3)
+ - CURLOPT_TCP_KEEPCNT (3)
Protocol:
- - All
+ - TCP
---
# NAME
Pass a long. If set to 1, TCP keepalive probes are used. The delay and
frequency of these probes can be controlled by the
-CURLOPT_TCP_KEEPIDLE(3) and CURLOPT_TCP_KEEPINTVL(3) options,
-provided the operating system supports them. Set to 0 (default behavior) to
-disable keepalive probes
+CURLOPT_TCP_KEEPIDLE(3), CURLOPT_TCP_KEEPINTVL(3), and CURLOPT_TCP_KEEPCNT(3)
+options, provided the operating system supports them. Set to 0 (default behavior)
+to disable keepalive probes.
# DEFAULT
/* interval time between keep-alive probes: 60 seconds */
curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L);
+ /* maximum number of keep-alive probes: 3 */
+ curl_easy_setopt(curl, CURLOPT_TCP_KEEPCNT, 3L);
+
curl_easy_perform(curl);
}
}
--- /dev/null
+---
+c: Copyright (C) Daniel Stenberg, <daniel.se>, et al.
+SPDX-License-Identifier: curl
+Title: CURLOPT_TCP_KEEPCNT
+Section: 3
+Source: libcurl
+See-also:
+ - CURLOPT_TCP_KEEPALIVE (3)
+ - CURLOPT_TCP_KEEPIDLE (3)
+ - CURLOPT_TCP_KEEPINTVL (3)
+Protocol:
+ - TCP
+---
+
+# NAME
+
+CURLOPT_TCP_KEEPCNT - Maximum number of TCP keep-alive probes
+
+# SYNOPSIS
+
+~~~c
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_TCP_KEEPCNT, long cnt);
+~~~
+
+# DESCRIPTION
+
+Pass a long. Sets the number of probes to send before dropping
+the connection. Not all operating systems support this option.
+(Added in 8.9.0)
+
+The maximum value this option accepts is INT_MAX or whatever your
+system allows.
+Any larger value is capped to this amount.
+
+# DEFAULT
+
+9
+
+# EXAMPLE
+
+~~~c
+int main(void)
+{
+ CURL *curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
+
+ /* enable TCP keep-alive for this transfer */
+ curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
+
+ /* set keep-alive idle time to 120 seconds */
+ curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L);
+
+ /* interval time between keep-alive probes: 60 seconds */
+ curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L);
+
+ /* maximum number of keep-alive probes: 3 */
+ curl_easy_setopt(curl, CURLOPT_TCP_KEEPCNT, 3L);
+
+ curl_easy_perform(curl);
+ }
+}
+~~~
+
+# AVAILABILITY
+
+Added in v8.9.0
+
+# RETURN VALUE
+
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
See-also:
- CURLOPT_TCP_KEEPALIVE (3)
- CURLOPT_TCP_KEEPINTVL (3)
+ - CURLOPT_TCP_KEEPCNT (3)
Protocol:
- - All
+ - TCP
---
# NAME
/* interval time between keep-alive probes: 60 seconds */
curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L);
+ /* maximum number of keep-alive probes: 3 */
+ curl_easy_setopt(curl, CURLOPT_TCP_KEEPCNT, 3L);
+
curl_easy_perform(curl);
}
}
See-also:
- CURLOPT_TCP_KEEPALIVE (3)
- CURLOPT_TCP_KEEPIDLE (3)
+ - CURLOPT_TCP_KEEPCNT (3)
Protocol:
- - All
+ - TCP
---
# NAME
/* interval time between keep-alive probes: 60 seconds */
curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L);
+ /* maximum number of keep-alive probes: 3 */
+ curl_easy_setopt(curl, CURLOPT_TCP_KEEPCNT, 3L);
+
curl_easy_perform(curl);
}
}
- CURLOPT_SOCKOPTFUNCTION (3)
- CURLOPT_TCP_KEEPALIVE (3)
Protocol:
- - All
+ - TCP
---
# NAME
CURLOPT_TCP_KEEPALIVE.3 \
CURLOPT_TCP_KEEPIDLE.3 \
CURLOPT_TCP_KEEPINTVL.3 \
+ CURLOPT_TCP_KEEPCNT.3 \
CURLOPT_TCP_NODELAY.3 \
CURLOPT_TELNETOPTIONS.3 \
CURLOPT_TFTP_BLKSIZE.3 \
CURLOPT_TCP_KEEPALIVE 7.25.0
CURLOPT_TCP_KEEPIDLE 7.25.0
CURLOPT_TCP_KEEPINTVL 7.25.0
+CURLOPT_TCP_KEEPCNT 8.9.0
CURLOPT_TCP_NODELAY 7.11.2
CURLOPT_TELNETOPTIONS 7.7
CURLOPT_TFTP_BLKSIZE 7.19.4
--ipv6 (-6) 7.10.8
--json 7.82.0
--junk-session-cookies (-j) 7.9.7
+--keepalive-cnt 8.9.0
--keepalive-time 7.18.0
--key 7.9.3
--key-type 7.9.3
/* millisecond version */
CURLOPT(CURLOPT_SERVER_RESPONSE_TIMEOUT_MS, CURLOPTTYPE_LONG, 324),
- /* set ECH configuration */
+ /* set ECH configuration */
CURLOPT(CURLOPT_ECH, CURLOPTTYPE_STRINGPOINT, 325),
+ /* maximum number of keepalive probes (Linux, *BSD, macOS, etc.) */
+ CURLOPT(CURLOPT_TCP_KEEPCNT, CURLOPTTYPE_LONG, 326),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
#if defined(USE_WINSOCK) || \
(defined(__sun) && !defined(TCP_KEEPIDLE)) || \
- (defined(__DragonFly__) && __DragonFly_version < 500702)
-/* Solaris < 11.4, DragonFlyBSD < 500702 and Windows
+ (defined(__DragonFly__) && __DragonFly_version < 500702) || \
+ (defined(_WIN32) && !defined(TCP_KEEPIDLE))
+/* Solaris < 11.4, DragonFlyBSD < 500702 and Windows < 10.0.16299
* use millisecond units. */
#define KEEPALIVE_FACTOR(x) (x *= 1000)
#else
sockfd, SOCKERRNO);
}
else {
-#if defined(SIO_KEEPALIVE_VALS)
+#if defined(SIO_KEEPALIVE_VALS) /* Windows */
+/* Windows 10, version 1709 (10.0.16299) and later versions */
+#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT)
+ optval = curlx_sltosi(data->set.tcp_keepidle);
+ KEEPALIVE_FACTOR(optval);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
+ (const char *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set TCP_KEEPIDLE on fd "
+ "%" CURL_FORMAT_SOCKET_T ": errno %d",
+ sockfd, SOCKERRNO);
+ }
+ optval = curlx_sltosi(data->set.tcp_keepintvl);
+ KEEPALIVE_FACTOR(optval);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
+ (const char *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set TCP_KEEPINTVL on fd "
+ "%" CURL_FORMAT_SOCKET_T ": errno %d",
+ sockfd, SOCKERRNO);
+ }
+ optval = curlx_sltosi(data->set.tcp_keepcnt);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT,
+ (const char *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set TCP_KEEPCNT on fd "
+ "%" CURL_FORMAT_SOCKET_T ": errno %d",
+ sockfd, SOCKERRNO);
+ }
+#else /* Windows < 10.0.16299 */
struct tcp_keepalive vals;
DWORD dummy;
vals.onoff = 1;
"%" CURL_FORMAT_SOCKET_T ": errno %d",
sockfd, SOCKERRNO);
}
-#else
+#endif
+#else /* !Windows */
#ifdef TCP_KEEPIDLE
optval = curlx_sltosi(data->set.tcp_keepidle);
KEEPALIVE_FACTOR(optval);
/* TCP_KEEPALIVE_ABORT_THRESHOLD should equal to
* TCP_KEEPCNT * TCP_KEEPINTVL on other platforms.
* The default value of TCP_KEEPCNT is 9 on Linux,
- * 8 on *BSD/macOS, 5 or 10 on Windows. We choose
- * 9 for Solaris <11.4 because there is no default
- * value for TCP_KEEPCNT on Solaris 11.4.
+ * 8 on *BSD/macOS, 5 or 10 on Windows. We use the
+ * default config for Solaris <11.4 because there is
+ * no default value for TCP_KEEPCNT on Solaris 11.4.
*
* Note that the consequent probes will not be sent
* at equal intervals on Solaris, but will be sent
* using the exponential backoff algorithm. */
- optval = 9 * curlx_sltosi(data->set.tcp_keepintvl);
+ optval = curlx_sltosi(data->set.tcp_keepcnt) *
+ curlx_sltosi(data->set.tcp_keepintvl);
KEEPALIVE_FACTOR(optval);
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD,
(void *)&optval, sizeof(optval)) < 0) {
sockfd, SOCKERRNO);
}
#endif
+#ifdef TCP_KEEPCNT
+ optval = curlx_sltosi(data->set.tcp_keepcnt);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT,
+ (void *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set TCP_KEEPCNT on fd "
+ "%" CURL_FORMAT_SOCKET_T ": errno %d",
+ sockfd, SOCKERRNO);
+ }
+#endif
#endif
}
}
CURLOT_LONG, 0},
{"TCP_FASTOPEN", CURLOPT_TCP_FASTOPEN, CURLOT_LONG, 0},
{"TCP_KEEPALIVE", CURLOPT_TCP_KEEPALIVE, CURLOT_LONG, 0},
+ {"TCP_KEEPCNT", CURLOPT_TCP_KEEPCNT, CURLOT_LONG, 0},
{"TCP_KEEPIDLE", CURLOPT_TCP_KEEPIDLE, CURLOT_LONG, 0},
{"TCP_KEEPINTVL", CURLOPT_TCP_KEEPINTVL, CURLOT_LONG, 0},
{"TCP_NODELAY", CURLOPT_TCP_NODELAY, CURLOT_LONG, 0},
*/
int Curl_easyopts_check(void)
{
- return ((CURLOPT_LASTENTRY%10000) != (325 + 1));
+ return ((CURLOPT_LASTENTRY%10000) != (326 + 1));
}
#endif
arg = INT_MAX;
data->set.tcp_keepintvl = (int)arg;
break;
+ case CURLOPT_TCP_KEEPCNT:
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ else if(arg > INT_MAX)
+ arg = INT_MAX;
+ data->set.tcp_keepcnt = (int)arg;
+ break;
case CURLOPT_TCP_FASTOPEN:
#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \
defined(TCP_FASTOPEN_CONNECT)
set->tcp_keepalive = FALSE;
set->tcp_keepintvl = 60;
set->tcp_keepidle = 60;
+ set->tcp_keepcnt = 9;
set->tcp_fastopen = FALSE;
set->tcp_nodelay = TRUE;
set->ssl_enable_alpn = TRUE;
int tcp_keepidle; /* seconds in idle before sending keepalive probe */
int tcp_keepintvl; /* seconds between TCP keepalive probes */
+ int tcp_keepcnt; /* maximum number of keepalive probes */
long expect_100_timeout; /* in milliseconds */
#if defined(USE_HTTP2) || defined(USE_HTTP3)
bool post302;
bool post303;
bool nokeepalive; /* for keepalive needs */
- long alivetime;
+ long alivetime; /* keepalive-time */
+ long alivecnt; /* keepalive-cnt */
bool content_disposition; /* use Content-disposition filename */
int default_node_flags; /* default flags to search for each 'node', which
C_JSON,
C_JUNK_SESSION_COOKIES,
C_KEEPALIVE,
+ C_KEEPALIVE_CNT,
C_KEEPALIVE_TIME,
C_KEY,
C_KEY_TYPE,
{"json", ARG_STRG, ' ', C_JSON},
{"junk-session-cookies", ARG_BOOL, 'j', C_JUNK_SESSION_COOKIES},
{"keepalive", ARG_BOOL, ' ', C_KEEPALIVE},
+ {"keepalive-cnt", ARG_STRG, ' ', C_KEEPALIVE_CNT},
{"keepalive-time", ARG_STRG, ' ', C_KEEPALIVE_TIME},
{"key", ARG_FILE, ' ', C_KEY},
{"key-type", ARG_STRG, ' ', C_KEY_TYPE},
case C_KEEPALIVE_TIME: /* --keepalive-time */
err = str2unum(&config->alivetime, nextarg);
break;
+ case C_KEEPALIVE_CNT: /* --keepalive-cnt */
+ err = str2unum(&config->alivecnt, nextarg);
+ break;
case C_POST301: /* --post301 */
config->post301 = toggle;
break;
{"-j, --junk-session-cookies",
"Ignore session cookies read from file",
CURLHELP_HTTP},
+ {" --keepalive-cnt <integer>",
+ "Maximum number of keepalive probes",
+ CURLHELP_CONNECTION},
{" --keepalive-time <seconds>",
"Interval time for keepalive probes",
CURLHELP_CONNECTION},
my_setopt(curl, CURLOPT_TCP_KEEPIDLE, config->alivetime);
my_setopt(curl, CURLOPT_TCP_KEEPINTVL, config->alivetime);
}
+ if(config->alivecnt)
+ my_setopt(curl, CURLOPT_TCP_KEEPCNT, config->alivecnt);
}
else
my_setopt(curl, CURLOPT_TCP_KEEPALIVE, 0L);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 1L);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 1L);
+ curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 1L);
/* Enable uploading. */
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");