Add VNC reverse connections, by Eddie Kohler.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3951 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									3d575329a5
								
							
						
					
					
						commit
						3aa3eea310
					
				| 
						 | 
				
			
			@ -421,21 +421,21 @@ syntax for the @var{display} is
 | 
			
		|||
 | 
			
		||||
@table @code
 | 
			
		||||
 | 
			
		||||
@item @var{interface}:@var{d}
 | 
			
		||||
@item @var{host}:@var{d}
 | 
			
		||||
 | 
			
		||||
TCP connections will only be allowed from @var{interface} on display @var{d}.
 | 
			
		||||
By convention the TCP port is 5900+@var{d}. Optionally, @var{interface} can
 | 
			
		||||
be omitted in which case the server will bind to all interfaces.
 | 
			
		||||
TCP connections will only be allowed from @var{host} on display @var{d}.
 | 
			
		||||
By convention the TCP port is 5900+@var{d}. Optionally, @var{host} can
 | 
			
		||||
be omitted in which case the server will accept connections from any host.
 | 
			
		||||
 | 
			
		||||
@item @var{unix}:@var{path}
 | 
			
		||||
@item @code{unix}:@var{path}
 | 
			
		||||
 | 
			
		||||
Connections will be allowed over UNIX domain sockets where @var{path} is the
 | 
			
		||||
location of a unix socket to listen for connections on.
 | 
			
		||||
 | 
			
		||||
@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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -444,6 +444,13 @@ separated by commas. Valid options are
 | 
			
		|||
 | 
			
		||||
@table @code
 | 
			
		||||
 | 
			
		||||
@item reverse
 | 
			
		||||
 | 
			
		||||
Connect to a listening VNC client via a ``reverse'' connection. The
 | 
			
		||||
client is specified by the @var{display}. For reverse network
 | 
			
		||||
connections (@var{host}:@var{d},@code{reverse}), the @var{d} argument
 | 
			
		||||
is a TCP port number, not a display number.
 | 
			
		||||
 | 
			
		||||
@item password
 | 
			
		||||
 | 
			
		||||
Require that password based authentication is used for client connections.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										54
									
								
								vnc.c
								
								
								
								
							
							
						
						
									
										54
									
								
								vnc.c
								
								
								
								
							| 
						 | 
				
			
			@ -1898,6 +1898,22 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len)
 | 
			
		|||
    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 @@ static void vnc_listen_read(void *opaque)
 | 
			
		|||
 | 
			
		||||
    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 @@ int vnc_display_open(DisplayState *ds, const char *display)
 | 
			
		|||
    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
 | 
			
		||||
| 
						 | 
				
			
			@ -2103,6 +2109,8 @@ int vnc_display_open(DisplayState *ds, const char *display)
 | 
			
		|||
	options++;
 | 
			
		||||
	if (strncmp(options, "password", 8) == 0) {
 | 
			
		||||
	    password = 1; /* Require password auth */
 | 
			
		||||
	} else if (strncmp(options, "reverse", 7) == 0) {
 | 
			
		||||
	    reverse = 1;
 | 
			
		||||
#if CONFIG_VNC_TLS
 | 
			
		||||
	} else if (strncmp(options, "tls", 3) == 0) {
 | 
			
		||||
	    tls = 1; /* Require TLS */
 | 
			
		||||
| 
						 | 
				
			
			@ -2196,7 +2204,9 @@ int vnc_display_open(DisplayState *ds, const char *display)
 | 
			
		|||
	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 +2220,7 @@ int vnc_display_open(DisplayState *ds, const char *display)
 | 
			
		|||
	    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 +2243,22 @@ int vnc_display_open(DisplayState *ds, const char *display)
 | 
			
		|||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue