Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transfers/conn: document the TCP keepalive options #474

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@
* [How libcurl connects](transfers/conn/how.md)
* [Local address and port number](transfers/conn/local.md)
* [Connection reuse](transfers/conn/reuse.md)
* [Keep alive](transfers/conn/keepalive.md)
* [Name resolving](transfers/conn/names.md)
* [Proxies](transfers/conn/proxies.md)
* [Transfer control](transfers/control/README.md)
Expand Down
3 changes: 3 additions & 0 deletions index-words
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@ CURLOPT_SSL_VERIFYPEER
CURLOPT_SSLVERSION
CURLOPT_STDERR
CURLOPT_TCP_KEEPALIVE
CURLOPT_TCP_KEEPIDLE
CURLOPT_TCP_KEEPINTVL
CURLOPT_TCP_KEEPCNT
CURLOPT_TIMEOUT
CURLOPT_TLSAUTH_USERNAME
CURLOPT_UPLOAD
Expand Down
1 change: 1 addition & 0 deletions transfers/conn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ concepts for connections and options to control how it works with them.
* [How libcurl connects](how.md)
* [Local address and port number](local.md)
* [Connection reuse](reuse.md)
* [Keep alive](keepalive.md)
* [Name resolving](names.md)
* [Proxies](proxies.md)
85 changes: 85 additions & 0 deletions transfers/conn/keepalive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Keep alive

Once a TCP connection has been established, that connection is defined to be
valid until one side closes it. Once the connection has entered the connected
state, it will remain connected indefinitely. But, in reality, the connection
will not last indefinitely. Many firewalls or NAT systems close connections if
there has been no activity in some time period. The Keep Alive signal can be
used to refrain intermediate hosts from closing idle connection due to
inactivity.

libcurl offers several options to enable and control TCP Keep alive for
connections it creates. There is one main boolean option to switch the feature
on/off, and there are *three* separate options for the counters and timeouts
involved.

It can be noted that while this method tries to defeat middle boxes closing
down idle connections, there are also such boxes that plain simply ignore keep
alive probes. There are no guarantees that this actually works.

## Enable keep alive

Set the `CURLOPT_TCP_KEEPALIVE` long to 1 to enable, 0 to disable. If enabled,
libcurl will set TCP Keep Alive options on any new TCP connection it creates
using this handle. If it creates connections using other protocols, like UDP
or QUIC, those connections will not be affected.

## Idle time

You set the `CURLOPT_TCP_KEEPIDLE` long to the number of seconds you want the
connection to be idle before sending the first keep alive probe. The default
value is 60 seconds. It makes sense to try to set this to a time slightly
lower than the time limit in your strictest middle box.

## Probe interval

Set `CURLOPT_TCP_KEEPINTVL` to a long for the number of seconds to wait
between subsequent keep alive probes. The probes that follow once the first
keep alive probe has been sent. Default is 60 seconds.

## Probe count

Sometimes referred as keep alive retry. Set `CURLOPT_TCP_KEEPCNT` to a long
holding the number of retransmissions to be carried out before declaring that
remote end is not available and closing the connection. Default is 9. This
libcurl option was added in 8.9.0, long after the previous options.

## Example

A tiny example of libcurl application doing a transfer using TCP keep alive.

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);

/* 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);
}
}

## HTTP `Keep-Alive`

There was this old keyword called `Keep-Alive` used for HTTP/1.0 in the
`Connection:` header. It has an entirely separate functionality and is not
related to TCP Keep Alive: it meant that the connection should be kept alive
for persistent use in subsequent transfers. That became default for HTTP in
1.1.

## QUIC and HTTP/2

Both QUIC and HTTP/2 have PING frames that can be sent between two peers
involved in the communication that then have similar effects as TCP Keep
Alive. These options do however not control libcurl's use of PING frames.
1 change: 1 addition & 0 deletions wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ Referer
referer
repo
RETR
retransmissions
Rikard
ROADMAP
Rockbox
Expand Down
Loading