[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] PATCH: enabling TCP keepalives v2
From: |
David Ahern |
Subject: |
[Qemu-devel] PATCH: enabling TCP keepalives v2 |
Date: |
Tue, 28 Apr 2009 11:42:11 -0600 |
User-agent: |
Thunderbird 2.0.0.21 (X11/20090320) |
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 v1 -> v2:
- Added probes to configure
- Moved setsockopt calls into a generic handler named
enable_tcp_keepalive in net.c
- Added call to enable_tcp_keepalive() to vnc and qemu-char
Signed-off-by: David Ahern <address@hidden>
david
diff --git a/configure b/configure
index 1cbeabc..b932fc3 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..d52ca78 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -103,6 +103,15 @@
#include "qemu_socket.h"
+/* 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 CHAR_TCP_KEEPIDLE 60
+#define CHAR_TCP_KEEPIDLE 60
+#define CHAR_TCP_KEEPINTVL 12
+#define CHAR_TCP_KEEPCNT 5
+
/***********************************************************/
/* character device */
@@ -1990,6 +1999,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);
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] PATCH: enabling TCP keepalives v2,
David Ahern <=