static void qio_channel_socket_dgram_worker(QIOTask *task, gpointer opaque) { QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task)); struct QIOChannelSocketDGramWorkerData *data = opaque; Error *err = NULL; /* socket_dgram() blocks in DNS lookups, so we must use a thread */ qio_channel_socket_dgram_sync(ioc, data->localAddr, data->remoteAddr, &err); qio_task_set_error(task, err); }
static int qio_channel_socket_dgram_worker(QIOTask *task, Error **errp, gpointer opaque) { QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task)); struct QIOChannelSocketDGramWorkerData *data = opaque; int ret; /* socket_dgram() blocks in DNS lookups, so we must use a thread */ ret = qio_channel_socket_dgram_sync(ioc, data->localAddr, data->remoteAddr, errp); object_unref(OBJECT(ioc)); return ret; }
static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend, Error **errp) { const char *host = qemu_opt_get(opts, "host"); const char *port = qemu_opt_get(opts, "port"); const char *localaddr = qemu_opt_get(opts, "localaddr"); const char *localport = qemu_opt_get(opts, "localport"); bool has_local = false; SocketAddressLegacy *addr; ChardevUdp *udp; backend->type = CHARDEV_BACKEND_KIND_UDP; if (host == NULL || strlen(host) == 0) { host = "localhost"; } if (port == NULL || strlen(port) == 0) { error_setg(errp, "chardev: udp: remote port not specified"); return; } if (localport == NULL || strlen(localport) == 0) { localport = "0"; } else { has_local = true; } if (localaddr == NULL || strlen(localaddr) == 0) { localaddr = ""; } else { has_local = true; } udp = backend->u.udp.data = g_new0(ChardevUdp, 1); qemu_chr_parse_common(opts, qapi_ChardevUdp_base(udp)); addr = g_new0(SocketAddressLegacy, 1); addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET; addr->u.inet.data = g_new(InetSocketAddress, 1); *addr->u.inet.data = (InetSocketAddress) { .host = g_strdup(host), .port = g_strdup(port), .has_ipv4 = qemu_opt_get(opts, "ipv4"), .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0), .has_ipv6 = qemu_opt_get(opts, "ipv6"), .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0), }; udp->remote = addr; if (has_local) { udp->has_local = true; addr = g_new0(SocketAddressLegacy, 1); addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET; addr->u.inet.data = g_new(InetSocketAddress, 1); *addr->u.inet.data = (InetSocketAddress) { .host = g_strdup(localaddr), .port = g_strdup(localport), }; udp->local = addr; } } static void qmp_chardev_open_udp(Chardev *chr, ChardevBackend *backend, bool *be_opened, Error **errp) { ChardevUdp *udp = backend->u.udp.data; SocketAddress *local_addr = socket_address_flatten(udp->local); SocketAddress *remote_addr = socket_address_flatten(udp->remote); QIOChannelSocket *sioc = qio_channel_socket_new(); char *name; UdpChardev *s = UDP_CHARDEV(chr); int ret; ret = qio_channel_socket_dgram_sync(sioc, local_addr, remote_addr, errp); qapi_free_SocketAddress(local_addr); qapi_free_SocketAddress(remote_addr); if (ret < 0) { object_unref(OBJECT(sioc)); return; } name = g_strdup_printf("chardev-udp-%s", chr->label); qio_channel_set_name(QIO_CHANNEL(sioc), name); g_free(name); s->ioc = QIO_CHANNEL(sioc); /* be isn't opened until we get a connection */ *be_opened = false; }