From nobody Sat Apr 20 05:08:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486658979888762.9724253990504; Thu, 9 Feb 2017 08:49:39 -0800 (PST) Received: from localhost ([::1]:38912 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbruc-00056U-J8 for importer@patchew.org; Thu, 09 Feb 2017 11:49:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48100) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrsg-0003jQ-Vo for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbrse-0003CG-Ar for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:39 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54308) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cbrse-0003Bu-5O for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:36 -0500 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B7E3D711DE; Thu, 9 Feb 2017 16:47:35 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-117-196.ams2.redhat.com [10.36.117.196]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v19GlWWP030007; Thu, 9 Feb 2017 11:47:34 -0500 Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 06F0F804A2; Thu, 9 Feb 2017 17:47:24 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 9 Feb 2017 17:47:13 +0100 Message-Id: <1486658842-7143-2-git-send-email-kraxel@redhat.com> In-Reply-To: <1486658842-7143-1-git-send-email-kraxel@redhat.com> References: <1486658842-7143-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 09 Feb 2017 16:47:35 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 01/10] ui/vnc: Drop unused vnc_has_job() and vnc_jobs_clear() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Peter Maydell The functions vnc_has_job() and vnc_jobs_clear() are never used; remove them. Signed-off-by: Peter Maydell Reviewed-by: Gonglei Message-id: 1486146260-8092-1-git-send-email-peter.maydell@linaro.org Signed-off-by: Gerd Hoffmann --- ui/vnc-jobs.c | 23 ----------------------- ui/vnc-jobs.h | 2 -- 2 files changed, 25 deletions(-) diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index 98ca978..f786777 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -128,29 +128,6 @@ static bool vnc_has_job_locked(VncState *vs) return false; } =20 -bool vnc_has_job(VncState *vs) -{ - bool ret; - - vnc_lock_queue(queue); - ret =3D vnc_has_job_locked(vs); - vnc_unlock_queue(queue); - return ret; -} - -void vnc_jobs_clear(VncState *vs) -{ - VncJob *job, *tmp; - - vnc_lock_queue(queue); - QTAILQ_FOREACH_SAFE(job, &queue->jobs, next, tmp) { - if (job->vs =3D=3D vs || !vs) { - QTAILQ_REMOVE(&queue->jobs, job, next); - } - } - vnc_unlock_queue(queue); -} - void vnc_jobs_join(VncState *vs) { vnc_lock_queue(queue); diff --git a/ui/vnc-jobs.h b/ui/vnc-jobs.h index 044bf9f..59f66bc 100644 --- a/ui/vnc-jobs.h +++ b/ui/vnc-jobs.h @@ -34,8 +34,6 @@ VncJob *vnc_job_new(VncState *vs); int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h); void vnc_job_push(VncJob *job); -bool vnc_has_job(VncState *vs); -void vnc_jobs_clear(VncState *vs); void vnc_jobs_join(VncState *vs); =20 void vnc_jobs_consume_buffer(VncState *vs); --=20 1.8.3.1 From nobody Sat Apr 20 05:08:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486659250430105.99165172215476; Thu, 9 Feb 2017 08:54:10 -0800 (PST) Received: from localhost ([::1]:38935 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbryx-0000pw-PG for importer@patchew.org; Thu, 09 Feb 2017 11:54:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48099) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrsg-0003jP-VP for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbrsf-0003Cr-Bz for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:39 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54320) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cbrsf-0003CT-3d; Thu, 09 Feb 2017 11:47:37 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3B76D711DE; Thu, 9 Feb 2017 16:47:37 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-117-196.ams2.redhat.com [10.36.117.196]) by smtp.corp.redhat.com (Postfix) with ESMTP id CB16822FA03; Thu, 9 Feb 2017 16:47:34 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 195AB80A03; Thu, 9 Feb 2017 17:47:24 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 9 Feb 2017 17:47:14 +0100 Message-Id: <1486658842-7143-3-git-send-email-kraxel@redhat.com> In-Reply-To: <1486658842-7143-1-git-send-email-kraxel@redhat.com> References: <1486658842-7143-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 09 Feb 2017 16:47:37 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 02/10] vnc: do not disconnect on EAGAIN X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michael Tokarev , Gerd Hoffmann , qemu-stable@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Michael Tokarev When qemu vnc server is trying to send large update to clients, there might be a situation when system responds with something like EAGAIN, indicating that there's no system memory to send that much data (depending on the network speed, client and server and what is happening). In this case, something like this happens on qemu side (from strace): sendmsg(16, {msg_name(0)=3DNULL, msg_iov(1)=3D[{"\244\"..., 729186}], msg_controllen=3D0, msg_flags=3D0}, 0) =3D 103950 sendmsg(16, {msg_name(0)=3DNULL, msg_iov(1)=3D[{"lz\346"..., 1559618}], msg_controllen=3D0, msg_flags=3D0}, 0) =3D -1 EAGAIN sendmsg(-1, {msg_name(0)=3DNULL, msg_iov(1)=3D[{"lz\346"..., 1559618}], msg_controllen=3D0, msg_flags=3D0}, 0) =3D -1 EBADF qemu closes the socket before the retry, and obviously it gets EBADF when trying to send to -1. This is because there WAS a special handling for EAGAIN, but now it doesn't work anymore, after commit 04d2529da27db512dcbd5e99d0e26d333f16efcc, because now in all error-like cases we initiate vnc disconnect. This change were introduced in qemu 2.6, and caused numerous grief for many people, resulting in their vnc clients reporting sporadic random disconnects from vnc server. Fix that by doing the disconnect only when necessary, i.e. omitting this very case of EAGAIN. Hopefully the existing condition (comparing with QIO_CHANNEL_ERR_BLOCK) is sufficient, as the original code (before the above commit) were checking for other errno values too. Apparently there's another (semi?)bug exist somewhere here, since the code tries to write to fd# -1, it probably should check if the connection is open before. But this isn't important. Signed-off-by: Michael Tokarev Reviewed-by: Daniel P. Berrange Message-id: 1486115549-9398-1-git-send-email-mjt@msgid.tls.msk.ru Fixes: 04d2529da27db512dcbd5e99d0e26d333f16efcc Cc: Daniel P. Berrange Cc: Gerd Hoffmann Cc: qemu-stable@nongnu.org Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/vnc.c b/ui/vnc.c index cdeb79c..f2701e5 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1256,12 +1256,13 @@ ssize_t vnc_client_io_error(VncState *vs, ssize_t r= et, Error **errp) if (ret <=3D 0) { if (ret =3D=3D 0) { VNC_DEBUG("Closing down client sock: EOF\n"); + vnc_disconnect_start(vs); } else if (ret !=3D QIO_CHANNEL_ERR_BLOCK) { VNC_DEBUG("Closing down client sock: ret %zd (%s)\n", ret, errp ? error_get_pretty(*errp) : "Unknown"); + vnc_disconnect_start(vs); } =20 - vnc_disconnect_start(vs); if (errp) { error_free(*errp); *errp =3D NULL; --=20 1.8.3.1 From nobody Sat Apr 20 05:08:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 14866595032391005.5172564022312; Thu, 9 Feb 2017 08:58:23 -0800 (PST) Received: from localhost ([::1]:38961 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbs33-0004xc-R5 for importer@patchew.org; Thu, 09 Feb 2017 11:58:21 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48097) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrsg-0003jN-VG for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbrsd-0003C4-Qz for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:39 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36892) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cbrsd-0003Bc-LH for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:35 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8E07391D15 for ; Thu, 9 Feb 2017 16:47:34 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-117-196.ams2.redhat.com [10.36.117.196]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v19GlWkd026838; Thu, 9 Feb 2017 11:47:33 -0500 Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 31D5280A74; Thu, 9 Feb 2017 17:47:24 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 9 Feb 2017 17:47:15 +0100 Message-Id: <1486658842-7143-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1486658842-7143-1-git-send-email-kraxel@redhat.com> References: <1486658842-7143-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 09 Feb 2017 16:47:34 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 03/10] ui: fix regression handling bare 'websocket' option to -vnc X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Daniel P. Berrange" The -vnc argument is documented as accepting two syntaxes for the 'websocket' option, either a bare option name, or a port number. If using the bare option name, it is supposed to apply the display number as an offset to base port 5700. e.g. -vnc localhost:3,websocket should listen on port 5703, however, this was broken in 2.3.0 since commit 4db14629c38611061fc19ec6927405923de84f08 Author: Gerd Hoffmann Date: Tue Sep 16 12:33:03 2014 +0200 vnc: switch to QemuOpts, allow multiple servers instead qemu tries to listen on port "on" which gets looked up in /etc/services and fails. Fixes bug: #1455912 Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange Message-id: 20170203120649.15637-2-berrange@redhat.com Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/vnc.c b/ui/vnc.c index f2701e5..b0889b1 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3558,7 +3558,13 @@ void vnc_display_open(const char *id, Error **errp) wsaddr->type =3D SOCKET_ADDRESS_KIND_INET; inet =3D wsaddr->u.inet.data =3D g_new0(InetSocketAddress,= 1); inet->host =3D g_strdup(saddr->u.inet.data->host); - inet->port =3D g_strdup(websocket); + if (g_str_equal(websocket, "") || + g_str_equal(websocket, "on")) { + inet->port =3D g_strdup_printf( + "%d", (int)baseport + 5700); + } else { + inet->port =3D g_strdup(websocket); + } =20 if (to) { inet->has_to =3D true; --=20 1.8.3.1 From nobody Sat Apr 20 05:08:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486659254932493.40214843350725; Thu, 9 Feb 2017 08:54:14 -0800 (PST) Received: from localhost ([::1]:38936 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrz3-0000uJ-HC for importer@patchew.org; Thu, 09 Feb 2017 11:54:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48135) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrsi-0003jo-8E for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbrsg-0003Dy-Ow for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:40 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38698) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cbrsg-0003DG-G7 for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:38 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A228010F1A3 for ; Thu, 9 Feb 2017 16:47:38 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-117-196.ams2.redhat.com [10.36.117.196]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1BAA622FA05; Thu, 9 Feb 2017 16:47:36 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 4ACA980AE4; Thu, 9 Feb 2017 17:47:24 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 9 Feb 2017 17:47:16 +0100 Message-Id: <1486658842-7143-5-git-send-email-kraxel@redhat.com> In-Reply-To: <1486658842-7143-1-git-send-email-kraxel@redhat.com> References: <1486658842-7143-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 09 Feb 2017 16:47:38 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 04/10] ui: fix reporting of VNC auth in query-vnc-servers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann , Markus Armbruster Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Daniel P. Berrange" Currently the VNC authentication info is emitted at the top level of the query-vnc-servers data. This is wrong because the authentication scheme differs between plain and websockets when TLS is enabled. We should instead report auth against the individual servers. e.g. (QEMU) query-vnc-servers { "return": [ { "clients": [], "id": "default", "auth": "vencrypt", "vencrypt": "x509-vnc", "server": [ { "host": "127.0.0.1" "service": "5901", "websocket": false, "family": "ipv4", "auth": "vencrypt", "vencrypt": "x509-vnc" }, { "host": "127.0.0.1", "service": "5902", "websocket": true, "family": "ipv4", "auth": "vnc" } ] } ] } This also future proofs the QMP schema so that we can cope with multiple VNC server instances, listening on different interfaces or ports, with different auth setup. Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange Message-id: 20170203120649.15637-3-berrange@redhat.com Signed-off-by: Gerd Hoffmann --- qapi-schema.json | 28 ++++++++++++++++--- ui/vnc.c | 85 +++++++++++++++++++++++++++++++++-------------------= ---- 2 files changed, 74 insertions(+), 39 deletions(-) diff --git a/qapi-schema.json b/qapi-schema.json index cbdffdd..61151f3 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1506,7 +1506,8 @@ # # The network connection information for server # -# @auth: #optional authentication method +# @auth: #optional authentication method used for +# the plain (non-websocket) VNC server # # Since: 2.1 ## @@ -1597,6 +1598,25 @@ 'tls-plain', 'x509-plain', 'tls-sasl', 'x509-sasl' ] } =20 + +## +# @VncServerInfo2: +# +# The network connection information for server +# +# @auth: The current authentication type used by the servers +# +# @vencrypt: #optional The vencrypt sub authentication type used by the +# servers, only specified in case auth =3D=3D vencrypt. +# +# Since: 2.9 +## +{ 'struct': 'VncServerInfo2', + 'base': 'VncBasicInfo', + 'data': { 'auth' : 'VncPrimaryAuth', + '*vencrypt' : 'VncVencryptSubAuth' } } + + ## # @VncInfo2: # @@ -1612,9 +1632,9 @@ # @clients: A list of @VncClientInfo of all currently connected clients. # The list can be empty, for obvious reasons. # -# @auth: The current authentication type used by the server +# @auth: The current authentication type used by the non-websockets servers # -# @vencrypt: #optional The vencrypt sub authentication type used by the se= rver, +# @vencrypt: #optional The vencrypt authentication type used by the server= s, # only specified in case auth =3D=3D vencrypt. # # @display: #optional The display device the vnc server is linked to. @@ -1623,7 +1643,7 @@ ## { 'struct': 'VncInfo2', 'data': { 'id' : 'str', - 'server' : ['VncBasicInfo'], + 'server' : ['VncServerInfo2'], 'clients' : ['VncClientInfo'], 'auth' : 'VncPrimaryAuth', '*vencrypt' : 'VncVencryptSubAuth', diff --git a/ui/vnc.c b/ui/vnc.c index b0889b1..d0a08a7 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -429,12 +429,20 @@ out_error: return NULL; } =20 -static VncBasicInfoList *qmp_query_server_entry(QIOChannelSocket *ioc, - bool websocket, - VncBasicInfoList *prev) + +static void qmp_query_auth(int auth, int subauth, + VncPrimaryAuth *qmp_auth, + VncVencryptSubAuth *qmp_vencrypt, + bool *qmp_has_vencrypt); + +static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc, + bool websocket, + int auth, + int subauth, + VncServerInfo2List *prev) { - VncBasicInfoList *list; - VncBasicInfo *info; + VncServerInfo2List *list; + VncServerInfo2 *info; Error *err =3D NULL; SocketAddress *addr; =20 @@ -444,85 +452,91 @@ static VncBasicInfoList *qmp_query_server_entry(QIOCh= annelSocket *ioc, return prev; } =20 - info =3D g_new0(VncBasicInfo, 1); - vnc_init_basic_info(addr, info, &err); + info =3D g_new0(VncServerInfo2, 1); + vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err); qapi_free_SocketAddress(addr); if (err) { - qapi_free_VncBasicInfo(info); + qapi_free_VncServerInfo2(info); error_free(err); return prev; } info->websocket =3D websocket; =20 - list =3D g_new0(VncBasicInfoList, 1); + qmp_query_auth(auth, subauth, &info->auth, + &info->vencrypt, &info->has_vencrypt); + + list =3D g_new0(VncServerInfo2List, 1); list->value =3D info; list->next =3D prev; return list; } =20 -static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info) +static void qmp_query_auth(int auth, int subauth, + VncPrimaryAuth *qmp_auth, + VncVencryptSubAuth *qmp_vencrypt, + bool *qmp_has_vencrypt) { - switch (vd->auth) { + switch (auth) { case VNC_AUTH_VNC: - info->auth =3D VNC_PRIMARY_AUTH_VNC; + *qmp_auth =3D VNC_PRIMARY_AUTH_VNC; break; case VNC_AUTH_RA2: - info->auth =3D VNC_PRIMARY_AUTH_RA2; + *qmp_auth =3D VNC_PRIMARY_AUTH_RA2; break; case VNC_AUTH_RA2NE: - info->auth =3D VNC_PRIMARY_AUTH_RA2NE; + *qmp_auth =3D VNC_PRIMARY_AUTH_RA2NE; break; case VNC_AUTH_TIGHT: - info->auth =3D VNC_PRIMARY_AUTH_TIGHT; + *qmp_auth =3D VNC_PRIMARY_AUTH_TIGHT; break; case VNC_AUTH_ULTRA: - info->auth =3D VNC_PRIMARY_AUTH_ULTRA; + *qmp_auth =3D VNC_PRIMARY_AUTH_ULTRA; break; case VNC_AUTH_TLS: - info->auth =3D VNC_PRIMARY_AUTH_TLS; + *qmp_auth =3D VNC_PRIMARY_AUTH_TLS; break; case VNC_AUTH_VENCRYPT: - info->auth =3D VNC_PRIMARY_AUTH_VENCRYPT; - info->has_vencrypt =3D true; - switch (vd->subauth) { + *qmp_auth =3D VNC_PRIMARY_AUTH_VENCRYPT; + *qmp_has_vencrypt =3D true; + switch (subauth) { case VNC_AUTH_VENCRYPT_PLAIN: - info->vencrypt =3D VNC_VENCRYPT_SUB_AUTH_PLAIN; + *qmp_vencrypt =3D VNC_VENCRYPT_SUB_AUTH_PLAIN; break; case VNC_AUTH_VENCRYPT_TLSNONE: - info->vencrypt =3D VNC_VENCRYPT_SUB_AUTH_TLS_NONE; + *qmp_vencrypt =3D VNC_VENCRYPT_SUB_AUTH_TLS_NONE; break; case VNC_AUTH_VENCRYPT_TLSVNC: - info->vencrypt =3D VNC_VENCRYPT_SUB_AUTH_TLS_VNC; + *qmp_vencrypt =3D VNC_VENCRYPT_SUB_AUTH_TLS_VNC; break; case VNC_AUTH_VENCRYPT_TLSPLAIN: - info->vencrypt =3D VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN; + *qmp_vencrypt =3D VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN; break; case VNC_AUTH_VENCRYPT_X509NONE: - info->vencrypt =3D VNC_VENCRYPT_SUB_AUTH_X509_NONE; + *qmp_vencrypt =3D VNC_VENCRYPT_SUB_AUTH_X509_NONE; break; case VNC_AUTH_VENCRYPT_X509VNC: - info->vencrypt =3D VNC_VENCRYPT_SUB_AUTH_X509_VNC; + *qmp_vencrypt =3D VNC_VENCRYPT_SUB_AUTH_X509_VNC; break; case VNC_AUTH_VENCRYPT_X509PLAIN: - info->vencrypt =3D VNC_VENCRYPT_SUB_AUTH_X509_PLAIN; + *qmp_vencrypt =3D VNC_VENCRYPT_SUB_AUTH_X509_PLAIN; break; case VNC_AUTH_VENCRYPT_TLSSASL: - info->vencrypt =3D VNC_VENCRYPT_SUB_AUTH_TLS_SASL; + *qmp_vencrypt =3D VNC_VENCRYPT_SUB_AUTH_TLS_SASL; break; case VNC_AUTH_VENCRYPT_X509SASL: - info->vencrypt =3D VNC_VENCRYPT_SUB_AUTH_X509_SASL; + *qmp_vencrypt =3D VNC_VENCRYPT_SUB_AUTH_X509_SASL; break; default: - info->has_vencrypt =3D false; + *qmp_has_vencrypt =3D false; break; } break; case VNC_AUTH_SASL: - info->auth =3D VNC_PRIMARY_AUTH_SASL; + *qmp_auth =3D VNC_PRIMARY_AUTH_SASL; break; case VNC_AUTH_NONE: default: - info->auth =3D VNC_PRIMARY_AUTH_NONE; + *qmp_auth =3D VNC_PRIMARY_AUTH_NONE; break; } } @@ -538,7 +552,8 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp) info =3D g_new0(VncInfo2, 1); info->id =3D g_strdup(vd->id); info->clients =3D qmp_query_client_list(vd); - qmp_query_auth(vd, info); + qmp_query_auth(vd->auth, vd->subauth, &info->auth, + &info->vencrypt, &info->has_vencrypt); if (vd->dcl.con) { dev =3D DEVICE(object_property_get_link(OBJECT(vd->dcl.con), "device", NULL)); @@ -547,11 +562,11 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp) } if (vd->lsock !=3D NULL) { info->server =3D qmp_query_server_entry( - vd->lsock, false, info->server); + vd->lsock, false, vd->auth, vd->subauth, info->server); } if (vd->lwebsock !=3D NULL) { info->server =3D qmp_query_server_entry( - vd->lwebsock, true, info->server); + vd->lwebsock, true, vd->ws_auth, vd->ws_subauth, info->ser= ver); } =20 item =3D g_new0(VncInfo2List, 1); --=20 1.8.3.1 From nobody Sat Apr 20 05:08:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486660000788958.0228385864024; Thu, 9 Feb 2017 09:06:40 -0800 (PST) Received: from localhost ([::1]:39085 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbsB4-0003af-KH for importer@patchew.org; Thu, 09 Feb 2017 12:06:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48249) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrsl-0003mH-N9 for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbrsk-0003GP-6D for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:43 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33664) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cbrsj-0003Fj-UR for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:42 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 13A962B7847 for ; Thu, 9 Feb 2017 16:47:42 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-117-196.ams2.redhat.com [10.36.117.196]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4A7D022FA0B; Thu, 9 Feb 2017 16:47:37 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 6288D80B18; Thu, 9 Feb 2017 17:47:24 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 9 Feb 2017 17:47:17 +0100 Message-Id: <1486658842-7143-6-git-send-email-kraxel@redhat.com> In-Reply-To: <1486658842-7143-1-git-send-email-kraxel@redhat.com> References: <1486658842-7143-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 09 Feb 2017 16:47:42 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 05/10] ui: refactor VncDisplay to allow multiple listening sockets X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Daniel P. Berrange" Currently there is only a single listener for plain VNC and a single listener for websockets VNC. This means that if getaddrinfo() returns multiple IP addresses, for a hostname, the VNC server can only listen on one of them. This is just bearable if listening on wildcard interface, or if the host only has a single network interface to listen on, but if there are multiple NICs and the VNC server needs to listen on 2 or more specific IP addresses, it can't be done. This refactors the VncDisplay state so that it holds an array of listening sockets, but still only listens on one socket. Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange Message-id: 20170203120649.15637-4-berrange@redhat.com Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 103 +++++++++++++++++++++++++++++++++++++++++------------------= ---- ui/vnc.h | 10 ++++--- 2 files changed, 73 insertions(+), 40 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index d0a08a7..52df32d 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -224,8 +224,12 @@ static VncServerInfo *vnc_server_info_get(VncDisplay *= vd) VncServerInfo *info; Error *err =3D NULL; =20 + if (!vd->nlsock) { + return NULL; + } + info =3D g_malloc0(sizeof(*info)); - vnc_init_basic_info_from_server_addr(vd->lsock, + vnc_init_basic_info_from_server_addr(vd->lsock[0], qapi_VncServerInfo_base(info), &e= rr); info->has_auth =3D true; info->auth =3D g_strdup(vnc_auth_name(vd)); @@ -371,7 +375,7 @@ VncInfo *qmp_query_vnc(Error **errp) VncDisplay *vd =3D vnc_display_find(NULL); SocketAddress *addr =3D NULL; =20 - if (vd =3D=3D NULL || !vd->lsock) { + if (vd =3D=3D NULL || !vd->nlsock) { info->enabled =3D false; } else { info->enabled =3D true; @@ -384,7 +388,7 @@ VncInfo *qmp_query_vnc(Error **errp) return info; } =20 - addr =3D qio_channel_socket_get_local_address(vd->lsock, errp); + addr =3D qio_channel_socket_get_local_address(vd->lsock[0], errp); if (!addr) { goto out_error; } @@ -547,6 +551,7 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp) VncInfo2 *info; VncDisplay *vd; DeviceState *dev; + size_t i; =20 QTAILQ_FOREACH(vd, &vnc_displays, next) { info =3D g_new0(VncInfo2, 1); @@ -560,13 +565,14 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp) info->has_display =3D true; info->display =3D g_strdup(dev->id); } - if (vd->lsock !=3D NULL) { + for (i =3D 0; i < vd->nlsock; i++) { info->server =3D qmp_query_server_entry( - vd->lsock, false, vd->auth, vd->subauth, info->server); + vd->lsock[i], false, vd->auth, vd->subauth, info->server); } - if (vd->lwebsock !=3D NULL) { + for (i =3D 0; i < vd->nlwebsock; i++) { info->server =3D qmp_query_server_entry( - vd->lwebsock, true, vd->ws_auth, vd->ws_subauth, info->ser= ver); + vd->lwebsock[i], true, vd->ws_auth, + vd->ws_subauth, info->server); } =20 item =3D g_new0(VncInfo2List, 1); @@ -3085,15 +3091,22 @@ static gboolean vnc_listen_io(QIOChannel *ioc, VncDisplay *vd =3D opaque; QIOChannelSocket *sioc =3D NULL; Error *err =3D NULL; + bool isWebsock =3D false; + size_t i; + + for (i =3D 0; i < vd->nlwebsock; i++) { + if (ioc =3D=3D QIO_CHANNEL(vd->lwebsock[i])) { + isWebsock =3D true; + break; + } + } =20 sioc =3D qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err); if (sioc !=3D NULL) { qio_channel_set_name(QIO_CHANNEL(sioc), - ioc !=3D QIO_CHANNEL(vd->lsock) ? - "vnc-ws-server" : "vnc-server"); + isWebsock ? "vnc-ws-server" : "vnc-server"); qio_channel_set_delay(QIO_CHANNEL(sioc), false); - vnc_connect(vd, sioc, false, - ioc !=3D QIO_CHANNEL(vd->lsock)); + vnc_connect(vd, sioc, false, isWebsock); object_unref(OBJECT(sioc)); } else { /* client probably closed connection before we got there */ @@ -3153,24 +3166,33 @@ void vnc_display_init(const char *id) =20 static void vnc_display_close(VncDisplay *vd) { + size_t i; if (!vd) { return; } vd->is_unix =3D false; - if (vd->lsock !=3D NULL) { - if (vd->lsock_tag) { - g_source_remove(vd->lsock_tag); + for (i =3D 0; i < vd->nlsock; i++) { + if (vd->lsock_tag[i]) { + g_source_remove(vd->lsock_tag[i]); } - object_unref(OBJECT(vd->lsock)); - vd->lsock =3D NULL; + object_unref(OBJECT(vd->lsock[i])); } - if (vd->lwebsock !=3D NULL) { - if (vd->lwebsock_tag) { - g_source_remove(vd->lwebsock_tag); + g_free(vd->lsock); + g_free(vd->lsock_tag); + vd->lsock =3D NULL; + vd->nlsock =3D 0; + + for (i =3D 0; i < vd->nlwebsock; i++) { + if (vd->lwebsock_tag[i]) { + g_source_remove(vd->lwebsock_tag[i]); } - object_unref(OBJECT(vd->lwebsock)); - vd->lwebsock =3D NULL; + object_unref(OBJECT(vd->lwebsock[i])); } + g_free(vd->lwebsock); + g_free(vd->lwebsock_tag); + vd->lwebsock =3D NULL; + vd->nlwebsock =3D 0; + vd->auth =3D VNC_AUTH_INVALID; vd->subauth =3D VNC_AUTH_INVALID; if (vd->tlscreds) { @@ -3220,7 +3242,11 @@ static void vnc_display_print_local_addr(VncDisplay = *vd) SocketAddress *addr; Error *err =3D NULL; =20 - addr =3D qio_channel_socket_get_local_address(vd->lsock, &err); + if (!vd->nlsock) { + return; + } + + addr =3D qio_channel_socket_get_local_address(vd->lsock[0], &err); if (!addr) { return; } @@ -3784,8 +3810,6 @@ void vnc_display_open(const char *id, Error **errp) if (reverse) { /* connect to viewer */ QIOChannelSocket *sioc =3D NULL; - vd->lsock =3D NULL; - vd->lwebsock =3D NULL; if (ws_enabled) { error_setg(errp, "Cannot use websockets in reverse mode"); goto fail; @@ -3799,30 +3823,36 @@ void vnc_display_open(const char *id, Error **errp) vnc_connect(vd, sioc, false, false); object_unref(OBJECT(sioc)); } else { - vd->lsock =3D qio_channel_socket_new(); - qio_channel_set_name(QIO_CHANNEL(vd->lsock), "vnc-listen"); - if (qio_channel_socket_listen_sync(vd->lsock, saddr, errp) < 0) { + vd->nlsock =3D 1; + vd->lsock =3D g_new0(QIOChannelSocket *, 1); + vd->lsock_tag =3D g_new0(guint, 1); + + vd->lsock[0] =3D qio_channel_socket_new(); + qio_channel_set_name(QIO_CHANNEL(vd->lsock[0]), "vnc-listen"); + if (qio_channel_socket_listen_sync(vd->lsock[0], saddr, errp) < 0)= { goto fail; } vd->is_unix =3D saddr->type =3D=3D SOCKET_ADDRESS_KIND_UNIX; =20 if (ws_enabled) { - vd->lwebsock =3D qio_channel_socket_new(); - qio_channel_set_name(QIO_CHANNEL(vd->lwebsock), "vnc-ws-listen= "); - if (qio_channel_socket_listen_sync(vd->lwebsock, + vd->nlwebsock =3D 1; + vd->lwebsock =3D g_new0(QIOChannelSocket *, 1); + vd->lwebsock_tag =3D g_new0(guint, 1); + + vd->lwebsock[0] =3D qio_channel_socket_new(); + qio_channel_set_name(QIO_CHANNEL(vd->lwebsock[0]), "vnc-ws-lis= ten"); + if (qio_channel_socket_listen_sync(vd->lwebsock[0], wsaddr, errp) < 0) { - object_unref(OBJECT(vd->lsock)); - vd->lsock =3D NULL; goto fail; } } =20 - vd->lsock_tag =3D qio_channel_add_watch( - QIO_CHANNEL(vd->lsock), + vd->lsock_tag[0] =3D qio_channel_add_watch( + QIO_CHANNEL(vd->lsock[0]), G_IO_IN, vnc_listen_io, vd, NULL); if (ws_enabled) { - vd->lwebsock_tag =3D qio_channel_add_watch( - QIO_CHANNEL(vd->lwebsock), + vd->lwebsock_tag[0] =3D qio_channel_add_watch( + QIO_CHANNEL(vd->lwebsock[0]), G_IO_IN, vnc_listen_io, vd, NULL); } } @@ -3836,6 +3866,7 @@ void vnc_display_open(const char *id, Error **errp) return; =20 fail: + vnc_display_close(vd); qapi_free_SocketAddress(saddr); qapi_free_SocketAddress(wsaddr); ws_enabled =3D false; diff --git a/ui/vnc.h b/ui/vnc.h index d8c9de5..694cf32 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -146,10 +146,12 @@ struct VncDisplay int num_exclusive; int connections_limit; VncSharePolicy share_policy; - QIOChannelSocket *lsock; - guint lsock_tag; - QIOChannelSocket *lwebsock; - guint lwebsock_tag; + size_t nlsock; + QIOChannelSocket **lsock; + guint *lsock_tag; + size_t nlwebsock; + QIOChannelSocket **lwebsock; + guint *lwebsock_tag; DisplaySurface *ds; DisplayChangeListener dcl; kbd_layout_t *kbd_layout; --=20 1.8.3.1 From nobody Sat Apr 20 05:08:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486659320622746.0681228486641; Thu, 9 Feb 2017 08:55:20 -0800 (PST) Received: from localhost ([::1]:38938 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbs07-0001of-9s for importer@patchew.org; Thu, 09 Feb 2017 11:55:19 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48390) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrsn-0003o7-Uy for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbrsk-0003Hm-V0 for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:45 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34758) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cbrsk-0003GC-JD for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:42 -0500 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AAC35C05493D for ; Thu, 9 Feb 2017 16:47:42 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-117-196.ams2.redhat.com [10.36.117.196]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v19GlZDi030084; Thu, 9 Feb 2017 11:47:37 -0500 Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 78D5980B56; Thu, 9 Feb 2017 17:47:24 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 9 Feb 2017 17:47:18 +0100 Message-Id: <1486658842-7143-7-git-send-email-kraxel@redhat.com> In-Reply-To: <1486658842-7143-1-git-send-email-kraxel@redhat.com> References: <1486658842-7143-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Thu, 09 Feb 2017 16:47:42 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 06/10] ui: refactor code for populating SocketAddress from vnc_display_open X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Daniel P. Berrange" The code which interprets the CLI args to populate the SocketAddress objects for plain & websockets VNC is quite complex already and will need further enhancements shortly. Refactor it into separate methods to avoid vnc_display_open getting even larger. As a side effect of the refactoring, it is now possible to specify a listen address for the websocket server explicitly. e.g, -vnc localhost:5900,websockets=3D0.0.0.0:8080 will listen on localhost for the plain VNC server, but expose the websockets VNC server on the public interface. This refactoring also removes the restriction that prevents enabling websockets when the plain VNC server is listening on a UNIX socket. Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange Message-id: 20170203120649.15637-5-berrange@redhat.com [ kraxel: squashed clang build fix ] Signed-off-by: Gerd Hoffmann --- qemu-options.hx | 12 ++- ui/vnc.c | 282 ++++++++++++++++++++++++++++++++++++----------------= ---- 2 files changed, 189 insertions(+), 105 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index ad2f8fc..ac036b4 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1296,10 +1296,14 @@ is a TCP port number, not a display number. @item websocket =20 Opens an additional TCP listening port dedicated to VNC Websocket connecti= ons. -By definition the Websocket port is 5700+@var{display}. If @var{host} is -specified connections will only be allowed from this host. -As an alternative the Websocket port could be specified by using -@code{websocket}=3D@var{port}. +If a bare @var{websocket} option is given, the Websocket port is +5700+@var{display}. An alternative port can be specified with the +syntax @code{websocket}=3D@var{port}. + +If @var{host} is specified connections will only be allowed from this host. +It is possible to control the websocket listen address independently, using +the syntax @code{websocket}=3D@var{host}:@var{port}. + If no TLS credentials are provided, the websocket connection runs in unencrypted mode. If TLS credentials are provided, the websocket connection requires encrypted client connections. diff --git a/ui/vnc.c b/ui/vnc.c index 52df32d..7e988c6 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3495,6 +3495,178 @@ vnc_display_create_creds(bool x509, } =20 =20 +static int vnc_display_get_address(const char *addrstr, + bool websocket, + int displaynum, + int to, + bool has_ipv4, + bool has_ipv6, + bool ipv4, + bool ipv6, + SocketAddress **retaddr, + Error **errp) +{ + int ret =3D -1; + SocketAddress *addr =3D NULL; + + addr =3D g_new0(SocketAddress, 1); + + if (strncmp(addrstr, "unix:", 5) =3D=3D 0) { + addr->type =3D SOCKET_ADDRESS_KIND_UNIX; + addr->u.q_unix.data =3D g_new0(UnixSocketAddress, 1); + addr->u.q_unix.data->path =3D g_strdup(addrstr + 5); + + if (websocket) { + error_setg(errp, "UNIX sockets not supported with websock"); + goto cleanup; + } + + if (to) { + error_setg(errp, "Port range not support with UNIX socket"); + goto cleanup; + } + ret =3D 0; + } else { + const char *port; + size_t hostlen; + unsigned long long baseport =3D 0; + InetSocketAddress *inet; + + port =3D strrchr(addrstr, ':'); + if (!port) { + if (websocket) { + hostlen =3D 0; + port =3D addrstr; + } else { + error_setg(errp, "no vnc port specified"); + goto cleanup; + } + } else { + hostlen =3D port - addrstr; + port++; + if (*port =3D=3D '\0') { + error_setg(errp, "vnc port cannot be empty"); + goto cleanup; + } + } + + addr->type =3D SOCKET_ADDRESS_KIND_INET; + inet =3D addr->u.inet.data =3D g_new0(InetSocketAddress, 1); + if (addrstr[0] =3D=3D '[' && addrstr[hostlen - 1] =3D=3D ']') { + inet->host =3D g_strndup(addrstr + 1, hostlen - 2); + } else { + inet->host =3D g_strndup(addrstr, hostlen); + } + /* plain VNC port is just an offset, for websocket + * port is absolute */ + if (websocket) { + if (g_str_equal(addrstr, "") || + g_str_equal(addrstr, "on")) { + inet->port =3D g_strdup_printf( + "%d", displaynum + 5700); + if (to) { + inet->has_to =3D true; + inet->to =3D to + 5700; + } + } else { + inet->port =3D g_strdup(port); + } + } else { + if (parse_uint_full(port, &baseport, 10) < 0) { + error_setg(errp, "can't convert to a number: %s", port); + goto cleanup; + } + if (baseport > 65535 || + baseport + 5900 > 65535) { + error_setg(errp, "port %s out of range", port); + goto cleanup; + } + inet->port =3D g_strdup_printf( + "%d", (int)baseport + 5900); + + if (to) { + inet->has_to =3D true; + inet->to =3D to + 5900; + } + } + + inet->ipv4 =3D ipv4; + inet->has_ipv4 =3D has_ipv4; + inet->ipv6 =3D ipv6; + inet->has_ipv6 =3D has_ipv6; + + ret =3D baseport; + } + + *retaddr =3D addr; + + cleanup: + if (ret < 0) { + qapi_free_SocketAddress(addr); + } + return ret; +} + +static int vnc_display_get_addresses(QemuOpts *opts, + SocketAddress **retsaddr, + SocketAddress **retwsaddr, + Error **errp) +{ + SocketAddress *saddr =3D NULL; + SocketAddress *wsaddr =3D NULL; + const char *saddrstr =3D qemu_opt_get(opts, "vnc"); + const char *wsaddrstr =3D qemu_opt_get(opts, "websocket"); + int to =3D qemu_opt_get_number(opts, "to", 0); + bool has_ipv4 =3D qemu_opt_get(opts, "ipv4"); + bool has_ipv6 =3D qemu_opt_get(opts, "ipv6"); + bool ipv4 =3D qemu_opt_get_bool(opts, "ipv4", false); + bool ipv6 =3D qemu_opt_get_bool(opts, "ipv6", false); + + if (!saddrstr || strcmp(saddrstr, "none") =3D=3D 0) { + *retsaddr =3D NULL; + *retwsaddr =3D NULL; + return 0; + } + + if (wsaddrstr && + !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) { + error_setg(errp, + "SHA1 hash support is required for websockets"); + goto error; + } + + int displaynum =3D vnc_display_get_address(saddrstr, false, 0, to, + has_ipv4, has_ipv6, + ipv4, ipv6, + &saddr, errp); + if (displaynum < 0) { + goto error; + } + if (wsaddrstr) { + if (vnc_display_get_address(wsaddrstr, true, displaynum, to, + has_ipv4, has_ipv6, + ipv4, ipv6, + &wsaddr, errp) < 0) { + goto error; + } + if (saddr->type =3D=3D SOCKET_ADDRESS_KIND_INET && + wsaddr->type =3D=3D SOCKET_ADDRESS_KIND_INET && + g_str_equal(wsaddr->u.inet.data->host, "") && + !g_str_equal(saddr->u.inet.data->host, "")) { + g_free(wsaddr->u.inet.data->host); + wsaddr->u.inet.data->host =3D g_strdup(saddr->u.inet.data->hos= t); + } + } + *retsaddr =3D saddr; + *retwsaddr =3D wsaddr; + return 0; + + error: + qapi_free_SocketAddress(saddr); + qapi_free_SocketAddress(wsaddr); + return -1; +} + void vnc_display_open(const char *id, Error **errp) { VncDisplay *vd =3D vnc_display_find(id); @@ -3504,10 +3676,7 @@ void vnc_display_open(const char *id, Error **errp) QemuConsole *con; bool password =3D false; bool reverse =3D false; - const char *vnc; - char *h; const char *credid; - int show_vnc_port =3D 0; bool sasl =3D false; #ifdef CONFIG_VNC_SASL int saslErr; @@ -3515,7 +3684,6 @@ void vnc_display_open(const char *id, Error **errp) int acl =3D 0; int lock_key_sync =3D 1; int key_delay_ms; - bool ws_enabled =3D false; =20 if (!vd) { error_setg(errp, "VNC display not active"); @@ -3526,102 +3694,15 @@ void vnc_display_open(const char *id, Error **errp) if (!opts) { return; } - vnc =3D qemu_opt_get(opts, "vnc"); - if (!vnc || strcmp(vnc, "none") =3D=3D 0) { - return; - } =20 - h =3D strrchr(vnc, ':'); - if (h) { - size_t hlen =3D h - vnc; - - const char *websocket =3D qemu_opt_get(opts, "websocket"); - int to =3D qemu_opt_get_number(opts, "to", 0); - bool has_ipv4 =3D qemu_opt_get(opts, "ipv4"); - bool has_ipv6 =3D qemu_opt_get(opts, "ipv6"); - bool ipv4 =3D qemu_opt_get_bool(opts, "ipv4", false); - bool ipv6 =3D qemu_opt_get_bool(opts, "ipv6", false); - - saddr =3D g_new0(SocketAddress, 1); - if (websocket) { - if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) { - error_setg(errp, - "SHA1 hash support is required for websockets"); - goto fail; - } - - wsaddr =3D g_new0(SocketAddress, 1); - ws_enabled =3D true; - } - - if (strncmp(vnc, "unix:", 5) =3D=3D 0) { - saddr->type =3D SOCKET_ADDRESS_KIND_UNIX; - saddr->u.q_unix.data =3D g_new0(UnixSocketAddress, 1); - saddr->u.q_unix.data->path =3D g_strdup(vnc + 5); - - if (ws_enabled) { - error_setg(errp, "UNIX sockets not supported with websock"= ); - goto fail; - } - } else { - unsigned long long baseport; - InetSocketAddress *inet; - saddr->type =3D SOCKET_ADDRESS_KIND_INET; - inet =3D saddr->u.inet.data =3D g_new0(InetSocketAddress, 1); - if (vnc[0] =3D=3D '[' && vnc[hlen - 1] =3D=3D ']') { - inet->host =3D g_strndup(vnc + 1, hlen - 2); - } else { - inet->host =3D g_strndup(vnc, hlen); - } - if (parse_uint_full(h + 1, &baseport, 10) < 0) { - error_setg(errp, "can't convert to a number: %s", h + 1); - goto fail; - } - if (baseport > 65535 || - baseport + 5900 > 65535) { - error_setg(errp, "port %s out of range", h + 1); - goto fail; - } - inet->port =3D g_strdup_printf( - "%d", (int)baseport + 5900); - - if (to) { - inet->has_to =3D true; - inet->to =3D to + 5900; - show_vnc_port =3D 1; - } - inet->ipv4 =3D ipv4; - inet->has_ipv4 =3D has_ipv4; - inet->ipv6 =3D ipv6; - inet->has_ipv6 =3D has_ipv6; - - if (ws_enabled) { - wsaddr->type =3D SOCKET_ADDRESS_KIND_INET; - inet =3D wsaddr->u.inet.data =3D g_new0(InetSocketAddress,= 1); - inet->host =3D g_strdup(saddr->u.inet.data->host); - if (g_str_equal(websocket, "") || - g_str_equal(websocket, "on")) { - inet->port =3D g_strdup_printf( - "%d", (int)baseport + 5700); - } else { - inet->port =3D g_strdup(websocket); - } - - if (to) { - inet->has_to =3D true; - inet->to =3D to; - } - inet->ipv4 =3D ipv4; - inet->has_ipv4 =3D has_ipv4; - inet->ipv6 =3D ipv6; - inet->has_ipv6 =3D has_ipv6; - } - } - } else { - error_setg(errp, "no vnc port specified"); + if (vnc_display_get_addresses(opts, &saddr, &wsaddr, errp) < 0) { goto fail; } =20 + if (saddr =3D=3D NULL) { + return; + } + password =3D qemu_opt_get_bool(opts, "password", false); if (password) { if (fips_get_state()) { @@ -3810,7 +3891,7 @@ void vnc_display_open(const char *id, Error **errp) if (reverse) { /* connect to viewer */ QIOChannelSocket *sioc =3D NULL; - if (ws_enabled) { + if (wsaddr) { error_setg(errp, "Cannot use websockets in reverse mode"); goto fail; } @@ -3834,7 +3915,7 @@ void vnc_display_open(const char *id, Error **errp) } vd->is_unix =3D saddr->type =3D=3D SOCKET_ADDRESS_KIND_UNIX; =20 - if (ws_enabled) { + if (wsaddr) { vd->nlwebsock =3D 1; vd->lwebsock =3D g_new0(QIOChannelSocket *, 1); vd->lwebsock_tag =3D g_new0(guint, 1); @@ -3850,14 +3931,14 @@ void vnc_display_open(const char *id, Error **errp) vd->lsock_tag[0] =3D qio_channel_add_watch( QIO_CHANNEL(vd->lsock[0]), G_IO_IN, vnc_listen_io, vd, NULL); - if (ws_enabled) { + if (wsaddr) { vd->lwebsock_tag[0] =3D qio_channel_add_watch( QIO_CHANNEL(vd->lwebsock[0]), G_IO_IN, vnc_listen_io, vd, NULL); } } =20 - if (show_vnc_port) { + if (qemu_opt_get(opts, "to")) { vnc_display_print_local_addr(vd); } =20 @@ -3869,7 +3950,6 @@ fail: vnc_display_close(vd); qapi_free_SocketAddress(saddr); qapi_free_SocketAddress(wsaddr); - ws_enabled =3D false; } =20 void vnc_display_add_client(const char *id, int csock, bool skipauth) --=20 1.8.3.1 From nobody Sat Apr 20 05:08:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486660224883872.2942374166582; Thu, 9 Feb 2017 09:10:24 -0800 (PST) Received: from localhost ([::1]:39130 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbsEh-0006zM-2b for importer@patchew.org; Thu, 09 Feb 2017 12:10:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48286) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrsm-0003mt-G4 for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbrsk-0003Hf-Uc for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:44 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34760) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cbrsk-0003GJ-KM for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:42 -0500 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C20CDC05493E for ; Thu, 9 Feb 2017 16:47:42 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-117-196.ams2.redhat.com [10.36.117.196]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v19GlaWm030136; Thu, 9 Feb 2017 11:47:38 -0500 Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 8ED1E80B99; Thu, 9 Feb 2017 17:47:24 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 9 Feb 2017 17:47:19 +0100 Message-Id: <1486658842-7143-8-git-send-email-kraxel@redhat.com> In-Reply-To: <1486658842-7143-1-git-send-email-kraxel@redhat.com> References: <1486658842-7143-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Thu, 09 Feb 2017 16:47:42 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 07/10] ui: extract code to connect/listen from vnc_display_open X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Daniel P. Berrange" The code which takes a SocketAddress and connects/listens on the network is going to get more complicated to deal with multiple listeners. Pull it out into a separate method to avoid making the vnc_display_open method even more complex. Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange Message-id: 20170203120649.15637-6-berrange@redhat.com Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 122 +++++++++++++++++++++++++++++++++++++++++------------------= ---- 1 file changed, 80 insertions(+), 42 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 7e988c6..02c0b89 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3667,6 +3667,84 @@ static int vnc_display_get_addresses(QemuOpts *opts, return -1; } =20 +static int vnc_display_connect(VncDisplay *vd, + SocketAddress *saddr, + SocketAddress *wsaddr, + Error **errp) +{ + /* connect to viewer */ + QIOChannelSocket *sioc =3D NULL; + if (wsaddr) { + error_setg(errp, "Cannot use websockets in reverse mode"); + return -1; + } + vd->is_unix =3D saddr->type =3D=3D SOCKET_ADDRESS_KIND_UNIX; + sioc =3D qio_channel_socket_new(); + qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse"); + if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) { + return -1; + } + vnc_connect(vd, sioc, false, false); + object_unref(OBJECT(sioc)); + return 0; +} + + +static int vnc_display_listen_addr(VncDisplay *vd, + SocketAddress *addr, + const char *name, + QIOChannelSocket ***lsock, + guint **lsock_tag, + size_t *nlsock, + Error **errp) +{ + *nlsock =3D 1; + *lsock =3D g_new0(QIOChannelSocket *, 1); + *lsock_tag =3D g_new0(guint, 1); + + (*lsock)[0] =3D qio_channel_socket_new(); + qio_channel_set_name(QIO_CHANNEL((*lsock)[0]), name); + if (qio_channel_socket_listen_sync((*lsock)[0], addr, errp) < 0) { + return -1; + } + + (*lsock_tag)[0] =3D qio_channel_add_watch( + QIO_CHANNEL((*lsock)[0]), + G_IO_IN, vnc_listen_io, vd, NULL); + + return 0; +} + + +static int vnc_display_listen(VncDisplay *vd, + SocketAddress *saddr, + SocketAddress *wsaddr, + Error **errp) +{ + vd->is_unix =3D saddr->type =3D=3D SOCKET_ADDRESS_KIND_UNIX; + + if (vnc_display_listen_addr(vd, saddr, + "vnc-listen", + &vd->lsock, + &vd->lsock_tag, + &vd->nlsock, + errp) < 0) { + return -1; + } + if (wsaddr && + vnc_display_listen_addr(vd, wsaddr, + "vnc-ws-listen", + &vd->lwebsock, + &vd->lwebsock_tag, + &vd->nlwebsock, + errp) < 0) { + return -1; + } + + return 0; +} + + void vnc_display_open(const char *id, Error **errp) { VncDisplay *vd =3D vnc_display_find(id); @@ -3889,53 +3967,13 @@ void vnc_display_open(const char *id, Error **errp) } =20 if (reverse) { - /* connect to viewer */ - QIOChannelSocket *sioc =3D NULL; - if (wsaddr) { - error_setg(errp, "Cannot use websockets in reverse mode"); + if (vnc_display_connect(vd, saddr, wsaddr, errp) < 0) { goto fail; } - vd->is_unix =3D saddr->type =3D=3D SOCKET_ADDRESS_KIND_UNIX; - sioc =3D qio_channel_socket_new(); - qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse"); - if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) { - goto fail; - } - vnc_connect(vd, sioc, false, false); - object_unref(OBJECT(sioc)); } else { - vd->nlsock =3D 1; - vd->lsock =3D g_new0(QIOChannelSocket *, 1); - vd->lsock_tag =3D g_new0(guint, 1); - - vd->lsock[0] =3D qio_channel_socket_new(); - qio_channel_set_name(QIO_CHANNEL(vd->lsock[0]), "vnc-listen"); - if (qio_channel_socket_listen_sync(vd->lsock[0], saddr, errp) < 0)= { + if (vnc_display_listen(vd, saddr, wsaddr, errp) < 0) { goto fail; } - vd->is_unix =3D saddr->type =3D=3D SOCKET_ADDRESS_KIND_UNIX; - - if (wsaddr) { - vd->nlwebsock =3D 1; - vd->lwebsock =3D g_new0(QIOChannelSocket *, 1); - vd->lwebsock_tag =3D g_new0(guint, 1); - - vd->lwebsock[0] =3D qio_channel_socket_new(); - qio_channel_set_name(QIO_CHANNEL(vd->lwebsock[0]), "vnc-ws-lis= ten"); - if (qio_channel_socket_listen_sync(vd->lwebsock[0], - wsaddr, errp) < 0) { - goto fail; - } - } - - vd->lsock_tag[0] =3D qio_channel_add_watch( - QIO_CHANNEL(vd->lsock[0]), - G_IO_IN, vnc_listen_io, vd, NULL); - if (wsaddr) { - vd->lwebsock_tag[0] =3D qio_channel_add_watch( - QIO_CHANNEL(vd->lwebsock[0]), - G_IO_IN, vnc_listen_io, vd, NULL); - } } =20 if (qemu_opt_get(opts, "to")) { --=20 1.8.3.1 From nobody Sat Apr 20 05:08:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486658994057193.82355152522223; Thu, 9 Feb 2017 08:49:54 -0800 (PST) Received: from localhost ([::1]:38914 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbruq-0005FV-OQ for importer@patchew.org; Thu, 09 Feb 2017 11:49:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48259) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrsl-0003mV-UD for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbrsk-0003H1-NR for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:43 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54338) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cbrsk-0003G7-FU for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:42 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D0E26711C3 for ; Thu, 9 Feb 2017 16:47:39 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-117-196.ams2.redhat.com [10.36.117.196]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v19Gla3q021783; Thu, 9 Feb 2017 11:47:38 -0500 Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id A86F7809D5; Thu, 9 Feb 2017 17:47:24 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 9 Feb 2017 17:47:20 +0100 Message-Id: <1486658842-7143-9-git-send-email-kraxel@redhat.com> In-Reply-To: <1486658842-7143-1-git-send-email-kraxel@redhat.com> References: <1486658842-7143-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 09 Feb 2017 16:47:39 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 08/10] ui: let VNC server listen on all resolved IP addresses X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Daniel P. Berrange" Remove the limitation that the VNC server can only listen on a single resolved IP address. This uses the new DNS resolver API to resolve a SocketAddress struct into an array of SocketAddress structs containing raw IP addresses. The VNC server will then attempt to listen on all resolved IP addresses. The server must successfully listen on at least one of the resolved IP addresses, otherwise an error will be reported. Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange Message-id: 20170203120649.15637-7-berrange@redhat.com Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 52 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 02c0b89..5c11c2d 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -45,6 +45,7 @@ #include "crypto/tlscredsx509.h" #include "qom/object_interfaces.h" #include "qemu/cutils.h" +#include "io/dns-resolver.h" =20 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT #define VNC_REFRESH_INTERVAL_INC 50 @@ -3698,19 +3699,52 @@ static int vnc_display_listen_addr(VncDisplay *vd, size_t *nlsock, Error **errp) { - *nlsock =3D 1; - *lsock =3D g_new0(QIOChannelSocket *, 1); - *lsock_tag =3D g_new0(guint, 1); + QIODNSResolver *resolver =3D qio_dns_resolver_get_instance(); + SocketAddress **rawaddrs =3D NULL; + size_t nrawaddrs =3D 0; + Error *listenerr =3D NULL; + size_t i; =20 - (*lsock)[0] =3D qio_channel_socket_new(); - qio_channel_set_name(QIO_CHANNEL((*lsock)[0]), name); - if (qio_channel_socket_listen_sync((*lsock)[0], addr, errp) < 0) { + if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs, + &rawaddrs, errp) < 0) { return -1; } =20 - (*lsock_tag)[0] =3D qio_channel_add_watch( - QIO_CHANNEL((*lsock)[0]), - G_IO_IN, vnc_listen_io, vd, NULL); + for (i =3D 0; i < nrawaddrs; i++) { + QIOChannelSocket *sioc =3D qio_channel_socket_new(); + + qio_channel_set_name(QIO_CHANNEL(sioc), name); + if (qio_channel_socket_listen_sync( + sioc, rawaddrs[i], listenerr =3D=3D NULL ? &listenerr : NU= LL) < 0) { + continue; + } + (*nlsock)++; + *lsock =3D g_renew(QIOChannelSocket *, *lsock, *nlsock); + *lsock_tag =3D g_renew(guint, *lsock_tag, *nlsock); + + (*lsock)[*nlsock - 1] =3D sioc; + (*lsock_tag)[*nlsock - 1] =3D 0; + } + + for (i =3D 0; i < nrawaddrs; i++) { + qapi_free_SocketAddress(rawaddrs[i]); + } + g_free(rawaddrs); + + if (listenerr) { + if (*nlsock =3D=3D 0) { + error_propagate(errp, listenerr); + return -1; + } else { + error_free(listenerr); + } + } + + for (i =3D 0; i < *nlsock; i++) { + (*lsock_tag)[i] =3D qio_channel_add_watch( + QIO_CHANNEL((*lsock)[i]), + G_IO_IN, vnc_listen_io, vd, NULL); + } =20 return 0; } --=20 1.8.3.1 From nobody Sat Apr 20 05:08:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486659765079894.6154346970687; Thu, 9 Feb 2017 09:02:45 -0800 (PST) Received: from localhost ([::1]:39026 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbs7C-0008T6-AY for importer@patchew.org; Thu, 09 Feb 2017 12:02:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48186) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrsk-0003lU-LE for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbrsj-0003Fu-MZ for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:42 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39004) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cbrsj-0003FN-Hf for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:41 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0935043A3C for ; Thu, 9 Feb 2017 16:47:40 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-117-196.ams2.redhat.com [10.36.117.196]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v19GlbMG026959; Thu, 9 Feb 2017 11:47:38 -0500 Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id C176680BD2; Thu, 9 Feb 2017 17:47:24 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 9 Feb 2017 17:47:21 +0100 Message-Id: <1486658842-7143-10-git-send-email-kraxel@redhat.com> In-Reply-To: <1486658842-7143-1-git-send-email-kraxel@redhat.com> References: <1486658842-7143-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 09 Feb 2017 16:47:40 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 09/10] util: add iterators for QemuOpts values X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Daniel P. Berrange" To iterate over all QemuOpts currently requires using a callback function which is inconvenient for control flow. Add support for using iterator functions more directly QemuOptsIter iter; QemuOpt *opt; qemu_opts_iter_init(&iter, opts, "repeated-key"); while ((opt =3D qemu_opts_iter_next(&iter)) !=3D NULL) { ....do something... } Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange Message-id: 20170203120649.15637-8-berrange@redhat.com Signed-off-by: Gerd Hoffmann --- include/qemu/option.h | 9 +++++++++ util/qemu-option.c | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/qemu/option.h b/include/qemu/option.h index 1f9e3f9..e786df0 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -100,6 +100,15 @@ typedef int (*qemu_opt_loopfunc)(void *opaque, int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, Error **errp); =20 +typedef struct { + QemuOpts *opts; + QemuOpt *opt; + const char *name; +} QemuOptsIter; + +void qemu_opt_iter_init(QemuOptsIter *iter, QemuOpts *opts, const char *na= me); +const char *qemu_opt_iter_next(QemuOptsIter *iter); + QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id); QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists, Error **errp); diff --git a/util/qemu-option.c b/util/qemu-option.c index 3467dc2..d611946 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -332,6 +332,25 @@ const char *qemu_opt_get(QemuOpts *opts, const char *n= ame) return opt ? opt->str : NULL; } =20 +void qemu_opt_iter_init(QemuOptsIter *iter, QemuOpts *opts, const char *na= me) +{ + iter->opts =3D opts; + iter->opt =3D QTAILQ_FIRST(&opts->head); + iter->name =3D name; +} + +const char *qemu_opt_iter_next(QemuOptsIter *iter) +{ + QemuOpt *ret =3D iter->opt; + if (iter->name) { + while (ret && !g_str_equal(iter->name, ret->name)) { + ret =3D QTAILQ_NEXT(ret, next); + } + } + iter->opt =3D ret ? QTAILQ_NEXT(ret, next) : NULL; + return ret ? ret->str : NULL; +} + /* Get a known option (or its default) and remove it from the list * all in one action. Return a malloced string of the option value. * Result must be freed by caller with g_free(). --=20 1.8.3.1 From nobody Sat Apr 20 05:08:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486659573769848.8227348243286; Thu, 9 Feb 2017 08:59:33 -0800 (PST) Received: from localhost ([::1]:38971 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbs4C-00061i-I2 for importer@patchew.org; Thu, 09 Feb 2017 11:59:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48414) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cbrso-0003oF-6W for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cbrsl-0003IP-HZ for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:46 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54344) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cbrsl-0003Gu-7u for qemu-devel@nongnu.org; Thu, 09 Feb 2017 11:47:43 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A180272898 for ; Thu, 9 Feb 2017 16:47:42 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-117-196.ams2.redhat.com [10.36.117.196]) by smtp.corp.redhat.com (Postfix) with ESMTP id CA6D5233962; Thu, 9 Feb 2017 16:47:38 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id D6F5980C3E; Thu, 9 Feb 2017 17:47:24 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 9 Feb 2017 17:47:22 +0100 Message-Id: <1486658842-7143-11-git-send-email-kraxel@redhat.com> In-Reply-To: <1486658842-7143-1-git-send-email-kraxel@redhat.com> References: <1486658842-7143-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 09 Feb 2017 16:47:42 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 10/10] ui: add ability to specify multiple VNC listen addresses X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Daniel P. Berrange" This change allows the listen address and websocket address options for -vnc to be repeated. This causes the VNC server to listen on multiple addresses. e.g. $ $QEMU -vnc vnc=3Dlocalhost:1,vnc=3Dunix:/tmp/vnc,\ websocket=3D127.0.0.1:8080,websocket=3D[::]:8081 results in listening on 127.0.0.1:5901, 127.0.0.1:8080, ::1:5901, :::8081 & /tmp/vnc Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange Message-id: 20170203120649.15637-9-berrange@redhat.com Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 195 +++++++++++++++++++++++++++++++++++++++++++----------------= ---- 1 file changed, 133 insertions(+), 62 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 5c11c2d..62e85ed 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3563,6 +3563,10 @@ static int vnc_display_get_address(const char *addrs= tr, if (websocket) { if (g_str_equal(addrstr, "") || g_str_equal(addrstr, "on")) { + if (displaynum =3D=3D -1) { + error_setg(errp, "explicit websocket port is required"= ); + goto cleanup; + } inet->port =3D g_strdup_printf( "%d", displaynum + 5700); if (to) { @@ -3609,80 +3613,133 @@ static int vnc_display_get_address(const char *add= rstr, } =20 static int vnc_display_get_addresses(QemuOpts *opts, - SocketAddress **retsaddr, - SocketAddress **retwsaddr, + SocketAddress ***retsaddr, + size_t *retnsaddr, + SocketAddress ***retwsaddr, + size_t *retnwsaddr, Error **errp) { SocketAddress *saddr =3D NULL; SocketAddress *wsaddr =3D NULL; - const char *saddrstr =3D qemu_opt_get(opts, "vnc"); - const char *wsaddrstr =3D qemu_opt_get(opts, "websocket"); + QemuOptsIter addriter; + const char *addr; int to =3D qemu_opt_get_number(opts, "to", 0); bool has_ipv4 =3D qemu_opt_get(opts, "ipv4"); bool has_ipv6 =3D qemu_opt_get(opts, "ipv6"); bool ipv4 =3D qemu_opt_get_bool(opts, "ipv4", false); bool ipv6 =3D qemu_opt_get_bool(opts, "ipv6", false); + size_t i; + int displaynum =3D -1; + int ret =3D -1; =20 - if (!saddrstr || strcmp(saddrstr, "none") =3D=3D 0) { - *retsaddr =3D NULL; - *retwsaddr =3D NULL; - return 0; + *retsaddr =3D NULL; + *retnsaddr =3D 0; + *retwsaddr =3D NULL; + *retnwsaddr =3D 0; + + addr =3D qemu_opt_get(opts, "vnc"); + if (addr =3D=3D NULL || g_str_equal(addr, "none")) { + ret =3D 0; + goto cleanup; } - - if (wsaddrstr && + if (qemu_opt_get(opts, "websocket") && !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) { error_setg(errp, "SHA1 hash support is required for websockets"); - goto error; + goto cleanup; } =20 - int displaynum =3D vnc_display_get_address(saddrstr, false, 0, to, - has_ipv4, has_ipv6, - ipv4, ipv6, - &saddr, errp); - if (displaynum < 0) { - goto error; + qemu_opt_iter_init(&addriter, opts, "vnc"); + while ((addr =3D qemu_opt_iter_next(&addriter)) !=3D NULL) { + int rv; + rv =3D vnc_display_get_address(addr, false, 0, to, + has_ipv4, has_ipv6, + ipv4, ipv6, + &saddr, errp); + if (rv < 0) { + goto cleanup; + } + /* Historical compat - first listen address can be used + * to set the default websocket port + */ + if (displaynum =3D=3D -1) { + displaynum =3D rv; + } + *retsaddr =3D g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1); + (*retsaddr)[(*retnsaddr)++] =3D saddr; } - if (wsaddrstr) { - if (vnc_display_get_address(wsaddrstr, true, displaynum, to, + + /* If we had multiple primary displays, we don't do defaults + * for websocket, and require explicit config instead. */ + if (*retnsaddr > 1) { + displaynum =3D -1; + } + + qemu_opt_iter_init(&addriter, opts, "websocket"); + while ((addr =3D qemu_opt_iter_next(&addriter)) !=3D NULL) { + if (vnc_display_get_address(addr, true, displaynum, to, has_ipv4, has_ipv6, ipv4, ipv6, &wsaddr, errp) < 0) { - goto error; + goto cleanup; } - if (saddr->type =3D=3D SOCKET_ADDRESS_KIND_INET && + + /* Historical compat - if only a single listen address was + * provided, then this is used to set the default listen + * address for websocket too + */ + if (*retnsaddr =3D=3D 1 && + (*retsaddr)[0]->type =3D=3D SOCKET_ADDRESS_KIND_INET && wsaddr->type =3D=3D SOCKET_ADDRESS_KIND_INET && g_str_equal(wsaddr->u.inet.data->host, "") && - !g_str_equal(saddr->u.inet.data->host, "")) { + !g_str_equal((*retsaddr)[0]->u.inet.data->host, "")) { g_free(wsaddr->u.inet.data->host); - wsaddr->u.inet.data->host =3D g_strdup(saddr->u.inet.data->hos= t); + wsaddr->u.inet.data->host =3D + g_strdup((*retsaddr)[0]->u.inet.data->host); } + + *retwsaddr =3D g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + = 1); + (*retwsaddr)[(*retnwsaddr)++] =3D wsaddr; } - *retsaddr =3D saddr; - *retwsaddr =3D wsaddr; - return 0; =20 - error: - qapi_free_SocketAddress(saddr); - qapi_free_SocketAddress(wsaddr); - return -1; + ret =3D 0; + cleanup: + if (ret < 0) { + for (i =3D 0; i < *retnsaddr; i++) { + qapi_free_SocketAddress((*retsaddr)[i]); + } + g_free(*retsaddr); + for (i =3D 0; i < *retnwsaddr; i++) { + qapi_free_SocketAddress((*retwsaddr)[i]); + } + g_free(*retwsaddr); + *retsaddr =3D *retwsaddr =3D NULL; + *retnsaddr =3D *retnwsaddr =3D 0; + } + return ret; } =20 static int vnc_display_connect(VncDisplay *vd, - SocketAddress *saddr, - SocketAddress *wsaddr, + SocketAddress **saddr, + size_t nsaddr, + SocketAddress **wsaddr, + size_t nwsaddr, Error **errp) { /* connect to viewer */ QIOChannelSocket *sioc =3D NULL; - if (wsaddr) { + if (nwsaddr !=3D 0) { error_setg(errp, "Cannot use websockets in reverse mode"); return -1; } - vd->is_unix =3D saddr->type =3D=3D SOCKET_ADDRESS_KIND_UNIX; + if (nsaddr !=3D 1) { + error_setg(errp, "Expected a single address in reverse mode"); + return -1; + } + vd->is_unix =3D saddr[0]->type =3D=3D SOCKET_ADDRESS_KIND_UNIX; sioc =3D qio_channel_socket_new(); qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse"); - if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) { + if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) { return -1; } vnc_connect(vd, sioc, false, false); @@ -3703,6 +3760,7 @@ static int vnc_display_listen_addr(VncDisplay *vd, SocketAddress **rawaddrs =3D NULL; size_t nrawaddrs =3D 0; Error *listenerr =3D NULL; + bool listening =3D false; size_t i; =20 if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs, @@ -3718,6 +3776,7 @@ static int vnc_display_listen_addr(VncDisplay *vd, sioc, rawaddrs[i], listenerr =3D=3D NULL ? &listenerr : NU= LL) < 0) { continue; } + listening =3D true; (*nlsock)++; *lsock =3D g_renew(QIOChannelSocket *, *lsock, *nlsock); *lsock_tag =3D g_renew(guint, *lsock_tag, *nlsock); @@ -3732,7 +3791,7 @@ static int vnc_display_listen_addr(VncDisplay *vd, g_free(rawaddrs); =20 if (listenerr) { - if (*nlsock =3D=3D 0) { + if (!listening) { error_propagate(errp, listenerr); return -1; } else { @@ -3751,28 +3810,33 @@ static int vnc_display_listen_addr(VncDisplay *vd, =20 =20 static int vnc_display_listen(VncDisplay *vd, - SocketAddress *saddr, - SocketAddress *wsaddr, + SocketAddress **saddr, + size_t nsaddr, + SocketAddress **wsaddr, + size_t nwsaddr, Error **errp) { - vd->is_unix =3D saddr->type =3D=3D SOCKET_ADDRESS_KIND_UNIX; + size_t i; =20 - if (vnc_display_listen_addr(vd, saddr, - "vnc-listen", - &vd->lsock, - &vd->lsock_tag, - &vd->nlsock, - errp) < 0) { - return -1; + for (i =3D 0; i < nsaddr; i++) { + if (vnc_display_listen_addr(vd, saddr[i], + "vnc-listen", + &vd->lsock, + &vd->lsock_tag, + &vd->nlsock, + errp) < 0) { + return -1; + } } - if (wsaddr && - vnc_display_listen_addr(vd, wsaddr, - "vnc-ws-listen", - &vd->lwebsock, - &vd->lwebsock_tag, - &vd->nlwebsock, - errp) < 0) { - return -1; + for (i =3D 0; i < nwsaddr; i++) { + if (vnc_display_listen_addr(vd, wsaddr[i], + "vnc-ws-listen", + &vd->lwebsock, + &vd->lwebsock_tag, + &vd->nlwebsock, + errp) < 0) { + return -1; + } } =20 return 0; @@ -3783,7 +3847,8 @@ void vnc_display_open(const char *id, Error **errp) { VncDisplay *vd =3D vnc_display_find(id); QemuOpts *opts =3D qemu_opts_find(&qemu_vnc_opts, id); - SocketAddress *saddr =3D NULL, *wsaddr =3D NULL; + SocketAddress **saddr =3D NULL, **wsaddr =3D NULL; + size_t nsaddr, nwsaddr; const char *share, *device_id; QemuConsole *con; bool password =3D false; @@ -3796,6 +3861,7 @@ void vnc_display_open(const char *id, Error **errp) int acl =3D 0; int lock_key_sync =3D 1; int key_delay_ms; + size_t i; =20 if (!vd) { error_setg(errp, "VNC display not active"); @@ -3807,7 +3873,8 @@ void vnc_display_open(const char *id, Error **errp) return; } =20 - if (vnc_display_get_addresses(opts, &saddr, &wsaddr, errp) < 0) { + if (vnc_display_get_addresses(opts, &saddr, &nsaddr, + &wsaddr, &nwsaddr, errp) < 0) { goto fail; } =20 @@ -4001,11 +4068,11 @@ void vnc_display_open(const char *id, Error **errp) } =20 if (reverse) { - if (vnc_display_connect(vd, saddr, wsaddr, errp) < 0) { + if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) = < 0) { goto fail; } } else { - if (vnc_display_listen(vd, saddr, wsaddr, errp) < 0) { + if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) <= 0) { goto fail; } } @@ -4014,14 +4081,18 @@ void vnc_display_open(const char *id, Error **errp) vnc_display_print_local_addr(vd); } =20 - qapi_free_SocketAddress(saddr); - qapi_free_SocketAddress(wsaddr); + cleanup: + for (i =3D 0; i < nsaddr; i++) { + qapi_free_SocketAddress(saddr[i]); + } + for (i =3D 0; i < nwsaddr; i++) { + qapi_free_SocketAddress(wsaddr[i]); + } return; =20 fail: vnc_display_close(vd); - qapi_free_SocketAddress(saddr); - qapi_free_SocketAddress(wsaddr); + goto cleanup; } =20 void vnc_display_add_client(const char *id, int csock, bool skipauth) --=20 1.8.3.1