ui: let VNC server listen on all resolved IP addresses
Remove the limitation that the VNC server can only listen on a single resolved IP address. This uses the new DNS resolver API to resolve a SocketAddress struct into an array of SocketAddress structs containing raw IP addresses. The VNC server will then attempt to listen on all resolved IP addresses. The server must successfully listen on at least one of the resolved IP addresses, otherwise an error will be reported. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-id: 20170203120649.15637-7-berrange@redhat.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
8bd22f477f
commit
57a6d6d538
52
ui/vnc.c
52
ui/vnc.c
@ -45,6 +45,7 @@
|
||||
#include "crypto/tlscredsx509.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "io/dns-resolver.h"
|
||||
|
||||
#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
|
||||
#define VNC_REFRESH_INTERVAL_INC 50
|
||||
@ -3698,19 +3699,52 @@ static int vnc_display_listen_addr(VncDisplay *vd,
|
||||
size_t *nlsock,
|
||||
Error **errp)
|
||||
{
|
||||
*nlsock = 1;
|
||||
*lsock = g_new0(QIOChannelSocket *, 1);
|
||||
*lsock_tag = g_new0(guint, 1);
|
||||
QIODNSResolver *resolver = qio_dns_resolver_get_instance();
|
||||
SocketAddress **rawaddrs = NULL;
|
||||
size_t nrawaddrs = 0;
|
||||
Error *listenerr = NULL;
|
||||
size_t i;
|
||||
|
||||
(*lsock)[0] = qio_channel_socket_new();
|
||||
qio_channel_set_name(QIO_CHANNEL((*lsock)[0]), name);
|
||||
if (qio_channel_socket_listen_sync((*lsock)[0], addr, errp) < 0) {
|
||||
if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs,
|
||||
&rawaddrs, errp) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*lsock_tag)[0] = qio_channel_add_watch(
|
||||
QIO_CHANNEL((*lsock)[0]),
|
||||
G_IO_IN, vnc_listen_io, vd, NULL);
|
||||
for (i = 0; i < nrawaddrs; i++) {
|
||||
QIOChannelSocket *sioc = qio_channel_socket_new();
|
||||
|
||||
qio_channel_set_name(QIO_CHANNEL(sioc), name);
|
||||
if (qio_channel_socket_listen_sync(
|
||||
sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) {
|
||||
continue;
|
||||
}
|
||||
(*nlsock)++;
|
||||
*lsock = g_renew(QIOChannelSocket *, *lsock, *nlsock);
|
||||
*lsock_tag = g_renew(guint, *lsock_tag, *nlsock);
|
||||
|
||||
(*lsock)[*nlsock - 1] = sioc;
|
||||
(*lsock_tag)[*nlsock - 1] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < nrawaddrs; i++) {
|
||||
qapi_free_SocketAddress(rawaddrs[i]);
|
||||
}
|
||||
g_free(rawaddrs);
|
||||
|
||||
if (listenerr) {
|
||||
if (*nlsock == 0) {
|
||||
error_propagate(errp, listenerr);
|
||||
return -1;
|
||||
} else {
|
||||
error_free(listenerr);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < *nlsock; i++) {
|
||||
(*lsock_tag)[i] = qio_channel_add_watch(
|
||||
QIO_CHANNEL((*lsock)[i]),
|
||||
G_IO_IN, vnc_listen_io, vd, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user