Merge pull request #1549 from mfournier/socket-keepalive
authorMarc Fournier <marc.fournier@camptocamp.com>
Tue, 9 Aug 2016 14:55:03 +0000 (16:55 +0200)
committerGitHub <noreply@github.com>
Tue, 9 Aug 2016 14:55:03 +0000 (16:55 +0200)
Enable TCP socket keepalive on write plugins

src/daemon/common.c
src/daemon/common.h
src/write_graphite.c
src/write_riemann.c
src/write_sensu.c
src/write_tsdb.c

index b60530a..c4dbecb 100644 (file)
 # include <netinet/in.h>
 #endif
 
+#if HAVE_NETINET_TCP_H
+# include <netinet/tcp.h>
+#endif
+
 /* for ntohl and htonl */
 #if HAVE_ARPA_INET_H
 # include <arpa/inet.h>
@@ -1557,6 +1561,46 @@ int service_name_to_port_number (const char *service_name)
        return (-1);
 } /* int service_name_to_port_number */
 
+void set_sock_opts (int sockfd) /* {{{ */
+{
+       int status;
+       int socktype;
+
+       socklen_t socklen = sizeof (socklen_t);
+       int so_keepalive = 1;
+       int tcp_keepidle = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 100 + 1);
+       int tcp_keepintvl = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 1000 + 1);
+
+       status = getsockopt (sockfd, SOL_SOCKET, SO_TYPE, &socktype, &socklen);
+       if (status != 0)
+       {
+               WARNING ("set_sock_opts: failed to determine socket type");
+               return;
+       }
+
+       if (socktype == SOCK_STREAM)
+       {
+               status = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
+                               &so_keepalive, sizeof (so_keepalive));
+               if (status != 0)
+                       WARNING ("set_sock_opts: failed to set socket keepalive flag");
+
+#ifdef TCP_KEEPIDLE
+               status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
+                               &tcp_keepidle, sizeof (tcp_keepidle));
+               if (status != 0)
+                       WARNING ("set_sock_opts: failed to set socket tcp keepalive time");
+#endif
+
+#ifdef TCP_KEEPINTVL
+               status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
+                               &tcp_keepintvl, sizeof (tcp_keepintvl));
+               if (status != 0)
+                       WARNING ("set_sock_opts: failed to set socket tcp keepalive interval");
+#endif
+       }
+} /* }}} void set_sock_opts */
+
 int strtoderive (const char *string, derive_t *ret_value) /* {{{ */
 {
        derive_t tmp;
index 8079661..5ad2b50 100644 (file)
@@ -361,6 +361,9 @@ int value_to_rate (gauge_t *ret_rate, value_t value, int ds_type, cdtime_t t,
  * (in the range [1-65535]). Returns less than zero on error. */
 int service_name_to_port_number (const char *service_name);
 
+/* Sets various, non-default, socket options */
+void set_sock_opts (int sockfd);
+
 /** Parse a string to a derive_t value. Returns zero on success or non-zero on
  * failure. If failure is returned, ret_value is not touched. */
 int strtoderive (const char *string, derive_t *ret_value);
index 2dce2d7..77003f1 100644 (file)
@@ -240,6 +240,8 @@ static int wg_callback_init (struct wg_callback *cb)
             continue;
         }
 
+        set_sock_opts (cb->sock_fd);
+
         status = connect (cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
         if (status != 0)
         {
index 10f8958..f143723 100644 (file)
@@ -112,6 +112,8 @@ static int wrr_connect(struct riemann_host *host) /* {{{ */
     }
   }
 
+  set_sock_opts(riemann_client_get_fd(host->client));
+
   c_release(LOG_INFO, &host->init_complaint,
             "write_riemann plugin: Successfully connected to %s:%d", node,
             port);
index b07b3bf..77069c0 100644 (file)
@@ -196,6 +196,8 @@ static int sensu_connect(struct sensu_host *host) /* {{{ */
                if (setsockopt(host->s, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger) != 0)
                        WARNING("write_sensu plugin: failed to set socket close() lingering");
 
+               set_sock_opts(host->s);
+
                // connect the socket
                if (connect(host->s, ai->ai_addr, ai->ai_addrlen) != 0) {
                        close(host->s);
index 309418a..bf49ba5 100644 (file)
@@ -187,6 +187,8 @@ static int wt_callback_init(struct wt_callback *cb)
         if (cb->sock_fd < 0)
             continue;
 
+        set_sock_opts(cb->sock_fd);
+
         status = connect(cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
         if (status != 0)
         {