[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/3] Add unix domain socket and interface restrictio
From: |
Anthony Liguori |
Subject: |
[Qemu-devel] [PATCH 2/3] Add unix domain socket and interface restriction to VNC |
Date: |
Sat, 16 Dec 2006 12:04:50 -0600 |
User-agent: |
Thunderbird 1.5.0.8 (X11/20061115) |
The following patch allows a user to restrict which interface the VNC
server will listen on. It also adds unix domain socket support to VNC.
N.B. The old syntax of:
qemu -vnc 1
Is now:
qemu -vnc :1
Also, the syntax between the unix char devices and VNC is a bit
different. This is because the current VNC server does not support
reverse connections. I don't really think supporting reverse
connections is all that useful so I'm happy to leave it this way.
Some example usages:
qemu -hda ~/win2k.img -vnc :1 # listen on 0.0.0.0:5901 TCP
qemu -hda ~/win2k.img -vnc 192.168.1.0:1 # listen on 192.168.1.0:5901 TCP
qemu -hda ~/win2k.img -vnc unix:/home/anthony/vga.sock # listen on unix
socket /home/anthony/vga.sock
Regards,
Anthony Liguori
diff -r 9b429747f69c qemu-doc.texi
--- a/qemu-doc.texi Sat Dec 16 11:45:18 2006 -0600
+++ b/qemu-doc.texi Sat Dec 16 11:50:07 2006 -0600
@@ -247,14 +247,21 @@ the console. Therefore, you can still us
the console. Therefore, you can still use QEMU to debug a Linux kernel
with a serial console.
address@hidden -vnc d
address@hidden -vnc display
Normally, QEMU uses SDL to display the VGA output. With this option,
-you can have QEMU listen on VNC display @var{d} and redirect the VGA
+you can have QEMU listen on VNC display @var{display} and redirect the VGA
display over the VNC session. It is very useful to enable the usb
tablet device when using this option (option @option{-usbdevice
tablet}). When using the VNC display, you must use the @option{-k}
-option to set the keyboard layout.
+option to set the keyboard layout if you are not using en-us.
+
address@hidden may be in the form @var{interface:d}, in which case connections
+will only be allowed from @var{interface} on display @var{d}. Optionally,
address@hidden can be omitted. @var{display} can also be in the form
address@hidden:path} where @var{path} is the location of a unix socket to
listen for
+connections on.
+
@item -k language
diff -r 9b429747f69c vl.c
--- a/vl.c Sat Dec 16 11:45:18 2006 -0600
+++ b/vl.c Sat Dec 16 11:49:32 2006 -0600
@@ -152,7 +152,7 @@ int usb_enabled = 0;
int usb_enabled = 0;
static VLANState *first_vlan;
int smp_cpus = 1;
-int vnc_display = -1;
+const char *vnc_display;
#if defined(TARGET_SPARC)
#define MAX_CPUS 16
#elif defined(TARGET_I386)
@@ -6818,11 +6818,7 @@ int main(int argc, char **argv)
}
break;
case QEMU_OPTION_vnc:
- vnc_display = atoi(optarg);
- if (vnc_display < 0) {
- fprintf(stderr, "Invalid VNC display\n");
- exit(1);
- }
+ vnc_display = optarg;
break;
case QEMU_OPTION_no_acpi:
acpi_enabled = 0;
@@ -6946,7 +6942,7 @@ int main(int argc, char **argv)
/* terminal init */
if (nographic) {
dumb_display_init(ds);
- } else if (vnc_display != -1) {
+ } else if (vnc_display != NULL) {
vnc_display_init(ds, vnc_display);
} else {
#if defined(CONFIG_SDL)
diff -r 9b429747f69c vl.h
--- a/vl.h Sat Dec 16 11:45:18 2006 -0600
+++ b/vl.h Sat Dec 16 11:45:25 2006 -0600
@@ -867,7 +867,7 @@ void cocoa_display_init(DisplayState *ds
void cocoa_display_init(DisplayState *ds, int full_screen);
/* vnc.c */
-void vnc_display_init(DisplayState *ds, int display);
+void vnc_display_init(DisplayState *ds, const char *display);
/* ide.c */
#define MAX_DISKS 4
diff -r 9b429747f69c vnc.c
--- a/vnc.c Sat Dec 16 11:45:18 2006 -0600
+++ b/vnc.c Sat Dec 16 11:45:25 2006 -0600
@@ -1101,10 +1101,18 @@ static void vnc_listen_read(void *opaque
}
}
-void vnc_display_init(DisplayState *ds, int display)
-{
- struct sockaddr_in addr;
+extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
+
+void vnc_display_init(DisplayState *ds, const char *arg)
+{
+ struct sockaddr *addr;
+ struct sockaddr_in iaddr;
+#ifndef _WIN32
+ struct sockaddr_un uaddr;
+#endif
int reuse_addr, ret;
+ socklen_t addrlen;
+ const char *p;
VncState *vs;
vs = qemu_mallocz(sizeof(VncState));
@@ -1125,39 +1133,6 @@ void vnc_display_init(DisplayState *ds,
vs->kbd_layout = init_keyboard_layout(keyboard_layout);
if (!vs->kbd_layout)
exit(1);
-
- vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
- if (vs->lsock == -1) {
- fprintf(stderr, "Could not create socket\n");
- exit(1);
- }
-
- addr.sin_family = AF_INET;
- addr.sin_port = htons(5900 + display);
- memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));
-
- 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");
- exit(1);
- }
-
- if (bind(vs->lsock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
- fprintf(stderr, "bind() failed\n");
- exit(1);
- }
-
- if (listen(vs->lsock, 1) == -1) {
- fprintf(stderr, "listen() failed\n");
- exit(1);
- }
-
- ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read,
NULL, vs);
- if (ret == -1) {
- exit(1);
- }
vs->ds->data = NULL;
vs->ds->dpy_update = vnc_dpy_update;
@@ -1167,4 +1142,63 @@ void vnc_display_init(DisplayState *ds,
memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
vnc_dpy_resize(vs->ds, 640, 400);
-}
+
+#ifndef _WIN32
+ if (strstart(arg, "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");
+ exit(1);
+ }
+
+ uaddr.sun_family = AF_UNIX;
+ memset(uaddr.sun_path, 0, 108);
+ snprintf(uaddr.sun_path, 108, "%s", p);
+
+ unlink(uaddr.sun_path);
+ } else
+#endif
+ {
+ addr = (struct sockaddr *)&iaddr;
+ addrlen = sizeof(iaddr);
+
+ vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
+ if (vs->lsock == -1) {
+ fprintf(stderr, "Could not create socket\n");
+ exit(1);
+ }
+
+ if (parse_host_port(&iaddr, arg) < 0) {
+ fprintf(stderr, "Could not parse VNC address\n");
+ exit(1);
+ }
+
+ iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
+
+ 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");
+ exit(1);
+ }
+ }
+
+ if (bind(vs->lsock, addr, addrlen) == -1) {
+ fprintf(stderr, "bind() failed\n");
+ exit(1);
+ }
+
+ if (listen(vs->lsock, 1) == -1) {
+ fprintf(stderr, "listen() failed\n");
+ exit(1);
+ }
+
+ ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read,
NULL, vs);
+ if (ret == -1) {
+ exit(1);
+ }
+}