|
|
1a1a75 |
From 9e9f2b81652d2ed551e9f890d27cf5a0da6ba5f6 Mon Sep 17 00:00:00 2001
|
|
|
1a1a75 |
From: Jeremy White <jwhite@codeweavers.com>
|
|
|
1a1a75 |
Date: Tue, 30 Apr 2019 17:04:59 -0500
|
|
|
1a1a75 |
Subject: [PATCH] Detect timeout conditions more aggressively on Linux
|
|
|
1a1a75 |
|
|
|
1a1a75 |
This mitigates a fairly rare problem we see with our kiosk mode clients.
|
|
|
1a1a75 |
That is, normally if something goes wrong with a client connection
|
|
|
1a1a75 |
(e.g. the session is killed, or the server is restarted ), the kiosk will
|
|
|
1a1a75 |
exit on disconnect, and we get a chance to retry the connection, or
|
|
|
1a1a75 |
present the user with a 'server down' style message.
|
|
|
1a1a75 |
|
|
|
1a1a75 |
But in the case of a serious network problem or a server hard power
|
|
|
1a1a75 |
cycle (i.e. no TCP FIN packets can flow), our end user behavior is not
|
|
|
1a1a75 |
ideal - the kiosk appears to hang solid, requiring a power cycle.
|
|
|
1a1a75 |
|
|
|
1a1a75 |
That's because we've got the stock keepalive timeouts, or about 2 hours
|
|
|
1a1a75 |
and 11 minutes, before the client sees the disconnect.
|
|
|
1a1a75 |
|
|
|
1a1a75 |
This change will cause the client to recognize the server has vanished
|
|
|
1a1a75 |
without a TCP FIN after 75 seconds.
|
|
|
1a1a75 |
|
|
|
1a1a75 |
See this thread:
|
|
|
1a1a75 |
https://lists.freedesktop.org/archives/spice-devel/2017-March/036553.html
|
|
|
1a1a75 |
|
|
|
1a1a75 |
As well as this bug:
|
|
|
1a1a75 |
https://bugzilla.redhat.com/show_bug.cgi?id=1436589
|
|
|
1a1a75 |
|
|
|
1a1a75 |
Signed-off-by: Jeremy White <jwhite@codeweavers.com>
|
|
|
1a1a75 |
(cherry picked from commit 677782fb6aa471d5e6d007744a5c6564b1f3021f)
|
|
|
1a1a75 |
---
|
|
|
1a1a75 |
src/spice-session.c | 26 ++++++++++++++++++++++++++
|
|
|
1a1a75 |
1 file changed, 26 insertions(+)
|
|
|
1a1a75 |
|
|
|
1a1a75 |
diff --git a/src/spice-session.c b/src/spice-session.c
|
|
|
1a1a75 |
index ee6e4cf..59c20c7 100644
|
|
|
1a1a75 |
--- a/src/spice-session.c
|
|
|
1a1a75 |
+++ b/src/spice-session.c
|
|
|
1a1a75 |
@@ -17,6 +17,8 @@
|
|
|
1a1a75 |
*/
|
|
|
1a1a75 |
#include "config.h"
|
|
|
1a1a75 |
|
|
|
1a1a75 |
+/* include first, on Windows will override winsock definitions */
|
|
|
1a1a75 |
+#include <gio/gnetworking.h>
|
|
|
1a1a75 |
#include <gio/gio.h>
|
|
|
1a1a75 |
#include <glib.h>
|
|
|
1a1a75 |
#ifdef G_OS_UNIX
|
|
|
1a1a75 |
@@ -39,6 +41,13 @@ struct channel {
|
|
|
1a1a75 |
RingItem link;
|
|
|
1a1a75 |
};
|
|
|
1a1a75 |
|
|
|
1a1a75 |
+#if !defined(SOL_TCP) && defined(IPPROTO_TCP)
|
|
|
1a1a75 |
+#define SOL_TCP IPPROTO_TCP
|
|
|
1a1a75 |
+#endif
|
|
|
1a1a75 |
+#if !defined(TCP_KEEPIDLE) && defined(TCP_KEEPALIVE) && defined(__APPLE__)
|
|
|
1a1a75 |
+#define TCP_KEEPIDLE TCP_KEEPALIVE
|
|
|
1a1a75 |
+#endif
|
|
|
1a1a75 |
+
|
|
|
1a1a75 |
#define IMAGES_CACHE_SIZE_DEFAULT (1024 * 1024 * 80)
|
|
|
1a1a75 |
#define MIN_GLZ_WINDOW_SIZE_DEFAULT (1024 * 1024 * 12)
|
|
|
1a1a75 |
#define MAX_GLZ_WINDOW_SIZE_DEFAULT MIN((LZ_MAX_WINDOW_SIZE * 4), 1024 * 1024 * 64)
|
|
|
1a1a75 |
@@ -2233,6 +2242,23 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC
|
|
|
1a1a75 |
g_socket_set_timeout(socket, 0);
|
|
|
1a1a75 |
g_socket_set_blocking(socket, FALSE);
|
|
|
1a1a75 |
g_socket_set_keepalive(socket, TRUE);
|
|
|
1a1a75 |
+
|
|
|
1a1a75 |
+ /* Make client timeouts a bit more responsive */
|
|
|
1a1a75 |
+#if defined(_WIN32)
|
|
|
1a1a75 |
+ /* Windows does not support setting count */
|
|
|
1a1a75 |
+ struct tcp_keepalive keepalive = {
|
|
|
1a1a75 |
+ TRUE,
|
|
|
1a1a75 |
+ 30 * 1000,
|
|
|
1a1a75 |
+ 5 * 1000
|
|
|
1a1a75 |
+ };
|
|
|
1a1a75 |
+ DWORD written;
|
|
|
1a1a75 |
+ WSAIoctl(g_socket_get_fd(socket), SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive),
|
|
|
1a1a75 |
+ NULL, 0, &written, NULL, NULL);
|
|
|
1a1a75 |
+#elif defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL)
|
|
|
1a1a75 |
+ g_socket_set_option(socket, SOL_TCP, TCP_KEEPIDLE, 30, NULL);
|
|
|
1a1a75 |
+ g_socket_set_option(socket, SOL_TCP, TCP_KEEPINTVL, 15, NULL);
|
|
|
1a1a75 |
+ g_socket_set_option(socket, SOL_TCP, TCP_KEEPCNT, 3, NULL);
|
|
|
1a1a75 |
+#endif
|
|
|
1a1a75 |
}
|
|
|
1a1a75 |
|
|
|
1a1a75 |
g_clear_object(&open_host.client);
|
|
|
1a1a75 |
--
|
|
|
1a1a75 |
2.21.0
|
|
|
1a1a75 |
|