aboutsummaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/vnc.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/ui/vnc.c b/ui/vnc.c
index 02c0b89677..5c11c2dbd3 100644
--- a/ui/vnc.c
+++ b/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;
}