]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: add a function to configure tcp keepalive parameters
authorXiaofeng Liu <xiaofeng.liu@6wind.com>
Tue, 5 Dec 2017 09:25:16 +0000 (10:25 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 28 Jul 2022 14:42:01 +0000 (16:42 +0200)
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>
lib/sockopt.c
lib/sockopt.h

index 45f3c2333073143e07c130afc55eb61c356340f6..a66a5224e8ade9257502fe2a6615be7bcc222c14 100644 (file)
@@ -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
+}
index 6c80841e3c2b904ec20a8b1766bae21ef11e01e9..694edf7638aad6b39500dd57af8bb6680f005968 100644 (file)
@@ -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