diff --git a/vnc.c b/vnc.c index ab1f044..7a8bbd7 100644 --- a/vnc.c +++ b/vnc.c @@ -32,6 +32,12 @@ #define VNC_REFRESH_INTERVAL (1000 / 30) +#ifdef __linux__ +#define VNC_TCP_KEEPIDLE 60 +#define VNC_TCP_KEEPINTVL 12 +#define VNC_TCP_KEEPCNT 5 +#endif + #include "vnc_keysym.h" #include "d3des.h" @@ -2015,12 +2021,41 @@ static void vnc_listen_read(void *opaque) VncDisplay *vs = opaque; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); + int val; /* Catch-up */ vga_hw_update(); int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen); if (csock != -1) { +#ifdef __linux__ + /* best effort to enable keep alives */ + val = 1; + if (setsockopt(csock, SOL_SOCKET, SO_KEEPALIVE, + &val, sizeof(val)) < 0) { + fprintf(stderr, "VNC: failed to enable keepalives\n"); + } + + /* after N-seconds of idle time, send probes every X seconds + * dropping the connection after Y failed probes. + */ + val = VNC_TCP_KEEPIDLE; + if (setsockopt(csock, IPPROTO_TCP, TCP_KEEPIDLE, + &val, sizeof(val)) < 0) { + fprintf(stderr, "VNC: failed to set tcp idle interval\n"); + } + val = VNC_TCP_KEEPINTVL; + if (setsockopt(csock, IPPROTO_TCP, TCP_KEEPINTVL, + &val, sizeof(val)) < 0) { + fprintf(stderr, "VNC: failed to set tcp probe interval\n"); + } + val = VNC_TCP_KEEPCNT; + if (setsockopt(csock, IPPROTO_TCP, TCP_KEEPCNT, + &val, sizeof(val)) < 0) { + fprintf(stderr, "VNC: failed to set tcp missed probe count\n"); + } +#endif + vnc_connect(vs, csock); } }