xref: /openbmc/qemu/util/qemu-sockets.c (revision 228aa992)
1 /*
2  *  inet and unix socket functions for qemu
3  *
4  *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; under version 2 of the License.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  * Contributions after 2012-01-13 are licensed under the terms of the
16  * GNU GPL, version 2 or (at your option) any later version.
17  */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <unistd.h>
24 
25 #include "monitor/monitor.h"
26 #include "qemu/sockets.h"
27 #include "qemu/main-loop.h"
28 
29 #ifndef AI_ADDRCONFIG
30 # define AI_ADDRCONFIG 0
31 #endif
32 
33 /* used temporarily until all users are converted to QemuOpts */
34 QemuOptsList socket_optslist = {
35     .name = "socket",
36     .head = QTAILQ_HEAD_INITIALIZER(socket_optslist.head),
37     .desc = {
38         {
39             .name = "path",
40             .type = QEMU_OPT_STRING,
41         },{
42             .name = "host",
43             .type = QEMU_OPT_STRING,
44         },{
45             .name = "port",
46             .type = QEMU_OPT_STRING,
47         },{
48             .name = "to",
49             .type = QEMU_OPT_NUMBER,
50         },{
51             .name = "ipv4",
52             .type = QEMU_OPT_BOOL,
53         },{
54             .name = "ipv6",
55             .type = QEMU_OPT_BOOL,
56         },
57         { /* end if list */ }
58     },
59 };
60 
61 static int inet_getport(struct addrinfo *e)
62 {
63     struct sockaddr_in *i4;
64     struct sockaddr_in6 *i6;
65 
66     switch (e->ai_family) {
67     case PF_INET6:
68         i6 = (void*)e->ai_addr;
69         return ntohs(i6->sin6_port);
70     case PF_INET:
71         i4 = (void*)e->ai_addr;
72         return ntohs(i4->sin_port);
73     default:
74         return 0;
75     }
76 }
77 
78 static void inet_setport(struct addrinfo *e, int port)
79 {
80     struct sockaddr_in *i4;
81     struct sockaddr_in6 *i6;
82 
83     switch (e->ai_family) {
84     case PF_INET6:
85         i6 = (void*)e->ai_addr;
86         i6->sin6_port = htons(port);
87         break;
88     case PF_INET:
89         i4 = (void*)e->ai_addr;
90         i4->sin_port = htons(port);
91         break;
92     }
93 }
94 
95 NetworkAddressFamily inet_netfamily(int family)
96 {
97     switch (family) {
98     case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6;
99     case PF_INET:  return NETWORK_ADDRESS_FAMILY_IPV4;
100     case PF_UNIX:  return NETWORK_ADDRESS_FAMILY_UNIX;
101     }
102     return NETWORK_ADDRESS_FAMILY_UNKNOWN;
103 }
104 
105 int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
106 {
107     struct addrinfo ai,*res,*e;
108     const char *addr;
109     char port[33];
110     char uaddr[INET6_ADDRSTRLEN+1];
111     char uport[33];
112     int slisten, rc, to, port_min, port_max, p;
113 
114     memset(&ai,0, sizeof(ai));
115     ai.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
116     ai.ai_family = PF_UNSPEC;
117     ai.ai_socktype = SOCK_STREAM;
118 
119     if ((qemu_opt_get(opts, "host") == NULL) ||
120         (qemu_opt_get(opts, "port") == NULL)) {
121         error_setg(errp, "host and/or port not specified");
122         return -1;
123     }
124     pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port"));
125     addr = qemu_opt_get(opts, "host");
126 
127     to = qemu_opt_get_number(opts, "to", 0);
128     if (qemu_opt_get_bool(opts, "ipv4", 0))
129         ai.ai_family = PF_INET;
130     if (qemu_opt_get_bool(opts, "ipv6", 0))
131         ai.ai_family = PF_INET6;
132 
133     /* lookup */
134     if (port_offset) {
135         unsigned long long baseport;
136         if (parse_uint_full(port, &baseport, 10) < 0) {
137             error_setg(errp, "can't convert to a number: %s", port);
138             return -1;
139         }
140         if (baseport > 65535 ||
141             baseport + port_offset > 65535) {
142             error_setg(errp, "port %s out of range", port);
143             return -1;
144         }
145         snprintf(port, sizeof(port), "%d", (int)baseport + port_offset);
146     }
147     rc = getaddrinfo(strlen(addr) ? addr : NULL, port, &ai, &res);
148     if (rc != 0) {
149         error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
150                    gai_strerror(rc));
151         return -1;
152     }
153 
154     /* create socket + bind */
155     for (e = res; e != NULL; e = e->ai_next) {
156         getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen,
157 		        uaddr,INET6_ADDRSTRLEN,uport,32,
158 		        NI_NUMERICHOST | NI_NUMERICSERV);
159         slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol);
160         if (slisten < 0) {
161             if (!e->ai_next) {
162                 error_setg_errno(errp, errno, "Failed to create socket");
163             }
164             continue;
165         }
166 
167         socket_set_fast_reuse(slisten);
168 #ifdef IPV6_V6ONLY
169         if (e->ai_family == PF_INET6) {
170             /* listen on both ipv4 and ipv6 */
171             const int off = 0;
172             qemu_setsockopt(slisten, IPPROTO_IPV6, IPV6_V6ONLY, &off,
173                             sizeof(off));
174         }
175 #endif
176 
177         port_min = inet_getport(e);
178         port_max = to ? to + port_offset : port_min;
179         for (p = port_min; p <= port_max; p++) {
180             inet_setport(e, p);
181             if (bind(slisten, e->ai_addr, e->ai_addrlen) == 0) {
182                 goto listen;
183             }
184             if (p == port_max) {
185                 if (!e->ai_next) {
186                     error_setg_errno(errp, errno, "Failed to bind socket");
187                 }
188             }
189         }
190         closesocket(slisten);
191     }
192     freeaddrinfo(res);
193     return -1;
194 
195 listen:
196     if (listen(slisten,1) != 0) {
197         error_setg_errno(errp, errno, "Failed to listen on socket");
198         closesocket(slisten);
199         freeaddrinfo(res);
200         return -1;
201     }
202     snprintf(uport, sizeof(uport), "%d", inet_getport(e) - port_offset);
203     qemu_opt_set(opts, "host", uaddr);
204     qemu_opt_set(opts, "port", uport);
205     qemu_opt_set(opts, "ipv6", (e->ai_family == PF_INET6) ? "on" : "off");
206     qemu_opt_set(opts, "ipv4", (e->ai_family != PF_INET6) ? "on" : "off");
207     freeaddrinfo(res);
208     return slisten;
209 }
210 
211 #ifdef _WIN32
212 #define QEMU_SOCKET_RC_INPROGRESS(rc) \
213     ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY)
214 #else
215 #define QEMU_SOCKET_RC_INPROGRESS(rc) \
216     ((rc) == -EINPROGRESS)
217 #endif
218 
219 /* Struct to store connect state for non blocking connect */
220 typedef struct ConnectState {
221     int fd;
222     struct addrinfo *addr_list;
223     struct addrinfo *current_addr;
224     NonBlockingConnectHandler *callback;
225     void *opaque;
226 } ConnectState;
227 
228 static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
229                              ConnectState *connect_state, Error **errp);
230 
231 static void wait_for_connect(void *opaque)
232 {
233     ConnectState *s = opaque;
234     int val = 0, rc = 0;
235     socklen_t valsize = sizeof(val);
236     bool in_progress;
237     Error *err = NULL;
238 
239     qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
240 
241     do {
242         rc = qemu_getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &val, &valsize);
243     } while (rc == -1 && socket_error() == EINTR);
244 
245     /* update rc to contain error */
246     if (!rc && val) {
247         rc = -1;
248         errno = val;
249     }
250 
251     /* connect error */
252     if (rc < 0) {
253         error_setg_errno(&err, errno, "Error connecting to socket");
254         closesocket(s->fd);
255         s->fd = rc;
256     }
257 
258     /* try to connect to the next address on the list */
259     if (s->current_addr) {
260         while (s->current_addr->ai_next != NULL && s->fd < 0) {
261             s->current_addr = s->current_addr->ai_next;
262             s->fd = inet_connect_addr(s->current_addr, &in_progress, s, NULL);
263             if (s->fd < 0) {
264                 error_free(err);
265                 err = NULL;
266                 error_setg_errno(&err, errno, "Unable to start socket connect");
267             }
268             /* connect in progress */
269             if (in_progress) {
270                 goto out;
271             }
272         }
273 
274         freeaddrinfo(s->addr_list);
275     }
276 
277     if (s->callback) {
278         s->callback(s->fd, err, s->opaque);
279     }
280     g_free(s);
281 out:
282     error_free(err);
283 }
284 
285 static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
286                              ConnectState *connect_state, Error **errp)
287 {
288     int sock, rc;
289 
290     *in_progress = false;
291 
292     sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
293     if (sock < 0) {
294         error_setg_errno(errp, errno, "Failed to create socket");
295         return -1;
296     }
297     socket_set_fast_reuse(sock);
298     if (connect_state != NULL) {
299         qemu_set_nonblock(sock);
300     }
301     /* connect to peer */
302     do {
303         rc = 0;
304         if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) {
305             rc = -socket_error();
306         }
307     } while (rc == -EINTR);
308 
309     if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
310         connect_state->fd = sock;
311         qemu_set_fd_handler2(sock, NULL, NULL, wait_for_connect,
312                              connect_state);
313         *in_progress = true;
314     } else if (rc < 0) {
315         error_setg_errno(errp, errno, "Failed to connect socket");
316         closesocket(sock);
317         return -1;
318     }
319     return sock;
320 }
321 
322 static struct addrinfo *inet_parse_connect_opts(QemuOpts *opts, Error **errp)
323 {
324     struct addrinfo ai, *res;
325     int rc;
326     const char *addr;
327     const char *port;
328 
329     memset(&ai, 0, sizeof(ai));
330 
331     ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
332     ai.ai_family = PF_UNSPEC;
333     ai.ai_socktype = SOCK_STREAM;
334 
335     addr = qemu_opt_get(opts, "host");
336     port = qemu_opt_get(opts, "port");
337     if (addr == NULL || port == NULL) {
338         error_setg(errp, "host and/or port not specified");
339         return NULL;
340     }
341 
342     if (qemu_opt_get_bool(opts, "ipv4", 0)) {
343         ai.ai_family = PF_INET;
344     }
345     if (qemu_opt_get_bool(opts, "ipv6", 0)) {
346         ai.ai_family = PF_INET6;
347     }
348 
349     /* lookup */
350     rc = getaddrinfo(addr, port, &ai, &res);
351     if (rc != 0) {
352         error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
353                    gai_strerror(rc));
354         return NULL;
355     }
356     return res;
357 }
358 
359 /**
360  * Create a socket and connect it to an address.
361  *
362  * @opts: QEMU options, recognized parameters strings "host" and "port",
363  *        bools "ipv4" and "ipv6".
364  * @errp: set on error
365  * @callback: callback function for non-blocking connect
366  * @opaque: opaque for callback function
367  *
368  * Returns: -1 on error, file descriptor on success.
369  *
370  * If @callback is non-null, the connect is non-blocking.  If this
371  * function succeeds, callback will be called when the connection
372  * completes, with the file descriptor on success, or -1 on error.
373  */
374 int inet_connect_opts(QemuOpts *opts, Error **errp,
375                       NonBlockingConnectHandler *callback, void *opaque)
376 {
377     Error *local_err = NULL;
378     struct addrinfo *res, *e;
379     int sock = -1;
380     bool in_progress;
381     ConnectState *connect_state = NULL;
382 
383     res = inet_parse_connect_opts(opts, errp);
384     if (!res) {
385         return -1;
386     }
387 
388     if (callback != NULL) {
389         connect_state = g_malloc0(sizeof(*connect_state));
390         connect_state->addr_list = res;
391         connect_state->callback = callback;
392         connect_state->opaque = opaque;
393     }
394 
395     for (e = res; e != NULL; e = e->ai_next) {
396         error_free(local_err);
397         local_err = NULL;
398         if (connect_state != NULL) {
399             connect_state->current_addr = e;
400         }
401         sock = inet_connect_addr(e, &in_progress, connect_state, &local_err);
402         if (sock >= 0) {
403             break;
404         }
405     }
406 
407     if (sock < 0) {
408         error_propagate(errp, local_err);
409     } else if (in_progress) {
410         /* wait_for_connect() will do the rest */
411         return sock;
412     } else {
413         if (callback) {
414             callback(sock, NULL, opaque);
415         }
416     }
417     g_free(connect_state);
418     freeaddrinfo(res);
419     return sock;
420 }
421 
422 int inet_dgram_opts(QemuOpts *opts, Error **errp)
423 {
424     struct addrinfo ai, *peer = NULL, *local = NULL;
425     const char *addr;
426     const char *port;
427     int sock = -1, rc;
428 
429     /* lookup peer addr */
430     memset(&ai,0, sizeof(ai));
431     ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
432     ai.ai_family = PF_UNSPEC;
433     ai.ai_socktype = SOCK_DGRAM;
434 
435     addr = qemu_opt_get(opts, "host");
436     port = qemu_opt_get(opts, "port");
437     if (addr == NULL || strlen(addr) == 0) {
438         addr = "localhost";
439     }
440     if (port == NULL || strlen(port) == 0) {
441         error_setg(errp, "remote port not specified");
442         return -1;
443     }
444 
445     if (qemu_opt_get_bool(opts, "ipv4", 0))
446         ai.ai_family = PF_INET;
447     if (qemu_opt_get_bool(opts, "ipv6", 0))
448         ai.ai_family = PF_INET6;
449 
450     if (0 != (rc = getaddrinfo(addr, port, &ai, &peer))) {
451         error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
452                    gai_strerror(rc));
453 	return -1;
454     }
455 
456     /* lookup local addr */
457     memset(&ai,0, sizeof(ai));
458     ai.ai_flags = AI_PASSIVE;
459     ai.ai_family = peer->ai_family;
460     ai.ai_socktype = SOCK_DGRAM;
461 
462     addr = qemu_opt_get(opts, "localaddr");
463     port = qemu_opt_get(opts, "localport");
464     if (addr == NULL || strlen(addr) == 0) {
465         addr = NULL;
466     }
467     if (!port || strlen(port) == 0)
468         port = "0";
469 
470     if (0 != (rc = getaddrinfo(addr, port, &ai, &local))) {
471         error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
472                    gai_strerror(rc));
473         goto err;
474     }
475 
476     /* create socket */
477     sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol);
478     if (sock < 0) {
479         error_setg_errno(errp, errno, "Failed to create socket");
480         goto err;
481     }
482     socket_set_fast_reuse(sock);
483 
484     /* bind socket */
485     if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {
486         error_setg_errno(errp, errno, "Failed to bind socket");
487         goto err;
488     }
489 
490     /* connect to peer */
491     if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) {
492         error_setg_errno(errp, errno, "Failed to connect socket");
493         goto err;
494     }
495 
496     freeaddrinfo(local);
497     freeaddrinfo(peer);
498     return sock;
499 
500 err:
501     if (-1 != sock)
502         closesocket(sock);
503     if (local)
504         freeaddrinfo(local);
505     if (peer)
506         freeaddrinfo(peer);
507     return -1;
508 }
509 
510 /* compatibility wrapper */
511 InetSocketAddress *inet_parse(const char *str, Error **errp)
512 {
513     InetSocketAddress *addr;
514     const char *optstr, *h;
515     char host[64];
516     char port[33];
517     int to;
518     int pos;
519 
520     addr = g_new0(InetSocketAddress, 1);
521 
522     /* parse address */
523     if (str[0] == ':') {
524         /* no host given */
525         host[0] = '\0';
526         if (1 != sscanf(str, ":%32[^,]%n", port, &pos)) {
527             error_setg(errp, "error parsing port in address '%s'", str);
528             goto fail;
529         }
530     } else if (str[0] == '[') {
531         /* IPv6 addr */
532         if (2 != sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos)) {
533             error_setg(errp, "error parsing IPv6 address '%s'", str);
534             goto fail;
535         }
536         addr->ipv6 = addr->has_ipv6 = true;
537     } else {
538         /* hostname or IPv4 addr */
539         if (2 != sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos)) {
540             error_setg(errp, "error parsing address '%s'", str);
541             goto fail;
542         }
543         if (host[strspn(host, "0123456789.")] == '\0') {
544             addr->ipv4 = addr->has_ipv4 = true;
545         }
546     }
547 
548     addr->host = g_strdup(host);
549     addr->port = g_strdup(port);
550 
551     /* parse options */
552     optstr = str + pos;
553     h = strstr(optstr, ",to=");
554     if (h) {
555         h += 4;
556         if (sscanf(h, "%d%n", &to, &pos) != 1 ||
557             (h[pos] != '\0' && h[pos] != ',')) {
558             error_setg(errp, "error parsing to= argument");
559             goto fail;
560         }
561         addr->has_to = true;
562         addr->to = to;
563     }
564     if (strstr(optstr, ",ipv4")) {
565         addr->ipv4 = addr->has_ipv4 = true;
566     }
567     if (strstr(optstr, ",ipv6")) {
568         addr->ipv6 = addr->has_ipv6 = true;
569     }
570     return addr;
571 
572 fail:
573     qapi_free_InetSocketAddress(addr);
574     return NULL;
575 }
576 
577 static void inet_addr_to_opts(QemuOpts *opts, const InetSocketAddress *addr)
578 {
579     bool ipv4 = addr->ipv4 || !addr->has_ipv4;
580     bool ipv6 = addr->ipv6 || !addr->has_ipv6;
581 
582     if (!ipv4 || !ipv6) {
583         qemu_opt_set_bool(opts, "ipv4", ipv4);
584         qemu_opt_set_bool(opts, "ipv6", ipv6);
585     }
586     if (addr->has_to) {
587         char to[20];
588         snprintf(to, sizeof(to), "%d", addr->to);
589         qemu_opt_set(opts, "to", to);
590     }
591     qemu_opt_set(opts, "host", addr->host);
592     qemu_opt_set(opts, "port", addr->port);
593 }
594 
595 int inet_listen(const char *str, char *ostr, int olen,
596                 int socktype, int port_offset, Error **errp)
597 {
598     QemuOpts *opts;
599     char *optstr;
600     int sock = -1;
601     InetSocketAddress *addr;
602 
603     addr = inet_parse(str, errp);
604     if (addr != NULL) {
605         opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
606         inet_addr_to_opts(opts, addr);
607         qapi_free_InetSocketAddress(addr);
608         sock = inet_listen_opts(opts, port_offset, errp);
609         if (sock != -1 && ostr) {
610             optstr = strchr(str, ',');
611             if (qemu_opt_get_bool(opts, "ipv6", 0)) {
612                 snprintf(ostr, olen, "[%s]:%s%s",
613                          qemu_opt_get(opts, "host"),
614                          qemu_opt_get(opts, "port"),
615                          optstr ? optstr : "");
616             } else {
617                 snprintf(ostr, olen, "%s:%s%s",
618                          qemu_opt_get(opts, "host"),
619                          qemu_opt_get(opts, "port"),
620                          optstr ? optstr : "");
621             }
622         }
623         qemu_opts_del(opts);
624     }
625     return sock;
626 }
627 
628 /**
629  * Create a blocking socket and connect it to an address.
630  *
631  * @str: address string
632  * @errp: set in case of an error
633  *
634  * Returns -1 in case of error, file descriptor on success
635  **/
636 int inet_connect(const char *str, Error **errp)
637 {
638     QemuOpts *opts;
639     int sock = -1;
640     InetSocketAddress *addr;
641 
642     addr = inet_parse(str, errp);
643     if (addr != NULL) {
644         opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
645         inet_addr_to_opts(opts, addr);
646         qapi_free_InetSocketAddress(addr);
647         sock = inet_connect_opts(opts, errp, NULL, NULL);
648         qemu_opts_del(opts);
649     }
650     return sock;
651 }
652 
653 /**
654  * Create a non-blocking socket and connect it to an address.
655  * Calls the callback function with fd in case of success or -1 in case of
656  * error.
657  *
658  * @str: address string
659  * @callback: callback function that is called when connect completes,
660  *            cannot be NULL.
661  * @opaque: opaque for callback function
662  * @errp: set in case of an error
663  *
664  * Returns: -1 on immediate error, file descriptor on success.
665  **/
666 int inet_nonblocking_connect(const char *str,
667                              NonBlockingConnectHandler *callback,
668                              void *opaque, Error **errp)
669 {
670     QemuOpts *opts;
671     int sock = -1;
672     InetSocketAddress *addr;
673 
674     g_assert(callback != NULL);
675 
676     addr = inet_parse(str, errp);
677     if (addr != NULL) {
678         opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
679         inet_addr_to_opts(opts, addr);
680         qapi_free_InetSocketAddress(addr);
681         sock = inet_connect_opts(opts, errp, callback, opaque);
682         qemu_opts_del(opts);
683     }
684     return sock;
685 }
686 
687 #ifndef _WIN32
688 
689 int unix_listen_opts(QemuOpts *opts, Error **errp)
690 {
691     struct sockaddr_un un;
692     const char *path = qemu_opt_get(opts, "path");
693     int sock, fd;
694 
695     sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
696     if (sock < 0) {
697         error_setg_errno(errp, errno, "Failed to create socket");
698         return -1;
699     }
700 
701     memset(&un, 0, sizeof(un));
702     un.sun_family = AF_UNIX;
703     if (path && strlen(path)) {
704         snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
705     } else {
706         char *tmpdir = getenv("TMPDIR");
707         snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX",
708                  tmpdir ? tmpdir : "/tmp");
709         /*
710          * This dummy fd usage silences the mktemp() unsecure warning.
711          * Using mkstemp() doesn't make things more secure here
712          * though.  bind() complains about existing files, so we have
713          * to unlink first and thus re-open the race window.  The
714          * worst case possible is bind() failing, i.e. a DoS attack.
715          */
716         fd = mkstemp(un.sun_path); close(fd);
717         qemu_opt_set(opts, "path", un.sun_path);
718     }
719 
720     unlink(un.sun_path);
721     if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
722         error_setg_errno(errp, errno, "Failed to bind socket");
723         goto err;
724     }
725     if (listen(sock, 1) < 0) {
726         error_setg_errno(errp, errno, "Failed to listen on socket");
727         goto err;
728     }
729 
730     return sock;
731 
732 err:
733     closesocket(sock);
734     return -1;
735 }
736 
737 int unix_connect_opts(QemuOpts *opts, Error **errp,
738                       NonBlockingConnectHandler *callback, void *opaque)
739 {
740     struct sockaddr_un un;
741     const char *path = qemu_opt_get(opts, "path");
742     ConnectState *connect_state = NULL;
743     int sock, rc;
744 
745     if (path == NULL) {
746         error_setg(errp, "unix connect: no path specified");
747         return -1;
748     }
749 
750     sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
751     if (sock < 0) {
752         error_setg_errno(errp, errno, "Failed to create socket");
753         return -1;
754     }
755     if (callback != NULL) {
756         connect_state = g_malloc0(sizeof(*connect_state));
757         connect_state->callback = callback;
758         connect_state->opaque = opaque;
759         qemu_set_nonblock(sock);
760     }
761 
762     memset(&un, 0, sizeof(un));
763     un.sun_family = AF_UNIX;
764     snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
765 
766     /* connect to peer */
767     do {
768         rc = 0;
769         if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) {
770             rc = -socket_error();
771         }
772     } while (rc == -EINTR);
773 
774     if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
775         connect_state->fd = sock;
776         qemu_set_fd_handler2(sock, NULL, NULL, wait_for_connect,
777                              connect_state);
778         return sock;
779     } else if (rc >= 0) {
780         /* non blocking socket immediate success, call callback */
781         if (callback != NULL) {
782             callback(sock, NULL, opaque);
783         }
784     }
785 
786     if (rc < 0) {
787         error_setg_errno(errp, -rc, "Failed to connect socket");
788         close(sock);
789         sock = -1;
790     }
791 
792     g_free(connect_state);
793     return sock;
794 }
795 
796 #else
797 
798 int unix_listen_opts(QemuOpts *opts, Error **errp)
799 {
800     error_setg(errp, "unix sockets are not available on windows");
801     errno = ENOTSUP;
802     return -1;
803 }
804 
805 int unix_connect_opts(QemuOpts *opts, Error **errp,
806                       NonBlockingConnectHandler *callback, void *opaque)
807 {
808     error_setg(errp, "unix sockets are not available on windows");
809     errno = ENOTSUP;
810     return -1;
811 }
812 #endif
813 
814 /* compatibility wrapper */
815 int unix_listen(const char *str, char *ostr, int olen, Error **errp)
816 {
817     QemuOpts *opts;
818     char *path, *optstr;
819     int sock, len;
820 
821     opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
822 
823     optstr = strchr(str, ',');
824     if (optstr) {
825         len = optstr - str;
826         if (len) {
827             path = g_malloc(len+1);
828             snprintf(path, len+1, "%.*s", len, str);
829             qemu_opt_set(opts, "path", path);
830             g_free(path);
831         }
832     } else {
833         qemu_opt_set(opts, "path", str);
834     }
835 
836     sock = unix_listen_opts(opts, errp);
837 
838     if (sock != -1 && ostr)
839         snprintf(ostr, olen, "%s%s", qemu_opt_get(opts, "path"), optstr ? optstr : "");
840     qemu_opts_del(opts);
841     return sock;
842 }
843 
844 int unix_connect(const char *path, Error **errp)
845 {
846     QemuOpts *opts;
847     int sock;
848 
849     opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
850     qemu_opt_set(opts, "path", path);
851     sock = unix_connect_opts(opts, errp, NULL, NULL);
852     qemu_opts_del(opts);
853     return sock;
854 }
855 
856 
857 int unix_nonblocking_connect(const char *path,
858                              NonBlockingConnectHandler *callback,
859                              void *opaque, Error **errp)
860 {
861     QemuOpts *opts;
862     int sock = -1;
863 
864     g_assert(callback != NULL);
865 
866     opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
867     qemu_opt_set(opts, "path", path);
868     sock = unix_connect_opts(opts, errp, callback, opaque);
869     qemu_opts_del(opts);
870     return sock;
871 }
872 
873 SocketAddress *socket_parse(const char *str, Error **errp)
874 {
875     SocketAddress *addr;
876 
877     addr = g_new0(SocketAddress, 1);
878     if (strstart(str, "unix:", NULL)) {
879         if (str[5] == '\0') {
880             error_setg(errp, "invalid Unix socket address");
881             goto fail;
882         } else {
883             addr->kind = SOCKET_ADDRESS_KIND_UNIX;
884             addr->q_unix = g_new(UnixSocketAddress, 1);
885             addr->q_unix->path = g_strdup(str + 5);
886         }
887     } else if (strstart(str, "fd:", NULL)) {
888         if (str[3] == '\0') {
889             error_setg(errp, "invalid file descriptor address");
890             goto fail;
891         } else {
892             addr->kind = SOCKET_ADDRESS_KIND_FD;
893             addr->fd = g_new(String, 1);
894             addr->fd->str = g_strdup(str + 3);
895         }
896     } else {
897         addr->kind = SOCKET_ADDRESS_KIND_INET;
898         addr->inet = inet_parse(str, errp);
899         if (addr->inet == NULL) {
900             goto fail;
901         }
902     }
903     return addr;
904 
905 fail:
906     qapi_free_SocketAddress(addr);
907     return NULL;
908 }
909 
910 int socket_connect(SocketAddress *addr, Error **errp,
911                    NonBlockingConnectHandler *callback, void *opaque)
912 {
913     QemuOpts *opts;
914     int fd;
915 
916     opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
917     switch (addr->kind) {
918     case SOCKET_ADDRESS_KIND_INET:
919         inet_addr_to_opts(opts, addr->inet);
920         fd = inet_connect_opts(opts, errp, callback, opaque);
921         break;
922 
923     case SOCKET_ADDRESS_KIND_UNIX:
924         qemu_opt_set(opts, "path", addr->q_unix->path);
925         fd = unix_connect_opts(opts, errp, callback, opaque);
926         break;
927 
928     case SOCKET_ADDRESS_KIND_FD:
929         fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
930         if (fd >= 0 && callback) {
931             qemu_set_nonblock(fd);
932             callback(fd, NULL, opaque);
933         }
934         break;
935 
936     default:
937         abort();
938     }
939     qemu_opts_del(opts);
940     return fd;
941 }
942 
943 int socket_listen(SocketAddress *addr, Error **errp)
944 {
945     QemuOpts *opts;
946     int fd;
947 
948     opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
949     switch (addr->kind) {
950     case SOCKET_ADDRESS_KIND_INET:
951         inet_addr_to_opts(opts, addr->inet);
952         fd = inet_listen_opts(opts, 0, errp);
953         break;
954 
955     case SOCKET_ADDRESS_KIND_UNIX:
956         qemu_opt_set(opts, "path", addr->q_unix->path);
957         fd = unix_listen_opts(opts, errp);
958         break;
959 
960     case SOCKET_ADDRESS_KIND_FD:
961         fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
962         break;
963 
964     default:
965         abort();
966     }
967     qemu_opts_del(opts);
968     return fd;
969 }
970 
971 int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
972 {
973     QemuOpts *opts;
974     int fd;
975 
976     opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
977     switch (remote->kind) {
978     case SOCKET_ADDRESS_KIND_INET:
979         inet_addr_to_opts(opts, remote->inet);
980         if (local) {
981             qemu_opt_set(opts, "localaddr", local->inet->host);
982             qemu_opt_set(opts, "localport", local->inet->port);
983         }
984         fd = inet_dgram_opts(opts, errp);
985         break;
986 
987     default:
988         error_setg(errp, "socket type unsupported for datagram");
989         fd = -1;
990     }
991     qemu_opts_del(opts);
992     return fd;
993 }
994