static int vnc_display_get_addresses(QemuOpts *opts, bool reverse, SocketAddressLegacy ***retsaddr, size_t *retnsaddr, SocketAddressLegacy ***retwsaddr, size_t *retnwsaddr, Error **errp) { SocketAddressLegacy *saddr = NULL; SocketAddressLegacy *wsaddr = NULL; QemuOptsIter addriter; const char *addr; int to = qemu_opt_get_number(opts, "to", 0); bool has_ipv4 = qemu_opt_get(opts, "ipv4"); bool has_ipv6 = qemu_opt_get(opts, "ipv6"); bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false); bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false); size_t i; int displaynum = -1; int ret = -1; *retsaddr = NULL; *retnsaddr = 0; *retwsaddr = NULL; *retnwsaddr = 0; addr = qemu_opt_get(opts, "vnc"); if (addr == NULL || g_str_equal(addr, "none")) { ret = 0; goto cleanup; } if (qemu_opt_get(opts, "websocket") && !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) { error_setg(errp, "SHA1 hash support is required for websockets"); goto cleanup; } qemu_opt_iter_init(&addriter, opts, "vnc"); while ((addr = qemu_opt_iter_next(&addriter)) != NULL) { int rv; rv = vnc_display_get_address(addr, false, reverse, 0, to, has_ipv4, has_ipv6, ipv4, ipv6, &saddr, errp); if (rv < 0) { goto cleanup; } /* Historical compat - first listen address can be used * to set the default websocket port */ if (displaynum == -1) { displaynum = rv; } *retsaddr = g_renew(SocketAddressLegacy *, *retsaddr, *retnsaddr + 1); (*retsaddr)[(*retnsaddr)++] = saddr; } /* If we had multiple primary displays, we don't do defaults * for websocket, and require explicit config instead. */ if (*retnsaddr > 1) { displaynum = -1; } qemu_opt_iter_init(&addriter, opts, "websocket"); while ((addr = qemu_opt_iter_next(&addriter)) != NULL) { if (vnc_display_get_address(addr, true, reverse, displaynum, to, has_ipv4, has_ipv6, ipv4, ipv6, &wsaddr, errp) < 0) { goto cleanup; } /* Historical compat - if only a single listen address was * provided, then this is used to set the default listen * address for websocket too */ if (*retnsaddr == 1 && (*retsaddr)[0]->type == SOCKET_ADDRESS_LEGACY_KIND_INET && wsaddr->type == SOCKET_ADDRESS_LEGACY_KIND_INET && g_str_equal(wsaddr->u.inet.data->host, "") && !g_str_equal((*retsaddr)[0]->u.inet.data->host, "")) { g_free(wsaddr->u.inet.data->host); wsaddr->u.inet.data->host = g_strdup((*retsaddr)[0]->u.inet.data->host); } *retwsaddr = g_renew(SocketAddressLegacy *, *retwsaddr, *retnwsaddr + 1); (*retwsaddr)[(*retnwsaddr)++] = wsaddr; } ret = 0; cleanup: if (ret < 0) { for (i = 0; i < *retnsaddr; i++) { qapi_free_SocketAddressLegacy((*retsaddr)[i]); } g_free(*retsaddr); for (i = 0; i < *retnwsaddr; i++) { qapi_free_SocketAddressLegacy((*retwsaddr)[i]); } g_free(*retwsaddr); *retsaddr = *retwsaddr = NULL; *retnsaddr = *retnwsaddr = 0; } return ret; }