ui: convert VNC startup code to use SocketAddress
The VNC code is currently using QemuOpts to configure the sockets connections / listeners it needs. Convert it to use SocketAddress to bring it in line with modern QAPI based code elsewhere in QEMU. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
		
							parent
							
								
									0983f5e6af
								
							
						
					
					
						commit
						e0d03b8ceb
					
				
							
								
								
									
										162
									
								
								ui/vnc.c
								
								
								
								
							
							
						
						
									
										162
									
								
								ui/vnc.c
								
								
								
								
							| 
						 | 
				
			
			@ -3506,18 +3506,14 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		|||
{
 | 
			
		||||
    VncDisplay *vs = vnc_display_find(id);
 | 
			
		||||
    QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
 | 
			
		||||
    QemuOpts *sopts, *wsopts;
 | 
			
		||||
    SocketAddress *saddr = NULL, *wsaddr = NULL;
 | 
			
		||||
    const char *share, *device_id;
 | 
			
		||||
    QemuConsole *con;
 | 
			
		||||
    bool password = false;
 | 
			
		||||
    bool reverse = false;
 | 
			
		||||
    const char *vnc;
 | 
			
		||||
    const char *has_to;
 | 
			
		||||
    char *h;
 | 
			
		||||
    bool has_ipv4 = false;
 | 
			
		||||
    bool has_ipv6 = false;
 | 
			
		||||
    const char *credid;
 | 
			
		||||
    const char *websocket;
 | 
			
		||||
    bool sasl = false;
 | 
			
		||||
#ifdef CONFIG_VNC_SASL
 | 
			
		||||
    int saslErr;
 | 
			
		||||
| 
						 | 
				
			
			@ -3539,44 +3535,83 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sopts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
 | 
			
		||||
    wsopts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
 | 
			
		||||
 | 
			
		||||
    h = strrchr(vnc, ':');
 | 
			
		||||
    if (h) {
 | 
			
		||||
        char *host;
 | 
			
		||||
        size_t hlen = h - vnc;
 | 
			
		||||
 | 
			
		||||
        if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
 | 
			
		||||
            host = g_strndup(vnc + 1, hlen - 2);
 | 
			
		||||
        } else {
 | 
			
		||||
            host = g_strndup(vnc, hlen);
 | 
			
		||||
        const char *websocket = qemu_opt_get(opts, "websocket");
 | 
			
		||||
        int to = qemu_opt_get_number(opts, "to", 0);
 | 
			
		||||
        bool has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
 | 
			
		||||
        bool has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
 | 
			
		||||
 | 
			
		||||
        saddr = g_new0(SocketAddress, 1);
 | 
			
		||||
        if (websocket) {
 | 
			
		||||
            if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
 | 
			
		||||
                error_setg(errp,
 | 
			
		||||
                           "SHA1 hash support is required for websockets");
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            wsaddr = g_new0(SocketAddress, 1);
 | 
			
		||||
            vs->ws_enabled = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (strncmp(vnc, "unix:", 5) == 0) {
 | 
			
		||||
            saddr->kind = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
            saddr->q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
            saddr->q_unix->path = g_strdup(vnc + 5);
 | 
			
		||||
 | 
			
		||||
            if (vs->ws_enabled) {
 | 
			
		||||
                error_setg(errp, "UNIX sockets not supported with websock");
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            unsigned long long baseport;
 | 
			
		||||
            saddr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
            saddr->inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
            if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
 | 
			
		||||
                saddr->inet->host = g_strndup(vnc + 1, hlen - 2);
 | 
			
		||||
            } else {
 | 
			
		||||
                saddr->inet->host = g_strndup(vnc, hlen);
 | 
			
		||||
            }
 | 
			
		||||
            if (parse_uint_full(h + 1, &baseport, 10) < 0) {
 | 
			
		||||
                error_setg(errp, "can't convert to a number: %s", h + 1);
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
            if (baseport > 65535 ||
 | 
			
		||||
                baseport + 5900 > 65535) {
 | 
			
		||||
                error_setg(errp, "port %s out of range", h + 1);
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
            saddr->inet->port = g_strdup_printf(
 | 
			
		||||
                "%d", (int)baseport + 5900);
 | 
			
		||||
 | 
			
		||||
            if (to) {
 | 
			
		||||
                saddr->inet->has_to = true;
 | 
			
		||||
                saddr->inet->to = to;
 | 
			
		||||
            }
 | 
			
		||||
            saddr->inet->ipv4 = saddr->inet->has_ipv4 = has_ipv4;
 | 
			
		||||
            saddr->inet->ipv6 = saddr->inet->has_ipv6 = has_ipv6;
 | 
			
		||||
 | 
			
		||||
            if (vs->ws_enabled) {
 | 
			
		||||
                wsaddr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
                wsaddr->inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
                wsaddr->inet->host = g_strdup(saddr->inet->host);
 | 
			
		||||
                wsaddr->inet->port = g_strdup(websocket);
 | 
			
		||||
 | 
			
		||||
                if (to) {
 | 
			
		||||
                    wsaddr->inet->has_to = true;
 | 
			
		||||
                    wsaddr->inet->to = to;
 | 
			
		||||
                }
 | 
			
		||||
                wsaddr->inet->ipv4 = wsaddr->inet->has_ipv4 = has_ipv4;
 | 
			
		||||
                wsaddr->inet->ipv6 = wsaddr->inet->has_ipv6 = has_ipv6;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        qemu_opt_set(sopts, "host", host, &error_abort);
 | 
			
		||||
        qemu_opt_set(wsopts, "host", host, &error_abort);
 | 
			
		||||
        qemu_opt_set(sopts, "port", h+1, &error_abort);
 | 
			
		||||
        g_free(host);
 | 
			
		||||
    } else {
 | 
			
		||||
        error_setg(errp, "no vnc port specified");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    has_to = qemu_opt_get(opts, "to");
 | 
			
		||||
    has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
 | 
			
		||||
    has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
 | 
			
		||||
    if (has_to) {
 | 
			
		||||
        qemu_opt_set(sopts, "to", has_to, &error_abort);
 | 
			
		||||
        qemu_opt_set(wsopts, "to", has_to, &error_abort);
 | 
			
		||||
    }
 | 
			
		||||
    if (has_ipv4) {
 | 
			
		||||
        qemu_opt_set(sopts, "ipv4", "on", &error_abort);
 | 
			
		||||
        qemu_opt_set(wsopts, "ipv4", "on", &error_abort);
 | 
			
		||||
    }
 | 
			
		||||
    if (has_ipv6) {
 | 
			
		||||
        qemu_opt_set(sopts, "ipv6", "on", &error_abort);
 | 
			
		||||
        qemu_opt_set(wsopts, "ipv6", "on", &error_abort);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    password = qemu_opt_get_bool(opts, "password", false);
 | 
			
		||||
    if (password) {
 | 
			
		||||
        if (fips_get_state()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3682,16 +3717,6 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		|||
    }
 | 
			
		||||
    vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
 | 
			
		||||
 | 
			
		||||
    websocket = qemu_opt_get(opts, "websocket");
 | 
			
		||||
    if (websocket) {
 | 
			
		||||
        vs->ws_enabled = true;
 | 
			
		||||
        qemu_opt_set(wsopts, "port", websocket, &error_abort);
 | 
			
		||||
        if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
 | 
			
		||||
            error_setg(errp, "SHA1 hash support is required for websockets");
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_VNC_JPEG
 | 
			
		||||
    vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -3725,7 +3750,7 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		|||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (vnc_display_setup_auth(vs, password, sasl, websocket, errp) < 0) {
 | 
			
		||||
    if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3770,37 +3795,31 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		|||
        int csock;
 | 
			
		||||
        vs->lsock = -1;
 | 
			
		||||
        vs->lwebsock = -1;
 | 
			
		||||
        if (strncmp(vnc, "unix:", 5) == 0) {
 | 
			
		||||
            csock = unix_connect(vnc+5, errp);
 | 
			
		||||
        } else {
 | 
			
		||||
            csock = inet_connect(vnc, errp);
 | 
			
		||||
        if (vs->ws_enabled) {
 | 
			
		||||
            error_setg(errp, "Cannot use websockets in reverse mode");
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
        csock = socket_connect(saddr, errp, NULL, NULL);
 | 
			
		||||
        if (csock < 0) {
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
        vs->is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        vnc_connect(vs, csock, false, false);
 | 
			
		||||
    } else {
 | 
			
		||||
        /* listen for connects */
 | 
			
		||||
        if (strncmp(vnc, "unix:", 5) == 0) {
 | 
			
		||||
            vs->lsock = unix_listen(vnc+5, NULL, 0, errp);
 | 
			
		||||
            if (vs->lsock < 0) {
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
            vs->is_unix = true;
 | 
			
		||||
        } else {
 | 
			
		||||
            vs->lsock = inet_listen_opts(sopts, 5900, errp);
 | 
			
		||||
            if (vs->lsock < 0) {
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
            if (vs->ws_enabled) {
 | 
			
		||||
                vs->lwebsock = inet_listen_opts(wsopts, 0, errp);
 | 
			
		||||
                if (vs->lwebsock < 0) {
 | 
			
		||||
                    if (vs->lsock != -1) {
 | 
			
		||||
                        close(vs->lsock);
 | 
			
		||||
                        vs->lsock = -1;
 | 
			
		||||
                    }
 | 
			
		||||
                    goto fail;
 | 
			
		||||
        vs->lsock = socket_listen(saddr, errp);
 | 
			
		||||
        if (vs->lsock < 0) {
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
        vs->is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        if (vs->ws_enabled) {
 | 
			
		||||
            vs->lwebsock = socket_listen(wsaddr, errp);
 | 
			
		||||
            if (vs->lwebsock < 0) {
 | 
			
		||||
                if (vs->lsock != -1) {
 | 
			
		||||
                    close(vs->lsock);
 | 
			
		||||
                    vs->lsock = -1;
 | 
			
		||||
                }
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        vs->enabled = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -3810,13 +3829,14 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		|||
                                NULL, vs);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    qemu_opts_del(sopts);
 | 
			
		||||
    qemu_opts_del(wsopts);
 | 
			
		||||
 | 
			
		||||
    qapi_free_SocketAddress(saddr);
 | 
			
		||||
    qapi_free_SocketAddress(wsaddr);
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    qemu_opts_del(sopts);
 | 
			
		||||
    qemu_opts_del(wsopts);
 | 
			
		||||
    qapi_free_SocketAddress(saddr);
 | 
			
		||||
    qapi_free_SocketAddress(wsaddr);
 | 
			
		||||
    vs->enabled = false;
 | 
			
		||||
    vs->ws_enabled = false;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue