All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Ahern <dsahern@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] PATCH: enabling TCP keepalives - v3
Date: Thu, 30 Apr 2009 13:40:42 -0600	[thread overview]
Message-ID: <49F9FEBA.6050901@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 488 bytes --]

Did not see a response to the last version.

This patch enables TCP keepalives on VNC connections and TCP-based char
devices.

Default parameters have keep alive probes sent after 60-seconds of idle
time. Probes are sent every 12 seconds with the connection resetting
after 5 failed probes (ie., connection is closed if no response received
in 60-seconds).

Changes v2 -> v3
Removed duplicate definition and fixed typo in comments.

Signed-off-by: David Ahern <dsahern@gmail.com>


david

[-- Attachment #2: enable-tcp-keepalives-v3.patch --]
[-- Type: text/plain, Size: 4658 bytes --]

diff --git a/configure b/configure
index 82fb60a..41ba86a 100755
--- a/configure
+++ b/configure
@@ -1673,6 +1673,37 @@ if test "$fdt" = "yes" ; then
   echo "FDT_LIBS=-lfdt" >> $config_mak
 fi
 
+cat > $TMPC << EOF
+#include <sys/socket.h>
+int main(void) {
+  int val = 1;
+  if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) < 0)
+    return 1;
+  return 0;
+}
+EOF
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC >/dev/null 2> /dev/null ; then
+  echo "#define HAVE_SO_KEEPALIVE 1" >> $config_h
+fi
+cat > $TMPC << EOF
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+#include <netinet/in.h>
+int main(void) {
+  int val = 1;
+  if (setsockopt(0, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0)
+    return 1;
+  if (setsockopt(0, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0)
+    return 1;
+  if (setsockopt(0, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0)
+    return 1;
+  return 0;
+}
+EOF
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC >/dev/null 2> /dev/null ; then
+  echo "#define HAVE_TCP_KEEPXXXX 1" >> $config_h
+fi
+
 # XXX: suppress that
 if [ "$bsd" = "yes" ] ; then
   echo "#define O_LARGEFILE 0" >> $config_h
diff --git a/net.c b/net.c
index 7ae1e6d..bb85889 100644
--- a/net.c
+++ b/net.c
@@ -2209,3 +2209,36 @@ void net_client_check(void)
                     vlan->id);
     }
 }
+
+int enable_tcp_keepalive(int sd, int keepidle, int keepintvl, int keepcnt)
+{
+#ifdef HAVE_SO_KEEPALIVE
+    int val = 1;
+
+    if (setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) < 0) {
+		return -1;
+    }
+
+#ifdef HAVE_TCP_KEEPXXXX
+    val = keepidle;
+    if ((val > 0) &&
+	    (setsockopt(sd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0)) {
+        fprintf(stderr, "failed to set tcp idle interval on fd %d\n", sd);
+    }
+
+    val = keepintvl;
+    if ((val > 0) &&
+        (setsockopt(sd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0)) {
+        fprintf(stderr, "failed to set tcp probe interval on fd %d\n", sd);
+    }
+
+    val = keepcnt;
+    if ((val > 0) &&
+        (setsockopt(sd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0)) {
+        fprintf(stderr, "failed to set tcp missed probe count on fd %d\n", sd);
+    }
+#endif
+#endif
+
+    return 0;
+}
diff --git a/net.h b/net.h
index cdf63a4..c7dbadf 100644
--- a/net.h
+++ b/net.h
@@ -119,6 +119,8 @@ void net_client_check(void);
 void net_host_device_add(Monitor *mon, const char *device, const char *opts);
 void net_host_device_remove(Monitor *mon, int vlan_id, const char *device);
 
+int enable_tcp_keepalive(int sd, int keepidle, int keepintvl, int keepcnt);
+
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
 #ifdef __sun__
diff --git a/qemu-char.c b/qemu-char.c
index 664cbfd..e1411c4 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -103,6 +103,14 @@
 
 #include "qemu_socket.h"
 
+/* timers for TCP keepalives: start probes after CHAR_TCP_KEEPIDLE
+ * seconds of no activity, send probes every CHAR_TCP_KEEPINTVL seconds,
+ * close connection after CHAR_TCP_KEEPCNT failed probes
+ */
+#define CHAR_TCP_KEEPIDLE  60
+#define CHAR_TCP_KEEPINTVL 12
+#define CHAR_TCP_KEEPCNT    5
+
 /***********************************************************/
 /* character device */
 
@@ -1990,6 +1998,10 @@ static void tcp_chr_accept(void *opaque)
         if (fd < 0 && errno != EINTR) {
             return;
         } else if (fd >= 0) {
+            if (enable_tcp_keepalive(fd, CHAR_TCP_KEEPIDLE,
+                                  CHAR_TCP_KEEPINTVL, CHAR_TCP_KEEPCNT) != 0) {
+                fprintf(stderr, "VNC: failed to enable TCP keep alives\n");
+            }
             if (s->do_telnetopt)
                 tcp_chr_telnet_init(fd);
             break;
diff --git a/vnc.c b/vnc.c
index ab1f044..c42cba9 100644
--- a/vnc.c
+++ b/vnc.c
@@ -32,6 +32,14 @@
 
 #define VNC_REFRESH_INTERVAL (1000 / 30)
 
+/* timers for TCP keepalives: start probes after VNC_TCP_KEEPIDLE
+ * seconds of no activity, send probes every VNC_TCP_KEEPINTVL seconds,
+ * close connection after VNC_TCP_KEEPCNT failed probes
+ */
+#define VNC_TCP_KEEPIDLE  60
+#define VNC_TCP_KEEPINTVL 12
+#define VNC_TCP_KEEPCNT    5
+
 #include "vnc_keysym.h"
 #include "d3des.h"
 
@@ -2021,6 +2029,11 @@ static void vnc_listen_read(void *opaque)
 
     int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
     if (csock != -1) {
+        if (enable_tcp_keepalive(csock, VNC_TCP_KEEPIDLE, 
+                                 VNC_TCP_KEEPINTVL, VNC_TCP_KEEPCNT) != 0) {
+            fprintf(stderr, "VNC: failed to enable TCP keep alives\n");
+        }
+
         vnc_connect(vs, csock);
     }
 }

             reply	other threads:[~2009-04-30 19:40 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-30 19:40 David Ahern [this message]
2009-05-01 11:32 ` [Qemu-devel] PATCH: enabling TCP keepalives - v3 Richard W.M. Jones
2009-05-01 12:23   ` Jamie Lokier
2009-05-01 12:49   ` David Ahern
2009-05-01 15:23     ` Daniel P. Berrange
2009-05-01 15:47       ` David Ahern
2009-05-01 17:21         ` Richard W.M. Jones
2009-05-05  1:31         ` Jamie Lokier
2009-05-05  2:59           ` David Ahern
2009-05-01 15:52       ` Avi Kivity
2009-05-01 16:11         ` John Haxby
2009-05-05  1:35           ` Jamie Lokier
2009-05-01 14:43 ` Anthony Liguori
2009-05-01 14:47   ` David Ahern
2009-05-01 14:51     ` Anthony Liguori
2009-05-01 15:16       ` Paul Brook
2009-05-01 15:57         ` Anthony Liguori
2009-05-01 16:04           ` Paul Brook
2009-05-01 16:11             ` David Ahern

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49F9FEBA.6050901@gmail.com \
    --to=dsahern@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.