From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JF2hz-00007d-VN for qemu-devel@nongnu.org; Wed, 16 Jan 2008 02:29:12 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JF2hy-00006a-UV for qemu-devel@nongnu.org; Wed, 16 Jan 2008 02:29:11 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JF2hy-00006M-7E for qemu-devel@nongnu.org; Wed, 16 Jan 2008 02:29:10 -0500 Received: from smtp-13.smtp.ucla.edu ([169.232.46.240]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1JF2hx-00032D-Pe for qemu-devel@nongnu.org; Wed, 16 Jan 2008 02:29:10 -0500 Received: from mail.ucla.edu (mail.ucla.edu [169.232.48.151]) by smtp-13.smtp.ucla.edu (8.14.2/8.14.2) with ESMTP id m0G7T0hi023610 for ; Tue, 15 Jan 2008 23:29:00 -0800 Received: from mug.lcdf.org (s2264-202.resnet.ucla.edu [164.67.64.202]) (authenticated bits=0) by mail.ucla.edu (8.13.8/8.13.8) with ESMTP id m0G7SxFQ002968 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Tue, 15 Jan 2008 23:29:00 -0800 Message-ID: <478DB1D3.60905@cs.ucla.edu> Date: Tue, 15 Jan 2008 23:27:15 -0800 From: Eddie Kohler MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------020401020606080906080001" Subject: [Qemu-devel] [PATCH] add VNC reverse connections Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------020401020606080906080001 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi all, This patch against current CVS adds VNC reverse connections, where the server connects actively to a waiting client, as in "-vnc rev:5500" or "-vnc rev:read.cs.ucla.edu:5500". This is quite useful if the user expects to run QEMU many times in succession (for example, is debugging a toy OS), and doesn't want to reopen a VNC client each time. Eddie --------------020401020606080906080001 Content-Type: text/x-patch; name="qemu-cvs-vnc-rev.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qemu-cvs-vnc-rev.patch" Index: qemu-doc.texi =================================================================== RCS file: /sources/qemu/qemu/qemu-doc.texi,v retrieving revision 1.179 diff -u -r1.179 qemu-doc.texi --- qemu-doc.texi 14 Jan 2008 22:09:11 -0000 1.179 +++ qemu-doc.texi 16 Jan 2008 07:25:30 -0000 @@ -429,10 +429,16 @@ Connections will be allowed over UNIX domain sockets where @var{path} is the location of a unix socket to listen for connections on. +@item @var{rev}:@var{interface}:@var{port} + +Makes a reverse connection to a VNC viewer listening on +@var{interface} on port @var{port}. Optionally, @var{interface} can be +omitted in which case QEMU will connect to @var{port} on the local machine. + @item none -VNC is initialized by not started. The monitor @code{change} command can be used -to later start the VNC server. +VNC is initialized but not started. The monitor @code{change} command +can be used to later start the VNC server. @end table Index: vnc.c =================================================================== RCS file: /sources/qemu/qemu/vnc.c,v retrieving revision 1.33 diff -u -r1.33 vnc.c --- vnc.c 14 Jan 2008 21:45:55 -0000 1.33 +++ vnc.c 16 Jan 2008 07:25:30 -0000 @@ -1898,6 +1898,22 @@ return 0; } +static void vnc_connect(VncState *vs) +{ + VNC_DEBUG("New client on socket %d\n", vs->csock); + socket_set_nonblock(vs->csock); + qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); + vnc_write(vs, "RFB 003.008\n", 12); + vnc_flush(vs); + vnc_read_when(vs, protocol_version, 12); + memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height); + memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); + vs->has_resize = 0; + vs->has_hextile = 0; + vs->ds->dpy_copy = NULL; + vnc_update_client(vs); +} + static void vnc_listen_read(void *opaque) { VncState *vs = opaque; @@ -1909,18 +1925,7 @@ vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen); if (vs->csock != -1) { - VNC_DEBUG("New client on socket %d\n", vs->csock); - socket_set_nonblock(vs->csock); - qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque); - vnc_write(vs, "RFB 003.008\n", 12); - vnc_flush(vs); - vnc_read_when(vs, protocol_version, 12); - memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height); - memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); - vs->has_resize = 0; - vs->has_hextile = 0; - vs->ds->dpy_copy = NULL; - vnc_update_client(vs); + vnc_connect(vs); } } @@ -2087,6 +2092,7 @@ VncState *vs = ds ? (VncState *)ds->opaque : vnc_state; const char *options; int password = 0; + int reverse = 0; #if CONFIG_VNC_TLS int tls = 0, x509 = 0; #endif @@ -2179,6 +2185,13 @@ } #endif } + if (strstart(display, "rev:", &p)) { + reverse = 1; + display = p; + if (!strchr(display, ':')) { + display = p - 1; + } + } #ifndef _WIN32 if (strstart(display, "unix:", &p)) { addr = (struct sockaddr *)&uaddr; @@ -2196,7 +2209,9 @@ memset(uaddr.sun_path, 0, 108); snprintf(uaddr.sun_path, 108, "%s", p); - unlink(uaddr.sun_path); + if (!reverse) { + unlink(uaddr.sun_path); + } } else #endif { @@ -2210,7 +2225,7 @@ return -1; } - iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900); + iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900)); vs->lsock = socket(PF_INET, SOCK_STREAM, 0); if (vs->lsock == -1) { @@ -2233,6 +2248,22 @@ } } + if (reverse) { + if (connect(vs->lsock, addr, addrlen) == -1) { + fprintf(stderr, "Connection to VNC client failed\n"); + close(vs->lsock); + vs->lsock = -1; + free(vs->display); + vs->display = NULL; + return -1; + } else { + vs->csock = vs->lsock; + vs->lsock = -1; + vnc_connect(vs); + return 0; + } + } + if (bind(vs->lsock, addr, addrlen) == -1) { fprintf(stderr, "bind() failed\n"); close(vs->lsock); --------------020401020606080906080001--