Keep alive
Once a TCP connection has been established, that connection is defined to bevalid until one side closes it. Once the connection has entered the connectedstate, it will remain connected indefinitely. In reality, the connection willnot last indefinitely. Many firewalls or NAT systems close connections ifthere has been no activity in some time period. The Keep Alive signal can beused to refrain intermediate hosts from closing idle connection due toinactivity.
libcurl offers several options to enable and control TCP Keep alive forconnections it creates. There is one main boolean option to switch the featureon/off, and there arethree separate options for the counters and timeoutsinvolved.
It can be noted that while this method tries to defeat middle boxes closingdown idle connections, there are also such boxes that plain simply ignore keepalive probes. There are no guarantees that this actually works.
Enable keep alive
Set theCURLOPT_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 createsusing this handle. If it creates connections using other protocols, like UDPor QUIC, those connections will not be affected.
Idle time
You set theCURLOPT_TCP_KEEPIDLE
long to the number of seconds you want theconnection to be idle before sending the first keep alive probe. The defaultvalue is 60 seconds. It makes sense to try to set this to a time slightlylower than the time limit in your strictest middle box.
Probe interval
SetCURLOPT_TCP_KEEPINTVL
to a long for the number of seconds to waitbetween subsequent keep alive probes. The probes that follow once the firstkeep alive probe has been sent. Default is 60 seconds.
Probe count
Sometimes referred as keep alive retry. SetCURLOPT_TCP_KEEPCNT
to a longholding the number of retransmissions to be carried out before declaring thatremote end is not available and closing the connection. Default is 9. Thislibcurl 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); }}
HTTPKeep-Alive
There was this old keyword calledKeep-Alive
used for HTTP/1.0 in theConnection:
header. It has an entirely separate functionality and is notrelated to TCP Keep Alive: it meant that the connection should be kept alivefor persistent use in subsequent transfers. That became default for HTTP in1.1.
QUIC and HTTP/2
Both QUIC and HTTP/2 have PING frames that can be sent between two peersinvolved in the communication that then have similar effects as TCP KeepAlive. These options do however not control libcurl's use of PING frames.