summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorXiaofeng Liu <xiaofeng.liu@6wind.com>2017-12-05 10:25:16 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2022-07-28 16:42:01 +0200
commit5c480b5db3d14f37682eee1a6ae431b88ead0f9e (patch)
treef858b0c3d60a17cbb65ff9af4e98493c9ca534c3 /lib
parent9982282d41466f6be1422a7610774fb0421ba8da (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.c49
-rw-r--r--lib/sockopt.h22
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