[Spice-devel] [PATCH] usbredirserver : enable TCP keepalive
Frediano Ziglio
fziglio at redhat.com
Fri Mar 9 07:49:13 UTC 2018
>
> In some bad cases, for example, host OS crashes without
> sending any FIN to usbredirserver, and usbredirserver
> will keep idle connection for a long time.
>
> We can also set the kernel arguments, it means that other
> processes may be affected.
>
> Setting a sensible timeout(like 10 minutes) seems good.
> But QEMU is restarted after host OS crashes, it usually
> needs to reconnect usbredirserver within 2 minutes.
>
> So, add cmdline argument '-k' and "--keepalive" for
> usbredirserver to set tcp keepalive idle time(30s),
> interval time(10s), and maximum number of keepalive probes
> count(3). Detecting disconnection costs time is :
> 30s + 10s * 3 = 60s
>
> If setting TCP keepalive fails with errno ENOTSUP, ignore
> the specific error.
>
> Signed-off-by: zhenwei.pi <zhenwei.pi at youruncloud.com>
> ---
> usbredirserver/usbredirserver.c | 41
> ++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/usbredirserver/usbredirserver.c
> b/usbredirserver/usbredirserver.c
> index 5575181..246171c 100644
> --- a/usbredirserver/usbredirserver.c
> +++ b/usbredirserver/usbredirserver.c
> @@ -37,6 +37,7 @@
> #include <netdb.h>
> #include <netinet/in.h>
> #include <arpa/inet.h>
> +#include <netinet/tcp.h>
> #include "usbredirhost.h"
>
>
> @@ -52,6 +53,7 @@ static const struct option longopts[] = {
> { "verbose", required_argument, NULL, 'v' },
> { "ipv4", required_argument, NULL, '4' },
> { "ipv6", required_argument, NULL, '6' },
> + { "keepalive", no_argument, NULL, 'k' },
> { "help", no_argument, NULL, 'h' },
> { NULL, 0, NULL, 0 }
> };
> @@ -98,6 +100,7 @@ static void usage(int exit_code, char *argv0)
> fprintf(exit_code? stderr:stdout,
> "Usage: %s [-p|--port <port>] [-v|--verbose <0-5>] "
> "[[-4|--ipv4 ipaddr]|[-6|--ipv6 ipaddr]] "
> + "[-k|--keepalive] "
> "<busnum-devnum|vendorid:prodid>\n",
> argv0);
> exit(exit_code);
> @@ -203,6 +206,7 @@ int main(int argc, char *argv[])
> int usbvendor = -1;
> int usbproduct = -1;
> int on = 1;
> + int keepalive = 0;
> char *ipv4_addr = NULL, *ipv6_addr = NULL;
> union {
> struct sockaddr_in v4;
> @@ -211,7 +215,7 @@ int main(int argc, char *argv[])
> struct sigaction act;
> libusb_device_handle *handle = NULL;
>
> - while ((o = getopt_long(argc, argv, "hp:v:4:6:", longopts, NULL)) != -1)
> {
> + while ((o = getopt_long(argc, argv, "hp:v:4:6:k", longopts, NULL)) !=
> -1) {
> switch (o) {
> case 'p':
> port = strtol(optarg, &endptr, 10);
> @@ -233,6 +237,9 @@ int main(int argc, char *argv[])
> case '6':
> ipv6_addr = optarg;
> break;
> + case 'k':
> + keepalive = 1;
> + break;
> case '?':
> case 'h':
> usage(o == '?', argv[0]);
> @@ -348,6 +355,38 @@ int main(int argc, char *argv[])
> break;
> }
>
> + if (keepalive) {
> + int optval = 1;
> + socklen_t optlen = sizeof(optval);
> + if (setsockopt(client_fd, SOL_SOCKET, SO_KEEPALIVE, &optval,
> optlen) == -1) {
> + if (errno != ENOTSUP) {
> + perror("setsockopt SO_KEEPALIVE error.");
> + break;
> + }
> + }
> + optval = 30; /* set default TCP_KEEPIDLE time as 30s */
> + if (setsockopt(client_fd, SOL_TCP, TCP_KEEPIDLE, &optval,
> optlen) == -1) {
> + if (errno != ENOTSUP) {
> + perror("setsockopt TCP_KEEPIDLE error.");
> + break;
> + }
> + }
> + optval = 10; /* set default TCP_KEEPINTVL time as 10s */
> + if (setsockopt(client_fd, SOL_TCP, TCP_KEEPINTVL, &optval,
> optlen) == -1) {
> + if (errno != ENOTSUP) {
> + perror("setsockopt TCP_KEEPINTVL error.");
> + break;
> + }
> + }
> + optval = 3; /* set default TCP_KEEPCNT as 3 */
> + if (setsockopt(client_fd, SOL_TCP, TCP_KEEPCNT, &optval, optlen)
> == -1) {
> + if (errno != ENOTSUP) {
> + perror("setsockopt TCP_KEEPCNT error.");
> + break;
> + }
> + }
> + }
> +
> flags = fcntl(client_fd, F_GETFL);
> if (flags == -1) {
> perror("fcntl F_GETFL");
Good for me.
I would have expect a less strong change, kind of keeping the keepalive
argument and use for just TCP_KEEPIDLE and set the other options with
fixed values. I remember you had an observation about different
environment were could be needed to tweak the time.
Otherwise,
Acked-by: Frediano Ziglio <fziglio at redhat.com>
Note that the patch was tested by Uri Lublin, I would add (whomever is
going to merge it) at least a
Tested-by: Uri Lublin <uril at redhat.com>
Frediano
More information about the Spice-devel
mailing list