Compare commits
No commits in common. "c9s" and "c8s" have entirely different histories.
16
.gitignore
vendored
16
.gitignore
vendored
@ -1,17 +1 @@
|
||||
/usbredir-0.3.tar.bz2
|
||||
/usbredir-0.3.1.tar.bz2
|
||||
/usbredir-0.3.2.tar.bz2
|
||||
/usbredir-0.3.3.tar.bz2
|
||||
/usbredir-0.4.tar.bz2
|
||||
/usbredir-0.4.1.tar.bz2
|
||||
/usbredir-0.4.2.tar.bz2
|
||||
/usbredir-0.4.3.tar.bz2
|
||||
/usbredir-0.5.tar.bz2
|
||||
/usbredir-0.5.1.tar.bz2
|
||||
/usbredir-0.5.2.tar.bz2
|
||||
/usbredir-0.6.tar.bz2
|
||||
/usbredir-0.7.tar.bz2
|
||||
/usbredir-0.7.1.tar.bz2
|
||||
/usbredir-0.8.0.tar.bz2
|
||||
/usbredir-0.12.0.tar.xz
|
||||
/usbredir-0.13.0.tar.xz
|
||||
|
||||
@ -1,593 +0,0 @@
|
||||
From e06a042c1c0eccefeccc63e419b9b09bef11e28f Mon Sep 17 00:00:00 2001
|
||||
From: Victor Toso <victortoso@redhat.com>
|
||||
Date: Wed, 30 Nov 2022 21:02:20 +0100
|
||||
Subject: [PATCH] Revert "remove usbredirserver"
|
||||
Content-type: text/plain
|
||||
|
||||
This reverts commit f4ffdce329305da2803684776f7659083a530819.
|
||||
---
|
||||
README.md | 4 +
|
||||
meson.build | 1 +
|
||||
usbredirserver/meson.build | 12 +
|
||||
usbredirserver/usbredirserver.1 | 41 +++
|
||||
usbredirserver/usbredirserver.c | 474 ++++++++++++++++++++++++++++++++
|
||||
5 files changed, 532 insertions(+)
|
||||
create mode 100644 usbredirserver/meson.build
|
||||
create mode 100644 usbredirserver/usbredirserver.1
|
||||
create mode 100644 usbredirserver/usbredirserver.c
|
||||
|
||||
diff --git a/README.md b/README.md
|
||||
index ed04cca..2acb7b0 100644
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -28,6 +28,10 @@ The usbredirect binary is an usbredir client for exporting an USB device either
|
||||
as TCP client or server, for use from another (virtual) machine through the
|
||||
usbredir protocol.
|
||||
|
||||
+## usbredirserver
|
||||
+
|
||||
+A simple tcp server usb-host, using usbredirhost
|
||||
+
|
||||
## usbredirtestclient
|
||||
|
||||
A small testclient for the usbredir protocol over tcp, using usbredirparser
|
||||
diff --git a/meson.build b/meson.build
|
||||
index aac9909..e740778 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -103,6 +103,7 @@ if get_option('tools').enabled()
|
||||
subdir('tools')
|
||||
endif
|
||||
if host_machine.system() != 'windows'
|
||||
+ subdir('usbredirserver')
|
||||
subdir('usbredirtestclient')
|
||||
|
||||
if get_option('fuzzing').enabled()
|
||||
diff --git a/usbredirserver/meson.build b/usbredirserver/meson.build
|
||||
new file mode 100644
|
||||
index 0000000..de40681
|
||||
--- /dev/null
|
||||
+++ b/usbredirserver/meson.build
|
||||
@@ -0,0 +1,12 @@
|
||||
+usbredirserver_sources = [
|
||||
+ 'usbredirserver.c',
|
||||
+]
|
||||
+
|
||||
+executable('usbredirserver',
|
||||
+ sources : usbredirserver_sources,
|
||||
+ c_args : '-Wno-deprecated-declarations',
|
||||
+ install : true,
|
||||
+ install_dir: get_option('sbindir'),
|
||||
+ dependencies : usbredir_host_lib_dep)
|
||||
+
|
||||
+install_man('usbredirserver.1')
|
||||
diff --git a/usbredirserver/usbredirserver.1 b/usbredirserver/usbredirserver.1
|
||||
new file mode 100644
|
||||
index 0000000..d5a6793
|
||||
--- /dev/null
|
||||
+++ b/usbredirserver/usbredirserver.1
|
||||
@@ -0,0 +1,41 @@
|
||||
+.TH USBREDIRSERVER "1" "April 2012" "usbredirserver" "User Commands"
|
||||
+.SH NAME
|
||||
+usbredirserver \- exporting an USB device for use from another (virtual) machine
|
||||
+.SH SYNOPSIS
|
||||
+.B usbredirserver
|
||||
+[\fI-p|--port <port>\fR] [\fI-v|--verbose <0-5>\fR] [\fI-4 <ipv4_addr|I-6 <ipv6_addr>]
|
||||
+\fI<busnum-devnum|vendorid:prodid>\fR
|
||||
+.SH DESCRIPTION
|
||||
+usbredirserver is a small standalone server for exporting an USB device for
|
||||
+use from another (virtual) machine through the usbredir protocol.
|
||||
+.PP
|
||||
+You can specify the USB device to export either by USB id in the form of
|
||||
+\fI<vendorid>:<prodid>\fR, or by USB bus number and device address in the form
|
||||
+of \fI<usbbus>-<usbaddr>\fR.
|
||||
+.PP
|
||||
+Notice that an instance of usbredirserver can only be used to export a
|
||||
+single USB device. If you want to export multiple devices you can start
|
||||
+multiple instances listening on different TCP ports.
|
||||
+.SH OPTIONS
|
||||
+.TP
|
||||
+\fB\-p\fR, \fB\-\-port\fR=\fIPORT\fR
|
||||
+Set the TCP port to listen on to \fIPORT\fR
|
||||
+.TP
|
||||
+\fB\-v\fR, \fB\-\-verbose\fR=\fIVERBOSE\fR
|
||||
+Set usbredirserver's verbosity level to \fIVERBOSE\fR, this mostly affects USB
|
||||
+redirection related messages. Valid values are 0-5:
|
||||
+.br
|
||||
+0:Silent 1:Errors 2:Warnings 3:Info 4:Debug 5:Debug++
|
||||
+.SH AUTHOR
|
||||
+Written by Hans de Goede <hdegoede@redhat.com>
|
||||
+.SH REPORTING BUGS
|
||||
+You can report bugs to the spice-devel mailinglist:
|
||||
+http://lists.freedesktop.org/mailman/listinfo/spice-devel
|
||||
+or filing an issue at:
|
||||
+https://gitlab.freedesktop.org/spice/usbredir/issues/new
|
||||
+.SH COPYRIGHT
|
||||
+Copyright 2010-2012 Red Hat, Inc.
|
||||
+License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.
|
||||
+.br
|
||||
+This is free software: you are free to change and redistribute it.
|
||||
+There is NO WARRANTY, to the extent permitted by law.
|
||||
diff --git a/usbredirserver/usbredirserver.c b/usbredirserver/usbredirserver.c
|
||||
new file mode 100644
|
||||
index 0000000..badb7bc
|
||||
--- /dev/null
|
||||
+++ b/usbredirserver/usbredirserver.c
|
||||
@@ -0,0 +1,474 @@
|
||||
+/* usbredirserver.c simple usb network redirection tcp/ip server (host).
|
||||
+
|
||||
+ Copyright 2010-2011 Red Hat, Inc.
|
||||
+
|
||||
+ Red Hat Authors:
|
||||
+ Hans de Goede <hdegoede@redhat.com>
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
+*/
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <string.h>
|
||||
+#include <getopt.h>
|
||||
+#include <unistd.h>
|
||||
+#include <errno.h>
|
||||
+#include <poll.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <signal.h>
|
||||
+#include <sys/socket.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/time.h>
|
||||
+#include <netdb.h>
|
||||
+#include <netinet/in.h>
|
||||
+#include <arpa/inet.h>
|
||||
+#include <netinet/tcp.h>
|
||||
+#include "usbredirhost.h"
|
||||
+
|
||||
+
|
||||
+#define SERVER_VERSION "usbredirserver " PACKAGE_VERSION
|
||||
+
|
||||
+#if !defined(SOL_TCP) && defined(IPPROTO_TCP)
|
||||
+#define SOL_TCP IPPROTO_TCP
|
||||
+#endif
|
||||
+#if !defined(TCP_KEEPIDLE) && defined(TCP_KEEPALIVE) && defined(__APPLE__)
|
||||
+#define TCP_KEEPIDLE TCP_KEEPALIVE
|
||||
+#endif
|
||||
+
|
||||
+static int verbose = usbredirparser_info;
|
||||
+static int client_fd, running = 1;
|
||||
+static libusb_context *ctx;
|
||||
+static struct usbredirhost *host;
|
||||
+
|
||||
+static const struct option longopts[] = {
|
||||
+ { "port", required_argument, NULL, 'p' },
|
||||
+ { "verbose", required_argument, NULL, 'v' },
|
||||
+ { "ipv4", required_argument, NULL, '4' },
|
||||
+ { "ipv6", required_argument, NULL, '6' },
|
||||
+ { "keepalive", required_argument, NULL, 'k' },
|
||||
+ { "help", no_argument, NULL, 'h' },
|
||||
+ { NULL, 0, NULL, 0 }
|
||||
+};
|
||||
+
|
||||
+static void usbredirserver_log(void *priv, int level, const char *msg)
|
||||
+{
|
||||
+ if (level <= verbose)
|
||||
+ fprintf(stderr, "%s\n", msg);
|
||||
+}
|
||||
+
|
||||
+static int usbredirserver_read(void *priv, uint8_t *data, int count)
|
||||
+{
|
||||
+ int r = read(client_fd, data, count);
|
||||
+ if (r < 0) {
|
||||
+ if (errno == EAGAIN)
|
||||
+ return 0;
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (r == 0) { /* Client disconnected */
|
||||
+ close(client_fd);
|
||||
+ client_fd = -1;
|
||||
+ }
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static int usbredirserver_write(void *priv, uint8_t *data, int count)
|
||||
+{
|
||||
+ int r = write(client_fd, data, count);
|
||||
+ if (r < 0) {
|
||||
+ if (errno == EAGAIN)
|
||||
+ return 0;
|
||||
+ if (errno == EPIPE) { /* Client disconnected */
|
||||
+ close(client_fd);
|
||||
+ client_fd = -1;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+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 seconds] "
|
||||
+ "<busnum-devnum|vendorid:prodid>\n",
|
||||
+ argv0);
|
||||
+ exit(exit_code);
|
||||
+}
|
||||
+
|
||||
+static void invalid_usb_device_id(char *usb_device_id, char *argv0)
|
||||
+{
|
||||
+ fprintf(stderr, "Invalid usb device identifier: %s\n", usb_device_id);
|
||||
+ usage(1, argv0);
|
||||
+}
|
||||
+
|
||||
+static void run_main_loop(void)
|
||||
+{
|
||||
+ const struct libusb_pollfd **pollfds = NULL;
|
||||
+ fd_set readfds, writefds;
|
||||
+ int i, n, nfds;
|
||||
+ struct timeval timeout, *timeout_p;
|
||||
+
|
||||
+ while (running && client_fd != -1) {
|
||||
+ FD_ZERO(&readfds);
|
||||
+ FD_ZERO(&writefds);
|
||||
+
|
||||
+ FD_SET(client_fd, &readfds);
|
||||
+ if (usbredirhost_has_data_to_write(host)) {
|
||||
+ FD_SET(client_fd, &writefds);
|
||||
+ }
|
||||
+ nfds = client_fd + 1;
|
||||
+
|
||||
+ free(pollfds);
|
||||
+ pollfds = libusb_get_pollfds(ctx);
|
||||
+ for (i = 0; pollfds && pollfds[i]; i++) {
|
||||
+ if (pollfds[i]->events & POLLIN) {
|
||||
+ FD_SET(pollfds[i]->fd, &readfds);
|
||||
+ }
|
||||
+ if (pollfds[i]->events & POLLOUT) {
|
||||
+ FD_SET(pollfds[i]->fd, &writefds);
|
||||
+ }
|
||||
+ if (pollfds[i]->fd >= nfds)
|
||||
+ nfds = pollfds[i]->fd + 1;
|
||||
+ }
|
||||
+
|
||||
+ if (libusb_get_next_timeout(ctx, &timeout) == 1) {
|
||||
+ timeout_p = &timeout;
|
||||
+ } else {
|
||||
+ timeout_p = NULL;
|
||||
+ }
|
||||
+ n = select(nfds, &readfds, &writefds, NULL, timeout_p);
|
||||
+ if (n == -1) {
|
||||
+ if (errno == EINTR) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ perror("select");
|
||||
+ break;
|
||||
+ }
|
||||
+ memset(&timeout, 0, sizeof(timeout));
|
||||
+ if (n == 0) {
|
||||
+ libusb_handle_events_timeout(ctx, &timeout);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (FD_ISSET(client_fd, &readfds)) {
|
||||
+ if (usbredirhost_read_guest_data(host)) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ /* usbredirhost_read_guest_data may have detected client disconnect */
|
||||
+ if (client_fd == -1)
|
||||
+ break;
|
||||
+
|
||||
+ if (FD_ISSET(client_fd, &writefds)) {
|
||||
+ if (usbredirhost_write_guest_data(host)) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; pollfds && pollfds[i]; i++) {
|
||||
+ if (FD_ISSET(pollfds[i]->fd, &readfds) ||
|
||||
+ FD_ISSET(pollfds[i]->fd, &writefds)) {
|
||||
+ libusb_handle_events_timeout(ctx, &timeout);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (client_fd != -1) { /* Broken out of the loop because of an error ? */
|
||||
+ close(client_fd);
|
||||
+ client_fd = -1;
|
||||
+ }
|
||||
+ free(pollfds);
|
||||
+}
|
||||
+
|
||||
+static void quit_handler(int sig)
|
||||
+{
|
||||
+ running = 0;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char *argv[])
|
||||
+{
|
||||
+ int o, flags, server_fd = -1;
|
||||
+ char *endptr, *delim;
|
||||
+ int port = 4000;
|
||||
+ int usbbus = -1;
|
||||
+ int usbaddr = -1;
|
||||
+ int usbvendor = -1;
|
||||
+ int usbproduct = -1;
|
||||
+ int on = 1;
|
||||
+ int keepalive = -1;
|
||||
+ char *ipv4_addr = NULL, *ipv6_addr = NULL;
|
||||
+ union {
|
||||
+ struct sockaddr_in v4;
|
||||
+ struct sockaddr_in6 v6;
|
||||
+ } serveraddr;
|
||||
+ struct sigaction act;
|
||||
+ libusb_device_handle *handle = NULL;
|
||||
+
|
||||
+ while ((o = getopt_long(argc, argv, "hp:v:4:6:k:", longopts, NULL)) != -1) {
|
||||
+ switch (o) {
|
||||
+ case 'p':
|
||||
+ port = strtol(optarg, &endptr, 10);
|
||||
+ if (*endptr != '\0') {
|
||||
+ fprintf(stderr, "Invalid value for --port: '%s'\n", optarg);
|
||||
+ usage(1, argv[0]);
|
||||
+ }
|
||||
+ break;
|
||||
+ case 'v':
|
||||
+ verbose = strtol(optarg, &endptr, 10);
|
||||
+ if (*endptr != '\0') {
|
||||
+ fprintf(stderr, "Invalid value for --verbose: '%s'\n", optarg);
|
||||
+ usage(1, argv[0]);
|
||||
+ }
|
||||
+ break;
|
||||
+ case '4':
|
||||
+ ipv4_addr = optarg;
|
||||
+ break;
|
||||
+ case '6':
|
||||
+ ipv6_addr = optarg;
|
||||
+ break;
|
||||
+ case 'k':
|
||||
+ keepalive = strtol(optarg, &endptr, 10);
|
||||
+ if (*endptr != '\0') {
|
||||
+ fprintf(stderr, "Invalid value for -k: '%s'\n", optarg);
|
||||
+ usage(1, argv[0]);
|
||||
+ }
|
||||
+ break;
|
||||
+ case '?':
|
||||
+ case 'h':
|
||||
+ usage(o == '?', argv[0]);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (optind == argc) {
|
||||
+ fprintf(stderr, "Missing usb device identifier argument\n");
|
||||
+ usage(1, argv[0]);
|
||||
+ }
|
||||
+ delim = strchr(argv[optind], '-');
|
||||
+ if (delim && delim[1]) {
|
||||
+ usbbus = strtol(argv[optind], &endptr, 10);
|
||||
+ if (*endptr != '-') {
|
||||
+ invalid_usb_device_id(argv[optind], argv[0]);
|
||||
+ }
|
||||
+ usbaddr = strtol(delim + 1, &endptr, 10);
|
||||
+ if (*endptr != '\0') {
|
||||
+ invalid_usb_device_id(argv[optind], argv[0]);
|
||||
+ }
|
||||
+ } else {
|
||||
+ delim = strchr(argv[optind], ':');
|
||||
+ if (!delim || !delim[1]) {
|
||||
+ invalid_usb_device_id(argv[optind], argv[0]);
|
||||
+ }
|
||||
+ usbvendor = strtol(argv[optind], &endptr, 16);
|
||||
+ if (*endptr != ':' || usbvendor <= 0 || usbvendor > 0xffff) {
|
||||
+ invalid_usb_device_id(argv[optind], argv[0]);
|
||||
+ }
|
||||
+ usbproduct = strtol(delim + 1, &endptr, 16);
|
||||
+ /* Product ID 0000 is valid */
|
||||
+ if (*endptr != '\0' || usbproduct < 0 || usbproduct > 0xffff) {
|
||||
+ invalid_usb_device_id(argv[optind], argv[0]);
|
||||
+ }
|
||||
+ }
|
||||
+ optind++;
|
||||
+ if (optind != argc) {
|
||||
+ fprintf(stderr, "Excess non option arguments\n");
|
||||
+ usage(1, argv[0]);
|
||||
+ }
|
||||
+
|
||||
+ memset(&act, 0, sizeof(act));
|
||||
+ act.sa_handler = quit_handler;
|
||||
+ sigaction(SIGINT, &act, NULL);
|
||||
+ sigaction(SIGHUP, &act, NULL);
|
||||
+ sigaction(SIGTERM, &act, NULL);
|
||||
+ sigaction(SIGQUIT, &act, NULL);
|
||||
+
|
||||
+ if (libusb_init(&ctx)) {
|
||||
+ fprintf(stderr, "Could not init libusb\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+#if LIBUSB_API_VERSION >= 0x01000106
|
||||
+ libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, verbose);
|
||||
+#else
|
||||
+ libusb_set_debug(ctx, verbose);
|
||||
+#endif
|
||||
+
|
||||
+ if (ipv4_addr) {
|
||||
+ server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
+ } else {
|
||||
+ server_fd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
+ }
|
||||
+ if (server_fd == -1) {
|
||||
+ perror("Error creating ip socket");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) {
|
||||
+ perror("Error setsockopt(SO_REUSEADDR) failed");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ memset(&serveraddr, 0, sizeof(serveraddr));
|
||||
+
|
||||
+ if (ipv4_addr) {
|
||||
+ serveraddr.v4.sin_family = AF_INET;
|
||||
+ serveraddr.v4.sin_port = htons(port);
|
||||
+ if ((inet_pton(AF_INET, ipv4_addr,
|
||||
+ &serveraddr.v4.sin_addr)) != 1) {
|
||||
+ perror("Error convert ipv4 address");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ } else {
|
||||
+ serveraddr.v6.sin6_family = AF_INET6;
|
||||
+ serveraddr.v6.sin6_port = htons(port);
|
||||
+ if (ipv6_addr) {
|
||||
+ if ((inet_pton(AF_INET6, ipv6_addr,
|
||||
+ &serveraddr.v6.sin6_addr)) != 1) {
|
||||
+ perror("Error convert ipv6 address");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ } else {
|
||||
+ serveraddr.v6.sin6_addr = in6addr_any;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (bind(server_fd, (struct sockaddr *)&serveraddr,
|
||||
+ sizeof(serveraddr))) {
|
||||
+ perror("Error bind");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (listen(server_fd, 1)) {
|
||||
+ perror("Error listening");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ while (running) {
|
||||
+ client_fd = accept(server_fd, NULL, 0);
|
||||
+ if (client_fd == -1) {
|
||||
+ if (errno == EINTR) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ perror("accept");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (keepalive > 0) {
|
||||
+ 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 = keepalive; /* set default TCP_KEEPIDLE time from cmdline */
|
||||
+ 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");
|
||||
+ break;
|
||||
+ }
|
||||
+ flags = fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
|
||||
+ if (flags == -1) {
|
||||
+ perror("fcntl F_SETFL O_NONBLOCK");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Try to find the specified usb device */
|
||||
+ if (usbvendor != -1) {
|
||||
+ handle = libusb_open_device_with_vid_pid(ctx, usbvendor,
|
||||
+ usbproduct);
|
||||
+ if (!handle) {
|
||||
+ fprintf(stderr,
|
||||
+ "Could not open an usb-device with vid:pid %04x:%04x\n",
|
||||
+ usbvendor, usbproduct);
|
||||
+ } else if (verbose >= usbredirparser_info) {
|
||||
+ libusb_device *dev;
|
||||
+ dev = libusb_get_device(handle);
|
||||
+ fprintf(stderr, "Open a usb-device with vid:pid %04x:%04x on "
|
||||
+ "bus %03x device %03x\n",
|
||||
+ usbvendor, usbproduct,
|
||||
+ libusb_get_bus_number(dev),
|
||||
+ libusb_get_device_address(dev));
|
||||
+ }
|
||||
+ } else {
|
||||
+ libusb_device **list = NULL;
|
||||
+ ssize_t i, n;
|
||||
+
|
||||
+ n = libusb_get_device_list(ctx, &list);
|
||||
+ for (i = 0; i < n; i++) {
|
||||
+ if (libusb_get_bus_number(list[i]) == usbbus &&
|
||||
+ libusb_get_device_address(list[i]) == usbaddr)
|
||||
+ break;
|
||||
+ }
|
||||
+ if (i < n) {
|
||||
+ if (libusb_open(list[i], &handle) != 0) {
|
||||
+ fprintf(stderr,
|
||||
+ "Could not open usb-device at busnum-devnum %d-%d\n",
|
||||
+ usbbus, usbaddr);
|
||||
+ }
|
||||
+ } else {
|
||||
+ fprintf(stderr,
|
||||
+ "Could not find an usb-device at busnum-devnum %d-%d\n",
|
||||
+ usbbus, usbaddr);
|
||||
+ }
|
||||
+ libusb_free_device_list(list, 1);
|
||||
+ }
|
||||
+ if (!handle) {
|
||||
+ close(client_fd);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ host = usbredirhost_open(ctx, handle, usbredirserver_log,
|
||||
+ usbredirserver_read, usbredirserver_write,
|
||||
+ NULL, SERVER_VERSION, verbose, 0);
|
||||
+ if (!host)
|
||||
+ exit(1);
|
||||
+ run_main_loop();
|
||||
+ usbredirhost_close(host);
|
||||
+ handle = NULL;
|
||||
+ }
|
||||
+
|
||||
+ close(server_fd);
|
||||
+ libusb_exit(ctx);
|
||||
+ exit(0);
|
||||
+}
|
||||
--
|
||||
2.38.1
|
||||
|
||||
193
0001-usbredirparser-Fix-unserialize-on-pristine-check.patch
Normal file
193
0001-usbredirparser-Fix-unserialize-on-pristine-check.patch
Normal file
@ -0,0 +1,193 @@
|
||||
From 6bf41a231b445ac5190c32e281b698b1ee5379b4 Mon Sep 17 00:00:00 2001
|
||||
From: Victor Toso <victortoso@redhat.com>
|
||||
Date: Fri, 24 Jun 2022 23:29:08 +0200
|
||||
Subject: [PATCH 1/2] usbredirparser: Fix unserialize on pristine check
|
||||
Content-type: text/plain
|
||||
|
||||
As mentioned in the bug below, the user is trying to migrate QEMU and
|
||||
it is failing on the unserialization of usbredirparser at the target
|
||||
host. The user does not have USB attached to the VM at all.
|
||||
|
||||
I've added a test that shows that serialization is currently broken.
|
||||
It fails at the 'pristine' check in usbredirparser_unserialize().
|
||||
|
||||
This check was added with e37d86c "Skip empty write buffers when
|
||||
unserializing parser" and restricted further with 186c4c7 "Avoid
|
||||
memory leak from ill-formatted serialization data"
|
||||
|
||||
The issue here is that usbredirparser's initialization sets some
|
||||
fields and thus it isn't guaranteed to be pristine.
|
||||
|
||||
The parser's basic data is:
|
||||
|
||||
| write_buf_count ... : 1
|
||||
| write_buf ........ : 0xbc03e0
|
||||
| write_buf_total_size: 80
|
||||
| data ............. : (nil)
|
||||
| header_read: ...... : 0
|
||||
| type_header_read .. : 0
|
||||
| data_read: ........ : 0
|
||||
|
||||
The current fix is to to ignore write_buf checks as, again, they are
|
||||
not guaranteed to be pristine. usbredirparser library should properly
|
||||
overwrite them when unserializing the data and if there were pending
|
||||
buffers, they should be freed.
|
||||
|
||||
Related: https://bugzilla.redhat.com/show_bug.cgi?id=2096008
|
||||
|
||||
Signed-off-by: Victor Toso <victortoso@redhat.com>
|
||||
---
|
||||
tests/meson.build | 1 +
|
||||
tests/serializer.c | 113 ++++++++++++++++++++++++++++++++
|
||||
usbredirparser/usbredirparser.c | 4 +-
|
||||
3 files changed, 115 insertions(+), 3 deletions(-)
|
||||
create mode 100644 tests/serializer.c
|
||||
|
||||
diff --git a/tests/meson.build b/tests/meson.build
|
||||
index 0d4397b..2a179c9 100644
|
||||
--- a/tests/meson.build
|
||||
+++ b/tests/meson.build
|
||||
@@ -1,5 +1,6 @@
|
||||
tests = [
|
||||
'filter',
|
||||
+ 'serializer',
|
||||
]
|
||||
|
||||
deps = dependency('glib-2.0')
|
||||
diff --git a/tests/serializer.c b/tests/serializer.c
|
||||
new file mode 100644
|
||||
index 0000000..4bd669e
|
||||
--- /dev/null
|
||||
+++ b/tests/serializer.c
|
||||
@@ -0,0 +1,113 @@
|
||||
+/*
|
||||
+ * Copyright 2022 Red Hat, Inc.
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
+*/
|
||||
+#include "config.h"
|
||||
+
|
||||
+#define G_LOG_DOMAIN "serializer"
|
||||
+#define G_LOG_USE_STRUCTURED
|
||||
+
|
||||
+#include "usbredirparser.h"
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <locale.h>
|
||||
+#include <glib.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+
|
||||
+static void
|
||||
+log_cb(void *priv, int level, const char *msg)
|
||||
+{
|
||||
+ GLogLevelFlags glog_level;
|
||||
+
|
||||
+ switch(level) {
|
||||
+ case usbredirparser_error:
|
||||
+ glog_level = G_LOG_LEVEL_ERROR;
|
||||
+ break;
|
||||
+ case usbredirparser_warning:
|
||||
+ glog_level = G_LOG_LEVEL_WARNING;
|
||||
+ break;
|
||||
+ case usbredirparser_info:
|
||||
+ glog_level = G_LOG_LEVEL_INFO;
|
||||
+ break;
|
||||
+ case usbredirparser_debug:
|
||||
+ case usbredirparser_debug_data:
|
||||
+ glog_level = G_LOG_LEVEL_DEBUG;
|
||||
+ break;
|
||||
+ default:
|
||||
+ g_warn_if_reached();
|
||||
+ return;
|
||||
+ }
|
||||
+ g_log_structured(G_LOG_DOMAIN, glog_level, "MESSAGE", msg);
|
||||
+}
|
||||
+
|
||||
+static struct usbredirparser *
|
||||
+get_usbredirparser(void)
|
||||
+{
|
||||
+ struct usbredirparser *parser = usbredirparser_create();
|
||||
+ g_assert_nonnull(parser);
|
||||
+
|
||||
+ uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
|
||||
+ /* Typical caps set by usbredirhost */
|
||||
+ usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
|
||||
+ usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
|
||||
+ usbredirparser_caps_set_cap(caps, usb_redir_cap_device_disconnect_ack);
|
||||
+ usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
|
||||
+ usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
|
||||
+ usbredirparser_caps_set_cap(caps, usb_redir_cap_32bits_bulk_length);
|
||||
+ usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_receiving);
|
||||
+#if LIBUSBX_API_VERSION >= 0x01000103
|
||||
+ usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_streams);
|
||||
+#endif
|
||||
+ int parser_flags = usbredirparser_fl_usb_host;
|
||||
+
|
||||
+ parser->log_func = log_cb;
|
||||
+ usbredirparser_init(parser,
|
||||
+ PACKAGE_STRING,
|
||||
+ caps,
|
||||
+ USB_REDIR_CAPS_SIZE,
|
||||
+ parser_flags);
|
||||
+ return parser;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+simple (gconstpointer user_data)
|
||||
+{
|
||||
+ uint8_t *state = NULL;
|
||||
+ int ret, len = -1;
|
||||
+
|
||||
+ struct usbredirparser *source = get_usbredirparser();
|
||||
+ ret = usbredirparser_serialize(source, &state, &len);
|
||||
+ g_assert_cmpint(ret, ==, 0);
|
||||
+
|
||||
+ struct usbredirparser *target = get_usbredirparser();
|
||||
+ ret = usbredirparser_unserialize(target, state, len);
|
||||
+ g_assert_cmpint(ret, ==, 0);
|
||||
+
|
||||
+ g_clear_pointer(&state, free);
|
||||
+ usbredirparser_destroy(source);
|
||||
+ usbredirparser_destroy(target);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main(int argc, char **argv)
|
||||
+{
|
||||
+ setlocale(LC_ALL, "");
|
||||
+ g_test_init(&argc, &argv, NULL);
|
||||
+
|
||||
+ g_test_add_data_func("/serializer/serialize-and-unserialize", NULL, simple);
|
||||
+
|
||||
+ return g_test_run();
|
||||
+}
|
||||
diff --git a/usbredirparser/usbredirparser.c b/usbredirparser/usbredirparser.c
|
||||
index cd1136b..a5dd0e7 100644
|
||||
--- a/usbredirparser/usbredirparser.c
|
||||
+++ b/usbredirparser/usbredirparser.c
|
||||
@@ -1816,9 +1816,7 @@ int usbredirparser_unserialize(struct usbredirparser *parser_pub,
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (!(parser->write_buf_count == 0 && parser->write_buf == NULL &&
|
||||
- parser->write_buf_total_size == 0 &&
|
||||
- parser->data == NULL && parser->header_read == 0 &&
|
||||
+ if (!(parser->data == NULL && parser->header_read == 0 &&
|
||||
parser->type_header_read == 0 && parser->data_read == 0)) {
|
||||
ERROR("unserialization must use a pristine parser");
|
||||
usbredirparser_assert_invariants(parser);
|
||||
--
|
||||
2.37.1
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
From b93c4cae1aebda786a478677d6364308e4579ade Mon Sep 17 00:00:00 2001
|
||||
From: Victor Toso <victortoso@redhat.com>
|
||||
Date: Sat, 25 Jun 2022 00:29:12 +0200
|
||||
Subject: [PATCH 2/2] usbredirparser: reset parser's fields on unserialize
|
||||
Content-type: text/plain
|
||||
|
||||
This is a followup from previous commit and fixes the following leak.
|
||||
|
||||
| 104 (24 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 15 of 19
|
||||
| at 0x484A464: calloc (vg_replace_malloc.c:1328)
|
||||
| by 0x485A238: usbredirparser_queue (usbredirparser.c:1235)
|
||||
| by 0x485A571: usbredirparser_init (usbredirparser.c:227)
|
||||
| by 0x40130B: get_usbredirparser (serializer.c:77)
|
||||
| by 0x401379: simple (serializer.c:95)
|
||||
| by 0x48FA3DD: ??? (in /usr/lib64/libglib-2.0.so.0.7200.2)
|
||||
| by 0x48FA144: ??? (in /usr/lib64/libglib-2.0.so.0.7200.2)
|
||||
| by 0x48FA8E1: g_test_run_suite (in /usr/lib64/libglib-2.0.so.0.7200.2)
|
||||
| by 0x48FA94C: g_test_run (in /usr/lib64/libglib-2.0.so.0.7200.2)
|
||||
| by 0x401161: main (serializer.c:112)
|
||||
|
|
||||
| LEAK SUMMARY:
|
||||
| definitely lost: 24 bytes in 1 blocks
|
||||
| indirectly lost: 80 bytes in 1 blocks
|
||||
| possibly lost: 0 bytes in 0 blocks
|
||||
| still reachable: 25,500 bytes in 17 blocks
|
||||
| suppressed: 0 bytes in 0 blocks
|
||||
| Reachable blocks (those to which a pointer was found) are not shown.
|
||||
| To see them, rerun with: --leak-check=full --show-leak-kinds=all
|
||||
|
||||
Signed-off-by: Victor Toso <victortoso@redhat.com>
|
||||
---
|
||||
usbredirparser/usbredirparser.c | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/usbredirparser/usbredirparser.c b/usbredirparser/usbredirparser.c
|
||||
index a5dd0e7..9bfc27c 100644
|
||||
--- a/usbredirparser/usbredirparser.c
|
||||
+++ b/usbredirparser/usbredirparser.c
|
||||
@@ -1823,6 +1823,21 @@ int usbredirparser_unserialize(struct usbredirparser *parser_pub,
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ {
|
||||
+ /* We need to reset parser's state to receive unserialized
|
||||
+ * data. */
|
||||
+ struct usbredirparser_buf *wbuf = parser->write_buf;
|
||||
+ while (wbuf) {
|
||||
+ struct usbredirparser_buf *next_wbuf = wbuf->next;
|
||||
+ free(wbuf->buf);
|
||||
+ free(wbuf);
|
||||
+ wbuf = next_wbuf;
|
||||
+ }
|
||||
+ parser->write_buf = NULL;
|
||||
+ parser->write_buf_count = 0;
|
||||
+ parser->write_buf_total_size = 0;
|
||||
+ }
|
||||
+
|
||||
if (unserialize_int(parser, &state, &remain, &i, "length")) {
|
||||
usbredirparser_assert_invariants(parser);
|
||||
return -1;
|
||||
--
|
||||
2.37.1
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
From c1246d5d8332890df0dab7b29de86a42c2b7b36a Mon Sep 17 00:00:00 2001
|
||||
From e30b0ce5c46c0e2a75b6e38759876ba1369b2168 Mon Sep 17 00:00:00 2001
|
||||
From: Frediano Ziglio <freddy77@gmail.com>
|
||||
Date: Fri, 16 Sep 2022 20:14:28 +0100
|
||||
Subject: [PATCH 2/4] Use typedef on redirect structure to simplify some
|
||||
Subject: [PATCH 3/8] Use typedef on redirect structure to simplify some
|
||||
statements
|
||||
|
||||
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
|
||||
@ -10,7 +10,7 @@ Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
|
||||
1 file changed, 13 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/tools/usbredirect.c b/tools/usbredirect.c
|
||||
index ff910ab..a479c55 100644
|
||||
index 98e5a8c..89a42a6 100644
|
||||
--- a/tools/usbredirect.c
|
||||
+++ b/tools/usbredirect.c
|
||||
@@ -22,7 +22,7 @@
|
||||
@ -31,7 +31,7 @@ index ff910ab..a479c55 100644
|
||||
|
||||
static bool
|
||||
parse_opt_device(const char *device, int *vendor, int *product)
|
||||
@@ -125,7 +125,7 @@ parse_opt_uri(const char *uri, char **adr, int *port)
|
||||
@@ -124,7 +124,7 @@ parse_opt_uri(const char *uri, char **adr, int *port)
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ index ff910ab..a479c55 100644
|
||||
parse_opts(int *argc, char ***argv)
|
||||
{
|
||||
char *device = NULL;
|
||||
@@ -133,7 +133,7 @@ parse_opts(int *argc, char ***argv)
|
||||
@@ -132,7 +132,7 @@ parse_opts(int *argc, char ***argv)
|
||||
char *localaddr = NULL;
|
||||
gboolean keepalive = FALSE;
|
||||
gint verbosity = 0; /* none */
|
||||
@ -49,7 +49,7 @@ index ff910ab..a479c55 100644
|
||||
|
||||
GOptionEntry entries[] = {
|
||||
{ "device", 0, 0, G_OPTION_ARG_STRING, &device, "Local USB device to be redirected", NULL },
|
||||
@@ -162,7 +162,7 @@ parse_opts(int *argc, char ***argv)
|
||||
@@ -161,7 +161,7 @@ parse_opts(int *argc, char ***argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ index ff910ab..a479c55 100644
|
||||
if (!parse_opt_device(device, &self->device.vendor, &self->device.product)) {
|
||||
g_printerr("Failed to parse device: '%s' - expected: vendor:product or busnum-devnum\n", device);
|
||||
g_clear_pointer(&self, g_free);
|
||||
@@ -202,7 +202,7 @@ end:
|
||||
@@ -201,7 +201,7 @@ end:
|
||||
static gpointer
|
||||
thread_handle_libusb_events(gpointer user_data)
|
||||
{
|
||||
@ -67,7 +67,7 @@ index ff910ab..a479c55 100644
|
||||
|
||||
int res = 0;
|
||||
const char *desc = "";
|
||||
@@ -280,7 +280,7 @@ usbredir_log_cb(void *priv, int level, const char *msg)
|
||||
@@ -279,7 +279,7 @@ usbredir_log_cb(void *priv, int level, const char *msg)
|
||||
static int
|
||||
usbredir_read_cb(void *priv, uint8_t *data, int count)
|
||||
{
|
||||
@ -76,7 +76,7 @@ index ff910ab..a479c55 100644
|
||||
GIOStream *iostream = G_IO_STREAM(self->connection);
|
||||
GError *err = NULL;
|
||||
|
||||
@@ -308,7 +308,7 @@ usbredir_read_cb(void *priv, uint8_t *data, int count)
|
||||
@@ -307,7 +307,7 @@ usbredir_read_cb(void *priv, uint8_t *data, int count)
|
||||
static int
|
||||
usbredir_write_cb(void *priv, uint8_t *data, int count)
|
||||
{
|
||||
@ -85,7 +85,7 @@ index ff910ab..a479c55 100644
|
||||
GIOStream *iostream = G_IO_STREAM(self->connection);
|
||||
GError *err = NULL;
|
||||
|
||||
@@ -336,7 +336,7 @@ usbredir_write_cb(void *priv, uint8_t *data, int count)
|
||||
@@ -335,7 +335,7 @@ usbredir_write_cb(void *priv, uint8_t *data, int count)
|
||||
static void
|
||||
usbredir_write_flush_cb(void *user_data)
|
||||
{
|
||||
@ -94,7 +94,7 @@ index ff910ab..a479c55 100644
|
||||
if (!self || !self->usbredirhost) {
|
||||
return;
|
||||
}
|
||||
@@ -387,7 +387,7 @@ usbredir_unlock_lock(void *user_data)
|
||||
@@ -386,7 +386,7 @@ usbredir_unlock_lock(void *user_data)
|
||||
static gboolean
|
||||
connection_handle_io_cb(GIOChannel *source, GIOCondition condition, gpointer user_data)
|
||||
{
|
||||
@ -103,7 +103,7 @@ index ff910ab..a479c55 100644
|
||||
|
||||
if (condition & G_IO_ERR || condition & G_IO_HUP) {
|
||||
g_warning("Connection: err=%d, hup=%d - exiting", (condition & G_IO_ERR), (condition & G_IO_HUP));
|
||||
@@ -419,7 +419,7 @@ end:
|
||||
@@ -418,7 +418,7 @@ end:
|
||||
static gboolean
|
||||
signal_handler(gpointer user_data)
|
||||
{
|
||||
@ -112,7 +112,7 @@ index ff910ab..a479c55 100644
|
||||
g_main_loop_quit(self->main_loop);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -431,7 +431,7 @@ connection_incoming_cb(GSocketService *service,
|
||||
@@ -430,7 +430,7 @@ connection_incoming_cb(GSocketService *service,
|
||||
GObject *source_object,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -121,7 +121,7 @@ index ff910ab..a479c55 100644
|
||||
self->connection = g_object_ref(client_connection);
|
||||
|
||||
/* Add a GSource watch to handle polling for us and handle IO in the callback */
|
||||
@@ -456,7 +456,7 @@ main(int argc, char *argv[])
|
||||
@@ -455,7 +455,7 @@ main(int argc, char *argv[])
|
||||
goto err_init;
|
||||
}
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
From 307747e2a73cf68a239ddd7b70333bbddf7f3e3b Mon Sep 17 00:00:00 2001
|
||||
From 5399d3d5ce420891adfd4beedb023515a28ceab1 Mon Sep 17 00:00:00 2001
|
||||
From: Frediano Ziglio <freddy77@gmail.com>
|
||||
Date: Fri, 16 Sep 2022 20:14:28 +0100
|
||||
Subject: [PATCH 3/4] Factor out a function to create watches
|
||||
Subject: [PATCH 4/8] Factor out a function to create watches
|
||||
|
||||
---
|
||||
tools/usbredirect.c | 37 ++++++++++++++++++++-----------------
|
||||
1 file changed, 20 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/tools/usbredirect.c b/tools/usbredirect.c
|
||||
index a479c55..afe9dee 100644
|
||||
index 89a42a6..6a8b68b 100644
|
||||
--- a/tools/usbredirect.c
|
||||
+++ b/tools/usbredirect.c
|
||||
@@ -415,6 +415,24 @@ end:
|
||||
@@ -414,6 +414,24 @@ end:
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ index a479c55..afe9dee 100644
|
||||
#ifdef G_OS_UNIX
|
||||
static gboolean
|
||||
signal_handler(gpointer user_data)
|
||||
@@ -437,12 +455,7 @@ connection_incoming_cb(GSocketService *service,
|
||||
@@ -436,12 +454,7 @@ connection_incoming_cb(GSocketService *service,
|
||||
/* Add a GSource watch to handle polling for us and handle IO in the callback */
|
||||
GSocket *connection_socket = g_socket_connection_get_socket(self->connection);
|
||||
g_socket_set_keepalive(connection_socket, self->keepalive);
|
||||
@ -50,7 +50,7 @@ index a479c55..afe9dee 100644
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
@@ -552,17 +565,7 @@ main(int argc, char *argv[])
|
||||
@@ -551,17 +564,7 @@ main(int argc, char *argv[])
|
||||
|
||||
GSocket *connection_socket = g_socket_connection_get_socket(self->connection);
|
||||
g_socket_set_keepalive(connection_socket, self->keepalive);
|
||||
@ -1,7 +1,7 @@
|
||||
From 3fcbd4a2569f227ae6fad6a37c8864d33271e5f4 Mon Sep 17 00:00:00 2001
|
||||
From f5e24c5cf77b92ab2737eb230db7ae0b2fb102cc Mon Sep 17 00:00:00 2001
|
||||
From: Frediano Ziglio <freddy77@gmail.com>
|
||||
Date: Sat, 17 Sep 2022 09:28:08 +0100
|
||||
Subject: [PATCH 4/4] Recreate watch if needed
|
||||
Subject: [PATCH 5/8] Recreate watch if needed
|
||||
|
||||
Do not always watch for output buffer.
|
||||
Watching for output buffer if we don't have nothing to write
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
|
||||
1 file changed, 26 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/usbredirect.c b/tools/usbredirect.c
|
||||
index afe9dee..59452aa 100644
|
||||
index 6a8b68b..b6a30ad 100644
|
||||
--- a/tools/usbredirect.c
|
||||
+++ b/tools/usbredirect.c
|
||||
@@ -29,6 +29,7 @@ typedef struct redirect {
|
||||
@ -35,7 +35,7 @@ index afe9dee..59452aa 100644
|
||||
static bool
|
||||
parse_opt_device(const char *device, int *vendor, int *product)
|
||||
{
|
||||
@@ -163,6 +166,7 @@ parse_opts(int *argc, char ***argv)
|
||||
@@ -162,6 +165,7 @@ parse_opts(int *argc, char ***argv)
|
||||
}
|
||||
|
||||
self = g_new0(redirect, 1);
|
||||
@ -43,7 +43,7 @@ index afe9dee..59452aa 100644
|
||||
if (!parse_opt_device(device, &self->device.vendor, &self->device.product)) {
|
||||
g_printerr("Failed to parse device: '%s' - expected: vendor:product or busnum-devnum\n", device);
|
||||
g_clear_pointer(&self, g_free);
|
||||
@@ -277,6 +281,20 @@ usbredir_log_cb(void *priv, int level, const char *msg)
|
||||
@@ -276,6 +280,20 @@ usbredir_log_cb(void *priv, int level, const char *msg)
|
||||
g_log_structured(G_LOG_DOMAIN, glog_level, "MESSAGE", msg);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ index afe9dee..59452aa 100644
|
||||
static int
|
||||
usbredir_read_cb(void *priv, uint8_t *data, int count)
|
||||
{
|
||||
@@ -322,6 +340,7 @@ usbredir_write_cb(void *priv, uint8_t *data, int count)
|
||||
@@ -321,6 +339,7 @@ usbredir_write_cb(void *priv, uint8_t *data, int count)
|
||||
if (g_error_matches(err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
|
||||
/* Try again later */
|
||||
nbytes = 0;
|
||||
@ -72,7 +72,7 @@ index afe9dee..59452aa 100644
|
||||
} else {
|
||||
if (err != NULL) {
|
||||
g_warning("Failure at %s: %s", __func__, err->message);
|
||||
@@ -401,13 +420,18 @@ connection_handle_io_cb(GIOChannel *source, GIOCondition condition, gpointer use
|
||||
@@ -400,13 +419,18 @@ connection_handle_io_cb(GIOChannel *source, GIOCondition condition, gpointer use
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@ -92,7 +92,7 @@ index afe9dee..59452aa 100644
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
end:
|
||||
@@ -428,7 +452,7 @@ create_watch(redirect *self)
|
||||
@@ -427,7 +451,7 @@ create_watch(redirect *self)
|
||||
#endif
|
||||
|
||||
self->watch_server_id = g_io_add_watch(io_channel,
|
||||
@ -1,7 +1,7 @@
|
||||
From 79c3214ef403a801762a79702be20cf8a829e37b Mon Sep 17 00:00:00 2001
|
||||
From b3482e8d8f8970d481b9bfdb6662a8b67a973537 Mon Sep 17 00:00:00 2001
|
||||
From: John Call <johnsimcall@gmail.com>
|
||||
Date: Mon, 19 Dec 2022 19:01:50 +0000
|
||||
Subject: [PATCH 5/7] Add documentation examples for using bus-device
|
||||
Subject: [PATCH 6/8] Add documentation examples for using bus-device
|
||||
identification
|
||||
|
||||
---
|
||||
@ -34,10 +34,10 @@ index d6b2a63..2be8be0 100644
|
||||
Notice that an instance of usbredirect can only be used to export a single USB
|
||||
device and it will close once the other side closes the connection. If you
|
||||
diff --git a/tools/usbredirect.c b/tools/usbredirect.c
|
||||
index 59452aa..88c553b 100644
|
||||
index b6a30ad..95f3580 100644
|
||||
--- a/tools/usbredirect.c
|
||||
+++ b/tools/usbredirect.c
|
||||
@@ -139,7 +139,7 @@ parse_opts(int *argc, char ***argv)
|
||||
@@ -138,7 +138,7 @@ parse_opts(int *argc, char ***argv)
|
||||
redirect *self = NULL;
|
||||
|
||||
GOptionEntry entries[] = {
|
||||
@ -1,7 +1,7 @@
|
||||
From ebfcffbee055ef5ddf981b77240223790dcc0140 Mon Sep 17 00:00:00 2001
|
||||
From 813afe206c8ff10cbbe715bf94980bf8ba6be70f Mon Sep 17 00:00:00 2001
|
||||
From: Victor Toso <victortoso@redhat.com>
|
||||
Date: Thu, 22 Dec 2022 16:13:08 +0100
|
||||
Subject: [PATCH 6/7] usbredirect: allow multiple devices by vendor:product
|
||||
Subject: [PATCH 7/8] usbredirect: allow multiple devices by vendor:product
|
||||
|
||||
Currently, if an user tries to redirect two devices with the same
|
||||
vendor:product info, the second instance of usbredirect will not
|
||||
@ -24,10 +24,10 @@ Signed-off-by: Victor Toso <victortoso@redhat.com>
|
||||
1 file changed, 85 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/tools/usbredirect.c b/tools/usbredirect.c
|
||||
index 88c553b..78fe5c2 100644
|
||||
index 95f3580..0b04418 100644
|
||||
--- a/tools/usbredirect.c
|
||||
+++ b/tools/usbredirect.c
|
||||
@@ -467,6 +467,90 @@ signal_handler(gpointer user_data)
|
||||
@@ -466,6 +466,90 @@ signal_handler(gpointer user_data)
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -118,7 +118,7 @@ index 88c553b..78fe5c2 100644
|
||||
static gboolean
|
||||
connection_incoming_cb(GSocketService *service,
|
||||
GSocketConnection *client_connection,
|
||||
@@ -516,11 +600,7 @@ main(int argc, char *argv[])
|
||||
@@ -515,11 +599,7 @@ main(int argc, char *argv[])
|
||||
g_unix_signal_add(SIGTERM, signal_handler, self);
|
||||
#endif
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
From c2fc30ec2b424ac6e45e45f756a2559848bd3116 Mon Sep 17 00:00:00 2001
|
||||
From c32774c8a46aa04bf8f882ea552df8cb2d9f3a59 Mon Sep 17 00:00:00 2001
|
||||
From: Victor Toso <victortoso@redhat.com>
|
||||
Date: Thu, 22 Dec 2022 16:58:43 +0100
|
||||
Subject: [PATCH 7/7] usbredirect: use the correct bus-device
|
||||
Subject: [PATCH 8/8] usbredirect: use the correct bus-device
|
||||
|
||||
This patch is a continuation from:
|
||||
"usbredirect: allow multiple devices by vendor:product"
|
||||
@ -19,11 +19,11 @@ device to redirect.
|
||||
Related: https://gitlab.freedesktop.org/spice/usbredir/-/issues/29
|
||||
Signed-off-by: Victor Toso <victortoso@redhat.com>
|
||||
---
|
||||
tools/usbredirect.c | 61 +++++++++++++++++++--------------------------
|
||||
1 file changed, 26 insertions(+), 35 deletions(-)
|
||||
tools/usbredirect.c | 63 ++++++++++++++++++++-------------------------
|
||||
1 file changed, 28 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/tools/usbredirect.c b/tools/usbredirect.c
|
||||
index 78fe5c2..0451dda 100644
|
||||
index 0b04418..cad9d23 100644
|
||||
--- a/tools/usbredirect.c
|
||||
+++ b/tools/usbredirect.c
|
||||
@@ -24,9 +24,14 @@
|
||||
@ -50,7 +50,7 @@ index 78fe5c2..0451dda 100644
|
||||
{
|
||||
if (!device) {
|
||||
g_warning("No device to redirect. For testing only\n");
|
||||
@@ -54,38 +59,15 @@ parse_opt_device(const char *device, int *vendor, int *product)
|
||||
@@ -54,37 +59,15 @@ parse_opt_device(const char *device, int *vendor, int *product)
|
||||
}
|
||||
|
||||
if (g_strrstr(device, "-") != NULL) {
|
||||
@ -63,9 +63,6 @@ index 78fe5c2..0451dda 100644
|
||||
}
|
||||
- gint64 bus = g_ascii_strtoll(usbid[0], NULL, 10);
|
||||
- gint64 addr = g_ascii_strtoll(usbid[1], NULL, 10);
|
||||
+ self->device.bus = g_ascii_strtoll(usbid[0], NULL, 10);
|
||||
+ self->device.device_number = g_ascii_strtoll(usbid[1], NULL, 10);
|
||||
g_strfreev(usbid);
|
||||
-
|
||||
- libusb_device **list = NULL;
|
||||
- ssize_t i, n;
|
||||
@ -89,10 +86,13 @@ index 78fe5c2..0451dda 100644
|
||||
- *product = desc.idProduct;
|
||||
-
|
||||
- libusb_free_device_list(list, true);
|
||||
+ self->device.bus = g_ascii_strtoll(usbid[0], NULL, 10);
|
||||
+ self->device.device_number = g_ascii_strtoll(usbid[1], NULL, 10);
|
||||
+ g_strfreev(usbid);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -95,12 +77,14 @@ parse_opt_device(const char *device, int *vendor, int *product)
|
||||
@@ -94,12 +77,14 @@ parse_opt_device(const char *device, int *vendor, int *product)
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ index 78fe5c2..0451dda 100644
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -167,7 +151,7 @@ parse_opts(int *argc, char ***argv)
|
||||
@@ -166,7 +151,7 @@ parse_opts(int *argc, char ***argv)
|
||||
|
||||
self = g_new0(redirect, 1);
|
||||
self->watch_inout = true;
|
||||
@ -120,7 +120,7 @@ index 78fe5c2..0451dda 100644
|
||||
g_printerr("Failed to parse device: '%s' - expected: vendor:product or busnum-devnum\n", device);
|
||||
g_clear_pointer(&self, g_free);
|
||||
goto end;
|
||||
@@ -536,9 +520,16 @@ open_usb_device(redirect *self)
|
||||
@@ -535,9 +520,16 @@ open_usb_device(redirect *self)
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -140,6 +140,14 @@ index 78fe5c2..0451dda 100644
|
||||
}
|
||||
|
||||
if (can_claim_usb_device(devs[i], &dev_handle)) {
|
||||
@@ -674,6 +666,7 @@ main(int argc, char *argv[])
|
||||
|
||||
socket_service = g_socket_service_new ();
|
||||
GInetAddress *iaddr = g_inet_address_new_loopback(G_SOCKET_FAMILY_IPV4);
|
||||
+
|
||||
GSocketAddress *saddr = g_inet_socket_address_new(iaddr, self->port);
|
||||
g_object_unref(iaddr);
|
||||
|
||||
--
|
||||
2.39.0
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-9
|
||||
- rhel-8
|
||||
decision_context: osci_compose_gate
|
||||
rules: []
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: manual.sst_graphics_infrastructure.usbredir.sanity}
|
||||
|
||||
2
sources
2
sources
@ -1 +1 @@
|
||||
SHA512 (usbredir-0.13.0.tar.xz) = dd27b1794233d4a278c3ca0e2a1ef9518946d8c7422cf58bb83d8ed5b4358133da27bdb0f44ad7b679a9983b3c419c3ab014486735614f7ceea85bfa62904273
|
||||
SHA512 (usbredir-0.12.0.tar.xz) = f509a6b5d410fec53efbdc186b80376d6b7f5b34c6c33f2037a83bf105743667c5a18a6d1ef33d6b3c57c1ed6a52b94536369ca768eddb70fda7b436d35fe6ab
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
Name: usbredir
|
||||
Version: 0.13.0
|
||||
Release: 2%{?dist}
|
||||
Version: 0.12.0
|
||||
Release: 4%{?dist}
|
||||
Summary: USB network redirection protocol libraries
|
||||
Group: System Environment/Libraries
|
||||
License: LGPLv2+
|
||||
URL: https://spice-space.org/usbredir.html
|
||||
URL: https://www.spice-space.org/usbredir.html
|
||||
Source0: http://spice-space.org/download/%{name}/%{name}-%{version}.tar.xz
|
||||
Patch0001: 0001-Revert-remove-usbredirserver.patch
|
||||
Patch0002: 0002-Use-typedef-on-redirect-structure-to-simplify-some-s.patch
|
||||
Patch0003: 0003-Factor-out-a-function-to-create-watches.patch
|
||||
Patch0004: 0004-Recreate-watch-if-needed.patch
|
||||
Patch0005: 0005-Add-documentation-examples-for-using-bus-device-iden.patch
|
||||
Patch0006: 0006-usbredirect-allow-multiple-devices-by-vendor-product.patch
|
||||
Patch0007: 0007-usbredirect-use-the-correct-bus-device.patch
|
||||
BuildRequires: gcc
|
||||
Patch0001: 0001-usbredirparser-Fix-unserialize-on-pristine-check.patch
|
||||
Patch0002: 0002-usbredirparser-reset-parser-s-fields-on-unserialize.patch
|
||||
Patch0003: 0003-Use-typedef-on-redirect-structure-to-simplify-some-s.patch
|
||||
Patch0004: 0004-Factor-out-a-function-to-create-watches.patch
|
||||
Patch0005: 0005-Recreate-watch-if-needed.patch
|
||||
Patch0006: 0006-Add-documentation-examples-for-using-bus-device-iden.patch
|
||||
Patch0007: 0007-usbredirect-allow-multiple-devices-by-vendor-product.patch
|
||||
Patch0008: 0008-usbredirect-use-the-correct-bus-device.patch
|
||||
BuildRequires: glib2-devel
|
||||
BuildRequires: libusb1-devel >= 1.0.9
|
||||
BuildRequires: git-core
|
||||
@ -35,6 +36,7 @@ All that an application wishing to implement a USB host needs to do is:
|
||||
|
||||
%package devel
|
||||
Summary: Development files for %{name}
|
||||
Group: Development/Libraries
|
||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description devel
|
||||
@ -44,6 +46,7 @@ developing applications that use %{name}.
|
||||
|
||||
%package server
|
||||
Summary: Simple USB host TCP server
|
||||
Group: System Environment/Daemons
|
||||
License: GPLv2+
|
||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||
|
||||
@ -63,6 +66,7 @@ A simple USB host TCP server, using libusbredirhost.
|
||||
|
||||
%meson_build
|
||||
|
||||
|
||||
%install
|
||||
%meson_install
|
||||
|
||||
@ -91,60 +95,27 @@ A simple USB host TCP server, using libusbredirhost.
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Jan 05 2023 Victor Toso <victortoso@redhat.com> - 0.13.0-2
|
||||
- Fixes 100% CPU usage when usbredirect used as TCP server
|
||||
Related: rhbz#2157520
|
||||
- Fixes USB redirection of identical devices
|
||||
Resolves: rhbz#2157520
|
||||
* Wed Jan 25 2023 Victor Toso <victortoso@redhat.com> - 0.12.0-4
|
||||
- Rebuild to fix lack of elf sections
|
||||
Related: rhbz#2157521
|
||||
|
||||
* Wed Nov 30 2022 Victor Toso <victortoso@redhat.com> - 0.13.0-1
|
||||
- Rebase to latest upstream: 0.13.0
|
||||
- Keeps usbredirserver binary (removed upstream)
|
||||
Related: rhbz#2135760
|
||||
* Thu Jan 05 2023 Victor Toso <victortoso@redhat.com> - 0.12.0-3
|
||||
- Fixes 100% CPU usage when usbredirect used as TCP server.
|
||||
Related: rhbz#2157521
|
||||
- Fixes USB redirection of identical devices.
|
||||
Resolves: rhbz#2157521
|
||||
|
||||
* Thu Jul 28 2022 Victor Toso <victortoso@redhat.com> - 0.12.0-3
|
||||
- Fix unserialization (migration regression)
|
||||
Related: rhbz#2111368
|
||||
* Wed Jul 27 2022 Victor Toso <victortoso@redhat.com> - 0.12.0-2
|
||||
- Fixes unserialization on migration
|
||||
Resolves: rhbz#2111351
|
||||
|
||||
* Wed Jan 19 2022 Victor Toso <victortoso@redhat.com> - 0.12.0-2
|
||||
- Fix gating process
|
||||
Related: rhbz#2020215
|
||||
* Fri Nov 12 2021 Victor Toso <victortoso@redhat.com> - 0.12.0-1
|
||||
- Update to 0.12.0 release
|
||||
- Resolves: rhbz#2022751
|
||||
|
||||
* Mon Nov 15 2021 Victor Toso <victortoso@redhat.com> - 0.12.0-1
|
||||
- Rebase to latest upstream: 0.12.0
|
||||
Related: rhbz#2020215
|
||||
|
||||
* Wed Sep 15 2021 Victor Toso <victortoso@redhat.com> - 0.8.0-9
|
||||
- Avoid use-after-free in serialization
|
||||
Related: rhbz#1992873
|
||||
|
||||
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 0.8.0-8
|
||||
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
||||
Related: rhbz#1991688
|
||||
|
||||
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 0.8.0-7
|
||||
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
||||
|
||||
* Wed Jan 27 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.0-6
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
||||
|
||||
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.0-5
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||
|
||||
* Fri Jan 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.0-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
|
||||
|
||||
* Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.0-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||
|
||||
* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.0-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||
|
||||
* Tue Aug 07 2018 Victor Toso <victortoso@redhat.com> - 0.8.0-1
|
||||
- Update to 0.8.0
|
||||
|
||||
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.7.1-8
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
|
||||
* Thu Aug 23 2018 Victor Toso <victortoso@redhat.com> - 0.8.0-1
|
||||
- Update to 0.8.0 release
|
||||
- Resolves: rhbz#1620098
|
||||
|
||||
* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.7.1-7
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||
|
||||
Loading…
Reference in New Issue
Block a user