+static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
+ Error **errp)
+{
+ bool is_listen = qemu_opt_get_bool(opts, "server", false);
+ bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true);
+ bool is_telnet = qemu_opt_get_bool(opts, "telnet", false);
+ bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true);
+ int64_t reconnect = qemu_opt_get_number(opts, "reconnect", 0);
+ const char *path = qemu_opt_get(opts, "path");
+ const char *host = qemu_opt_get(opts, "host");
+ const char *port = qemu_opt_get(opts, "port");
+ SocketAddress *addr;
+
+ if (!path) {
+ if (!host) {
+ error_setg(errp, "chardev: socket: no host given");
+ return;
+ }
+ if (!port) {
+ error_setg(errp, "chardev: socket: no port given");
+ return;
+ }
+ }
+
+ backend->socket = g_new0(ChardevSocket, 1);
+
+ backend->socket->has_nodelay = true;
+ backend->socket->nodelay = do_nodelay;
+ backend->socket->has_server = true;
+ backend->socket->server = is_listen;
+ backend->socket->has_telnet = true;
+ backend->socket->telnet = is_telnet;
+ backend->socket->has_wait = true;
+ backend->socket->wait = is_waitconnect;
+ backend->socket->has_reconnect = true;
+ backend->socket->reconnect = reconnect;
+
+ addr = g_new0(SocketAddress, 1);
+ if (path) {
+ addr->kind = SOCKET_ADDRESS_KIND_UNIX;
+ addr->q_unix = g_new0(UnixSocketAddress, 1);
+ addr->q_unix->path = g_strdup(path);
+ } else {
+ addr->kind = SOCKET_ADDRESS_KIND_INET;
+ addr->inet = g_new0(InetSocketAddress, 1);
+ addr->inet->host = g_strdup(host);
+ addr->inet->port = g_strdup(port);
+ addr->inet->has_to = qemu_opt_get(opts, "to");
+ addr->inet->to = qemu_opt_get_number(opts, "to", 0);
+ addr->inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
+ addr->inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
+ addr->inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
+ addr->inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
+ }
+ backend->socket->addr = addr;
+}
+
+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;
+ SocketAddress *addr;
+
+ 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;
+ }
+
+ backend->udp = g_new0(ChardevUdp, 1);
+
+ addr = g_new0(SocketAddress, 1);
+ addr->kind = SOCKET_ADDRESS_KIND_INET;
+ addr->inet = g_new0(InetSocketAddress, 1);
+ addr->inet->host = g_strdup(host);
+ addr->inet->port = g_strdup(port);
+ addr->inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
+ addr->inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
+ addr->inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
+ addr->inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
+ backend->udp->remote = addr;
+
+ if (has_local) {
+ backend->udp->has_local = true;
+ addr = g_new0(SocketAddress, 1);
+ addr->kind = SOCKET_ADDRESS_KIND_INET;
+ addr->inet = g_new0(InetSocketAddress, 1);
+ addr->inet->host = g_strdup(localaddr);
+ addr->inet->port = g_strdup(localport);
+ backend->udp->local = addr;
+ }
+}
+