Commit 9712ecaf941b931c301f5e133caa985b522f080d

Authored by aliguori
1 parent d247d25f

sockets: switch vnc to new code, support vnc port auto-allocation (Gerd Hoffman)

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).

There are also new "ipv4" and "ipv6" options to make qemu try only
the specified internet protocol version.

The display actually allocated can be queried using the "info vnc"
monitor command.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5696 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 26 additions and 87 deletions
@@ -2139,8 +2139,6 @@ static void vnc_listen_read(void *opaque) @@ -2139,8 +2139,6 @@ static void vnc_listen_read(void *opaque)
2139 } 2139 }
2140 } 2140 }
2141 2141
2142 -extern int parse_host_port(struct sockaddr_in *saddr, const char *str);  
2143 -  
2144 void vnc_display_init(DisplayState *ds) 2142 void vnc_display_init(DisplayState *ds)
2145 { 2143 {
2146 VncState *vs; 2144 VncState *vs;
@@ -2291,18 +2289,11 @@ int vnc_display_password(DisplayState *ds, const char *password) @@ -2291,18 +2289,11 @@ int vnc_display_password(DisplayState *ds, const char *password)
2291 2289
2292 int vnc_display_open(DisplayState *ds, const char *display) 2290 int vnc_display_open(DisplayState *ds, const char *display)
2293 { 2291 {
2294 - struct sockaddr *addr;  
2295 - struct sockaddr_in iaddr;  
2296 -#ifndef _WIN32  
2297 - struct sockaddr_un uaddr;  
2298 - const char *p;  
2299 -#endif  
2300 - int reuse_addr, ret;  
2301 - socklen_t addrlen;  
2302 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state; 2292 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2303 const char *options; 2293 const char *options;
2304 int password = 0; 2294 int password = 0;
2305 int reverse = 0; 2295 int reverse = 0;
  2296 + int to_port = 0;
2306 #ifdef CONFIG_VNC_TLS 2297 #ifdef CONFIG_VNC_TLS
2307 int tls = 0, x509 = 0; 2298 int tls = 0, x509 = 0;
2308 #endif 2299 #endif
@@ -2321,6 +2312,8 @@ int vnc_display_open(DisplayState *ds, const char *display) @@ -2321,6 +2312,8 @@ int vnc_display_open(DisplayState *ds, const char *display)
2321 password = 1; /* Require password auth */ 2312 password = 1; /* Require password auth */
2322 } else if (strncmp(options, "reverse", 7) == 0) { 2313 } else if (strncmp(options, "reverse", 7) == 0) {
2323 reverse = 1; 2314 reverse = 1;
  2315 + } else if (strncmp(options, "to=", 3) == 0) {
  2316 + to_port = atoi(options+3) + 5900;
2324 #ifdef CONFIG_VNC_TLS 2317 #ifdef CONFIG_VNC_TLS
2325 } else if (strncmp(options, "tls", 3) == 0) { 2318 } else if (strncmp(options, "tls", 3) == 0) {
2326 tls = 1; /* Require TLS */ 2319 tls = 1; /* Require TLS */
@@ -2398,67 +2391,14 @@ int vnc_display_open(DisplayState *ds, const char *display) @@ -2398,67 +2391,14 @@ int vnc_display_open(DisplayState *ds, const char *display)
2398 } 2391 }
2399 #endif 2392 #endif
2400 } 2393 }
2401 -#ifndef _WIN32  
2402 - if (strstart(display, "unix:", &p)) {  
2403 - addr = (struct sockaddr *)&uaddr;  
2404 - addrlen = sizeof(uaddr);  
2405 -  
2406 - vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);  
2407 - if (vs->lsock == -1) {  
2408 - fprintf(stderr, "Could not create socket\n");  
2409 - free(vs->display);  
2410 - vs->display = NULL;  
2411 - return -1;  
2412 - }  
2413 -  
2414 - uaddr.sun_family = AF_UNIX;  
2415 - memset(uaddr.sun_path, 0, 108);  
2416 - snprintf(uaddr.sun_path, 108, "%s", p);  
2417 -  
2418 - if (!reverse) {  
2419 - unlink(uaddr.sun_path);  
2420 - }  
2421 - } else  
2422 -#endif  
2423 - {  
2424 - addr = (struct sockaddr *)&iaddr;  
2425 - addrlen = sizeof(iaddr);  
2426 -  
2427 - if (parse_host_port(&iaddr, display) < 0) {  
2428 - fprintf(stderr, "Could not parse VNC address\n");  
2429 - free(vs->display);  
2430 - vs->display = NULL;  
2431 - return -1;  
2432 - }  
2433 -  
2434 - iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900));  
2435 -  
2436 - vs->lsock = socket(PF_INET, SOCK_STREAM, 0);  
2437 - if (vs->lsock == -1) {  
2438 - fprintf(stderr, "Could not create socket\n");  
2439 - free(vs->display);  
2440 - vs->display = NULL;  
2441 - return -1;  
2442 - }  
2443 -  
2444 - reuse_addr = 1;  
2445 - ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,  
2446 - (const char *)&reuse_addr, sizeof(reuse_addr));  
2447 - if (ret == -1) {  
2448 - fprintf(stderr, "setsockopt() failed\n");  
2449 - close(vs->lsock);  
2450 - vs->lsock = -1;  
2451 - free(vs->display);  
2452 - vs->display = NULL;  
2453 - return -1;  
2454 - }  
2455 - }  
2456 2394
2457 if (reverse) { 2395 if (reverse) {
2458 - if (connect(vs->lsock, addr, addrlen) == -1) {  
2459 - fprintf(stderr, "Connection to VNC client failed\n");  
2460 - close(vs->lsock);  
2461 - vs->lsock = -1; 2396 + /* connect to viewer */
  2397 + if (strncmp(display, "unix:", 5) == 0)
  2398 + vs->lsock = unix_connect(display+5);
  2399 + else
  2400 + vs->lsock = inet_connect(display, SOCK_STREAM);
  2401 + if (-1 == vs->lsock) {
2462 free(vs->display); 2402 free(vs->display);
2463 vs->display = NULL; 2403 vs->display = NULL;
2464 return -1; 2404 return -1;
@@ -2466,26 +2406,25 @@ int vnc_display_open(DisplayState *ds, const char *display) @@ -2466,26 +2406,25 @@ int vnc_display_open(DisplayState *ds, const char *display)
2466 vs->csock = vs->lsock; 2406 vs->csock = vs->lsock;
2467 vs->lsock = -1; 2407 vs->lsock = -1;
2468 vnc_connect(vs); 2408 vnc_connect(vs);
2469 - return 0;  
2470 } 2409 }
2471 - }  
2472 -  
2473 - if (bind(vs->lsock, addr, addrlen) == -1) {  
2474 - fprintf(stderr, "bind() failed\n");  
2475 - close(vs->lsock);  
2476 - vs->lsock = -1;  
2477 - free(vs->display);  
2478 - vs->display = NULL;  
2479 - return -1;  
2480 - } 2410 + return 0;
2481 2411
2482 - if (listen(vs->lsock, 1) == -1) {  
2483 - fprintf(stderr, "listen() failed\n");  
2484 - close(vs->lsock);  
2485 - vs->lsock = -1;  
2486 - free(vs->display);  
2487 - vs->display = NULL;  
2488 - return -1; 2412 + } else {
  2413 + /* listen for connects */
  2414 + char *dpy;
  2415 + dpy = qemu_malloc(256);
  2416 + if (strncmp(display, "unix:", 5) == 0) {
  2417 + strcpy(dpy, "unix:");
  2418 + vs->lsock = unix_listen(display, dpy+5, 256-5);
  2419 + } else {
  2420 + vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900);
  2421 + }
  2422 + if (-1 == vs->lsock) {
  2423 + free(dpy);
  2424 + } else {
  2425 + free(vs->display);
  2426 + vs->display = dpy;
  2427 + }
2489 } 2428 }
2490 2429
2491 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs); 2430 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);