From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KvtR9-0004Ek-4Z for qemu-devel@nongnu.org; Fri, 31 Oct 2008 08:49:11 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KvtR7-0004CR-8A for qemu-devel@nongnu.org; Fri, 31 Oct 2008 08:49:10 -0400 Received: from [199.232.76.173] (port=56576 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KvtR7-0004CG-3w for qemu-devel@nongnu.org; Fri, 31 Oct 2008 08:49:09 -0400 Received: from mx2.redhat.com ([66.187.237.31]:47790) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KvtR5-0001lF-SW for qemu-devel@nongnu.org; Fri, 31 Oct 2008 08:49:08 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id m9VCn3Yv007716 for ; Fri, 31 Oct 2008 08:49:03 -0400 From: Gerd Hoffmann Date: Fri, 31 Oct 2008 13:47:33 +0100 Message-Id: <1225457254-1000-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1225457254-1000-1-git-send-email-kraxel@redhat.com> References: <1225457254-1000-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 3/4] sockets: switch vnc to new code, support vnc port auto-allocation. 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 Cc: Gerd Hoffmann This patch switches the vnc code ofer to the new socket helper functions. It adds support IPv6 support and for automatically allocating an unused vnc display port. The latter is handled ising a to= option, specifying the upper limit for the display number to try. Scanning is started at the display number given in the display specification, i.e. this command line: -vnc localhost:7,to=11 will try displays 7 to 11 (inclusive). The display actually allocated can be queried using the "info vnc" monitor command. Signed-off-by: Gerd Hoffmann --- vl.c | 1 + vnc.c | 114 +++++++++++++++------------------------------------------------- 2 files changed, 28 insertions(+), 87 deletions(-) diff --git a/vl.c b/vl.c index e9fe478..e4648f9 100644 --- a/vl.c +++ b/vl.c @@ -8284,6 +8284,7 @@ static void help(int exitcode) "-ipv4 Use IPv4 only.\n" "-ipv6 Use UPv6 only.\n" " By default qemu uses what is available on your machine.\n" + " Applies to -vnc.\n" "\n" "Linux boot specific:\n" "-kernel bzImage use 'bzImage' as kernel image\n" diff --git a/vnc.c b/vnc.c index 9df4dbe..9aeaaa0 100644 --- a/vnc.c +++ b/vnc.c @@ -28,6 +28,7 @@ #include "sysemu.h" #include "qemu_socket.h" #include "qemu-timer.h" +#include "qemu-sockets.h" #define VNC_REFRESH_INTERVAL (1000 / 30) @@ -2139,8 +2140,6 @@ static void vnc_listen_read(void *opaque) } } -extern int parse_host_port(struct sockaddr_in *saddr, const char *str); - void vnc_display_init(DisplayState *ds) { VncState *vs; @@ -2291,18 +2290,11 @@ int vnc_display_password(DisplayState *ds, const char *password) int vnc_display_open(DisplayState *ds, const char *display) { - struct sockaddr *addr; - struct sockaddr_in iaddr; -#ifndef _WIN32 - struct sockaddr_un uaddr; - const char *p; -#endif - int reuse_addr, ret; - socklen_t addrlen; VncState *vs = ds ? (VncState *)ds->opaque : vnc_state; const char *options; int password = 0; int reverse = 0; + int to_port = 0; #ifdef CONFIG_VNC_TLS int tls = 0, x509 = 0; #endif @@ -2321,6 +2313,8 @@ int vnc_display_open(DisplayState *ds, const char *display) password = 1; /* Require password auth */ } else if (strncmp(options, "reverse", 7) == 0) { reverse = 1; + } else if (strncmp(options, "to=", 3) == 0) { + to_port = atoi(options+3) + 5900; #ifdef CONFIG_VNC_TLS } else if (strncmp(options, "tls", 3) == 0) { tls = 1; /* Require TLS */ @@ -2398,67 +2392,14 @@ int vnc_display_open(DisplayState *ds, const char *display) } #endif } -#ifndef _WIN32 - if (strstart(display, "unix:", &p)) { - addr = (struct sockaddr *)&uaddr; - addrlen = sizeof(uaddr); - - vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0); - if (vs->lsock == -1) { - fprintf(stderr, "Could not create socket\n"); - free(vs->display); - vs->display = NULL; - return -1; - } - - uaddr.sun_family = AF_UNIX; - memset(uaddr.sun_path, 0, 108); - snprintf(uaddr.sun_path, 108, "%s", p); - - if (!reverse) { - unlink(uaddr.sun_path); - } - } else -#endif - { - addr = (struct sockaddr *)&iaddr; - addrlen = sizeof(iaddr); - - if (parse_host_port(&iaddr, display) < 0) { - fprintf(stderr, "Could not parse VNC address\n"); - free(vs->display); - vs->display = NULL; - return -1; - } - - iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900)); - - vs->lsock = socket(PF_INET, SOCK_STREAM, 0); - if (vs->lsock == -1) { - fprintf(stderr, "Could not create socket\n"); - free(vs->display); - vs->display = NULL; - return -1; - } - - reuse_addr = 1; - ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR, - (const char *)&reuse_addr, sizeof(reuse_addr)); - if (ret == -1) { - fprintf(stderr, "setsockopt() failed\n"); - close(vs->lsock); - vs->lsock = -1; - free(vs->display); - vs->display = NULL; - return -1; - } - } if (reverse) { - if (connect(vs->lsock, addr, addrlen) == -1) { - fprintf(stderr, "Connection to VNC client failed\n"); - close(vs->lsock); - vs->lsock = -1; + /* connect to viewer */ + if (strncmp(display, "unix:", 5) == 0) + vs->lsock = unix_connect(display+5); + else + vs->lsock = inet_connect(display, SOCK_STREAM); + if (-1 == vs->lsock) { free(vs->display); vs->display = NULL; return -1; @@ -2466,26 +2407,25 @@ int vnc_display_open(DisplayState *ds, const char *display) 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); - vs->lsock = -1; - free(vs->display); - vs->display = NULL; - return -1; - } + return 0; - if (listen(vs->lsock, 1) == -1) { - fprintf(stderr, "listen() failed\n"); - close(vs->lsock); - vs->lsock = -1; - free(vs->display); - vs->display = NULL; - return -1; + } else { + /* listen for connects */ + char *dpy; + dpy = qemu_malloc(256); + if (strncmp(display, "unix:", 5) == 0) { + strcpy(dpy, "unix:"); + vs->lsock = unix_listen(display, dpy+5, 256-5); + } else { + vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900); + } + if (-1 == vs->lsock) { + free(dpy); + } else { + free(vs->display); + vs->display = dpy; + } } return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs); -- 1.5.6.5