diff options
| author | Xiaofeng Liu <xiaofeng.liu@6wind.com> | 2017-12-05 10:25:16 +0100 |
|---|---|---|
| committer | Philippe Guibert <philippe.guibert@6wind.com> | 2022-07-28 16:42:01 +0200 |
| commit | 5c480b5db3d14f37682eee1a6ae431b88ead0f9e (patch) | |
| tree | f858b0c3d60a17cbb65ff9af4e98493c9ca534c3 /lib | |
| parent | 9982282d41466f6be1422a7610774fb0421ba8da (diff) | |
lib: add a function to configure tcp keepalive parameters
New function setsockopt_tcp_keepalive() is added to enable TCP keepalive
mechanism for specified socket. Also TCP keepalive idle time, interval
and maximum probes are configured.
Signed-off-by: Xiaofeng Liu <xiaofeng.liu@6wind.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sockopt.c | 49 | ||||
| -rw-r--r-- | lib/sockopt.h | 22 |
2 files changed, 71 insertions, 0 deletions
diff --git a/lib/sockopt.c b/lib/sockopt.c index 45f3c23330..a66a5224e8 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -699,3 +699,52 @@ int sockopt_tcp_mss_get(int sock) return tcp_maxseg; } + +int setsockopt_tcp_keepalive(int sock, uint16_t keepalive_idle, + uint16_t keepalive_intvl, + uint16_t keepalive_probes) +{ + int val = 1; + + if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) < 0) { + flog_err_sys(EC_LIB_SYSTEM_CALL, + "%s failed: setsockopt SO_KEEPALIVE (%d): %s", + __func__, sock, safe_strerror(errno)); + return -1; + } + +#if defined __OpenBSD__ + return 0; +#else + /* Send first probe after keepalive_idle seconds */ + val = keepalive_idle; + if (setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < + 0) { + flog_err_sys(EC_LIB_SYSTEM_CALL, + "%s failed: setsockopt TCP_KEEPIDLE (%d): %s", + __func__, sock, safe_strerror(errno)); + return -1; + } + + /* Set interval between two probes */ + val = keepalive_intvl; + if (setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < + 0) { + flog_err_sys(EC_LIB_SYSTEM_CALL, + "%s failed: setsockopt TCP_KEEPINTVL (%d): %s", + __func__, sock, safe_strerror(errno)); + return -1; + } + + /* Set maximum probes */ + val = keepalive_probes; + if (setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { + flog_err_sys(EC_LIB_SYSTEM_CALL, + "%s failed: setsockopt TCP_KEEPCNT (%d): %s", + __func__, sock, safe_strerror(errno)); + return -1; + } + + return 0; +#endif +} diff --git a/lib/sockopt.h b/lib/sockopt.h index 6c80841e3c..694edf7638 100644 --- a/lib/sockopt.h +++ b/lib/sockopt.h @@ -153,6 +153,28 @@ extern int sockopt_tcp_mss_set(int sock, int tcp_maxseg); * Socket to get max segement size. */ extern int sockopt_tcp_mss_get(int sock); + +/* + * Configure TCP keepalive for a given socket + * + * sock + * Socket to enable keepalive option on. + * + * keepalive_idle + * number of seconds a connection needs to be idle + * before sending out keep-alive proves + * + * keepalive_intvl + * number of seconds between TCP keep-alive probes + * + * keepalive_probes + * max number of probers to send before giving up + * and killing tcp connection + */ +extern int setsockopt_tcp_keepalive(int sock, uint16_t keepalive_idle, + uint16_t keepalive_intvl, + uint16_t keepalive_probes); + #ifdef __cplusplus } #endif |
